SQL:使用MAX()+ SUM()和3个相关表创建视图

时间:2019-06-15 10:25:39

标签: sql sql-server

在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和其他技术。

谢谢您的时间。我已经尽力说明了这个问题,如果需要任何其他信息,请随时询问:)。

2 个答案:

答案 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