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

问题描述 投票:0回答:4
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所以我想保留这个)。

任何人都可以帮助我或指出类似的问题吗?

sql oracle
4个回答
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;

0
投票

使用相关子查询使用exists

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

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

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
© www.soinside.com 2019 - 2024. All rights reserved.