目前我正面临SQL挑战,并且想知道,如果我的方法是正确的话。 让我们考虑以下简化数据模型:
Table CAT:
----------
ID
COLOR
Table DOMESTIC_CAT:
-------------------
CAT_ID
DOMESTIC_ATTRIBUTE
Table PERSIAN_CAT:
------------------
CAT_ID
PERSIAN_ATTRIBUTE
我们假设表格中有以下数据:
Table CAT:
ID COLOR
--------------
1 'BLACK'
2 'WHITE'
3 'BLACK'
4 'WHITE'
5 'BLACK'
6 'RED'
7 'WHITE'
8 'WHITE'
9 'RED'
10 'BLACK'
Table DOMESTIC_CAT:
CAT_ID DOMESTIC_ATTRIBUTE
----------------------------
1 'Domestic1'
2 'Domestic2'
3 'Domestic3'
7 'Domestic4'
8 'Domestic5'
Table PERSIAN_CAT
CAT_ID PERSIAN_ATTRIBUTE
---------------------------
4 'Persian1'
5 'Persian2'
6 'Persian3'
9 'Persian4'
10 'Persian5'
我想使用以下结果执行聚合查询:
CAT_TYPE CAT_COLOR COUNT
---------------------------------
'DOMESTIC_CAT' 'BLACK' 2
'DOMESTIC_CAT' 'WHITE' 3
'PERSIAN_CAT' 'WHITE' 1
'PERSIAN_CAT' 'BLACK' 2
'PERSIAN_CAT' 'RED' 2
如您所见,我想通过以下值对'count'结果进行分组: - 事实上,给定的猫是国内的还是波斯的 - 猫的颜色
第一个是难事 - 我实际上不知道是否有可能执行“加入表组”?我打破了我的脑袋,但找不到任何解决方案:(实际使用的RDBMS将是Oracle 11。
答案 0 :(得分:2)
您可以使用cat
中的外部联接到其他表,并确定哪个表匹配,并使用它来填充cat_type
列:
select case when dc.cat_id is not null then 'DOMESTIC_CAT'
when pc.cat_id is not null then 'PERSIAN_CAT' end as cat_type,
c.color,
count(*) as "COUNT"
from cat c
left join domestic_cat dc on dc.cat_id = c.id
left join persian_cat pc on pc.cat_id = c.id
group by case when dc.cat_id is not null then 'DOMESTIC_CAT'
when pc.cat_id is not null then 'PERSIAN_CAT' end,
c.color
order by 1,2;
根据您的实际问题,这可能比内部联接/联合选项更好,但您可能需要尝试两者以查看哪个更好(更快,更高效,更易维护......)。 / p>
答案 1 :(得分:1)
只做
SELECT 'DOMESTIC_CAT', c.color, count(*)
FROM domestic_cat d INNER JOIN cat c ON c.id = d.cat_id
GROUP BY c.color
UNION ALL
SELECT 'PERSIAN_CAT' .... the same for the other table
答案 2 :(得分:1)
另一种方法(Oracle 11g及更高版本):
select cat_type
, color
, cat_cnt
from (select c.color
, count(dc.domestic_attribute) as domestic_cat
, count(pc.persian_attribute) as persian_cat
from cat c
left join domestic_cat dc
on (c.id1 = dc.cat_id)
left join persian_cat pc
on (c.id1 = pc.cat_id)
group by c.color
)
unpivot(
cat_cnt for cat_type in (domestic_cat, persian_cat)
)
order by cat_type
结果:
CAT_TYPE COLOR CAT_CNT
------------------------------------
DOMESTIC_CAT RED 0
DOMESTIC_CAT WHITE 3
DOMESTIC_CAT BLACK 2
PERSIAN_CAT WHITE 1
PERSIAN_CAT BLACK 2
PERSIAN_CAT RED 2
答案 3 :(得分:1)
与安格斯的反应差别不大,但我更喜欢:
select ct.cat_type, c.color, count(*)
from cat c
inner join (
select 'DOMESTIC_CAT' cat_type, cat_id
from domestic_cat
union all
select 'PERSIAN_CAT' cat_type, cat_id
from persian_cat
) ct
on ct.cat_id = c.id
group by ct.cat_type, c.color
order by ct.cat_type, c.color;
这只会在cat表上打一次,并且不会有太多重复的代码需要维护。
答案 4 :(得分:0)
WITH cat_types AS (
SELECT CASE
WHEN EXISTS ( SELECT 1 FROM domestic_cat d WHERE d.cat_id = c.id )
THEN 'Domestic_Cat'
WHEN EXISTS ( SELECT 1 FROM persian_cat d WHERE d.cat_id = c.id )
THEN 'Persian_Cat'
ELSE 'Unknown_Cat' END AS Cat_Type,
id,
color
FROM cat c
)
SELECT Cat_Type,
Color,
COUNT( 1 ) AS cat_cnt
FROM cat_types
GROUP BY Cat_Type, color
ORDER BY Cat_Type, cat_cnt;