我有两张桌子:"包"和"项目"。
" packages
"有以下列:pack_id | item_id
" items
"有以下列.......:item_id | type
一个包可以包含多个 商品。
更新:
样本数据和预期结果:
pack_id | item_id
1 1
1 2
1 3
2 2
2 1
3 4
3 5
3 6
item_id | type
1 C
2 F
3 Z
4 Z
5 Z
6 Z
预期结果:
pack_id | pack_type
1 Mixed
2 Cool
3 Not Cool
我的问题是:
有没有更好的方法来查询这两个表,以获得第三个表,具有列:" pack_id"和新专栏" pack_type"?这些UNION似乎为运行时间增加了大量时间。
SELECT pack_id, pack_type
FROM (
-- CASE 1 - pack_type is 'Cool' - type 'C' or 'F', but not 'Z'
SELECT Distinct q1.pack_id, 'Cool' AS pack_type
FROM (
SELECT Distinct p.pack_id, i.type
FROM packages p
INNER JOIN items i
ON p.item_id = i.item_id
WHERE i.type <> 'Z') q1
WHERE q1.type IN ('C','F')
UNION
-- CASE 2 - pack_type is 'Not-Cool' - type 'Z', but not 'C' or 'F'
SELECT Distinct q2.pack_id, 'Not-Cool' AS pack_type
FROM (
SELECT Distinct p.pack_id, i.type
FROM packages p
INNER JOIN items i
ON p.item_id = i.item_id
WHERE i.type = 'Z') q2
WHERE q2.type NOT IN ('C','F')
UNION
-- CASE 3 - pack_type is 'Mixed' - type 'Z' and ('C' or 'F')
SELECT Distinct q3.pack_id, 'Mixed' AS pack_type
FROM (
SELECT Distinct p.pack_id, i.type
FROM packages p
INNER JOIN items i
ON p.item_id = i.item_id
WHERE i.type = 'Z') q3
WHERE q3.type IN ('C','F')
) m
注意:多个注释的一些解释指向&#34; A类型不能是Z,也不能是C或F&#34;。
我也这么认为,但我理解查询行为的方式是,如果你说&#34;输入IN(&#39; C&#39;,&#39; F&#39;)&# 34;它将查看每个类型的项目&#39; C&#39;或者&#39; F&#39;并获取具有该项目的包ID。但是,包装类型为&#39; C&#39;或者&#39; F&#39;也可以有类型&#39; Z&#39;的项目,因此内部选择,处理类型&#39; Z&#39;第一
答案 0 :(得分:5)
也许我误解了一些东西,但这不是你真正想要的东西:
SELECT DISTINCT
pack_id,
pack_type = CASE WHEN i.type IN ('C','F') THEN 'Cool'
WHEN i.type IN ('Z') THEN 'Not-Cool'
ELSE 'Mixed' END
FROM packages p INNER JOIN items i ON p.item_id = i.item_id
有三种类型:酷或不酷,以及其他一切,你不需要过滤器(只是唯一的)。
答案 1 :(得分:1)
即使没有解释这个问题,我猜你的包类型是从它上面的项目组合中得出的。所以你需要对每个包装上的物品进行分组
<强> SQL DEMO 强>
WITH cte as (
SELECT pack_id,
COUNT(CASE WHEN i.type IN ('C','F') THEN 1 END) as total_CF,
COUNT(CASE WHEN i.type = 'Z' THEN 1 END) as total_Z
FROM packages p
INNER JOIN items i
ON p.item_id = i.item_id
GROUP BY pack_id
)
SELECT pack_id,
CASE WHEN total_CF > 0 and total_Z = 0 THEN 'Cool'
WHEN total_CF = 0 and total_Z > 0 THEN 'Not Cool'
WHEN total_CF > 0 and total_Z > 0 THEN 'Mixed'
-- ELSE 'NOT determinated'
END as type
FROM cte
<强>输出强>
答案 2 :(得分:0)
我认为你可以把它放在像这样的单一查询中
SELECT Distinct *
FROM (
SELECT p.pack_id,
CASE WHEN i.type <> 'Z' AND i.type IN ('C','F') THEN 'Cool'
WHEN i.type = 'Z' AND i.type NOT IN ('C','F') THEN 'Not-Cool'
WHEN i.type = 'Z' AND i.type IN ('C','F') THEN 'Mixed'
END AS pack_type
FROM packages p
INNER JOIN items i ON p.item_id = i.item_id
WHERE (i.type <> 'Z' AND i.type IN ('C','F'))
OR (i.type = 'Z' AND i.type NOT IN ('C','F'))
OR (i.type = 'Z' AND i.type IN ('C','F'))
) as temp
更新:仔细检查了您的逻辑后,我认为@Tim的回答是正确的