PostgreSQL如果查询?
问题描述:
有没有办法使用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
我要选择num
和dis
其中dis
是最低数......所以,这将产生以下结果的查询:
id | num | dis
1 | 4 | 0.5234333
4 | 8 | 1.4553
答
如果您想要组中的所有最小值的行:
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对 效仿松散索引扫描,是非常有效的 如果分组列有 低基数。
答
使用此:
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)
答
。
http://www.postgresql.org/docs/8.4/interactive/plpgsql-control-structures.html
但尝试用SQL解决您的问题,第一,如果可能的话,这将是更快,使用PL/pgSQL在SQL解决不了你的问题。
如果有两行具有相同的num和dis,但是不同的id,哪些应该返回?或者你想要两个?或者这种情况不可能? – 2010-04-26 20:37:47
您的表中大概会有多少行?还有多少组?表的大小与性能原因相关。 – 2010-04-27 06:23:21