#sql #oracle
#sql #Oracle
Вопрос:
Я довольно долго искал и, похоже, не могу найти решение, которое соответствует тому, что мне нужно.
У меня есть таблица со многими, многими клиентами, и проблема в том, что в этой таблице много, много дубликатов.
Я смог показать клиентов, у которых есть повторяющиеся записи, и подсчитать, сколько их в таблице с тем же именем, но теперь я пытаюсь разделить это и показать всю их информацию, чтобы мы могли подтвердить, что клиент правильный, когда мы их ищем.
Я использовал этот код:
SELECT COUNT(NAME), NAME
FROM DEV.ALL_CUSTOMER
GROUP BY NAME
HAVING COUNT(NAME) > 1;
Что дает результаты, которые отображаются следующим образом:
COUNT(NAME) | NAME
------------|-------------------
3 | Smith, John
2 | Doe, Jane
2 | Doe, Joe
2 | Smith, Jane
Затем я добавил все необходимые мне информационные поля:
SELECT COUNT(NAME), NAME, TOTAL_PURCHASED, ADDRESS, CITY, STATE_PROV, POSTAL_CODE, COUNTRY, HOME_PHONE, WORK_PHONE, WORK_EXT, OTHER_PHONE, EMAIL_ADDRESS
FROM DEV.ALL_CUSTOMER
GROUP BY NAME, TOTAL_PURCHASED, ADDRESS, CITY, STATE_PROV, POSTAL_CODE, COUNTRY, HOME_PHONE, WORK_PHONE, WORK_EXT, OTHER_PHONE, EMAIL_ADDRESS
HAVING COUNT(NAME) > 1;
Но при этом они по-прежнему группируются и не отображают информацию для каждой записи:
COUNT(NAME) | NAME | TOTAL_PURCHASED | ADDRESS | CITY ...
------------|-------------|-----------------|---------|------- ..
3 | Smith, John | 0 | (null) | (null) ..
2 | Doe, Jane | 0 | (null) | (null) ..
2 | Doe, Joe | 0 | (null) | (null) ..
Но я точно знаю, что один из пяти клиентов «John Smith» купил что-то.
Вместо этого я хотел бы, чтобы результаты выглядели так:
NAME | TOTAL_PURCHASED | ADDRESS | CITY ...
------------|-----------------|---------------|------- ..
Smith, John | 250 | 123 Fake St. | (null) ..
Smith, John | 0 | (null) | Oshawa ..
Smith, John | 300 | (null) | Toronto .
Doe, Jane | 0 | (null) | (null) ..
Doe, Jane | 300 | 456 Fake St. | Toronto .
Doe, Joe | 11235 | (null) | (null) ..
Doe, Joe | 0 | (null) | (null) ..
Комментарии:
1. Возможно, я что-то упускаю, но разве ваши желаемые результаты не просто «выбрать * из порядка all_customers по имени»? Возможно, с
where name in (<<your group by/ having>>)
помощью .2. Я пробовал
SELECT [FIELDS] FROM DEV.ALL_CUSTOMER HAVING COUNT(NAME) > 1;
, но это ошибки.
Ответ №1:
Используйте оконные функции:
SELECT c.*
FROM (SELECT c.*, COUNT(*) OVER (PARTITION BY NAME) as cnt
FROM DEV.ALL_CUSTOMER c
) c
WHERE cnt > 1
ORDER BY NAME;
Это даст вам строки, которые дублируются NAME
.
Комментарии:
1. Мне нужны только те поля, которые я опубликовал во втором
SELECT
заявлении. Должен ли я просто заменитьc.*
оба выбранных в вашем коде этими конкретными полями? Вот так:SELECT [SPECIFIC FIELDS] FROM (SELECT [SPECIFIC FIELDS], COUNT(NAME) OVER (PARTITION BY NAME) as cnt FROM DEV.ALL_CUSTOMER c ) c WHERE cnt > 1 ORDER BY NAME;
2. @WolfieeifloW . , , Вы можете просто поместить нужные вам поля во внешний
select
.