根据 SQL 中的动态 ID 获取自定义产品选择
Posted
技术标签:
【中文标题】根据 SQL 中的动态 ID 获取自定义产品选择【英文标题】:Get custom product selection upon dynamic ID in SQL 【发布时间】:2021-10-28 10:55:27 【问题描述】:我有下面的表格结构,我想获得以下形式的结果:
首先,这是我的项目表输出:
orderID code action id level description Price solvedChoice
--------------------------------------------------------------------------
321 622 RECIPE 0 0 SPICM1 15.5 NULL
321 10 RECIPE 0 1 SPICKN 17 NULL
321 7091 RECIPE 0 1 RFRY 8.5 NULL
321 521 CHOICE 0 1 R-COKE 7.5 10000003
321 612 RECIPE 1 0 BIGTM1 20.5 NULL
321 13 RECIPE 1 1 BTASTY 21 NULL
321 7091 RECIPE 1 1 RFRY 8.5 NULL
321 522 CHOICE 1 1 R-FANT 7.5 10000003
321 608 RECIPE 2 0 ROYAL1 18.5 NULL
321 11 RECIPE 2 1 MCROYA 18 NULL
321 7091 RECIPE 2 1 RFRY 8.5 NULL
321 411 CHOICE 2 1 ARWA 7.5 10000003
321 612 RECIPE 3 0 BIGTM1 20.5 NULL
321 13 RECIPE 3 1 BTASTY 21 NULL
321 7091 RECIPE 3 1 RFRY 8.5 NULL
321 524 CHOICE 3 1 R-SPRT 7.5 10000003
我想在每顿饭下选择什么,例如 id = 0,代表一顿饭及其子级别(组件),我们可以看到做出的选择是 R-Coke,而对于 id =1,做出的选择是 R-FANT。
输出应该是这样的:
R-COKE R-FANT ARWA R-SPRT
--------------------------------------
SPICM1 1 0 0 0
BIGTM1 0 1 0 1
ROYAL1 0 0 1 0
【问题讨论】:
根据问题指南,请向我们展示您的尝试并解释您遇到的问题。 您正在寻找某种支点或案例陈述,花了 3 次阅读此内容,但我认为它就在那里。将有助于在结果中有一个计数列,BIGTM1
很难看出这个RECIPE
有两个订单
输出可能是这样的 - 可能是,或者应该是那样的??还有什么可能?
什么是饭菜?它是否以某种方式出现在您的数据中?
【参考方案1】:
对我来说,这看起来像是两个级别的聚合:
select col1,
sum(r_coke) as r_coke,
sum(r_fant) as r_fant,
sum(arwa) as arwa,
sum(r_sprt) as r_sprt
from (select max(case when level = 0 then description end) as col1,
sum(case when description = 'R-COKE' then 1 else 0 end) as r_coke,
sum(case when description = 'R-FANT' then 1 else 0 end) as r_fant,
sum(case when description = 'ARWA' then 1 else 0 end) as arwa,
sum(case when description = 'R-SPRT' then 1 else 0 end) as r_sprt
from t
group by id
) x
group by col1;
或者,也许更简单,使用窗口函数:
select col1,
sum(case when description = 'R-COKE' then 1 else 0 end) as r_coke,
sum(case when description = 'R-FANT' then 1 else 0 end) as r_fant,
sum(case when description = 'ARWA' then 1 else 0 end) as arwa,
sum(case when description = 'R-SPRT' then 1 else 0 end) as r_sprt
from (select t.*,
max(case when level = 0 then description end) over (partition by id) as col1
from t
) t
group by col1;
【讨论】:
【参考方案2】:只需遵循提供的输入和输出
select orderID, x, [R-COKE], [R-FANT], [ARWA], [R-SPRT]
from (
select orderID, id
, max(case when level = 0 then description end) x
, max(case when level = 1 and solvedChoice is not null then description end) y
from mytable
group by orderID, id
) t
pivot (count(id) for y in ([R-COKE], [R-FANT], [ARWA], [R-SPRT]) ) pvt;
【讨论】:
【参考方案3】:您可以将表连接到自身。像这样的
drop TABLE if exists #MyItemTable;
go
CREATE TABLE #MyItemTable
(
orderID INT,
code int,
action char(6),
id int,
level int,
description varchar(10),
price money,
solvedChoice int
)
INSERT INTO #MyItemTable (orderID, code, action, id , level, description, Price, solvedChoice)
VALUES
(321, 622 ,'RECIPE',0,0,'SPICM1',15.5 ,NULL)
,(321, 10 ,'RECIPE',0,1,'SPICKN',17 ,NULL )
,(321, 7091,'RECIPE',0,1,'RFRY ',8.5 ,NULL )
,(321, 521 ,'CHOICE',0,1,'R-COKE',7.5 ,10000003)
,(321, 612 ,'RECIPE',1,0,'BIGTM1',20.5 ,NULL )
,(321, 13 ,'RECIPE',1,1,'BTASTY',21 ,NULL )
,(321, 7091,'RECIPE',1,1,'RFRY ',8.5 ,NULL )
,(321, 522 ,'CHOICE',1,1,'R-FANT',7.5 ,10000003)
,(321, 608 ,'RECIPE',2,0,'ROYAL1',18.5 ,NULL )
,(321, 11 ,'RECIPE',2,1,'MCROYA',18 ,NULL )
,(321, 7091,'RECIPE',2,1,'RFRY ',8.5 ,NULL )
,(321, 411 ,'CHOICE',2,1,'ARWA ',7.5 ,10000003)
,(321, 612 ,'RECIPE',3,0,'BIGTM1',20.5 ,NULL )
,(321, 13 ,'RECIPE',3,1,'BTASTY',21 ,NULL )
,(321, 7091,'RECIPE',3,1,'RFRY ',8.5 ,NULL )
,(321, 524 ,'CHOICE',3,1,'R-SPRT',7.5 ,10000003);
select i.[description],
sum(case when i2.[description] = 'R-COKE' then 1 else 0 end) as r_coke,
sum(case when i2.[description] = 'R-FANT' then 1 else 0 end) as r_fant,
sum(case when i2.[description] = 'ARWA' then 1 else 0 end) as arwa,
sum(case when i2.[description] = 'R-SPRT' then 1 else 0 end) as r_sprt
from #MyItemTable i
left join #MyItemTable i2 on i.id=i2.id
and i2.[action]='CHOICE'
where i.[level]=0
group by i.[description];
description r_coke r_fant arwa r_sprt
BIGTM1 0 1 0 1
ROYAL1 0 0 1 0
SPICM1 1 0 0 0
【讨论】:
【参考方案4】:目的是为每种类型的订单获得1个结果,由level=0
表示,id
是订单标识符。
您需要首先通过分别查询订单和CHOICE
项目来规范化结果,然后您可以将它们与连接关联。
一旦您确定了单独的 order
和 item
记录,我们就可以轻松地使用聚合来定位它们,在本例中为简单的 COUNT
COUNT
在这种情况下效果很好,因为它将排除NULL
值。
SELECT [order].description
, COUNT(DISTINCT [order].id) as [Orders]
, COUNT(CASE WHEN item.description = 'R-COKE' THEN 1 END) as [R-COKE]
, COUNT(CASE WHEN item.description = 'R-FANT' THEN 1 END) as [R-FANT]
, COUNT(CASE WHEN item.description = 'ARWA' THEN 1 END) as [ARWA]
, COUNT(CASE WHEN item.description = 'R-SPRT' THEN 1 END) as [R-SPRT]
FROM tblOrders [order]
INNER JOIN tblOrders item ON item.id = [order].id AND item.level = 1
WHERE [order].level = 0
GROUP BY [order].description
在这个小提琴中尝试一下:http://sqlfiddle.com/#!18/81ec5/1
为了进一步突出分组,我列出了单独订单的数量,因为我们也在计算饮料。
【讨论】:
由于某种原因,我得到的值是 2 而不是 1,我仍在调试它以上是关于根据 SQL 中的动态 ID 获取自定义产品选择的主要内容,如果未能解决你的问题,请参考以下文章
根据 WooCommerce 中的自定义结帐单选按钮和文本字段设置动态费用