首页 > 解决方案 > 在 SQL 中编写多个子查询是否有更好的选择?

问题描述

我在 Redash 上查询以提取带有定价网格的停车位汇总列表。列表包含停车详细信息(名称、地址、链接)和多个定价列,具体取决于停留时间。

我正在使用两张桌子(公园和优惠)。报价表具有三个字段,park_id、价格和持续时间。每个 park_id 可能具有对应于特定停留时间的价格。例如,公园 #1 的 3600 秒收费 2 美元,86400 秒收费 30 美元,以此类推。

我编写了单独的子查询来获取每个持续时间的这些价格,从 1 小时到 24 小时(1 天),然后持续到 31 天,然后是 93 天、186 天和 372 天。总共有 57 个子查询。

结果表有 57 列价格(price1h、price2h….price1d、price 2d….. price31d、price93d、price186d、price372d)。

条件:我必须使用两个重要条件来获得价格。一个是 offer.duration = 3600/7200 等,然后我筛选出哪些套餐类型而不是订阅类型的优惠。最后,AND offer.park_id = parks.id 链接表 park 和 offer 中的两个关键字段。

问题是我在不同的持续时间内多次重复这个子查询,执行速度非常慢并且超过了'Redash查询执行时间限制'</p>

查询的片段如下:

SELECT DISTINCT parkid AS ID,
park_name AS Name,
park_address AS full_address,
park_url_description AS park_url,

      (SELECT offers.price
          FROM offers
          WHERE offers.type = 'package'
            AND offers.duration = 3600
            AND offers.park_id = park.parkid) AS price1h,
         
           (SELECT offers.price
           FROM offers
           WHERE offers.type = 'package'
           AND offers.duration = 7200
           AND offers.park_id = park.parkid) AS price2h,       

          (SELECT offers.price
          FROM offers
          WHERE offers.type = 'package'
          AND offers.duration = 10800
          AND offers.park_id = park.parkid) AS price3h,       
          …….. /* and so on */
FROM park
LEFT JOIN offers ON park.parkid = offers.park_id
GROUP BY id, Name, full_address, park_url

结果表是这样的: https ://i.stack.imgur.com/0opp0.png

谁能建议一个更好的选择来获得这些价格?我尝试使用 CTE 方法,但我没有足够的经验,所以我无法提出解决方案(我是实习生,仍在学习。)提前谢谢你。

标签: mysqlredash

解决方案


假设您每个公园+持续时间有一个报价,您可以通过有条件地使用聚合函数来做到这一点:

SELECT 
  p.parkid AS ID,
  p.park_name AS Name,
  p.park_address AS full_address,
  p.park_url_description AS park_url,
  max(if (o.duration = 3600, o.price, null)) as price1h,
  max(if (o.duration = 7200, o.price, null)) as price2h,
  max(if (o.duration = 10800, o.price, null)) as price3h
FROM park p
  LEFT JOIN offers o ON p.parkid = o.park_id and o.type = 'package'
  AND o.duration in (3600, 7200, 10800)
GROUP BY p.parkid, p.park_name, p.park_address, p.park_url_description

dbfiddle


推荐阅读