如果一个列值仅与另一列中的一个值相关联,则过滤出行

时间:2019-04-09 07:54:49

标签: sql oracle

A   B   C   D   E
1981    a   b   CY3 2
1981    c   l   CY3 1
1981    f   r   CY3 5
1255    ee  ee  CY3 1
1255    ff  ff  CY3 1
1387    g   g   CY5 2
1387    h   h   CY5 10
1387    P   h   CY5 C7

我通过以下查询(ORACLE pl / sql)获取此表:

SELECT A,B,C,D,COUNT(*) AS E
FROM TAB1  t1 INNER JOIN TAB2 t2 ON t1.A = t2.B
             INNER JOIN TAB3 t3 ON t1.A = t3.C
GROUP BY A,B,C,D
ORDER BY D ASC, A DESC;

我想通过编辑上面的查询来获得以下结果:

A   B   C   D   E
1981    a   b   CY3 2
1981    c   l   CY3 1
1981    f   r   CY3 5
1255    ee  ee  CY3 1
1255    ff  ff  CY3 1

我想过滤出最后三行,因为列D具有一个值(即CY5),该值仅与列A中的一个值(即1387)相关,而CY3与两个不同值(即1981)相关联&12550,所以我想保留这个。)

有人可以帮助我或给我指出类似的问题吗?

4 个答案:

答案 0 :(得分:1)

大多数DBMS支持窗口聚合

select *
from
 (
    SELECT A,B,C,D,COUNT(*) AS E,
       MIN(A) OVER (PARTITION BY D) AS minA,-- minimum A for all rows with the same D
       MAX(A) OVER (PARTITION BY D) AS maxA -- maximum A for all rows with the same D
    FROM TAB1  t1 INNER JOIN TAB2 t2 ON t1.A = t2.B
                 INNER JOIN TAB3 t3 ON t1.A = t3.C
    GROUP BY A,B,C,D
 ) as dt
where minA <> maxA -- there must be at least 2 different values (usually cheaper than COUNT(DISTINCT)
ORDER BY D ASC, A DESC;

编辑:

对于Oracle,要返回不同值的数量:

select *
from
 (
    SELECT A,B,C,D,COUNT(*) AS E,
       COUNT(DISTINCT A) OVER (PARTITION BY D) AS countA
    FROM TAB1  t1 INNER JOIN TAB2 t2 ON t1.A = t2.B
                 INNER JOIN TAB3 t3 ON t1.A = t3.C
    GROUP BY A,B,C,D
 ) dt -- you don't need the alias in Oracle, but STandard SQL requires it
where countA > 1
ORDER BY D ASC, A DESC;

答案 1 :(得分:0)

使用存在的相关子查询

SELECT A,B,C,D,COUNT(*) AS E
FROM TABLESS t1
where exists (select 1 from TABLESS t2 where t1.D=t2.D having count(A)>1)
GROUP BY A,B,C,D
ORDER BY D ASC, A DESC

答案 2 :(得分:0)

看看!

    DECLARE @TEST AS TABLE
(A VARCHAR(100),B VARCHAR(100),C VARCHAR(100),D VARCHAR(100))

INSERT INTO @TEST VALUES
('1981','A','B','CY3'),
('1981','A','B','CY3'),
('1981','C','L','CY3'),
('1981','F','R','CY3'),
('1981','F','R','CY3'),
('1981','F','R','CY3'),
('1981','F','R','CY3'),
('1981','F','R','CY3'),
('1255','EE','EE','CY3'),
('1255','FF','FF','CY3'),
('1387','G','G','CY5'),
('1387','G','G','CY5'),
('1387','H','H','CY5'),
('1387','H','H','CY5'),
('1387','H','H','CY5'),
('1387','H','H','CY5'),
('1387','H','H','CY5'),
('1387','H','H','CY5'),
('1387','H','H','CY5'),
('1387','H','H','CY5'),
('1387','H','H','CY5'),
('1387','H','H','CY5'),
('1387','P','H','CY5'),
('1387','P','H','CY5'),
('1387','P','H','CY5'),
('1387','P','H','CY5'),
('1387','P','H','CY5'),
('1387','P','H','CY5'),
('1387','P','H','CY5')

SELECT DATA.* FROM 
(
SELECT T.D,COUNT(T.A) AS DISTINCT_RECORD FROM (
SELECT DISTINCT D,A FROM @TEST) T
GROUP BY T.D
HAVING COUNT(T.A)>1
) 

CRITERIA LEFT JOIN 

(
SELECT A,B,C,D,COUNT(*) AS E
FROM @TEST
GROUP BY A,B,C,D
) 

DATA ON CRITERIA.D=DATA.D

答案 3 :(得分:0)

with s (a, b, c, d, e) as (
select 1981, 'a'  , 'b' , 'CY3', 2  from dual union all
select 1981, 'c'  , 'l' , 'CY3', 1  from dual union all
select 1981, 'f'  , 'r' , 'CY3', 5  from dual union all
select 1255, 'ee' , 'ee', 'CY3', 1  from dual union all
select 1255, 'ff' , 'ff', 'CY3', 1  from dual union all
select 1387, 'g'  , 'g' , 'CY5', 2  from dual union all
select 1387, 'h'  , 'h' , 'CY5', 10 from dual union all
select 1387, 'P'  , 'h' , 'CY5', 17 from dual)
select a, b, c, d, e
from 
    (select s.*, count(distinct a) over (partition by d) cnt_dict
     from s
    )
where cnt_dict > 1;

         A B  C  D            E
---------- -- -- --- ----------
      1255 ee ee CY3          1
      1255 ff ff CY3          1
      1981 f  r  CY3          5
      1981 c  l  CY3          1
      1981 a  b  CY3          2