Postgresql - как получить записи в таблице, которые не совпадают в другой таблице - PullRequest
19 голосов
/ 24 февраля 2012

У меня есть вопрос, но я не знаю, как его задать! Пожалуйста, потерпите меня:

SELECT      sc.*, 
        scd.siteid, scd.desc_frontend
FROM        shipping_code sc
LEFT OUTER JOIN shipping_code_description scd
    ON          scd.shippingid=sc.shippingid
    AND         scd.siteid IN (SELECT siteid FROM site_international WHERE published='t')

Для объяснения вышеизложенного у нас есть коды доставки (доставки) в одной таблице, называемой «код_отправки», и, поскольку у нас многоязычный сайт, у нас есть другая таблица с описаниями языков для этих кодов в разделе «код_доставки». У нас также есть таблица с названием «site_international», которая имеет следующие поля: «siteid» (идентификатор сайта - например, для Великобритании, DE, FR .. (английский, немецкий, французский ..) и «опубликовано» (логическое поле, т.е. сайт жив или нет?

Приведенный выше запрос SELECT получает все коды доставки с описаниями их языков только для этих опубликованных сайтов.

Теперь мы также хотим знать, какие коды доставки НЕ имеют описания на определенных сайтах. Если код доставки совершенно новый, то для этого кода будет возвращена 1 строка (из-за LEFT OUTER JOIN). 'Scd.siteid' и 'scd.desc_frontend' будут иметь значение NULL.

Однако, если описание для британского (английского) сайта существует, но описания для FR и DE не существует, то вышеупомянутый запрос просто вернет ОДНУ строку, а не ТРИ строки. Как я могу сказать, что описания DE и FR отсутствуют для определенного кода доставки?

Вот мои варианты:

1) Я мог бы как-то сделать все это в одном запросе. Должен быть способ ( Я никогда раньше не использовал UNION, EXCEPT и т. Д., И я не уверен, что это то, что я должен использовать ).

2) ИЛИ я мог бы просто сделать еще один запрос ВЫБЕРИТЕ siteid ИЗ ОТ site_international ГДЕ опубликовано = 't'

и выше приведут мне все опубликованные сайты. Затем, используя PHP (который я использую для кодирования своего сайта), для каждого результата вышеупомянутого более крупного запроса я проверю и посмотрю, отсутствуют ли какие-либо описания. Например. Приведенный выше запрос siteid вернет 3 идентификатора (UK, DE, FR). Затем, если для определенного кода доставки будет возвращена только одна британская строка, я буду знать, что DE и FR отсутствуют, и я могу пометить это своему клиенту.

Сообщите, пожалуйста, существует ли лучший вариант "1"?

Большое спасибо!

Ответы [ 2 ]

38 голосов
/ 24 февраля 2012

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

SELECT  l.*
FROM    t_left l
LEFT JOIN t_right r
ON      r.value = l.value
WHERE   r.value IS NULL
1 голос
/ 24 февраля 2012

Я думаю, это то, что вы ищете.Левое соединение получает все возможные пары кода доставки и кода сайта, а затем определяет, какие из них не имеют записи в таблице описаний.Это то, что делает предложение Exists.

SELECT      
    Shipping_Code.*,
    Site_International.SiteID 
FROM        
    Shipping_Code 
    LEFT JOIN Site_International ON Site_International.Published = 't'
WHERE
    NOT EXISTS (
        SELECT
            NULL
        FROM
            Shipping_Code_Description
        WHERE
            Shipping_Code.ShippingID = Shipping_Code_Description.ShippingID
        AND SiteInternational.SiteID = Shipping_Code_Description.SiteID)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...