如何基于表的几列组合来拉出不同的行

时间:2014-07-22 14:59:26

标签: sql sql-server count group-by distinct

原谅问题标题,但我有表CUSTOMER(ACCT_NUM,LRN,NAME,ADDRESS,CITY,STATE,COUNTRY)

我必须编写一个查询,以便为相同的acct_num和LRN 组合提取名称,地址,城市,州和国家/地区的1个(不同)组合的记录。 这是我尝试过但我不确定它是否正确。 我只是想通过acct_num和LRN进行分组,但我知道group不会允许我排除其他列。

select distinct name, address, state, country, city, 
COUNT(1) from CUSTOMER 
group by acct_num,
 LRN ,
 name,
 address,
 state, 
 country, 
 city
 having COUNT(1) > 1

请帮忙。

5 个答案:

答案 0 :(得分:2)

创建一些测试数据

DECLARE @Customer TABLE
(
    ACCT_NUM INT,
    LRN INT,
    name varchar(20),
    address varchar(100),
    state varchar(2),
    country varchar(100),
    city varchar(100)
)

INSERT INTO @Customer
VALUES
( 1, 1, 'Test1', 'Addr1', 'FL', 'USA', 'Tampa' ),
( 1, 1, 'Test1', 'Addr2', 'FL', 'USA', 'Tampa' ),
( 1, 1, 'Test1', 'Addr3', 'FL', 'USA', 'Tampa' ),
( 1, 1, 'Test1', 'Addr4', 'FL', 'USA', 'Tampa' ),
( 2, 1, 'Test2', 'Addr1', 'FL', 'USA', 'Tampa' ),
( 2, 1, 'Test2', 'Addr1', 'FL', 'USA', 'Tampa' ),
( 3, 1, 'Test3', 'Addr1', 'FL', 'USA', 'Tampa' )

我使用排名来计算所有不同的组合(如果它们相等,排名也相等)

 SELECT * FROM
 (
    SELECT *, 
        Rank() OVER (PARTITION BY c.ACCT_NUM, c.LRN ORDER BY c.Name, c.Address, c.State, c.Country, c.City) RK
    FROM @Customer c
) d
WHERE d.RK > 1

输出:

ACCT_NUM    LRN name    address state   country city    RK
1   1   Test1   Addr2   FL  USA Tampa   2
1   1   Test1   Addr3   FL  USA Tampa   3
1   1   Test1   Addr4   FL  USA Tampa   4

答案 1 :(得分:2)

RANK() OVER答案是正确的,但未能在结果中显示第一个地址。

我更愿意使用额外的嵌套级别来完成此任务。

SELECT
  *
FROM
(
  SELECT
    *,
    COUNT(*) OVER (PARTITION BY acct_num, LRN) AS distinct_matches
  FROM
  (
    SELECT
      acct_num, LRN, name, address, state, country, city
    FROM
      CUSTOMER
    GROUP BY
      acct_num, LRN, name, address, state, country, city
  )
    AS unique_rows
)
  AS counted_unique_rows
WHERE
  distinct_matches > 1
;

答案 2 :(得分:0)

SELECT distinct name, address, state, country, city, acct_num
FROM (
    SELECT  COUNT(*) OVER (PARTITION BY name, address, state, country, city) AS RN
    FROM CUSTOMER 
    group by acct_num,
             LRN ,
             name,
             address,
             state, 
             country, 
             city) AS n
WHERE RN > 1

根据我的假设,这可能是有效的。

答案 3 :(得分:0)

这将返回acct_num&具有多个其他字段的不同组合的LRN组合。如果你想看到所有其他不同的信息,那就有可能会破坏聚合IMO的目的。

select acct_num, LRN, COUNT(*)
from CUSTOMER
group by acct_num, LRN
having COUNT(*) > 1

答案 4 :(得分:0)

我是这样做的。

这是link to SQL Fiddle从Kevin的答案中借用示例数据集,以便您可以看到结果。

获取不同客户的列表。从acct_num和lrn上的这个列表组。任何计数> 1表示考虑其余字段时,有超过1个组合。现在从上一个查询中存在的客户处获取它以获取所有数据。

select distinct * from customer c
where exists
  (
    select acct_num, lrn
    from
      (
        select distinct * from customer
       ) base
    where c.acct_num = base.acct_num and c.lrn = base.lrn
    group by acct_num, lrn
    having count(1) > 1
  )