根据 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 项目来规范化结果,然后您可以将它们与连接关联。

一旦您确定了单独的 orderitem 记录,我们就可以轻松地使用聚合来定位它们,在本例中为简单的 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 获取自定义产品选择的主要内容,如果未能解决你的问题,请参考以下文章

SQL 选择结果:多表、自定义字段

根据 WooCommerce 中的自定义结帐单选按钮和文本字段设置动态费用

在Woocommerce中根据产品类别添加自定义结帐字段

在 Virtuemart 中获取产品自定义字段值

根据 Woocommerce 中的产品类别按项目自定义电子邮件通知

如何用jquery获取页面中的自定义标签