Как выбрать одну запись в левом соединении - PullRequest
26 голосов
/ 09 сентября 2011

Мне нужно выбрать конкретную модель из таблицы Models, используя ее ключ ModelID. Мне также нужно добавить всплеск содержимого из таблицы Model_Content. Однако таблица Models_Content содержит несколько фрагментов содержимого для каждой модели. Мне нужно выбрать только первый всплеск.

Мои таблицы выглядят так:

 Models // table
 ModelID // pk
 Model // varchar

 Models_Content // table
 ContentID // pk
 ModelID // fk
 Content // varchar

 SELECT M.ModelID, M.Model, C.Content
 FROM   Models M LEFT JOIN Models_Content C ON M.ModelID =  C.ModelID
 WHERE      M.ModelID = 5

Как мне настроить мой запрос, чтобы выбрать только самый первый всплеск контента для конкретной модели?

Ответы [ 7 ]

47 голосов
/ 09 сентября 2011
 SELECT
   M.ModelID, M.Model, C.Content
 FROM
   Models M
 LEFT JOIN
   Models_Content C
     ON C.ContentID = (SELECT MIN(ContentID) FROM Models_Content WHERE ModelID = M.ModelID)
 WHERE
   M.ModelID = 5

Или

;WITH sorted_content AS
(
  SELECT
    ROW_NUMBER() OVER (PARTITION BY ModelID ORDER BY ContentID) AS itemID,
    *
  FROM
    Models_Content
)
 SELECT
   M.ModelID, M.Model, C.Content
 FROM
   Models M
 LEFT JOIN
   sorted_content C
     ON  C.ModelID = M.ModelID
     AND C.itemID  = 1
 WHERE
   M.ModelID = 5
9 голосов
/ 09 сентября 2011

Ответ Шона - лучшее конкретное решение, но просто добавьте еще одно «обобщенное» решение

SELECT M.ModelID,
       M.Model,
       C.Content
FROM   Models M
       OUTER APPLY (SELECT TOP 1 *
                    FROM   Models_Content C
                    WHERE  M.ModelID = C.ModelID
                    ORDER  BY C.ContentID ASC) C
WHERE  M.ModelID = 5  
4 голосов
/ 09 сентября 2011
 SELECT TOP 1 M.ModelID, M.Model, C.Content
 FROM   Models M LEFT JOIN Models_Content C ON M.ModelID =  C.ModelID
 WHERE      M.ModelID = 5
 ORDER BY C.ContentID ASC
1 голос
/ 09 сентября 2011

Измените JOIN на:

LEFT JOIN (SELECT ModelID, MAX(Content) as Content FROM Models_Content GROUP BY ModelID)

Предполагается, что вам все равно, какой Content вы получите.

0 голосов
/ 10 марта 2016

Это может быть расширение ответа Рэнди, но мне это не совсем понятно.

Из соображений производительности я хотел минимизировать количество операторов SELECT в своем запросе, поэтому я использовал оператор MIN в основном выборе вместо JOIN:

SELECT 
    table_1.id AS id, 
    table_1.name AS name,
    MIN(table_2.id) AS table_2_id 
FROM table_1
LEFT JOIN table_2 ON table_2.table_1_id = table_1.id
-- additional JOINs and WHERE excluded
GROUP BY table_1.id, table_1.name
LIMIT 5

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

0 голосов
/ 09 сентября 2011
SELECT  M.ModelID
      , M.Model
      , (SELECT TOP 1 Content 
         FROM Models_Content 
         WHERE ModelID = M.ModelID 
         ORDER BY ContentId ASC) as Content
FROM    Models M 
WHERE   M.ModelID = 5
0 голосов
/ 09 сентября 2011

вы можете выбрать MIN ( contentID )

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