Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как вытащить отдельные строки на основе комбинации нескольких столбцов таблицы

Автор вопроса: Reeya OberoiОтветов: 5

Извините за заголовок вопроса, но у меня есть таблица CUSTOMER (ACCT_NUM, LRN, NAME, ADDRESS, CITY, STATE, COUNTRY)

Мне нужно написать запрос для извлечения записей, которые содержат более 1 (различной) комбинации имени, адреса, города, штата и страны для одной и той же комбинации acct_num и LRN. Это то, что я пробовал, но я не уверен, что это правильно. Я просто хочу сгруппировать по acct_num и LRN, но я знаю, что группировка по не позволит мне исключить другие столбцы.

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

Пожалуйста помоги.

sqlsql-servercountgroup-bydistinct

Ответы

Ответ 1 · рейтинг 2 · Kevin Cook

Создание некоторых тестовых данных

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

Ответ 2 · рейтинг 2 · MatBailie

Ответ 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
;

Ответ 3 · mohan111

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

Может быть, это работает !!! согласно моему предположению.

Ответ 4 · How 'bout a Fresca

Это вернет комбинации acct_num и LRN с более чем одной комбинацией других полей. Если вы хотите увидеть всю другую информацию, которая отличается, это как бы противоречит цели агрегатов IMO.

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

Ответ 5 · SQLChao

Я сделал это так.

Вот ссылка на SQL Fiddle, заимствовавшая пример набора данных из ответа Кевина, чтобы вы могли увидеть результаты. .

Получить список отдельных клиентов. Из этого списка сгруппируйте по 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
  )

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы