Удалить дубликаты из левого внешнего соединения - PullRequest
19 голосов
/ 28 марта 2010

Мой вопрос очень похож на Ограничение LEFT JOIN , с вариацией.

Предположим, у меня есть таблица SHOP и другая таблица LOCATION. Location - это своего рода дочерняя таблица таблицы SHOP, в которой есть два интересующих столбца, один - это ключ деления (называемый просто KEY) и номер «SHOP». Это соответствует номеру «НЕТ» в таблице SHOP.

Я пробовал это левое внешнее соединение:

SELECT S.NO, L.KEY
FROM SHOP S
LEFT OUTER JOIN LOCATN L ON S.NO = L.SHOP

но я получаю много дубликатов, так как есть много мест, принадлежащих одному магазину. Я хочу устранить их и просто получить список записей "магазин, ключ" без дубликатов.

Данные верны, но дубликаты выглядят следующим образом:

SHOP     KEY
 1       XXX
 1       XXX
 2       YYY
 3       ZZZ
 3       ZZZ  etc.

Я бы хотел, чтобы данные отображались следующим образом:

SHOP     KEY
 1       XXX
 2       YYY
 3       ZZZ  etc.

МАГАЗИН стол:

 NO
 1       
 2       
 3       

РАСПОЛОЖЕННЫЙ стол:

 LOCATION   SHOP  KEY
   L-1       1    XXX   
   L-2       1    XXX   
   L-3       2    YYY   
   L-4       3    YYY   
   L-5       3    YYY   

(база данных ORACLE 10g)

Ответы [ 3 ]

25 голосов
/ 28 марта 2010

Вам нужно GROUP BY 'S.No' & 'L.KEY'

SELECT S.NO, L.KEY 
FROM SHOP S 
LEFT OUTER JOIN LOCATN L 
ON S.NO = L.SHOP
GROUP BY S.NO, L.KEY
7 голосов
/ 28 марта 2010

РЕДАКТИРОВАТЬ После обновления в вашем сценарии

Я думаю, что вы должны сделать это с помощью простого подзапроса (хотя я не проверял это на базе данных Oracle). Что-то вроде следующего

UPDATE shop s
SET divnkey = (SELECT DISTINCT L.KEY FROM LOCATN L WHERE S.NO = L.SHOP)

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

Если вы просто хотите игнорировать эту возможность и выбрать произвольную в этом случае, вы можете использовать

UPDATE shop s
SET divnkey = (SELECT MAX(L.KEY) FROM LOCATN L WHERE S.NO = L.SHOP)
6 голосов
/ 11 декабря 2012

У меня тоже была эта проблема, но я не мог использовать GROUP BY, чтобы исправить ее, потому что я также возвращал поля типа TEXT. (То же самое касается использования DISTINCT).

Этот код дал мне дубликаты:

select mx.*, case isnull(ty.ty_id,0) when 0 then 'N' else 'Y' end as inuse 
from master_x mx 
left outer join thing_y ty on mx.rpt_id = ty.rpt_id

Я исправил это, переписав его так:

select mx.*, 
case when exists (select 1 from thing_y ty where mx.rpt_id = ty.rpt_id) then 'Y' else 'N' end as inuse
from master_x mx 

Как вы можете видеть, меня не заботили данные во 2-й таблице (thing_y), только то, было ли совпадение с нулевым значением в rpt_id внутри нее. (К вашему сведению: rpt_id также не был первичным ключом в первой таблице, master_x).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...