简体   繁体   中英

Comparing between rows in same table in Oracle SQL

I'm trying to find the best way to compare between rows by CustomerID and Status. In other words, only show the CustomerID when the status are equal between multiple rows and CustomerID. If not, don't show the CustomerID.

Example data

CUSTOMERID        STATUS
1000              ACTIVE
1000              ACTIVE
1000              NOT ACTIVE
2000              ACTIVE
2000              ACTIVE

RESULT I'm hoping for

CUSTOMERID        STATUS
2000              ACTIVE

The only "Code" here is the last 4 lines in the code block. The other is establishing sample data.

with T1 as (
Select 1000 as CUSTOMERID,              'ACTIVE' as STATUS from dual union all 
select 1000,              'ACTIVE' from dual union all 
select 1000,              'NOT ACTIVE' from dual union all 
select 2000,              'ACTIVE' from dual union all 
select 2000,              'ACTIVE' from dual )

SELECT customerID, max(status) as status
FROM T1
GROUP BY  customerID
HAVING count(distinct Status) = 1
  • I used a CTE to setup sample data and called this Common table Expression T1.
  • Order of operations matter here. First the table T1 is identified
  • second the engine groups by customer ID
  • third the engine limits the results to those records having a distinct record status matching 1 and only 1 value.
  • 4th the engine picks the max status which will always be 1 value. min/max it doesn't matter as there is only 1 possible value. note, we have to use an aggregate here since we can't group by status or you wouldn't get the desired results.

You can do this with a WHERE NOT EXISTS :

Select  Distinct CustomerId, Status
From    YourTable   A
Where Not Exists
(
    Select  *
    From    YourTable   B
    Where   A.CustomerId = B.CustomerId
    And     A.Status <> B.Status
)
SELECT DISTINCT o.*
FROM
    (
       SELECT
          CustomerId
       FROm
          TableName 
       GROUP BY
          CustomerId
       HAVING
          COUNT(DISTINCT Status) = 1
    ) t
    INNER JOIN TableName o
    ON t.CustomerId = o.CustomerId

Here's a pretty simple one using IN :

SELECT DISTINCT CustomerID, Status
FROM My_Table
WHERE CustomerID IN
(SELECT CustomerID
FROM My_Table
GROUP BY CustomerID
HAVING COUNT(Distinct Status) = 1)

Addition: based on your comment, it seems what you really want is all the IDs that do not have a 'Not Active' row, which is actually easier:

SELECT Distinct CustomerID, Status
FROM My_Table
WHERE CustomerID NOT IN
(SELECT CustomerID
 FROM My_Table
 WHERE Status = 'Not Active')

This is a SQL Server answer, I believe it should work in Oracle.

SELECT
    a.AGMTNUM
FROM TableA a
WHERE NOT EXISTS (SELECT 1 FROM TableB b WHERE b.Status = 'NOT ACTIVE' AND a.AGMTNUM = b.AGMTNUM)
AND EXISTS (SELECT 1 FROM TableB c WHERE c.Status = 'ACTIVE' AND a.AGMTNUM = c.AGMTNUM)

This will only return values that have at least one 'ACTIVE' value and no 'NOT ACTIVE' values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM