SQL 一对多 JOIN 无需子查询?

发布于 2024-10-03 04:37:26 字数 305 浏览 6 评论 0原文

我有一个与 1 到 n 查询相关的问题,我希望有人能够解答这个问题。

这就是我想要实现的目标。

我有几个房子,每个房子可能有多个住户。我想选择 5 套房屋以及所有相关的居住者。我知道有两种方法。其中最常见的是一个 select 语句来获取 5 个房屋,然后使用 IN 条件的第二个 select 语句来获取关联的居住者。另一种方法是使用一个查询和一个子查询来实现两个查询的变体。

有没有其他方法可以在不使用子查询的情况下完成?

更新:

似乎一致认为使用子查询是不可能实现这一点的。

I've got a question related to a 1 to n query which I was hoping someone could shed some light on.

Here's what I'm looking to accomplish.

I have several homes each home may have multiple occupants. I'd like to select 5 homes and all the associated occupants. I know of two ways of doing. The most common of these is a select statement to get the 5 homes and then a second select statement using IN condition to get associated occupants. The other way to do this is a variation of the two queries using one query with a subquery.

Is there any other way to accomplish without the use of a subquery?

Update:

Seems the consensus is this is not possible with the use of a subquery.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

情绪操控生活 2024-10-10 04:37:26

您通常会使用 JOIN 从两个表中获取相关数据。

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

但是,TOP 5 只需要应用于 Homes。 MySQL 会是 LIMIT,而不是 TOP。

编辑:

窗口/排名函数仍然需要子查询或某些间接(例如 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

You'd normally use a JOIN to get related data from both tables

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

However, the TOP 5 needs to be applied to Homes only. It'd be LIMIT with MySQL, not TOP too.

Edit:

A window/ranking function still needs a sub-query or some indirection such as a CTE to allow filtering on the generated number.

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
梦中的蝴蝶 2024-10-10 04:37:26

您可以执行类似的操作,具体取决于数据库引擎支持:

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

You could do something like this, depending on DB engine support:

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
墟烟 2024-10-10 04:37:26

使用内连接。每个房屋都会被列出多次,该房屋中的每个居住者都会被列出一次。

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

然后你会得到:

Home1 OccupantA
Home1 OccupantB
Home2 OccupantC
Home2 OccupantD

Use an inner join. Each home will be listed multiple times, once for each occupant in that home.

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

And then you'll get:

Home1 OccupantA
Home1 OccupantB
Home2 OccupantC
Home2 OccupantD
多彩岁月 2024-10-10 04:37:26

如果您使用的是 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 拥有最好的通用数据库解决方案。

If you are using SQL Server (2005 and higher) you could use a 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 has the best generic database solution though.

ぃ弥猫深巷。 2024-10-10 04:37:26

特定于 SQL Server

是的,您可以使用联接来执行此操作。您没有显示您的数据库模式,但如果我猜测您可能想要这样的东西:

 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

sql server specific

yes you could use a join to do this. you did not show your db schema but if I take a guess you probably want something like this:

 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文