SQL один ко многим присоединяется без подзапроса? - PullRequest
2 голосов
/ 17 ноября 2010

У меня есть вопрос, связанный с запросом 1 к n, на который я надеялся, что кто-то может пролить некоторый свет.

Вот что я хочу сделать.В нескольких домах в каждом доме может быть несколько жильцов.Я хотел бы выбрать 5 домов и всех связанных с ними жильцов.Я знаю два способа сделать.Наиболее распространенным из них является оператор выбора для получения 5 домов, а затем второй оператор выбора, использующий условие IN для получения связанных жителей.Другой способ сделать это - вариация двух запросов с использованием одного запроса с подзапросом.

Есть ли другой способ выполнить без использования подзапроса?

Обновить:

Кажется, консенсус в том, что это невозможно с использованием подзапроса.

Ответы [ 5 ]

5 голосов
/ 17 ноября 2010

Обычно вы используете JOIN для получения связанных данных из обеих таблиц

SELECT
   *
FROM
   (SELECT TOP 5 * FROM Homes ORDER BY something) H
   JOIN
   Occupants O ON H.HomeID = O.HomeID

Тем не менее, ТОП 5 необходимо применять только к домам. Это будет ОГРАНИЧЕНИЕ с MySQL, а не ТОП тоже.

Edit:

Функция окна / ранжирования все еще нуждается в подзапросе или некотором косвенном указании, таком как CTE, чтобы разрешить фильтрацию сгенерированного числа.

SELECT
   *
FROM
   (SELECT *, ROW_NUMBER() OVER (ORDER BY something) AS RowNum
    FROM Homes) H
   JOIN
   Occupants O ON H.HomeID = O.HomeID
WHERE
   RowNum <= 5

;WITH CTE AS
(
   SELECT
    *, ROW_NUMBER() OVER (ORDER BY something) AS RowNum
   FROM
    Homes
 )
SELECT
   *
FROM
   CTE H
   JOIN
   Occupants O ON H.HomeID = O.HomeID
WHERE
   RowNum <= 5
1 голос
/ 17 ноября 2010

Вы можете сделать что-то вроде этого, в зависимости от поддержки движка БД:

select *
from
   (
       select top 5
           home_id,
           ... -- other columns
       from 
           home
       order by
           awesomeness desc
   ) h
       inner join occupant o on o.home_id = h.home_id
0 голосов
/ 17 ноября 2010

Если вы используете SQL Server (2005 и выше), вы можете использовать CTE

WITH MyTopFive (MyId, MyOtherField, SomeField) AS
(
SELECT TOP 5 MyId, MyOtherField, SomeField FROM Homes ORDER BY SomeField
)

SELECT * 
FROM Mytopfive t5
JOIN Occupants o ON o.myid = t5.myid

gbn имеет лучшее общее решение для баз данных.

0 голосов
/ 17 ноября 2010

Используйте внутреннее соединение. Каждый дом будет указан несколько раз, по одному на каждого жильца в этом доме.

select Home.HomeName, Occupant.OccupantName from Home 
inner join Occupant on Home.Id=Occupant.HomeId

И тогда вы получите:

Home1 OccupantA
Home1 OccupantB
Home2 OccupantC
Home2 OccupantD
0 голосов
/ 17 ноября 2010

sql для конкретного сервера

да, вы можете использовать объединение для этого.Вы не показали свою схему БД, но если я угадаю, вы, вероятно, захотите что-то вроде этого:

 select *, RANK() OVER (PARTITION BY home.homeid ORDER BY home.homeid DESC) as houserank
 from home
 join occupant on home.homeid = occupant.homeid
 where  houserank < 6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...