在SQL Server中,我有一个包含3个相关表的视图。 (材料,订单,订单明细)
每个“订单”包含几个“ OrderDetail”,每个“ OrderDetail”包含1个“ Material”。
Table Material
----------------------------
MaterialID MaterialName
1 egg
2 flour
3 butter
Table Order
----------------------------
OrderID Date
1 2019-1-01
2 2019-12-12
3 2019-6-06
Table OrderDetail
----------------------------
DetailID OrderID MaterialID Price Quantity Total
1 1 1 10 5 50
2 1 2 100 5 500
3 2 2 200 4 800
4 2 3 2000 4 8000
5 3 3 1000 3 3000
6 3 1 20 3 60
这是我创建的原始视图
View Original
----------------------------
MaterialID OrderID Date Price Total
1 1 2019-1-01 10 50
1 3 2019-6-06 20 60
2 1 2019-1-01 100 500
2 2 2019-12-12 200 800
3 2 2019-12-12 2000 8000
3 3 2019-6-06 1000 3000
现在,我希望它找到“最新价格”(与“最新日期”绑定)和“总和”(我在每种材料上花费的全部费用)
View Edit
----------------------------
MaterialID OrderID LatestDate LatestPrice Sum
1 3 2019-6-06 20 110
2 2 2019-12-12 200 1300
3 2 2019-12-12 2000 11100
我知道如何使用Max(Date)Max(Price)Sum(total)Group By分别过滤每个列,但是我仍然不熟悉Subquery,INNER join和其他技术。
谢谢您的时间。我已经尽力说明了这个问题,如果需要任何其他信息,请随时询问:)。
答案 0 :(得分:1)
这使用CROSS APPLY
回答了您的原始问题:
SELECT m.MaterialID, od.OrderID, od.Date, od.Price, od.Total
FROM Material m CROSS APPLY JOIN
(SELECT TOP (1) od.*, o.date
FROM OrderDetail od INNER JOIN
Orders o
ON od.OrderID = o.OrderID
WHERE m.MaterialID = od.MaterialID
ORDER BY o.Date DESC
) od
ORDER BY m.MaterialID;
这使用窗口函数回答了您的修订问题:
SELECT MaterialID, oOrderID, Date, Price, Total, sum_total
FROM (SELECT m.MaterialID, od.OrderID, o.Date,
od.Price, od.Total,
SUM(od.total) OVER (PARTITION BY m.MaterialId) as sum_total,
ROW_NUMBER() OVER (PARTITION BY m.MaterialId ORDER BY o.Date DESC) as seqnum
FROM Material m INNER JOIN
OrderDetail od
ON m.MaterialID = od.MaterialID INNER JOIN
Orders o
ON od.OrderID = o.OrderID
) mod
WHERE seqnum = 1
ORDER BY m.MaterialID;
答案 1 :(得分:1)
您可以通过CTE做到这一点:
WITH CTE AS (
SELECT
m.MaterialID, od.OrderID, o.Date,
od.Price, od.Total
FROM Material m
INNER JOIN OrderDetail od ON m.MaterialID = od.MaterialID
INNER JOIN [Order] o ON od.OrderID = o.OrderID
)
SELECT
c.MaterialID, c.OrderID, c.Date LatestDate,
c.Price LatestPrice, g.Sum
FROM CTE c INNER JOIN (
SELECT MaterialID, MAX(Date) maxdate, SUM(Total) Sum
FROM CTE
GROUP BY MaterialID
) g ON g.MaterialID = c.MaterialID AND g.maxdate = c.Date
ORDER BY c.MaterialID
请参见demo。
结果:
> MaterialID | OrderID | LatestDate | LatestPrice | Sum
> ---------: | ------: | :------------------ | ----------: | ---:
> 1 | 3 | 06/06/2019 00:00:00 | 20 | 110
> 2 | 2 | 12/12/2019 00:00:00 | 200 | 1300
> 3 | 2 | 12/12/2019 00:00:00 | 2000 |11000