I'm building a market sell points system using C# winForms, SQL Server 2014
My problem is the idea of storing the products and quantities
the program should display the quantity of some product when making a new sell bill
so before user make a sell he should know the quantity of this product, and see if it enough for the order or not
i created this table for items
Item_ID, Item, Buy_Price, Sell_Price, Quantity
but this makes confusions when user edit some bills , sell bills or buy bills
so for example when user edit some buy bill(invoice), edit the quantity in the buy bill
then the product quantity cell in items table will not match the quantity in buybills table
so i want to make it little more dynamic and remove the quantity cell from items table
and using the bills table to get the quantity of any item
that means when user search for an item(Product) to sell, system uses a sum funcation buy sql statement
quantity = sum(item_quantity) in buy_bills - sum(item_quantity) in sell_bills
does it works? or this will be so heavey when databases size and records count get larger?
Problem here is not related to SUM function as such (it will sum up whatever you put in your query and rather quickly - in general) but with concept of detecting available quantities. Assuming that there is more than one selling point it will be impossible to get accurate available quantity of any product if you do not provide some form of concurrency control.
So, you may use sum from table where you have history of buy or sell of products. But, before you accept any change you need to put some lock to prevent other sellers to change (sell) same quantity. After you have committed one sell you may allow other sellers to continue with their activities assuring that you refresh currently presented items quantities.
Do have in mind that this scenario is one of the basic ones that may occur in any multiuser business application.
So, to conclude, do provide
One point in time where you are sure that existing stock cannot be lowered
SUM in the way you see fit for your application
Refresh any pending sale with new quantities
I want to make it little more dynamic and remove the quantity cell from items table and using the bills table to get the quantity of any item that means when user search for an item(Product) to sell, system uses a sum funcation buy sql statement quantity = sum(item_quantity) in buy_bills - sum(item_quantity) in sell_bills does it works?
Assuming you have your syntax correct, it is possible to sum a column using the sum function. You can subtract two sums in a single statement. Ie, SUM(Column_1) - SUM(Column2) AS Column3. This assumes that you have everything else set up correctly.
or this will be so heavey when databases size and records count get larger?
This is 100% relative to your database setup and not answerable here. It is possible that it will slow down when the database gets larger. But, if your database is set up correctly, it should not be by much.
It is also possible, later on, to get around that issue by pre-loading the data.
Related
I am building an app with a SQL Server database. I have a main table of products (tblProducts) with a column that holds the quantity in hand (quantity). Another table holds the orders (tblOrders) that come from the supplier.
When an order comes in, I add the order to my database (tblOrders) and then I edit tblProducts to add to the quantity column the new received product.
As far, everything is good.
My question: after let's say 1 year of many many orders, with a lot of edits in quantity, do you guys, periodically check all orders to check if the quantity in main table tblProducts is correct ? Or do I just assume that it is always correct?
What procedures do you use for updating this kind of database? Do you sum all orders every time when you need quantity in hand?
Thanks!
This is really up to how you want to implement it.
Trusting that the values will always check out (with adequate testing to ensure only stable code will see production) is the easiest and the fastest way, but might be vulnerable to data corruption, and thus, not that recommended.
Always summing up the orders is the safest way and correct way, but will become increasingly slower as the size of your tables grow. If this is not an issue for you, then this is the recommended option.
What I consider a good intermediate method is to have a separate tblProductLogs table which stores the stock of an item at a specific timestamp. You can sum the inventory at set periods (daily, hourly, up to you), and when you want to retrieve the current inventory stock you only need to sum the values that were registered after the last log entry for that item, saving you query time. This could be made more safe if update operations were disabled on the log table, since you won't need to modify the entries there. This is faster than the second option, and somewhat more stable than the first.
I have developed an eCommerce application in C# and ASP.Net. For the Admin users "dashboard" landing page, I would like to give them a GridView that shows them the total sales dollar amount for a couple different time ranges, these would be my columns (ie last day, last week, last month, last year, total ever). I would like to give these values for orders that are in different status' (ie complete, paid but not shipped, in progress). Something similar to this:
|OrderStatus|Today|LastWeek|LastMonth|
|Processed |$10 |$100 |$34000 |
|PaidNotShip|$4 |$12 |$45 |
My question: What is the best/most efficient way to do this? I know that I could write separate SQL statements and union them together and bind the gridview to a sqldatasource:
(select amountForYesterday, amountForLastWeek from sales where orderStatus = processed)
UNION
(select amountForYesterday, amountForLastWeek from sales where orderStatus = paidnotshipped)
But that seems like a pain and very inefficient, since I would effectively be writing a separate query for each value.
I could also do this in the .cs page behind on load and programmatically populate the grid view row by row.
This GridView would only show information for the user's specific organization, so it would have to filter based on that as well.
I'm kind of at a loss as to how to do this without writing a massive query and continually hitting that query and database each time the page is viewed.
Any ideas?
I prefer using LINQ to work with data and/or GridViews (accessing the rows etc.). Have a look at a project I have on GitHub, which does exactly what I am mentioning here, as example. Note that this is just a sandbox I used previously for illustration purposes.
GitHub Repo
https://github.com/pauloosthuysen/int
Other useful info:
http://www.codeproject.com/Articles/33685/Simple-GridView-Binding-using-LINQ-to-SQL
The Sales etc. for LastWeek and LastMonth does not change very often. You could store that in a static Dictionary indexed by organization or summarize it in a separate table for faster access. This way you will not need to select the same huge amount of rows to get the same numbers over and over again. Unless special demands I would stick to the Dictionary solution because it is simple but a combination could also be a good solution
There is no direct way of doing it.
However instead of hitting the DB to the sum of every columns, you can perform the stuff using you datatable which is used for binging to your grid.
All you need to do is use
Dim iSumSal As Integer
iSumSal = StudentTable.Compute("SUM(sal)", "")
similarly you can perform for other columns.
once this is done. then just add a new row to you data table with all the summed values in it.
And then you can bind it to your grid.
optional - you can put some text value in the first column of you new row as "Total:"
thanks
rahul
Should the user's Account balance be stored in the database or calculated dynamically?
For accurate results calculating it dynamically make sense but then it might be a problem, when there are many user's and the database grows very large?
Transaction
Id (PK)
AccountId
Type
DateTime
Amount
etc..etc...
AccountBalance
TransactionId (PK/FK)
BalanceAmount
In order to keep accurate auditing you should make record of every transaction that affects the users account balance. This means you can calculate the balance dynamically, however for performance reasons I would have the balance stored as well. To ensure the balance is correct though, I would have a daily job run that recalculates the balance from scratch.
You need to ask yourself a few questions:
1) Who will OWN the calculation?
2) Who will NEED the result?
Now if the owner of the calculation is the only one who will need it - or if anyone else who needs it will get it from the owner, then there is no need to store the calculation.
However, in most applications that actually run for a long time, the calculated result will probably end up being needed somewhere else. For instance, a reporting application like SQLReportingServices will need the result of the calculation, so if the owner of the calculation is a web application, you have a problem. How will reporting services (which talks to the database only) get the result?
Solution in that case - either store the calculation OR make the database the owner OF the calculation and have a sql function that returns the result.
Personally, I tend to go for the non-purist approach - I store calculated results in the database. Space is cheap, and response time is faster on a read than on a read+function call.
I think this is a good question. Calculating every time is obviously easy to do but would probably result in a lot of needless calculations with the resultant performance hit.
But storing the current balance in some other table can lead to the issues in data concurrency, where the data the builds the aggregate is modified out of sync with the aggregate.
Perhaps a happy medium is to have a sql trigger on the transaction table that updates the aggregate value on an insert or update for that user.
the current balance is already available!
it is the balance in the last transaction for the account:
select top 1 [Balance]
from dbo.Trans
where [AccountID] = #AccountID
order by [TranID] desc
the balance has to be calculated and stored as part of every transaction
otherwise the system won't scale ...
also if you don't store the balance you have no checks and balances (as in balance must equal previous balance plus new credits less new debits)
If your application is not retrieving data from database for balance calculation while you need the balance, I will suggest that you should calculate the balance or else store in database.
If you need updated balance frequently and it is dynamically change based on more than one table then you should have table view instead of trigger.
this is more of an architectural question more than a specific code problem as I've hit a major block in how I am going to proceed with this project.
I'm building a financial scanning software that filters stock picks on specific criteria, for example. For example if out of 8000 stocks, its closing price today is above the SMA 100 and 10 days ago the closing price is below the SMA 100, then return this stock Symbol back to me.
However, note that the SMA (Simple Moving Average) is calculated with the last 100 days of data in the above example, but it could be that we could change the 100 days for lets say another value, 105 or 56 - could be anything.
In my Database I have a table definition called EODData with a few columns, here is the definition below;
EODData
sSymbol nvarchar(6)
mOpen money
mClose money
mHigh money
mLow money
Date datetime
The table will hold 3 years of End Of Day Data for the American Stock Exchange so that is approximately 6,264,000 rows, no problem for MS SQL 2008 R2.
Now, I'm currently using Entity Framework to retrieve data from my database, however what would be the best way to run or create my filter because the SMA must be calculated for each Symbol or underlying Stock Ticker each time a scan is performed because the 100 day variable can change.
Should I convert from Entity Objects to a DataSet for in memory filtering etc???
I've not worked with DataSets or DataTables much so I am looking for pointers.
Note that the SMA is just one of the filters, I have another algorithm that calculates the EMA (Exponential Moving Average, which is a much more complicated formula) and MACD (Moving Average Convergence Divergence).
Any opinions?
What about putting the calculations in the database? You have your EODData table, which is great. Create another table that is your SummaryData, something like:
SummaryData
stockSymbol varchar(6) -- don't need nvarchar, since AMSE doesn't have characters outside of normal English alphabet.
SMA decimal
MCDA decimal
EMA decimal
Then you can write some stored procedures that run on close of day and update this one table based on the data in your EODData table. Or you could write a trigger so that each insert of the EODData table updates the summary data in your database.
One downside to this is that you're putting some business logic in the database. Another downside is that you will be updating statistical data on a stock symbol that you might not need to do. For example, if nobody ever wants to see what XYZZ did, then the calculation on it is pointless.
However, this second issue is mitigated by the fact that 1. you're running SPs on the server which MSSQL can optimize and 2. You can run these after hours when everyone is at home, so if it takes a little bit of time you're not affected. (To be honest, I'd assume if they're calculations like rolling averages, min/max etc, SQL won't be that slow.)
One upside is your queries should be wicked fast, because you could write
select stockSymbol from SummaryData where SMA > 10 you've already done the calculation.
Another upside is that the data will only change once per day (at the close of the business day) but you might be querying several times throughout the day. For example, you want to run several different queries today for all the data up to and including yesterday. If you run 10 queries, and your partner runs the same 10 queries, you've just done the same calculation over. (Essentially, write once, read many.)
I am trying to have a ratings strategy in the hotels search website.Ratings is based on number of clicks by the users who view different hotels.I am trying to assign number of points to each click.
Suppose i have a POINTS column in the hotels table which increases by the number of clicks on each hotel, the problem i face is suppose i have a hotel1 which was introduced in week1 then it gains considerable amount of points by week2 but if i introduce a new hotel2 at week2 although this new hotel is competetively increasing the points it cant reach easily the hotel1 becoz of there difference in weeks which they were introduced.
I thought a way to solve the above problem by introducing a DAYS column then i can divide the POINTS of each HOTEL by number of days so that i can have clear ratings to each hotel.
I need your help about how i get the number of each passing day in the DAYS column after new hotel is added in the table of database.
It would probably be better to have a CreateDate column, and then in client side code do something along the lines of:
int days = Date.Now.Subtract(hotel.CreateDate).Days;
This will cause less updates to your database too, as the date only needs to be set on create.
I'm not going to go into the statistical theory of what you're doing, but let me state for the record that I think your stats are going to be misleading.
Be that as it may, just to achieve what you say you want to achieve, I would do what #Andy just said you should do. (Beat me to it!)
As I understand it, you are asking people to "vote" on the hotels, but the only possible votes are "yes" and "no vote".
Whether this is statistically valid will depend on when people are asked to vote. If every time someone visits a hotel, you ask him whether he was satisfied with his stay, and people consistently do this, I suppose it would be generally valid. But if the scoring system is such that users do not perceive a need to re-vote on a hotel that they have already voted on, then hotels that are on the list longer will see their ratings tend to sink. If it reached a point where every user who had visited a hotel has voted (or not), and no one saw a need to vote again, then that hotels score would gradually sink.
Also, this system would be biased in favor of big hotels. If hotel A has 500 rooms and hotel B has 10 rooms, it would b e very tough for hotel B to ever get as many votes as hotel A.
I think you'd be better to ask people to rate the hotel on some scale -- 1 to 5 stars or whatever -- and then present the average score. Probably along with the number of ratings, as people can probably figure out that if there's only one rating and it's the highest possible, that might be the owner rating his own hotel.
An alternative to calculating the days in code would be to use a computed column in the database (assuming by the sql tag you meant sql server). As the other posters have said, add a CreateDate column for the hotel and then add a computed column to return the date diff.