使用group by with sets

时间:2018-02-20 16:55:02

标签: sql join group-by impala

我可能会问错误的问题,但过去12个小时我一直在反对这个问题(我是初学者)并且无法找到如何得到我想要的东西:

我有下表名为“shipping_prices”

以下是我想要查询的内容: 在比较每个速度内的每个载波后返回最便宜的价格(因此结果是慢速,中速,快速的较低值)。

我写了这个查询:

SELECT carrier, speed, MIN(price) AS min_price 
FROM(
   SELECT speed, total_wt, zone, carrier, price
   FROM(
      SELECT speed, zone, total_wt, carrier, price
      FROM (
        SELECT key_id, carrier, zone, total_wt, speed, price
    FROM shipping_prices
    WHERE (speed = 'slow' OR speed = 'med' OR speed = 'fast')
    ) AS return_price
      WHERE total_wt = 45
      ) AS return_speed
   WHERE zone = 8
   ) as return_zone
GROUP BY carrier, speed;

但是这会在每个速度级别返回每个运营商的3个价格。

+---------+-------+-----------+
| carrier | speed | min_price |
+---------+-------+-----------+
| fedex   | med   | 257.23    |
| fedex   | slow  | 52.87     |
| fedex   | fast  | 328.16    |
| ups     | med   | 269.08    |
| ups     | fast  | 347.81    |
| ups     | slow  | 91.41     |
| usps    | med   | 103.95    |
| usps    | fast  | 261.1     |
| usps    | slow  | 97.78     |
+---------+-------+-----------+

我正在尝试使用子查询来处理它,但是使用连接可能更合适吗?

如果您要回答,请解释我想了解的内容。我经常遇到这些类型的问题,但我从来没有弄明白。

编辑:正在使用Impala查询此数据,该数据是在MySQL中创建并使用HIVE导入的。

谢谢!

2 个答案:

答案 0 :(得分:2)

这可以通过MIN窗口功能完成。子查询获取每个速度的最低价格。 PARTITION BY speed组速度值和MIN(price)每个速度的min价格超过该分组。 (运行内部查询以直观地了解窗口函数的工作原理)。此后,只需获取该行,请使用过滤条件。

SELECT carrier,speed,min_price
FROM (SELECT carrier, speed, price, MIN(price) OVER(PARTITION BY speed) as min_price
      FROM shipping_prices
      WHERE total_wt = 45 and zone = 8
     ) t
WHERE price=min_price

你可以使用像dense_rank这样的排名函数来完成相同的操作,当同一速度的不同运营商的最低价格相同时,它会处理关系。

SELECT carrier,speed,price as min_price
FROM (SELECT carrier, speed, price, DENSE_RANK() OVER(PARTITION BY speed ORDER BY price) as rnk
      FROM shipping_prices
      WHERE total_wt = 45 and zone = 8
     ) t
WHERE rnk=1

答案 1 :(得分:1)

此查询应该有效:

SELECT T1.carrier, T1.speed, T1.min_price 
    FROM (SELECT id 
              FROM shipping_pricing
              ORDER BY speed, min_price) AS Q1
    INNER JOIN shipping_pricing AS T1 ON T1.id = Q1.id
    GROUP BY T1.speed;

子查询正确地对数据进行排序并仅返回id,主查询加入id并获取所需的数据。通过对排序数据进行分组,您知道值是最小值(如果使用desc排序,则为最大值)