我有一个项目表。商品ID存储在ITEM
列中。所有项目都有不同的变体,名为"80"
,"85"
,"90"
,"95"
,"100"
,"105"
,"110"
,"115"
(也是现有列)。如果某个项目具有特殊类型的变体,则该列(由变体类型命名)将填充数字。
我想只选择那些至少有4个变种的项目(4个变量列填充数字)。
ITEM 80 85 90 95 100 105 110 115
A 1 1 3 <-- 3 variants
B 2 1 3 <-- 3 variants
C 1 3 <-- 2 variants
D 1 3 <-- 2 variants
E 1 1 1 1 <-- 4 variants
在此示例中,项目E 将是唯一选择的项目,因为它有4个变体。
create table itemtest (
item varchar2(30 char),
"80" integer,
"85" integer,
"90" integer,
"95" integer,
"100" integer,
"105" integer,
"110" integer,
"115" integer
);
insert into itemtest values ('A', 1, null, null, null, 1, null, null, 3);
insert into itemtest values ('B', 2, null, null, null, 1, null, null, 3);
insert into itemtest values ('C', null, null, null, 1, null, null, null, 3);
insert into itemtest values ('D', null, 1, null, null, null, null, null, 3);
insert into itemtest values ('E', 1, null, null, 1, null, null, 1, 1);
commit;
答案 0 :(得分:2)
避免输入繁琐的CASE
表达式。使用Oracle的低估NVL2()
功能!
select itemtest.*
from itemtest
where NVL2("80" , 1, 0) + NVL2("85" , 1, 0) +
NVL2("90" , 1, 0) + NVL2("95" , 1, 0) +
NVL2("100", 1, 0) + NVL2("105", 1, 0) +
NVL2("110", 1, 0) + NVL2("115", 1, 0) >= 4;
来自文档:
NVL2(expr1, expr2, expr3)
NVL2允许您根据指定的表达式是null还是非null来确定查询返回的值。如果expr1不为null,则NVL2返回expr2。如果expr1为null,则NVL2返回expr3。
我不知道为什么我之前没有想到它。实际上,为了对它们进行计数,您实际上是在对列进行非活动。方法如下:
SELECT item, COUNT(*)
FROM itemtest
UNPIVOT (
variants FOR code IN ("80", "85", "90", "95", "100", "105", "110", "115")
)
GROUP BY item
HAVING COUNT(*) >= 4
ORDER BY item
这将产生
ITEM COUNT(*)
--------------
E 4
如何运作?
这是一个简单的UNPIVOT
语句,没有分组和聚合:
SELECT *
FROM itemtest
UNPIVOT (
variants FOR code IN ("80", "85", "90", "95", "100", "105", "110", "115")
)
哪个收益......
ITEM CODE VARIANTS
--------------------
A 80 1
A 100 1
A 115 3
B 80 2
B 100 1
B 115 3
C 95 1
C 115 3
D 85 1
D 115 3
E 80 1
E 95 1
E 110 1
E 115 1
其余的(GROUP BY
和HAVING
)只是普通的SQL。
答案 1 :(得分:0)
只需计算它们并在大于或等于4时选择
select *
from itemtest
where
CASE WHEN "80" IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN "85" IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN "90" IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN "95" IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN "100" IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN "105" IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN "110" IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN "115" IS NOT NULL THEN 1 ELSE 0 END >= 4
答案 2 :(得分:0)
如果要根据变体数返回行,可以使用CASE语句检查填充的列数:
select
i.item
from
(
select
item,
case when "80" is not null then 1 else 0 end +
case when "85" is not null then 1 else 0 end +
case when "90" is not null then 1 else 0 end +
case when "95" is not null then 1 else 0 end +
case when "100" is not null then 1 else 0 end +
case when "105" is not null then 1 else 0 end +
case when "110" is not null then 1 else 0 end +
case when "115" is not null then 1 else 0 end num_variants
from
itemtest
) i
where
num_variants >= 4;
您可能仍然坚持设计,但如果可能的变体保存在单独的ITEM_VARIANT表中会更容易:
ITEM VARIANT_CODE VARIANT_VALUE
---- ------------ -------------
A 80 1
A 100 1
A 115 3
B 80 2
...
...
...
E 115 1
然后你有一个很好的直截了当的查询 - 例如以下内容:
select
item
from
(
select
item,
count(*) num_variants
from
item_variant
group by
item
)
where
num_variants >= 4;