WedX - журнал о программировании и компьютерных науках

Левое соединение без повторяющихся строк из левой таблицы

Посмотрите на следующий запрос:

tbl_Contents

Content_Id  Content_Title    Content_Text
10002   New case Study   New case Study
10003   New case Study   New case Study
10004   New case Study   New case Study
10005   New case Study   New case Study
10006   New case Study   New case Study
10007   New case Study   New case Study
10008   New case Study   New case Study
10009   New case Study   New case Study
10010   SEO News Title   SEO News Text
10011   SEO News Title   SEO News Text
10012   Publish Contents SEO News Text

tbl_Media

Media_Id    Media_Title  Content_Id
1000    New case Study   10012
1001    SEO News Title   10010
1002    SEO News Title   10011
1003    Publish Contents 10012

ЗАПРОС

SELECT 
C.Content_ID,
C.Content_Title,
M.Media_Id

FROM tbl_Contents C
LEFT JOIN tbl_Media M ON M.Content_Id = C.Content_Id 
ORDER BY C.Content_DatePublished ASC

РЕЗУЛЬТАТ

10002   New case Study  2014-03-31 13:39:29.280 NULL
10003   New case Study  2014-03-31 14:23:06.727 NULL
10004   New case Study  2014-03-31 14:25:53.143 NULL
10005   New case Study  2014-03-31 14:26:06.993 NULL
10006   New case Study  2014-03-31 14:30:18.153 NULL
10007   New case Study  2014-03-31 14:30:42.513 NULL
10008   New case Study  2014-03-31 14:31:56.830 NULL
10009   New case Study  2014-03-31 14:35:18.040 NULL
10010   SEO News Title  2014-03-31 15:22:15.983 1001
10011   SEO News Title  2014-03-31 15:22:30.333 1002
10012   Publish         2014-03-31 15:25:11.753 1000
10012   Publish         2014-03-31 15:25:11.753 1003

10012 идут дважды ...!

Мой запрос возвращает повторяющиеся строки из tbl_Contents (левая таблица в соединении)

Некоторые строки в tbl_Contents имеют более 1 связанной строки в tbl_Media. Мне нужны все строки из tbl_Contents, даже если в tbl_Media существуют значения Null, НО НЕТ ДУБЛИКАЦИОННЫХ ЗАПИСЕЙ.

31.03.2014

  • Это работает так, как задумано - строки не дублируются, каждая имеет свой media_id. В вашем примере, какую строку вы бы оставили? 31.03.2014
  • В вашем tbl_Media нет Content_Id. 31.03.2014
  • Я согласен, здесь нет никаких проблем. Это два разных ряда. 31.03.2014
  • Пожалуйста, проверьте обновленный / исправленный tbl_Media - теперь есть столбец Content_Id, спасибо 31.03.2014

Ответы:


1

Попробуйте OUTER APPLY

SELECT 
    C.Content_ID,
    C.Content_Title,
    C.Content_DatePublished,
    M.Media_Id
FROM 
    tbl_Contents C
    OUTER APPLY
    (
        SELECT TOP 1 *
        FROM tbl_Media M 
        WHERE M.Content_Id = C.Content_Id 
    ) m
ORDER BY 
    C.Content_DatePublished ASC

В качестве альтернативы вы можете GROUP BY результаты

SELECT 
    C.Content_ID,
    C.Content_Title,
    C.Content_DatePublished,
    M.Media_Id
FROM 
    tbl_Contents C
    LEFT OUTER JOIN tbl_Media M ON M.Content_Id = C.Content_Id 
GROUP BY
    C.Content_ID,
    C.Content_Title,
    C.Content_DatePublished,
    M.Media_Id
ORDER BY
    C.Content_DatePublished ASC

OUTER APPLY выбирает одну строку (или ни одной), которая соответствует каждой строке из левой таблицы.

GROUP BY выполняет все соединение, но затем сворачивает строки окончательного результата в предоставленных столбцах.

31.03.2014
  • Использование GROUP BY в этой ситуации приведет к двойному подсчету строк, если используется вместе с агрегатными функциями, такими как SUM или COUNT. 07.09.2016
  • Только если агрегатные функции не учитывают эту ситуацию должным образом ... 07.09.2016
  • Я думаю, вы забыли добавить агрегатную функцию к своему выбору для M.Media_Id. Эти столбцы не разрушатся сами по себе. В таком виде запрос должен выдавать ошибку imho. 04.07.2018
  • @vargen_, это точно. Я отредактировал ответ, чтобы отразить правильную агрегацию 05.07.2018

  • 2

    Вы можете сделать это, используя общий SQL с group by:

    SELECT C.Content_ID, C.Content_Title, MAX(M.Media_Id)
    FROM tbl_Contents C LEFT JOIN
         tbl_Media M
         ON M.Content_Id = C.Content_Id 
    GROUP BY C.Content_ID, C.Content_Title
    ORDER BY MAX(C.Content_DatePublished) ASC;
    

    Или с коррелированным подзапросом:

    SELECT C.Content_ID, C.Contt_Title,
           (SELECT M.Media_Id
            FROM tbl_Media M
            WHERE M.Content_Id = C.Content_Id
            ORDER BY M.MEDIA_ID DESC
            LIMIT 1
           ) as Media_Id
    FROM tbl_Contents C 
    ORDER BY C.Content_DatePublished ASC;
    

    Конечно, синтаксис limit 1 зависит от базы данных. Может быть top. Или rownum = 1. Или fetch first 1 rows. Или что-то вроде того.

    31.03.2014
  • Как я вижу, форма OP в таблице tbl_Media отсутствует столбец Content_Id. 31.03.2014
  • Пожалуйста, проверьте обновленный / исправленный tbl_Media - теперь есть столбец Content_Id, спасибо 31.03.2014
  • Не будет ли производительность коррелированного подзапроса действительно плохой? Я сталкивался с таким запросом на больших наборах результатов, и это было ужасно. Для каждой сопоставленной строки выполняется дополнительный запрос. 06.02.2015
  • @ mdon88. . . Производительность должна быть хорошей с индексом на tbl_Media(ContentId, Media_id). 06.02.2015

  • 3

    Использование флага DISTINCT удалит повторяющиеся строки.

    SELECT DISTINCT
    C.Content_ID,
    C.Content_Title,
    M.Media_Id
    
    FROM tbl_Contents C
    LEFT JOIN tbl_Media M ON M.Content_Id = C.Content_Id 
    ORDER BY C.Content_DatePublished ASC
    
    05.09.2018
  • добавление DISTINCT к запросам может быть очень неэффективным (в postgress с 5000+ строками я видел 10-кратное увеличение времени запроса) 13.02.2019
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]