简体   繁体   English

如何在 PostgreSQL 中获取不同城市的最新日期

[英]How to get latest date in distinct city in PostgreSQL

I'm currently trying to do a task on PostgreSQL right now where I need to prepare a list of cities with their date of last reservation which also must include a hotel ID, and a photo.我目前正在尝试在 PostgreSQL 上执行一项任务,我需要准备一份城市列表及其最后预订日期,其中还必须包括酒店 ID 和照片。

Here's my SQL query thus far:到目前为止,这是我的 SQL 查询:

SELECT city.name, booking.booking_date as last_booking_date, hotel.id as hotel_id, hotel.photos ->> 0 as hotel_photo
FROM city 
INNER JOIN hotel
    ON city.id = hotel.city_id 
INNER JOIN booking 
    ON booking.hotel_id = hotel.id
WHERE 
    booking.booking_date = (SELECT MAX(booking_date) FROM booking WHERE hotel_id = hotel.id)
ORDER BY city.name ASC;

Now what this does is return the cities (sorted in alphabetical order, and can duplicate) which also contains their booking dates (also sorted from earliest to latest).现在它所做的是返回城市(按字母顺序排序,并且可以重复),其中还包含它们的预订日期(也从最早到最晚排序)。 If many hotels have the same amount of bookings, then I'll have to sort them by ID如果许多酒店的预订量相同,那么我将不得不按 ID 对它们进行排序

Thanks to the answer below, and with some minor tweaks, I was able to return the distinct cities in alphabetical order, but not by their latest date for some cities.感谢下面的答案,并进行了一些小的调整,我能够按字母顺序返回不同的城市,但不能按某些城市的最新日期返回。

SELECT distinct on (city.name) 
  city.name, 
  booking.booking_date as last_booking_date, 
  hotel.id as hotel_id, 
  hotel.photos ->> 0 as hotel_photo
FROM city 
INNER JOIN hotel
    ON city.id = hotel.city_id 
INNER JOIN booking 
    ON booking.hotel_id = hotel.id
WHERE 
    booking.booking_date = (SELECT MAX(booking_date) 
                            FROM booking
                            WHERE hotel_id = hotel.id)
    AND 
    booking.id = (SELECT MAX(id) FROM booking WHERE hotel_id = hotel.id)
ORDER BY city.name, hotel.id ASC, booking.booking_date ASC;

This has the following result, with the expected result shown as well.这具有以下结果,并显示了预期的结果。 在此处输入图像描述

As you can see, some cities are not sorted by their latest date of booking.如您所见,某些城市未按最新预订日期排序。 I've tried variations of the SQL query above such as:我已经尝试过上面的 SQL 查询的变体,例如:

SELECT distinct on (city.name) 
  city.name, 
  booking.booking_date as last_booking_date, 
  hotel.id as hotel_id, 
  hotel.photos ->> 0 as hotel_photo
FROM city 
INNER JOIN hotel
    ON city.id = hotel.city_id 
INNER JOIN booking 
    ON booking.hotel_id = hotel.id
WHERE 
    booking.booking_date = (SELECT MAX(booking_date) 
                            FROM booking
                            WHERE hotel_id = hotel.id)
    AND 
    booking.hotel_id = (SELECT MAX(hotel_id) FROM booking WHERE hotel_id = hotel.id)
ORDER BY city.name, hotel.id ASC, booking.booking_date ASC;

and

SELECT distinct on (city.name) 
  city.name, 
  booking.booking_date as last_booking_date, 
  hotel.id as hotel_id, 
  hotel.photos ->> 0 as hotel_photo
FROM city 
INNER JOIN hotel
    ON city.id = hotel.city_id 
INNER JOIN booking 
    ON booking.hotel_id = hotel.id
WHERE 
    booking.booking_date = (SELECT MAX(booking_date) 
                            FROM booking
                            WHERE hotel_id = hotel.id)
    AND 
    booking.id = (SELECT MAX(id) FROM booking WHERE hotel_id = hotel.id)
    AND 
    booking.hotel_id = (SELECT MAX(hotel_id) FROM booking WHERE hotel_id = hotel.id)
ORDER BY city.name, hotel.id ASC, booking.booking_date ASC;

But they all show the same result as the one earlier.但它们都显示出与前一个相同的结果。

With that, how do I get the row with the latest date?有了这个,我如何获得最新日期的行? For context, this is what the first query returns.对于上下文,这是第一个查询返回的内容。 在此处输入图像描述

Use DISTINCT ON .使用DISTINCT ON It will pick the first element for the subset, according to the ordering in the ORDER BY clause.它将根据ORDER BY子句中的顺序选择子集的第一个元素。 For example:例如:

SELECT distinct on (city.name) -- changed here
  city.name, 
  booking.booking_date as last_booking_date, 
  hotel.id as hotel_id, 
  hotel.photos ->> 0 as hotel_photo
FROM city 
INNER JOIN hotel
    ON city.id = hotel.city_id 
INNER JOIN booking 
    ON booking.hotel_id = hotel.id
WHERE 
    booking.booking_date = (SELECT MAX(booking_date) 
                            FROM booking
                            WHERE hotel_id = hotel.id)
ORDER BY city.name, booking.booking_date DESC; -- changed here

I believe, you do not need the WHEN subquery.我相信,您不需要 WHEN 子查询。 Your ORDER BY statement is slightly off: it first sorts by city, then by hotel and only then choses a date.您的 ORDER BY 语句略有偏差:它首先按城市排序,然后按酒店排序,然后才选择日期。 So, if you modify ORDER BY to be by city.name, date DESC and then hotel_id it should make the work.因此,如果您将 ORDER BY 修改为按 city.name、date DESC 和 hotel_id,它应该可以正常工作。
Find the code below:找到下面的代码:

SELECT distinct on (city.name) 
  city.name, 
  booking.booking_date as last_booking_date, 
  hotel.id as hotel_id, 
  hotel.photos ->> 0 as hotel_photo
FROM city 
INNER JOIN hotel
    ON city.id = hotel.city_id 
INNER JOIN booking 
    ON booking.hotel_id = hotel.id
ORDER BY city.name, booking.booking_date DESC, hotel.id ASC;

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

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