如何在按SQL分组中选择最小值行

时间:2019-05-09 12:00:32

标签: sql sqlite

这是我正在使用的与SQLite非常相似的数据库-

CREATE TABLE sampleData(
   pincode INTEGER NOT NULL,
   place_id INTEGER NOT NULL,
   price INTEGER NOT NULL,
   name TEXT NOT NULL,
   UNIQUE(pincode, place_id)
);

我一直在寻找每个密码中的地名(每个密码中只有1个地方),而那里的价格最低。我能想到的最简单的查询-

SELECT * FROM sampleData 
WHERE price > 0
GROUP BY pincode
ORDER BY PRICE

似乎可以在sqlite(?)中工作,但是不能在pg9.6中工作,并且在Mysql中给出错误的结果。这是另一个似乎给出相同结果的-

SELECT * FROM sampleData 
WHERE price > 0
GROUP BY pincode
HAVING MIN(PRICE)

与上一个结果相似。我想知道这些查询出了什么问题,希望能为您设计正确的查询提供一些帮助。

SQLFIDDLE

3 个答案:

答案 0 :(得分:4)

您的第一个查询是格式错误的SQL。 SELECT *GROUP BY没有任何意义。碰巧,SQLite扩展了SQL语言以执行您想要的操作。我认为这是一件坏事。

在任何情况下,您都可以这样做:

SELECT sd.*
FROM sampleData sd
WHERE sd.price = (SELECT MIN(sd2.price)
                  FROM sampleData sd2
                  WHERE sd2.price > 0 AND
                        sd2.pincode = sd.pincode
                 );

如果多个地方的价格相同,则这可以返回重复的行。假设place_id是唯一的,则可以将其修改为:

SELECT sd.*
FROM sampleData sd
WHERE sd.place_id = (SELECT sd2.place_id
                     FROM sampleData sd2
                     WHERE sd2.price > 0 AND
                           sd2.pincode = sd.pincode
                     ORDER BY sd2.price ASC
                     LIMIT 1
                    );

答案 1 :(得分:0)

尝试一下...

SELECT pincode,place,name,MIN(PRICE)
FROM sampleData 
WHERE price > 0
GROUP BY pincode,place,name

答案 2 :(得分:0)

您需要查询以获取每个price的最小值pincode,然后将其联接到表中:

select s.* 
from sampledata s inner join (
  select pincode, min(price) price
  from sampledata
  group by pincode
) g on g.pincode = s.pincode and g.price = s.price  

请参见demo
结果:

| pincode | place_id | price | name   |
| ------- | -------- | ----- | ------ |
| 123     | 2        | 13    | Place2 |
| 222     | 18       | 21    | Place5 |
| 456     | 5        | 200   | Place3 |