我有以下数据:
ID Code1 Code2 Code3
1 c1 c2
2 c1 c2 c3
1 c1 c2
我需要在一个查询中按ID进行代码计数,而无需编写子查询。这是因为我通过数百万行运行它。编写子查询将给我“临时创建太久以前”类型的错误。我在SQL中尝试了以下内容,但它仍在计算空白。正确的代码计数应为5,但查询指示6.如何通过ID计算不同的非空白代码?
COUNT(DISTINCT ID||DECODE(CODE1,null,0,1)) +
COUNT(DISTINCT ID||DECODE(CODE2,null,0,1))+
COUNT(DISTINCT ID||DECODE(CODE3,null,0,1))
答案 0 :(得分:1)
Oracle安装程序:
CREATE TABLE table_name ( ID, Code1, Code2, Code3 ) AS
SELECT 1, 'c1', 'c2', NULL FROM DUAL UNION ALL
SELECT 2, 'c1', 'c2', 'c3' FROM DUAL UNION ALL
SELECT 1, 'c1', 'c2', NULL FROM DUAL;
<强>查询强>:
SELECT COUNT( DISTINCT ID || Code ) AS num_id_codes
FROM table_name
UNPIVOT ( code FOR name IN ( Code1, Code2, Code3 ) );
<强>输出强>:
NUM_ID_CODES
------------
5
答案 1 :(得分:0)
如果您只需要为 id 计算一次特定代码,那么:
select count(code)
from (
select id, Code1 as code
from tbl
union
select id, Code2
from tbl
union
select id, Code3
from tbl
)
请注意,union
消除了重复的ID,代码组合,count(code)
仅计算非空值。
答案 2 :(得分:0)
这是一个手动取消转轴,仅扫描您的桌子一次。 CROSS APPLY将强制使用嵌套循环将子查询合并到主查询中。如果不同值的数量对于实际数据足够小,则提示优化器使用HASH GROUP BY来计算不同的值(如果尚未计算),从而节省了昂贵的临时表排序。
SELECT COUNT(DISTINCT id||codex)
FROM
TABLE_NAME
CROSS APPLY
( SELECT code1 codex FROM DUAL
UNION ALL
SELECT code2 codex FROM DUAL
UNION ALL
SELECT code3 codex FROM DUAL
)
WHERE codex IS NOT NULL