带条件的DB2/Sql分组

fsi0uk1n  于 2022-12-13  发布在  DB2
关注(0)|答案(2)|浏览(236)

我在DB2 I系列4上运行了一个非常简单的sql查询,它只是执行一些简单的连接。问题是,我的materials表有它,因此可以在每个工作体上使用多个材料/颜色组合。现在,我正在获取每个组合的行,但我希望合并,以便如果test.materials.sequence的值为2,则它会创建两个额外的列(如果存在“如果组合没有序列2,则在那些列中它将仅仅是0和0。
查询:

Select bod.code, mat.material, mat.mat_color, 
from test.skus sk
inner join test.Bodies bod on sk.body_id = bod.id
inner join test.categories prc on prc.id = sk.category_id
inner join test.skus_to_materials stm on sk.id = stm.sku_id
inner join test.materials mat on stm.mat_id = mat.id
order by prc.desc;

数据表:
库存单位

id  |  code  |  body_id  |  category_id  
------------------------------------------- 
1      12345     9912            3
2.     12346     9913            3

主体

id   |  code 
--------------------------
9912    1234-5
9913    1234-6

类别

id  |  category
------------------
3     Test

SKU_到_材料

id  |  sku_id  |  mat_id  |  sequence
--------------------------------------
1     1           221         1
2     1           222         2
3     2           223         1

物料

id  |  material  |  mat_color 
-------------------------------
221    Fabric       black     
222    Fabric       white     
223    Leather      brown

这是我目前的成果:

code  | material  | mat_color
-------------------------
1234-5 | Fabric    | black
1234-5 | Fabric    | white

这就是我想要的结果:

code | material1 | mat_color1 | material2 | mat_color2
----------------------------------------------------------
1234-5    Fabric        black      Fabric     white
1234-6    Leather       brown       0           0

请查看1234-6仅具有一个材质组合,因此material 2与mat_color2将为零。
有没有办法通过分组和行操作来实现这一点?
最新消息:
在回答Charles的问题时,我意识到在一个数据较多的案例中存在一些问题。在按材料、颜色和说明分组后,我意识到我得到了丢失的记录,但现在却出现了以下问题:

code   |   material1   |   color1   |  material2  |  color2
------------------------------------------------------------
1234-5      Fabric         White         0               0
1234-5      0               0          Leather         white 
1234-5      Leather         Brown        0               0
1234-5      Leather         Tan          0               0
1234-6      Fabric         Black         0               0 
1234-6      0              0           Leather         Black 
1234-7     Fabric         White          0               0
hgb9j2n6

hgb9j2n61#

我认为查尔斯的第一个答案更接近。以下是我得到的结果:

SELECT SK.ID SKU
      ,BOD.CODE 
      ,MAT.MATERIAL MATERIAL_1
      ,MAT.MAT_COLOR MATERIAL_2
      ,COALESCE(MAT2.MATERIAL, '0') MATERIAL_2
      ,COALESCE(MAT2.MAT_COLOR, '0') COLOR_2
FROM SKUS SK
 INNER JOIN BODIES BOD ON SK.BODY_ID = BOD.ID
 INNER JOIN CATEGORIES PRC ON PRC.ID = SK.CATEGORY_ID
 INNER JOIN SKUS_TO_MATERIALS STM ON SK.ID = STM.SKU_ID AND STM.SEQUENCE = 1
 INNER JOIN MATERIALS MAT ON STM.MAT_ID = MAT.ID
 LEFT JOIN SKUS_TO_MATERIALS STM2 ON SK.ID = STM2.SKU_ID AND STM2.SEQUENCE = 2
 LEFT JOIN MATERIALS MAT2 ON STM2.MAT_ID = MAT2.ID;

导致:
| 库存单位|代码|材料_1|材料_2|材料_2|颜色_2|
| - -|- -|- -|- -|- -|- -|
| 六个|主体D|织物|黑色|第0页|第0页|
| 四个|博分贝|织物|黑色|皮革|黑色|
| 三个|博德A|织物|黑色|第0页|第0页|
| 2个|博德A|织物|黑色|皮革|黑色|
| 一个|博德A|织物|黑色|第0页|第0页|
| 一个|博德A|织物|白色|第0页|第0页|
| 五个|主体C|皮革|棕褐色|第0页|第0页|
| 一个|博德A|皮革|棕褐色|第0页|第0页|
| 一个|博德A|皮革|黑色|第0页|第0页|
View on DB Fiddle

pkwftd7m

pkwftd7m2#

“行到列”称为“透视”数据。
Db2 for IBM i没有内置的方法来进行透视,但是,假设有一组不同的值,您可以对其进行硬编码。
像这样的东西应该做你想做的事:

Select bod.code, max(mat1.material), max(mat1.mat_color),
       max(mat2.material), max(mat2.mat_color) 
from test.skus sk
inner join test.Bodies bod on sk.body_id = bod.id
inner join test.categories prc on prc.id = sk.category_id
inner join test.skus_to_materials stm on sk.id = stm.sku_id
inner join test.materials mat1 on stm.mat_id = mat1.id
           and mat1.sequence = 1
left outer join test.materials mat2 on stm.mat_id = mat2.id
           and mat2.sequence = 2
group by bod.code
order by prc.desc;

EDIT好的,如果序列实际上在skus_to_materials中,那么你需要一个不同的连接集。实际上在这种情况下,我可能会使用基于CTE的语句。

with allrows as (
  Select bod.code, prc.desc, stm.sequence
         , mat.material, mat.mat_color, 
    from test.skus sk
     inner join test.Bodies bod on sk.body_id = bod.id
     inner join test.categories prc on prc.id = sk.category_id
     inner join test.skus_to_materials stm on sk.id = stm.sku_id
     inner join test.materials mat on stm.mat_id = mat.id
}
select 
  code
  , max(case when sequence = 1 then material else '0' end) as material1
  , max(case when sequence = 1 then color else '0' end) as color1
  , max(case when sequence = 2 then material else '0' end) as material2
  , max(case when sequence = 2 then color else '0' end) as color2
from allRows
group by code
order by desc;

相关问题