我需要为此选择各行的相关表的最大值和顺序。
请以下面的用户,表和购买表为例。购买表可识别每个用户购买的商品。
现在,我需要获取按购买价最高值排序的用户列表(如果出现并购,则按最低购买日期排序)。
执行此查询的最佳方法是什么?
用户:
CREATE TABLE [Users]
(
[UserID] [uniqueidentifier] NOT NULL,
[UserName] [nvarchar](50) NOT NULL,
[Country] [nvarchar](50) NOT NULL,
PRIMARY KEY CLUSTERED ([UserID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY= OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [Users] ([UserID], [userName], [Country])
VALUES
(1, 'John', 'France'), (2, 'Mary', 'Germany'), (3, 'Paco', 'Spain'),
(4, 'Fran', 'Italy'), (5, 'Smith', 'USA'), (6, 'Anna', 'Italy'),
(7, 'Cris', 'Belgium')
UserID | UserName | Country
-------+----------+-------------
1 | John | France
2 | Mary | Germany
3 | Paco | Spain
4 | Fran | Italy
5 | Smith | USA
6 | Anna | Italy
7 | Cris | Belgium
项目:
CREATE TABLE [Items]
(
[ItemID] [uniqueidentifier] NOT NULL,
[ItemName] [nvarchar](50) NOT NULL,
[Value] [int] NULL,
PRIMARY KEY CLUSTERED ([ItemID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [Items] ([ItemID], [ItemName], [Value])
VALUES
(1, 'Keyboard', 10), (2, 'Mouse', 5),
(3, 'Display', 40), (4, 'Laptop', 50), (5, 'Tablet', 50)
ItemID | ItemName | Value
-------+----------+-----
1 | Keyboard | 10
2 | Mouse | 5
3 | Display | 40
4 | Laptop | 50
5 | Tablet | 50
购买:
CREATE TABLE [Purchases]
(
[UserID] [uniqueidentifier] NULL,
[ItemID] [uniqueidentifier] NULL,
[PurchaseDate] [datetime] NULL,
CONSTRAINT [PK_Purchases]
PRIMARY KEY NONCLUSTERED ([UserID] ASC, [ItemID] ASC, [PurchaseDate] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [Purchases] ([UserID], [ItemID], [PurchaseDate])
VALUES (3, 4, '2019-01-05'), (1, 2, '2019-02-07'), (3, 5, '2019-01-03'),
(2, 5, '2019-01-02'), (4, 4, '2019-01-01'), (5, 1, '2019-03-05'),
(6, 2, '2019-02-15'), (7, 1, '2019-01-01'), (5, 3, '2019-01-07')
UserID | ItemID | PurchaseDate
-------+--------+--------------
3 | 4 | 2019-01-05
1 | 2 | 2019-02-07
3 | 5 | 2019-01-03
2 | 5 | 2019-01-02
4 | 4 | 2019-01-01
5 | 1 | 2019-03-05
6 | 2 | 2019-02-15
7 | 1 | 2019-01-01
5 | 3 | 2019-01-07
这是我需要的查询结果:
UserName | ItemName | Value | PurchaseDate
---------+----------+-------+-------------
Fran | Laptop | 50 | 2019-01-01
Mary | Tablet | 50 | 2019-01-02
Paco | Tablet | 50 | 2019-01-03
Smith | Display | 40 | 2019-01-07
Cris | Keyboard | 10 | 2019-01-01
John | Mouse | 5 | 2019-02-07
Anna | Mouse | 5 | 2019-02-15
这是我现在正在尝试的代码:
SELECT
T1.UserName, T1.ItemName, T1.Value, T1.PurchaseDate
FROM
(SELECT
ROW_NUMBER() OVER (PARTITION BY U.UserName ORDER BY I.value DESC, P.PurchaseDate ASC) AS rn,
P.PurchaseDate, U.UserName, I.value, I.ItemName
FROM
Purchases P
INNER JOIN
Items I ON P.ItemID = I.ItemID
INNER JOIN
Users U ON P.UserID = U.UserID) T1
WHERE
T1.rn = 1
ORDER BY
Value DESC, PurchaseDate ASC
答案 0 :(得分:0)
您可以使用窗口函数FIRST_VALUE
检索具有最高价值的购买商品的ItemId。然后将这些值重新添加到“购买”表中以获取日期(如果重复,我会选择最新的日期)。
;WITH userPurchase AS
(
SELECT DISTINCT u.userId, FIRST_VALUE(p.ItemId) OVER (PARTITION BY u.UserId ORDER BY i.Value DESC) as ItemId
FROM Users u
INNER JOIN Purchases p
ON u.UserId = p.UserId
INNER JOIN Items i
on p.ItemId = i.ItemId
)
,TopPurchases AS
(
SELECT p.UserId, p.ItemId, MAX(p.PurchaseDate) as PurchaseDate
FROM userPurchase u
INNER JOIN Purchases p
ON u.userId = p.UserId AND u.ItemId = p.ItemId
GROUP BY p.UserId, p.ItemId
)
SELECT u.UserName, i.ItemName, i.Value , t.PurchaseDate
FROM TopPurchases t
INNER JOIN Users u
ON u.userId = t.userId
INNER JOIN Items i
ON i.ItemId = t.ItemId
ORDER BY i.Value DESC, t.PurchaseDate