SMH*_*rus 15 sql sql-server parent-child cross-apply outer-apply
在下面的例子中,我试图根据每个酒吧位置的可用性来计算我可以制作的饮料数量.
进一步澄清,如下例所示:基于下图中突出显示的数字; 我知道我只能在6/30/2018制作1玛格丽塔(如果我将物资运到该地点,则在DC或FL中).
数据表的样本
请使用以下代码输入上面的相关数据:
CREATE TABLE #drinks
(
a_date DATE,
loc NVARCHAR(2),
parent NVARCHAR(20),
line_num INT,
child NVARCHAR(20),
avail_amt INT
);
INSERT INTO #drinks VALUES ('6/26/2018','CA','Long Island','1','Vodka','7');
INSERT INTO #drinks VALUES ('6/27/2018','CA','Long Island','2','Gin','5');
INSERT INTO #drinks VALUES ('6/28/2018','CA','Long Island','3','Rum','26');
INSERT INTO #drinks VALUES ('6/26/2018','DC','Long Island','1','Vodka','15');
INSERT INTO #drinks VALUES ('6/27/2018','DC','Long Island','2','Gin','18');
INSERT INTO #drinks VALUES ('6/28/2018','DC','Long Island','3','Rum','5');
INSERT INTO #drinks VALUES ('6/26/2018','FL','Long Island','1','Vodka','34');
INSERT INTO #drinks VALUES ('6/27/2018','FL','Long Island','2','Gin','14');
INSERT INTO #drinks VALUES ('6/28/2018','FL','Long Island','3','Rum','4');
INSERT INTO #drinks VALUES ('6/30/2018','DC','Margarita','1','Tequila','6');
INSERT INTO #drinks VALUES ('7/1/2018','DC','Margarita','2','Triple Sec','3');
INSERT INTO #drinks VALUES ('6/29/2018','FL','Margarita','1','Tequila','1');
INSERT INTO #drinks VALUES ('6/30/2018','FL','Margarita','2','Triple Sec','0');
INSERT INTO #drinks VALUES ('7/2/2018','CA','Cuba Libre','1','Rum','1');
INSERT INTO #drinks VALUES ('7/8/2018','CA','Cuba Libre','2','Coke','5');
INSERT INTO #drinks VALUES ('7/13/2018','CA','Cuba Libre','3','Lime','14');
INSERT INTO #drinks VALUES ('7/5/2018','DC','Cuba Libre','1','Rum','0');
INSERT INTO #drinks VALUES ('7/19/2018','DC','Cuba Libre','2','Coke','12');
INSERT INTO #drinks VALUES ('7/31/2018','DC','Cuba Libre','3','Lime','9');
INSERT INTO #drinks VALUES ('7/2/2018','FL','Cuba Libre','1','Rum','1');
INSERT INTO #drinks VALUES ('7/19/2018','FL','Cuba Libre','2','Coke','3');
INSERT INTO #drinks VALUES ('7/17/2018','FL','Cuba Libre','3','Lime','2');
INSERT INTO #drinks VALUES ('6/30/2018','DC','Long Island','3','Rum','4');
INSERT INTO #drinks VALUES ('7/7/2018','FL','Cosmopolitan','5','Triple Sec','7');
Run Code Online (Sandbox Code Playgroud)
预期结果如下:
请注意,如预期结果所示,儿童可以互换.例如,在7/7/2018 Triple Sec抵达国际大都会; 然而,因为孩子也是朗姆酒,它改变了玛格丽塔酒对佛罗里达州的供应.
也不是06/30和06/31对古巴自由区DC区域的更新.
请考虑到部件是可互换的,并且每次新物品到货时,它现在可以提供任何物品.
最后 - 如果我可以添加另一个显示套件可用性的列,而不管基于孩子的可用性的位置,那将是非常棒的.对于Ex.如果在DC中有一个孩子#3而在FL中没有孩子他们FL可以假设他们有足够的库存来根据另一个位置的库存来制作饮料!
我认为这会给出所需的结果。
创建了一个获取库存的函数。
Create function GetInventoryByDateAndLocation
(@date DATE, @Loc NVARCHAR(2))
RETURNS TABLE
AS
RETURN
(
Select child,avail_amt from
(Select a_date, child,avail_amt,
ROW_NUMBER() over (partition by child order by a_date desc) as ranking
from drinks where loc = @Loc and a_date<=@date)c
where ranking = 1
)
Run Code Online (Sandbox Code Playgroud)
然后查询:
with parentChild as
(Select distinct parent, line_num, child from drinks),
ParentChildNo as
(Select parent, max(line_num) as ChildNo from parentChild group by parent)
,Inventory as
(Select a_date,loc,s.* from drinks d cross apply
GetInventoryByDateAndLocation(d.a_date, d.loc)s)
, Available as
(Select a_date,parent,loc,count(*) as childAvailable,min(avail_amt) as quantity
from Inventory i
join parentChild c
on i.child = c.child
group by parent,loc,a_date)
Select a_date,a.parent,loc,quantity from available a
join ParentChildNo pc
on a.parent = pc.parent and a.childAvailable = pc.ChildNo
where quantity > 0 order by 1
Run Code Online (Sandbox Code Playgroud)
这将给出可以从库存中制作的所有饮料。希望它能解决您的问题。
这些只是我的2分钱。有更好的方法可以做到这一点,我希望更多的人能阅读本文并提出更好的建议。
| 归档时间: |
|
| 查看次数: |
310 次 |
| 最近记录: |