我们在oracle数据库中有以下数据 -
col1 col2
Z1 A
Z1 B
Z2 A
Z2 C
Z3 A
Z4 D
我希望以第二栏的方式指望 -
输出 -
col2 count
A 3 (Z1,Z2,Z3)
B 0 (Dont count if A is already present for record)
C 0
D 1 (Z4)
最好的问候
答案 0 :(得分:1)
您可以使用窗口函数rank()
来实现此目的。
select col2, count(case when rn = 1 then 1 end) cnt from (
select t.*,
rank() over (partition by col1 order by case when col2 = 'A' then 1 else 2 end) rn
from table t
) group by col2;
答案 1 :(得分:1)
对您的命题的最常规解决方案,其中每个键COL1
仅在第一次出现的键COL2
中计算(按字母顺序排列)
WITH tab AS
(
SELECT 'Z1' col1, 'A' col2 FROM dual UNION ALL
SELECT 'Z1' col1, 'B' col2 FROM dual UNION ALL
SELECT 'Z2' col1, 'A' col2 FROM dual UNION ALL
SELECT 'Z2' col1, 'C' col2 FROM dual UNION ALL
SELECT 'Z3' col1, 'A' col2 FROM dual UNION ALL
SELECT 'Z4' col1, 'D' col2 FROM dual
), tab2 as (
select COL1, COL2,
row_number() over (partition by COL1 order by COL2) as rn
from tab)
select COL1, COL2,
case when rn = 1 then 1 else 0 end is_valid
from tab2
order by 1,2
;
COL1 COL2 IS_VALID
---- ---- ----------
Z1 A 1
Z1 B 0
Z2 A 1
Z2 C 0
Z3 A 1
Z4 D 1
其余部分是简单的分组,在IS_VALID
上有一个SUMselect COL2, sum(is_valid) cnt from tab3 -- TAB3 is the above row source
group by COL2
order by 1
COL2 CNT
---- ----------
A 3
B 0
C 0
D 1
答案 2 :(得分:0)
假设您的表名为table_name
,一种方法是使用它:
WITH table_a AS
(
SELECT DISTINCT col1
FROM table_name
WHERE col2 = 'A'
)
SELECT col2,
SUM(CASE WHEN col1 IN (SELECT col1 FROM table_a)
THEN DECODE(col2, 'A', 1, 0)
ELSE 1 END
) count
FROM table_name
GROUP BY col2
ORDER BY col2;
测试好了:
WITH table_name AS
(
SELECT 'Z1' col1, 'A' col2 FROM dual UNION ALL
SELECT 'Z1' col1, 'B' col2 FROM dual UNION ALL
SELECT 'Z2' col1, 'A' col2 FROM dual UNION ALL
SELECT 'Z2' col1, 'C' col2 FROM dual UNION ALL
SELECT 'Z3' col1, 'A' col2 FROM dual UNION ALL
--SELECT 'Z4' col1, 'B' col2 FROM dual UNION ALL
SELECT 'Z4' col1, 'D' col2 FROM dual
)
, table_a AS
(
SELECT DISTINCT col1
FROM table_name
WHERE col2 = 'A'
)
SELECT col2,
SUM(CASE WHEN col1 IN (SELECT col1 FROM table_a)
THEN DECODE(col2, 'A', 1, 0)
ELSE 1 END
) count
FROM table_name
GROUP BY col2
ORDER BY col2;
答案 3 :(得分:0)
您想要计算col1为“A”或col1没有“A”记录的每条记录。
select
col2,
count(
case
when col2 = 'A' or col1 not in (select col1 from table_name where col2 = 'A') then 1
end) as cnt
from table_name
group by col2;
答案 4 :(得分:0)
select col2, count(case when col2 = col3 then 'x' end) as ct
from ( select col2, min(col2) over (partition by col1) as col3
from your_table
)
group by col2
order by col2 -- if needed
;
<强>解释强>:
有一个内部查询(a.k.a。&#34;子查询&#34;),它为原始表中的每一行返回一行。它按原样返回col2
,另一个(新)列标记为col3
。 col3
计算为&#34;第一个&#34;或min()
值col2
(按字母顺序),表示原始表中与{0}当前行具有相同值的所有行。这是分析函数的典型示例; col1
类似于partition by col1
,但它返回组中的所有行(原始表中的所有原始行),而不是每个组一行,聚合函数也是如此。
要查看内部查询本身的作用,请选择它并在您喜欢的前端运行它。您可以将group by col1
添加到内部查询中的选择中 - 这将使此查询中的内容更加清晰。您将获得初始表格,其中还有一列col1
,其中显示了&#34; min&#34; col3
的每个值col2
。我没有在子查询中包含col1
,因为我不需要它,但是将其添加回来查看子查询的真正含义。
然后在外部查询中,我从内部查询中获取结果,并按col1
分组。对于每个col2
,我只计算它等于&#34; min&#34;相应col2
值的col2
值。那是col1
表达式在case
函数中的作用;当count()
不等于col2
时,col3
会返回case
(默认情况下),因此表达式 - 因此行 - 不计算在内。
我应该补充说,以这种方式编写的查询假设原始表中没有重复的null
行。如果有,那么内部子查询应该从子子查询中选择;我的代码的第3行应该是
(col1, col2)
答案 5 :(得分:0)
谢谢你们。但我可以这样做 -
select count(case
when (LISTAGG(col2,'-') WITHIN GROUP (ORDER BY col2)) like '%A%' then 1
else null
end) A,
count(case
when (LISTAGG(col2,'-') WITHIN GROUP (ORDER BY col2)) = 'B' then 1
else null
end) B,
count(case
when (LISTAGG(col2,'-') WITHIN GROUP (ORDER BY col2)) = 'C' then 1
else null
end) C,
count(case
when (LISTAGG(col2,'-') WITHIN GROUP (ORDER BY col2)) = 'D' then 1
else null
end) D
from T
GROUP BY col1
感谢您的回复
答案 6 :(得分:-1)
使用以下脚本:
SELECT A.COL2, NVL(B.CNT, 0) AS CNT
FROM (SELECT DISTINCT COL2 FROM TET) A
LEFT JOIN (SELECT COL2, COUNT(COL2) AS CNT
FROM (SELECT SUBSTR(F, 1, INSTR(F, ',') - 1) AS COL2,
ROW_NUMBER() OVER(PARTITION BY SUBSTR(F, 1, INSTR(F, ',') - 1) ORDER BY SUBSTR(F, 1, INSTR(F, ',') - 1)) AS U
FROM (SELECT COL1,
LISTAGG(COL2, ',') WITHIN GROUP(ORDER BY COL2) || ',' AS F
FROM TET
GROUP BY COL1)) A
GROUP BY COL2) B
ON A.COL2 = B.COL2
ORDER BY A.COL2;