Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
Heinz23
Yak Posting Veteran
84 Posts |
Posted - 2008-07-13 : 19:02:27
|
Hi all,I have a user table and a quantity table. Each user orders some products. Now I want to display the top 3 buyers from the last 7 days. Mainly it's easy but my problem: A user might have 2 records within the last 7 days, one from friday and the other from tuesday. If both would be in the top 3 I only want to see it once (but NOT added together).Example (Username - Ordered units - Order date):User A - 400 units - 1. JanUser B - 350 units - 1. JanUser C - 200 units - 1. JanUser A - 500 units - 4. JanUser C - 250 units - 4. JanUser D - 300 units - 5. JanThe query on 5. Jan should return the following top 3:User A - 500 unitsUser B - 350 unitsUser D - 300 unitsSo orders of User A (400 + 500) and also User C (200 + 250) are NOT summed up so User C should not appear in the list even though he has ordered more units than e.g. User B (450 <-> 350).My current script:SELECT TOP 3 Users.UserID, Users.Username, Orders.OrderedUnits, Orders.OrderDateFROM Users INNER JOIN Orders ON Users.UserID = Orders.UserIDWHERE (DATEDIFF(day, Matches.MatchDate, GETDATE()) <= 7)ORDER BY Orders.OrderedUnits Unfortunately the script returns:User A - 500 unitsUser A - 400 unitsUser B - 350 unitsHow could I modify the script so user A is only used once? Many thanks! |
|
|
sodeep
Master Smack Fu Yak Hacker
7174 Posts |
Posted - 2008-07-13 : 19:33:22
|
May be this:quote: Originally posted by Heinz23 Hi all,I have a user table and a quantity table. Each user orders some products. Now I want to display the top 3 buyers from the last 7 days. Mainly it's easy but my problem: A user might have 2 records within the last 7 days, one from friday and the other from tuesday. If both would be in the top 3 I only want to see it once (but NOT added together).Example (Username - Ordered units - Order date):User A - 400 units - 1. JanUser B - 350 units - 1. JanUser C - 200 units - 1. JanUser A - 500 units - 4. JanUser C - 250 units - 4. JanUser D - 300 units - 5. JanThe query on 5. Jan should return the following top 3:User A - 500 unitsUser B - 350 unitsUser D - 300 unitsSo orders of User A (400 + 500) and also User C (200 + 250) are NOT summed up so User C should not appear in the list even though he has ordered more units than e.g. User B (450 <-> 350).My current script:SELECT TOP 3 Users.UserID, Users.Username, Max(Orders.OrderedUnits), Orders.OrderDateFROM Users INNER JOIN Orders ON Users.UserID = Orders.UserIDWHERE (DATEDIFF(day, Matches.MatchDate, GETDATE()) <= 7)Group by Users.UserID,Users.Username, Orders.OrderDateORDER BY Orders.OrderedUnits Unfortunately the script returns:User A - 500 unitsUser A - 400 unitsUser B - 350 unitsHow could I modify the script so user A is only used once? Many thanks!
|
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-07-14 : 00:46:11
|
| [code]SELECT t.Username,t.OrderedUnitsFROM(SELECT ROW_NUMBER() OVER(ORDER BY OrderedUnits DESC) AS Seq,ROW_NUMBER() OVER (PARTITION BY Username ORDER BY OrderedUnits DESC) AS USeq,*FROM YourTable) tWHERE t.USeq=1AND t.Seq<=3AND t.MatchDate> DATEADD(d,DATEDIFF(d,0,GETDATE()),-7)[/code] |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-07-14 : 03:34:14
|
[code]SELECT TOP 3 UserID, UserName, OrderedUnits, OrderDateFROM ( SELECT Users.UserID, Users.Username, Orders.OrderedUnits, Orders.OrderDate, ROW_NUMBER() OVER (PARTITION BY Users.UserID ORDER BY Orders.OrderedUnits DESC) AS RecID FROM Users INNER JOIN Orders ON Orders.UserID = Users.UserID WHERE Matches.MatchDate >= DATEDIFF(DAY, '19000107', GETDATE()) AND Matches.MatchDate < DATEDIFF(DAY, '19000101', GETDATE()) ) AS xWHERE RecID = 1ORDER BY OrderedUnits DESC[/code] E 12°55'05.25"N 56°04'39.16" |
 |
|
|
Heinz23
Yak Posting Veteran
84 Posts |
Posted - 2008-07-14 : 07:32:38
|
Hi sodeep,trying your proposal fails with an error that I could not use Orders.OrderedUnits "because it is not contained in either an aggregate function or the GROUP BY clause.". But when I add it to the Group by I have the same result as before.Hi Visakh16,seems that in your proposal the JOIN to the Matches-Table is missing (Matches.MatchDate contains the date of the order). I tried to add it on my own but then NO row is returned anymore?Hi Peso,your script only returns the rows from UserA?Hm, maybe I confused you all with the script I included. I've seen that I did not supply information that 'OrderID' should be used to combine both tables, sorry to you all !! Please let me re-describe my need:Table 'Orders' has 2 columns: OrderID, OrderDate.123 - 14.07.2008456 - 12.07.2008789 - 02.07.2008Table 'Units' has 3 columns: OrderID, CustomerName, OrderedUnits.123 - CustomerA - 300123 - CustomerB - 230123 - CustomerC - 350456 - CustomerB - 250456 - CustomerC - 350456 - CustomerD - 400789 - CustomerE - 800I want to get the 3 largest order positions from the last 7 days. When I today (14.07.) run the query I need a result set like this:CustomerD - 400CustomerC - 350CustomerA - 300Many thanks for your help!! |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-07-14 : 07:44:18
|
| [code]SELECT t.Username,t.OrderedUnitsFROM(SELECT ROW_NUMBER() OVER(ORDER BY OrderedUnits DESC) AS Seq,ROW_NUMBER() OVER (PARTITION BY Username ORDER BY OrderedUnits DESC) AS USeq,y.*,m.MatchDateFROM YourTable yINNER JOIN Matches mON m.Lonkcol=y.Linkcol) tWHERE t.USeq=1AND t.Seq<=3AND t.MatchDate> DATEADD(d,DATEDIFF(d,0,GETDATE()),-7)[/code] |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-07-14 : 07:58:53
|
This is produces exactly what you want.DECLARE @Orders TABLE (OrderID INT, OrderDate DATETIME)SET DATEFORMAT DMYINSERT @OrdersSELECT 123, '14.07.2008' UNION ALLSELECT 456, '12.07.2008' UNION ALLSELECT 789, '02.07.2008'DECLARE @Units TABLE (OrderID INT, CustomerName VARCHAR(20), OrderedUnits INT)INSERT @UnitsSELECT 123, 'CustomerA', 300 UNION ALLSELECT 123, 'CustomerB', 230 UNION ALLSELECT 123, 'CustomerC', 350 UNION ALLSELECT 456, 'CustomerB', 250 UNION ALLSELECT 456, 'CustomerC', 350 UNION ALLSELECT 456, 'CustomerD', 400 UNION ALLSELECT 789, 'CustomerE', 800SELECT TOP 3 CustomerName, OrderedUnits, OrderDate, OrderIDFROM ( SELECT u.CustomerName, u.OrderedUnits, o.OrderDate, o.OrderID, ROW_NUMBER() OVER (PARTITION BY u.CustomerName ORDER BY u.OrderedUnits DESC) AS RecID FROM @Units AS u INNER JOIN @Orders AS o ON o.OrderID = u.OrderID WHERE o.OrderDate >= DATEDIFF(DAY, '19000107', GETDATE()) AND o.OrderDate < DATEDIFF(DAY, '18991231', GETDATE()) ) AS xWHERE RecID = 1ORDER BY OrderedUnits DESC E 12°55'05.25"N 56°04'39.16" |
 |
|
|
Heinz23
Yak Posting Veteran
84 Posts |
Posted - 2008-07-14 : 09:30:35
|
Hi all,fascinating! I've now tried Pesos solution and this works very well Thanks to both of you for your excellent and fast support! |
 |
|
|
|
|
|
|
|