sql在排序结果上选择前n个唯一行

时间:2014-10-11 09:28:59

标签: sql postgresql greatest-n-per-group

我查询了1列字符串,结果示例:

NAME:
-----
SOF
OTP
OTP
OTP
SOF
VIL
OTP
SOF
GGG

我希望能够获得SOF,OTP,VIL - 前3个独特的顶部,
我尝试使用DISTINCT和GROUP BY,但它不起作用,排序已损坏..

构建此结果的查询是:

SELECT DISTINCT d.adst 
FROM   (SELECT a.date              adate, 
               b.date              bdate, 
               a.price + b.price   total, 
               ( b.date - a.date ) days, 
               a.dst               adst 
        FROM   flights a 
               JOIN flights b 
                 ON a.dst = b.dst 
        ORDER  BY total) d 

我有详细的“航班”表,我需要获得3(= n)个最便宜的目的地。

由于

6 个答案:

答案 0 :(得分:2)

这可以使用窗口函数轻松完成:

select *
from (
       SELECT a.date as adate, 
              b.date as bdate, 
              a.price + b.price as total, 
              dense_rank() over (order by a.price + b.price) as rnk,
              b.date - a.date as days, 
              a.dst  as adst 
        FROM  flights a 
          JOIN flights b ON a.dst = b.dst 
) t
where rnk <= 3
order by rnk;

有关窗口功能的更多详细信息,请参见手册:
http://www.postgresql.org/docs/current/static/tutorial-window.html

答案 1 :(得分:0)

SELECT DISTINCT ON (column_name) FROM table_name order by name LIMIT 3;

答案 2 :(得分:0)

select 
   name
from 
   testname 
where 
   name in (
   select distinct(name) from testname) 
group by name order by min(ctid) limit 3

SQLFIDDLE DEMO

答案 3 :(得分:0)

SELECT DISTINCT(`EnteredOn`) FROM `rm_pr_patients` Group By `EnteredOn`

答案 4 :(得分:0)

找到一种方法。

我正在选择DST和PRICE,按价格分配DST和MIN功能并限制3。

我有更好的方法吗?

SELECT d.adst , min(d.total) mttl
FROM   (SELECT a.date              adate, 
               b.date              bdate, 
               a.price + b.price   total, 
               ( b.date - a.date ) days, 
               a.dst               adst 
    FROM   flights a 
           JOIN flights b 
             ON a.dst = b.dst 
    ORDER  BY total) d 
group by adst order by mttl;

答案 5 :(得分:0)

您可以调整查询以返回正确的结果,方法是在外部查询中添加where days > 0limit 3,如下所示:

select *
from 
(
   select 
     a.date adate, 
     b.date bdate, 
     (a.price + b.price) total, 
     (b.date - a.date) days , 
     a.dst adst
   from flights a 
   join flights b on a.dst = b.dst 
   order by total
) d
where days > 0
limit 3;

这假设第二个条目是date大于第一个条目的回程航班。这样你就有了积极的差异。


请注意,没有days > 0的查询将为您提供表格与自身之间的交叉联接,对于每个航班,您将获得4行,其中两行自带天数= 0和其他行有负天数所以我使用days > 0来获取正确的行。

我建议您添加一个新列,一个Id Flight_Id作为主键,另一个外键如From_Flight_Id。因此,主要航班将有null From_Flight_Id,返回航班的From_Flight_Id等于主要航线的flight_id,这样您就可以正常加入代替。