计算Oracle中不同的非空代码

时间:2016-07-17 19:39:31

标签: sql oracle

我有以下数据:

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))

3 个答案:

答案 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