计算库存水平 - SQL

时间:2017-02-08 09:03:34

标签: sql

以下是每日的库存水平。如果一周中没有记录,则表示当天库存为零。例如,在这种情况下,库存在第一周的第3天,第6天和第7天为零

Week |  Day of the Week | Product | Inventory
1   1   A   10
1   2   A   20
1   4   A   5
1   5   A   5
2   2   A   20
2   3   A   15
2   4   A   5
2   7   A   2

我正在寻找的输出在

之下
Week |  Product |   Inventory on first day of the week  | Inventory on last day of the week |   No of days product was available
1   A   10  0   4
2   A   0   2   4

我在采访中被问到这个问题,这就是我提出的问题。采访者告诉我,有更好的办法。所以。欢迎任何建议

WITH CTE_Inventory_Rank
     AS (SELECT Week,
                [Day of the Week],
                Product,
                Inventory,
                RANK() OVER(PARTITION BY WEEK ORDER BY [Day of the Week]) RankAsc,
                RANK() OVER(PARTITION BY WEEK ORDER BY [Day of the Week] DESC) RankDesc
         FROM Inventory),
     CTE_Inventory
     AS (SELECT WEEK,
                Product,
                COUNT(*) [No of days product was available]
         FROM Inventory
         GROUP BY WEEK,
                  PRODUCT)
     SELECT I.Week,
            I.Product,
            CASE
                WHEN first.[Day of the Week] = 1
                THEN first.Inventory
                ELSE 0
            END [Inventory on first day of the week],
            CASE
                WHEN last.[Day of the Week] = 7
                THEN last.Inventory
                ELSE 0
            END [Inventory on first day of the week],
            i.[No of days product was available]
     FROM CTE_INVENTORY I
          JOIN CTE_Inventory_Rank first ON I.week = first.week
                                           AND I.Product = first.Product
                                           AND first.RankAsc = 1
          JOIN CTE_Inventory_Rank last ON I.week = last.week
                                          AND I.Product = last.Product
                                          AND last.RankDesc = 1;

1 个答案:

答案 0 :(得分:1)

这真的取决于他的意思更好。更好的性能,更短,更漂亮?

postgres的实例: http://rextester.com/EMKQRJ98261

create table Inventory (week integer, dow integer, product varchar, inventory integer);

insert into Inventory (week, dow, product, inventory) VALUES
(1,1,'A',10),
(1,2,'A',20),
(1,4,'A',5),
(1,5,'A',5),
(2,2,'A',20),
(2,3,'A',15),
(2,4,'A',5),
(2,7,'A',2);


SELECT week,
       product,
       MAX(inv_first_dow) as "Inventory on first day of the week",
       MAX(inv_last_dow) as "Inventory on last day of the week",
       COUNT(*) as "No of days product was available"
FROM (
  SELECT week,
         product,
         CASE WHEN dow.dow = 1 THEN inventory ELSE 0 END AS inv_first_dow,
         CASE WHEN dow.dow = 7 THEN inventory ELSE 0 END AS inv_last_dow
  FROM unnest(array[1,2,3,4,5,6,7]) as dow
  JOIN Inventory ON Inventory.dow = dow.dow
) a
GROUP BY week, product
ORDER BY week

这是MS SQL服务器的版本:http://rextester.com/NQW89990

WITH unnest(dow) AS (SELECT 1 UNION ALL SELECT dow+1 FROM unnest WHERE dow < 7)
SELECT week,
       product, MAX(inv_first_dow) as "Inventory on first day of the week",
       MAX(inv_last_dow) as "Inventory on last day of the week",
       COUNT(*) as "No of days product was available"
FROM (
  SELECT week,
         product,
         CASE WHEN dow.dow = 1 THEN inventory ELSE 0 END AS inv_first_dow,
         CASE WHEN dow.dow = 7 THEN inventory ELSE 0 END AS inv_last_dow
  FROM unnest as dow
  JOIN Inventory ON Inventory.dow = dow.dow
) a
GROUP BY week, product
ORDER BY week