简体   繁体   English

SQL:选择 max(A), B 但不想分组或聚合 B

[英]SQL: select max(A), B but don't want to group by or aggregate B

If I have a house with multiple rooms, but I want the color of the most recently created, I would say:如果我有一个有多个房间的房子,但我想要最近创建的颜色,我会说:

select house.house_id, house.street_name, max(room.create_date), room.color
from house, room
where house.house_id = room.house_id
and house.house_id = 5
group by house.house_id, house.street_name

But I get the error:但我收到错误:

Column 'room.color' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.列“room.color”在选择列表中无效,因为它既不包含在聚合函数中也不包含在 GROUP BY 子句中。

If I say max(room.color), then sure, it will give me the max(color) along with the max(create_date), but I want the COLOR OF THE ROOM WITH THE MAX CREATE DATE.如果我说 max(room.color),那么当然,它会给我 max(color) 和 max(create_date),但我想要具有最大创建日期的房间的颜色。

just added the street_name because I do need to do the join, was just trying to simplify the query to clarify the question..刚刚添加了 street_name 因为我确实需要进行连接,只是试图简化查询以澄清问题..

In standard SQL, you would write this as:在标准 SQL 中,您可以将其写为:

select r.house_id, r.create_date, r..color
from room r
where r.house_id = 5
order by r.create_date desc
offset 0 row fetch first 1 row only;

Note that the house table is not needed.请注意,不需要house表。 If you did need columns from it, then you would use join / on syntax.如果您确实需要其中的列,那么您可以使用join / on语法。

Not all databases support the standard offset / fetch clause.并非所有数据库都支持标准的offset / fetch子句。 You might need to use limit , select top or something else depending on your database.根据您的数据库,您可能需要使用limitselect top或其他内容。

The above works in SQL Server, but is probably more commonly written as:以上适用于 SQL Server,但可能更常见的写法是:

select top (1) r.house_id, r.create_date, r..color
from room r
where r.house_id = 5
order by r.create_date desc;

One option is WITH TIES and also best to use the explicit JOIN一种选择是WITH TIES并且最好使用显式JOIN

If you want to see ties, change row_number() to dense_rank()如果你想看dense_rank() ,把row_number() dense_rank()

select top 1 with ties
       house.house_id
      ,room.create_date
      , room.color
from house
join room  on house.house_id = room.house_id
Where house.house_id = 5
Order by row_number() over (partition by house.house_ID order by room.create_date desc)

You could order by create_date and then select top 1:您可以按 create_date 订购,然后选择前 1 个:

select top 1 house.house_id, room.create_date, room.color
from house, room
where house.house_id = room.house_id
and house.house_id = 5
order by room.create_date desc

Expanding this to work for any number of houses (rather than only working for exactly one house)...将此扩展为适用于任意数量的房屋(而不是仅适用于一所房屋)......

SELECT
  house.*,
  room.*
FROM
  house
OUTER APPLY
(
  SELECT TOP (1) room.create_date, room.color
    FROM room
   WHERE house.house_id = room.house_id
ORDER BY room.create_date DESC
)
  AS room

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM