依靠案例Oracle

时间:2016-12-29 09:37:21

标签: sql oracle oracle11g

我们在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)

最好的问候

7 个答案:

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

上有一个SUM
select 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,另一个(新)列标记为col3col3计算为&#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;