2010-04-26 71 views
2

有没有办法使用if语句选择记录?PostgreSQL如果查询?

我的表看起来像这样:

id | num | dis 
1 | 4 | 0.5234333 
2 | 4 | 8.2234 
3 | 8 | 2.3325 
4 | 8 | 1.4553 
5 | 4 | 3.43324 

我要选择numdis其中dis是最低数......所以,这将产生以下结果的查询:

id | num | dis 
1 | 4 | 0.5234333 
4 | 8 | 1.4553 
+0

如果有两行具有相同的num和dis,但是不同的id,哪些应该返回?或者你想要两个?或者这种情况不可能? – 2010-04-26 20:37:47

+0

您的表中大概会有多少行?还有多少组?表的大小与性能原因相关。 – 2010-04-27 06:23:21

回答

4

如果您想要组中的所有最小值的行:

SELECT id, num, dis 
FROM table1 T1 
WHERE dis = (SELECT MIN(dis) FROM table1 T2 WHERE T1.num = T2.num) 

或者你可以使用一个连接来获得相同的结果:

SELECT T1.id, T1.num, T1.dis 
FROM table1 T1 
JOIN (
    SELECT num, MIN(dis) AS dis 
    FROM table1 
    GROUP BY num 
) T2 
ON T1.num = T2.num AND T1.dis = T2.dis 

如果只想从每个组单列,即使有关系,那么你可以使用这个:

SELECT id, dis, num FROM (
    SELECT id, dis, num, ROW_NUMBER() OVER (PARTITION BY num ORDER BY dis) rn 
    FROM table1 
) T1 
WHERE rn = 1 

不幸的是,这不会非常有效。如果您需要更高效的服务,请参阅的selecting rows with a groupwise maximum for PostgreSQL页面。在这里他提出了几种方法来执行这个查询并解释每个方法的性能。从文章摘要如下:

与MySQL和PostgreSQL实现 几个清洁和记录的方式来 选择组保持明智 最大值,其中包括窗口功能 和DISTINCT ON记录。

但是由PostgreSQL的 优化 扫描的支持,缺乏宽松的指数和PostgreSQL的索引的效率较低的使用 ,使用这些功能的查询 花费太长时间。

要解决这些问题,并提高 针对低 基数分组条件的查询时,应使用在 文章中描述的某些 溶液。

该解决方案使用递归CTE对 效仿松散索引扫描,是非常有效的 如果分组列有 低基数。

1

使用此:

SELECT DISTINCT ON (num) id, num, dis 
FROM tbl 
ORDER BY num, dis 

或者,如果您打算在将来使用其它RDBMS,使用这样的:如果你需要有IF逻辑,你可以使用PL/pgSQL的

select * from tbl a where dis = 
(select min(dis) from tbl b where b.num = a.num)