我正在尝试编写一个查询或一组查询来计算跨越多行的唯一集合,但行中的数据可能需要多次计算。
在下面的集合中,我想要按年度
分组的以下内容Number of unique SID, Year, Flag1 //2013=2, 2014=2
Number of unique SID, Year, Flag2 //2013=1, 2014=0
Number of unique SID, Year, Flag3 //2013=1, 2014=2
然后我想做同样的事情,按年/月分组
Number of unique SID, Year, Month, Flag1 //2013-Jan=2, 2013-Feb=2, 2013-Mar=1, etc
Number of unique SID, Year, Month, Flag2 //2013-Jan=1, 2013-Feb=1, 2013-Mar=1, etc
Number of unique SID, Year, Month, Flag3, //2013-Jan=1, 2013-Feb=1, 2013-Mar=1, etc
数据集
SID Year Month Flag1 Flag2 Flag3
--------------------------------------------------
1 2013 Jan Y Y Y
1 2013 Feb Y Y Y
1 2013 Mar Y Y Y
1 2014 Jan Y Y
1 2014 Feb Y
2 2013 Jan Y
2 2013 Feb Y
2 2014 Jan Y Y
2 2014 Feb Y Y
我可以通过针对每个计数的单个查询来执行此操作,但是非常希望将其合并到一个查询中。
我今年的多项计数如下:
select count(*) from
( select distinct SID, Year, Flag1 from Table WHERE Year = '2013' ) as 2013Flag1
select count(*) from
( select distinct SID, Year, Flag2 from Table WHERE Year = '2013' ) as 2013Flag2
select count(*) from
( select distinct SID, Year, Flag1 from Table WHERE Year = '2014' ) as 2014Flag1
等...
月份计数如下:
select count(*) from
( select distinct SID, Year, Month, Flag1 from Table WHERE Year = '2013' and Month = 'Jan' ) as 2013JanFlag1
等...
对每个计数的查询更容易吗,或者我可以选择哪种类型的笛卡尔积?任何想法都会很精彩。这来自Oracle数据库。我相信它的版本是10g。
答案 0 :(得分:0)
SELECT G.SID, G.YEAR, G.MONTH, G.FLAG, COUNT(*)
FROM (
SELECT Y.YEAR, Y.SID, Y.MONTH, 1 AS FLAG
(SELECT DISTINCT SID, YEAR FROM TABLE) AS Y
JOIN TABLE AS F
ON F.YEAR = Y.YEAR
AND F.FLAG1 = 'Y'
UNION ALL
SELECT Y.YEAR, Y.SID, Y.MONTH, 2 AS FLAG
(SELECT DISTINCT SID, YEAR FROM TABLE) AS Y
JOIN TABLE AS F
ON F.YEAR = Y.YEAR
AND F.FLAG2 = 'Y'
UNION ALL
SELECT Y.YEAR, Y.SID, Y.MONTH, 3 AS FLAG
(SELECT DISTINCT SID, YEAR FROM TABLE) AS Y
JOIN TABLE AS F
ON F.YEAR = Y.YEAR
AND F.FLAG3 = 'Y' ) AS G
GROUP BY G.SID, G.YEAR, G.FLAG, G.MONTH
ORDER BY G.SID, G.YEAR, G.FLAG, G.MONTH
答案 1 :(得分:0)
我没有得到关于标志的逻辑,但是ROLLUP或CUBE可以使查询更容易,更快。
以下陈述是等效的:
SELECT COUNT(DISTINCT SID), YEAR, MONTH, flag1, flag2, flag3
FROM a_table
GROUP BY flag1, flag2, flag3, ROLLUP(YEAR, MONTH);
SELECT COUNT(DISTINCT SID), YEAR, MONTH, flag1, flag2, flag3
FROM a_table
GROUP BY flag1, flag2, flag3, YEAR, MONTH
UNION ALL
SELECT COUNT(DISTINCT SID), YEAR, NULL AS MONTH, flag1, flag2, flag3
FROM a_table
GROUP BY flag1, flag2, flag3, YEAR
UNION ALL
SELECT COUNT(DISTINCT SID), NULL AS YEAR, NULL AS MONTH, flag1, flag2, flag3
FROM a_table
GROUP BY flag1, flag2, flag3;
CUBE的另一个例子:
SELECT COUNT(DISTINCT SID), YEAR, MONTH, flag1, flag2, flag3, GROUPING_ID(flag1, flag2, flag3) AS flag_ID
FROM a_table
GROUP BY YEAR, MONTH, CUBE(flag1, flag2, flag3)
SELECT COUNT(DISTINCT SID), YEAR, MONTH, flag1, flag2, flag3, 0 AS flag_id
FROM a_table
GROUP BY YEAR, MONTH, flag1, flag2, flag3
UNION ALL
SELECT COUNT(DISTINCT SID), YEAR, MONTH, flag1, flag2, NULL AS flag3, 1 AS flag_id
FROM a_table
GROUP BY YEAR, MONTH, flag1, flag2
UNION ALL
SELECT COUNT(DISTINCT SID), YEAR, MONTH, flag1, NULL AS flag2, flag3, 2 AS flag_id
FROM a_table
GROUP BY YEAR, MONTH, flag1, flag3
UNION ALL
SELECT COUNT(DISTINCT SID), YEAR, MONTH, flag1, NULL AS flag2, NULL AS flag3, 3 AS flag_id
FROM a_table
GROUP BY YEAR, MONTH, flag1
UNION ALL
SELECT COUNT(DISTINCT SID), YEAR, MONTH, NULL AS flag1, flag2, flag3, 4 AS flag_id
FROM a_table
GROUP BY YEAR, MONTH, flag2, flag3
UNION ALL
SELECT COUNT(DISTINCT SID), YEAR, MONTH, NULL AS flag1, flag2, NULL AS flag3, 5 AS flag_id
FROM a_table
GROUP BY YEAR, MONTH, flag2
UNION ALL
SELECT COUNT(DISTINCT SID), YEAR, MONTH, NULL AS flag1, NULL AS flag2, flag3, 6 AS flag_id
FROM a_table
GROUP BY YEAR, MONTH, flag3
UNION ALL
SELECT COUNT(DISTINCT SID), YEAR, MONTH, NULL AS flag1, NULL AS flag2, NULL AS flag3, 7 AS flag_id
FROM a_table
GROUP BY YEAR, MONTH
您可以在一个GROUP BY子句中同时使用ROLLUP和CUBE。
您在此处找到的ROLLUP和CUBE子句文档:http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_10002.htm#SQLRF55331
还可以检查GROUPING_ID和GROUPING的功能。这可以在HAVING
子句中使用,以根据您的需要限制输出。