Oracle SQL - 比较行

时间:2013-08-23 17:34:05

标签: sql oracle

我遇到了一个问题,我正在使用Oracle SQL,就像这样。

 PurchaseID    CustID      Location  
----1------------1-----------A  
----2------------1-----------A    
----3------------2-----------A  
----4------------2-----------B  
----5------------2-----------A  
----6------------3-----------B  
----7------------3-----------B  

我有兴趣查询Table以返回同一客户在不同位置进行购买的所有实例。所以,对于上表,我想要:

输出

PurchaseID    CustID      Location  
----3------------2-----------A  
----4------------2-----------B  
----5------------2-----------A  

关于如何实现这一目标的任何想法?我一直无法想到如何去做,我的大多数想法看起来都很笨重。我正在使用的数据库有1MM +记录,所以我不希望它运行得太慢。

任何帮助将不胜感激。谢谢!

6 个答案:

答案 0 :(得分:8)

SELECT *
FROM YourTable T
WHERE CustId IN (SELECT CustId
                 FROM YourTable
                 GROUP BY CustId
                 HAVING MIN(Location) <> MAX(Location))

答案 1 :(得分:7)

您应该可以使用类似于以下内容的内容:

select purchaseid, custid, location
from yourtable
where custid in (select custid
                  from yourtable
                  group by custid
                  having count(distinct location) >1);

请参阅SQL Fiddle with Demo

WHERE子句中的子查询返回具有大于1的不同位置总数的所有custids

答案 2 :(得分:6)

英文:

  

如果存在具有相同客户和不同位置的另一行,请选择一行。

在SQL中:

SELECT *
FROM atable t
WHERE EXISTS (
  SELECT *
  FROM atable
  WHERE CustID = t.CustID
    AND Location <> t.Location
);

答案 3 :(得分:0)

这是使用子查询的一种方法

SELECT T1.PurchaseID
        ,T1.CustID
        ,T1.Location
FROM    YourTable T1
INNER JOIN
        (SELECT T2.CustID
                ,COUNT (DISTINCT T2.Location )
        FROM    YourTable T1
        GROUP BY
                T2.CustID
        HAVING  COUNT (DISTINCT T2.Location )>1
        ) SQ
ON      SQ.CustID = T1.CustID

答案 4 :(得分:0)

这应该只需要一次全表扫描。

create table test (PurchaseID number, CustID number, Location varchar2(1));
insert into test values (1,1,'A');
insert into test values (2,1,'A');
insert into test values (3,2,'A');
insert into test values (4,2,'B');
insert into test values (5,2,'A');
insert into test values (6,3,'B');
insert into test values (7,3,'A');

with repeatCustDiffLocations as (
    select PurchaseID, custid, location, dense_rank () over (partition by custid order by location) r
    from test)
select b.*
from repeatCustDiffLocations a, repeatCustDiffLocations b
where a.r > 1
and a.custid = b.custid;

答案 5 :(得分:0)

这对我来说最有意义,因为我试图在整个表格中返回具有相同值的行,特别是对于两列,如in this stackoverflow answer here.

此格式的问题答案是:

SELECT DISTINCT a.*
FROM TEST a
INNER JOIN TEST b
ON a.CUSTOMERID = b.CUSTOMERID AND
a.LOCATION <> b.LOCATION;

然而,像我这样的问题的解决方案有两列在多行中具有匹配值(在这种情况下为2,因为所有PurchaseID都是唯一的,所以不会产生任何结果):

SELECT DISTINCT a.*
FROM TEST a
INNER JOIN TEST b
ON a.CUSTOMERID = b.CUSTOMERID AND
a.PURCHASEID = b.PURCHASEID AND
a.LOCATION <> b.LOCATION;

虽然这不会根据需要查询的内容返回正确的结果,但它表明查询逻辑有效

SELECT DISTINCT a.*
FROM TEST a
INNER JOIN TEST b
ON a.CUSTOMERID = b.CUSTOMERID AND
a.PURCHASEID <> b.PURCHASEID AND
a.LOCATION = b.LOCATION;

如果有人想在Oracle中尝试,请插入表格和值:

CREATE TABLE TEST (
PurchaseID integer,
CustomerID integer,
Location varchar(1));

INSERT ALL
  INTO TEST VALUES (1, 1, 'A')
  INTO TEST VALUES (2, 1, 'A')
  INTO TEST VALUES (3, 2, 'A')
  INTO TEST VALUES (4, 2, 'B')
  INTO TEST VALUES (5, 2, 'A')
  INTO TEST VALUES (6, 3, 'B')
  INTO TEST VALUES (7, 3, 'B')
SELECT * FROM DUAL;