具有条件空值的PostgreSQL查询,具体取决于前面的行

时间:2012-02-27 15:56:41

标签: sql postgresql

我正在研究一个postgresql查询,我不知道如何生成输出。

假设我有一个sql查询,我想要的输出是

         name    date     visit_number  visit
          x    2011-01-01     123         ??   (value i want=1)
          y    2011-01-01     123         ??   (value i want=empty)
          a    2011-02-02     345         ??   (value i want=1) 
          b    2011-02-02     345         ??    (empty)
          c    2011-02-02     345         ??     (empty)

目前我的sql查询包含除最后一列访问之外的所有值。我希望访问列以这种方式工作...如果visit_number包含多行的相同值,我希望列访问显示第一行的值1,对于visit_number相同的其余行只显示null或空。我该怎么做???

我可以用任何方式编写示例查询。它可以简单地是:

    select name,date,visit_number from sometable order by date;

我正在使用postgres 8.1版本。

由于

2 个答案:

答案 0 :(得分:0)

您应该做的第一件事是升级到PostgreSQL的现代版本。 Version 8.1 has reached end of life in November 2010

在更新的版本中,您可以使用window functions

方便地解决此问题
SELECT name, date, visit_number
     , CASE WHEN row_number() OVER (PARTITION BY visit_number
                                    ORDER BY date, name) = 1
          THEN 1
          ELSE NULL
       END AS visit
FROM   tbl
ORDER  BY date, name;

我还通过名字命令打破关系。


对于PostgreSQL 8.4之前的版本,此查询应该有效(未经测试):

SELECT name, date, visit_number
     , CASE WHEN EXISTS (
         SELECT *
         FROM   tbl t1
         WHERE  t1.visit_number =  tbl.visit_number -- more to make it unique?
         AND    t1.date <= tbl.date -- or more columns to make order unambiguous
         AND    t1.name <  tbl.name
         )
       THEN NULL ELSE 1 END AS visit
FROM   tbl
ORDER  BY date, name;

答案 1 :(得分:0)

这是查询:

select *, 
  case when row_number() over (partition by visit_number) = 1
    then 1
    else null
  end
from t

这是example

修改

没有窗口功能:

select t4.*, case when t3.name is not null then 1 end as visit from t t4
left join (
  select t1.* from t t1
  left join t t2 on t1.name > t2.name and t1.date = t2.date and 
    t1.visit_number = t2.visit_number
  where t2.name is null
) as t3
on t3.name = t4.name and t3.date = t4.date and t3.visit_number = t4.visit_number

这是example

注意:如果name是密钥,则可以删除最后一次比较t3.date = t4.date and t3.visit_number = t4.visit_number