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.
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'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.
Which system would be the best to go ahead with for voting function and why? ;
Putting the votes separately inside a database table and calculating the average when it is needed
Having only one row for one product. When a new vote comes, getting that vote form database, calculate it again and update the record. for example, we have a vote record for product 1. Its vote is totally 326 inside database and 45 people have voted. then we receive a new vote which is 4 and for product 1. We take the record from database and then do the following function;
(326 + 4) / (45 + 1)
then save it to database again with total value of 330 and 46 as voted people.
I always go ahead with the first option but I wanna know what others are doing.
Well, it always depends on what you want to with the additional information about the votes.
If you want to know for example trends in voting (is the average going up or down) or you want to know it the votes are relatively old / new or what user has casted the vote (the 1-vote-per-person-check) etc. etc. etc. you want to store each vote in a separate table.
If all you care about is the end result the second option is way more efficient.
If you want to suppress that people can vote twice you will need the 1-row-per-vote approach anyway, so I recommend the first option.
The second option might be better performance-wise - but should that ever be a problem, it's easy to use a caching-mechanism.
There are lots of factors to consider. Are you needing to defend against someone attacking your application server and modifying the vote count? Are you concerned with people's votes being discoverable? Are you concerned about locking-related performance issues? All of those will affect the decision, and the answers to those vary wildly depending on the specific scenario.
i hope the term 'lookup table' is well chosen, what i mean is for example a rate table (lookup) with the following rates:
cheap: $15,-
Medium: $30,-
expensive: $45,-
we're at the situation that for a given entity (we call it 'fault', it is a malfunction of a device, airco, elevator, krane, toilet etc.) a constructor is hired to fix that device.
that constructor has these three (made up) rates: cheap, medium and expensive.
When the constructor fixes the fault, he enters the hours worked and the rate (when a senior has done the job, 'expensive', and when a junior has done the job, 'cheap')
technically, we then add a FK from the Fault table to the Rates table.
So when the invoice has to be printed, we get the rate via the FK and the hours worked from the fault record.
Problem is that when the constructor changes his rates, and you recalculate an old invoice months later, other amounts are calculated for the invoice because the record has changed.
So we have to construct some kind of history, and that's the question: how is that done?
what i've come up with is 2 different situations, and the question is: is one of these a good one are there better ways?
1 add a valid-from and valid-until field at the rate table, so when you edit a value, you in fact create a new record with new valid dates. downside is you have to always get the rates with a specific date in mind, which for the current situation (the actual rate at this moment) is not neccessary.
2 don't put a FK from fault to rate, but when you set a rate at a fault, you just copy the VALUE from rate to fault. downside is that when the fault is still editable, when you edit the rate, the fault's rate is not updated. And, when you edit a fault, you get a dropdown box with 3 values to choose from, non of which are the same of the current values.
At this point thanks already for reading this entire post!
I don't like #2; I never like replacing relationships with actual values (denormalizing) if I can help it. Also, it makes auditing a lot harder; if there's a weird value in for the rate, where did it come from?
The problem with #1, though, is that if for some reason you change the date of the invoice, it should probably still have the same rate that it had when it was originally created.
For these reasons, I'd recommend doing the part of #1 where a rate change always created a new row, but then link from each fault to the rate that was actually applied (i.e. rather than relying on the date to join to a rate, actually store a rate id with the fault).
One approach to finding the current rate is just to look for the one that has no end date. Or alternately, don't use end dates at all (the start date of the next rate is treated as the end date of the previous rate), and just sort by date and take the last one.
There was a good discussion of this over on Programmers.SE
How to Store Prices That Have Effective Dates
It's a well-known problem and using effective dates is the best way to do it.
I'd suggest keeping a table of contractor rates, ordered by date. When a contractor's rates change, instead of changing the existing rate add a new entry. When you need to get the current rate, sort by the timestamp descending and limit 1. Add the date entry for the current rate entry to each job record and then you can perform a simple join to get all the information at once.
You make a gaming website where the user can buy gaming credits and the funds are deposited/credited into the user's virtual account to play some game etc...etc..
1
If you got an accountant to record the transaction, it would be recorded like this (maybe a bit more complex but you get the point)
TRANSACTION
PK_ID1 Cash - $10 (System)
PK_ID2 Deposit $10 (System)
TRANSACTION
PK_ID3 Bank Account - $10 (John)
PK_ID4 Deposit $10 (John)
2
As a developer, do you really need to waste 2 extra records? why not just record it like this…(then you might store information where the funds came from, status in other columns under the same deposit record)
TRANSACTION
PK_ID1 Cash - $10 (system)
PK_ID2 Deposit $10 (John)
Is there any real advantage of option #1 over option #2 and vice visa?
EDIT: modified question, removed CR, DR and replaced with a sign.
(Answering your question, but also responding some points raised in paxdiablo's answer.)
It is nothing to do with the accountant looking inside your database. With Double entry, errors are easy to trace; it is an Accounting and IRS requirement, so really, you do not have a choice, you need double entry for any system that deals with public funds.
(Please do not try to tell me what "double entry" is; I have written double entry systems for banks, to Audit requirements.) Double entry is an accounting method, based on a set of accounts. Every financial transaction is Journal Entry; if all the transactions were re-applied from the beginning, all the accounts would at their exact same balance as they are today.
Double Entry means every transaction has a "To" and a "From" account; money never leaves the system or enters the system. Every Credit has a Debit attached to it.
Therefore (1) is not the "double entry" version of (2), they cannot be readily compared. The double entry version of John's transaction is (one financial transaction), in logical accounting terms:
From: JohnAccount To: SystemAccount Amount: 10.00 (dollars)
That may well be two rows in a table, one a credit and the other a debit, the two inserts wrapped in an SQL Transaction.
That is it for the Accounting system, which is internal, and deals with money. We are done.
But you are additionally marrying the accounting system to a purchase/sale system (without having explicitly declared it). Of course for the ten bucks you took from John, you need to give him whatever he purchased for it, and record that. John bought ten bucks worth of gaming credits, if you are tracking that, then yes, you also need:
From: SystemGamingAccount To: JohnGamingAccount Amount: 100 (credits)
or,expressed in dollars:
From: SystemGamingAccount To: JohnGamingAccount Amount: 10.00 (dollars)
That, too, may well be two rows in a table, one a credit and the other a debit, the four inserts wrapped in an SQL Transaction.
To be clear, if you were selling widgets instead of gaming credits, the second (widget tracking) transaction would be:
From: Warehouse To: PublicSale Amount: 1 (widgets)
and since you are tracking Units in the warehouse but not how many widgets John Q Public has in his pocket, that is two inserts plus one update (UPDATE Part SET QtInStock = QtyInStock - 1 WHERE PartCode = "Widget"), all wrapped in a SQL transaction.
And there IS an Account for each user, right. Virtual, esoteric or physical, it is a Legal Entity, against which transactions are made. So let's not pretend it does not exist because it is virtual. For gaming, one dollar Account plus one gaming (credit) Account.
Credit/Debit
I would put the CR/DB back in; not CHAR (2), but boolean. It will help you later when the table is large,
WHERE IsCredit = 1
is much faster than
WHERE Amount >= 0.
Note that with ">=" you have to ensure that every code segment is coded the same way, not ">" sometimes. Boolean or char does not have that problem.
In terms of the data (which is what you're asking), no. You should store it as a signed value. Double-entry bookkeeping is not something the mob does so it can hide the real profits from the IRS :-)
It means transaction have to be balanced (value is never created or destroyed, just transformed). And it'll be a lot easier to balance transactions (and the books) if you just store them in one column with a sign.
In terms of visual presentation, some accountant may like them in separate columns but the vast majority will generate reports with the "negatives" simply indicated differently (such as surrounding them with parentheses).
It may well be that (like many other accounting things), the dual columns are carried forward from many moons ago. It would be easier to add up two columns then subtract the negative total from the positive total to get the current position (as opposed to adding and subtracting in a intermixed fashion). But that's supposition on my part.
See also here.