【问题标题】:SQL - JOIN newest 1 value in a one-to-many relationshipSQL - 在一对多关系中加入最新的 1 值
【发布时间】:2020-10-07 02:01:12
【问题描述】:

我有以下查询,其中显示有关“厨师”的信息,以及他们为食品服务应用销售的食品。它显示了每个卖家、一些个人信息以及他们在平台上销售的食品。

这是一个 postgresql 数据库。

当前查询引用并汇总来自 7 个不同表的数据。我在下面包含了每个表的图表,以及它们之间的链接关系。我同意,这个查询应该被拆分成单独的更相关的报告,但这是客户要求的。

这个查询几乎完成了,最后的要求是以某种方式包含一个列来显示每个食品项目的最近订购时间 (orders.time_placed)。

想到一个主要问题:

这可能吗?考虑到“订单”表没有包含所购买食品的列。 “订单”表仅链接回“商店”表......这让我相信我能做的最好的事情就是拉动每家商店的最后一次销售时间(而不是降低到商品级别)。

在四处搜索时,我发现了一些与我非常相似的情况——尤其是这个:link

虽然我没有成功实施该解决方案。是不是太复杂了?

这是我当前的查询:

select 
account.id as "Account ID",
account.firstname as "Seller First Name", 
account.lastname as "Seller Last Name",
account.email as "Seller Email",
account.phone as "Seller Phone",
address.address as "Seller Address (Street)",
address.address_2 as "Seller Address 2",
account.zip_code as "Seller Zip",
address.neighborhood as "Seller Neighborhood",
menu.name as "Name of active menu",
kitchen_item.name as "Dishes", 
kitchen_item.price as "Price",
kitchen_item.daily_max_orders as "Quantity",
menu.pickup_start_time as "Start time", 
menu.pickup_end_time as "End time",
menu.repeat_mon as "Monday",
menu.repeat_tues as "Tuesday",
menu.repeat_wed as "Wednesday",
menu.repeat_thurs as "Thursday",
menu.repeat_fri as "Friday",
menu.repeat_sat as "Saturday", 
menu.repeat_sun as "Sunday"
from account
left join store on account.id = store.account_id
left join menu on store.id = menu.store_id
left join menu_item on menu.id = menu_item.menu_id
left join kitchen_item on (menu_item.kitchen_item_id = kitchen_item.id and store.id = kitchen_item.store_id)
join store_address on store.id = store_address.store_id
join address on store_address.address_id = address.id
group by account.id, account.firstname, account.lastname, account.email, account.phone, address.address, address.address_2, account.zip_code, address.neighborhood, menu.name, kitchen_item.name, kitchen_item.price, kitchen_item.daily_max_orders, menu.pickup_start_time, menu.pickup_end_time, menu.repeat_mon, menu.repeat_tues, menu.repeat_wed, menu.repeat_thurs, menu.repeat_fri, menu.repeat_sat, menu.repeat_sun
order by account.id asc;

这是我试图从上面的链接中借用的解决方案......令人惊讶的是,它不起作用:)(插入到最后一个 JOIN 的正下方):

inner join (
    SELECT orders.store_id,
    MAX(orders.placed) maxdate
    from orders
    group by orders.store_id
    ) maxdates on account.id = maxdates.buyer_account_id INNER JOIN
    orders o on maxdates.store_id = store.id
    and maxdates.maxdate = o.placed

有没有更简单的方法来完成这个看似简单的任务? 谢谢

编辑 - 很抱歉,我意识到除了屏幕截图之外提供示例数据和预期输出对我来说有点太多了。链接问题中有一个简化示例,但我不知道如何在此处将逻辑应用于我的查询。

【问题讨论】:

    标签: sql postgresql join


    【解决方案1】:

    正如您所怀疑的,您无法查询您没有的数据。由于您的架构不包含有关何时订购某些商品的任何信息,因此您无法检索该信息。

    要获得商店的最新促销信息,您可以使用 postgresql 的 DISTINCT ON(请参阅docs)。

    select distinct on (account.id, kitchen_item.name)
    account.id as "Account ID",
    account.firstname as "Seller First Name", 
    account.lastname as "Seller Last Name",
    account.email as "Seller Email",
    account.phone as "Seller Phone",
    address.address as "Seller Address (Street)",
    address.address_2 as "Seller Address 2",
    account.zip_code as "Seller Zip",
    address.neighborhood as "Seller Neighborhood",
    menu.name as "Name of active menu",
    kitchen_item.name as "Dishes", 
    kitchen_item.price as "Price",
    kitchen_item.daily_max_orders as "Quantity",
    menu.pickup_start_time as "Start time", 
    menu.pickup_end_time as "End time",
    menu.repeat_mon as "Monday",
    menu.repeat_tues as "Tuesday",
    menu.repeat_wed as "Wednesday",
    menu.repeat_thurs as "Thursday",
    menu.repeat_fri as "Friday",
    menu.repeat_sat as "Saturday", 
    menu.repeat_sun as "Sunday",
    orders.time_placed as "Last Store Sale"
    from account
    left join store on account.id = store.account_id
    left join menu on store.id = menu.store_id
    left join menu_item on menu.id = menu_item.menu_id
    left join kitchen_item on (menu_item.kitchen_item_id = kitchen_item.id and store.id = kitchen_item.store_id)
    left join orders on (orders.store_id = store.id)
    join store_address on store.id = store_address.store_id
    join address on store_address.address_id = address.id
    order by account.id asc, kitchen_item.name asc, orders.time_placed desc;
    

    【讨论】:

    • 感谢您的意见。我没有创建这个数据库,所以我想在发布坏消息之前保持积极态度。所以我能做的最好的就是在最后一列中列出每个商店的最近订单时间(max(orders.placed)?)。非常感谢,我会试一试的。
    • 另外,虽然我认为你很接近......但有一个问题。最初,查询返回 3 行(这个厨师的“菜肴”(kitchen_item.name)中的每一个都有一行。当我尝试你的实现时,它只返回一行。我试图在 kitchen_item.name 上选择不同的,但是那个错误出来了。现在正在努力解决这个问题。再次感谢
    • 啊,抱歉,编辑了我的代码以包含多道菜的选项。
    • 你先生,是个魔术师!我最终不得不将 menu.name 添加到“select distinct on”以及底部的“order by”中,以考虑多个菜单,但它现在看起来可以工作了。那么我应该添加可能具有多个不同值的每一列吗?我希望我明白它是如何工作的。哈哈。谢谢!
    • 我建议阅读文档或 postgres DISTINCT ON 的教程。其实也不是很复杂!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多