选择一行第一个非空值

时间:2015-12-18 02:54:12

标签: database postgresql

我有下表。如果评论者投票列具有相同的 product_id ,我该如何选择第一个非空值?第一行是指按 created_at

排序的第一行
+------------+-----------+--------+---------------------+
| product_id | reviewers | voting |     created_at      |
+------------+-----------+--------+---------------------+
| B0021ZFV9M | null      | null   | 2015-03-20 00:34:09 |
| B0021ZFV9M | 4         | 3      | 2015-03-24 00:34:09 |
| B0021ZFV9M | null      | null   | 2015-04-13 00:55:51 |
| B0021ZFV9M | 30        | 4      | 2015-04-15 00:44:38 |
| B00JKO4CHO | null      | null   | 2015-09-17 00:41:40 |
| B00JKO4CHO | null      | null   | 2015-09-19 00:41:47 |
| B00JKO4CHO | 50        | 1      | 2015-09-21 00:41:31 |
+------------+-----------+--------+---------------------+

预期

+------------+-----------+--------+---------------------+
| product_id | reviewers | voting |     created_at      |
+------------+-----------+--------+---------------------+
| B0021ZFV9M | 4         | 3      | 2015-03-20 00:34:09 |
| B0021ZFV9M | 4         | 3      | 2015-03-24 00:34:09 |
| B0021ZFV9M | 30        | 4      | 2015-04-13 00:55:51 |
| B0021ZFV9M | 30        | 4      | 2015-04-15 00:44:38 |
| B00JKO4CHO | 50        | 1      | 2015-09-17 00:41:40 |
| B00JKO4CHO | 50        | 1      | 2015-09-19 00:41:47 |
| B00JKO4CHO | 50        | 1      | 2015-09-21 00:41:31 |
+------------+-----------+--------+---------------------+

2 个答案:

答案 0 :(得分:1)

试试这个:

set req.http.ThisUserId = regsub(req.http.Cookie,"MATCH_EVEYRTHING_EXCEPT_THISUSERID","");

set req.http.ViewerUserId = regsub(req.http.Cookie,"MATCH_EVEYRTHING_EXCEPT_VIEWERUSERID","");

if(req.http.ViewerUserId == req.http.ThisUserId){
      return(pass); // Don't cache if viewer is browsing his own pages
}

示例:http://sqlfiddle.com/#!9/546dff/3

select
  product_id,

  case
  when reviewers is null then (
    select reviewers from test 
    where product_id = a.product_id
      and created_at > a.created_at
      and reviewers is not null
    limit 1)
  else reviewers
  end as reviewers,

  case
  when voting is null then (
    select voting from test 
    where product_id = a.product_id
      and created_at > a.created_at
      and voting is not null
    limit 1)
  else voting
  end as voting,

  created_at
from test a;

结果:

create table test (
  product_id varchar(20),
  reviewers int,
  voting int,
  created_at datetime
);

insert into test values 
 ('B0021ZFV9M',null      , null   ,'2015-03-20 00:34:09')
,('B0021ZFV9M',4         , 3      ,'2015-03-24 00:34:09')
,('B0021ZFV9M',null      , null   ,'2015-04-13 00:55:51')
,('B0021ZFV9M',30        , 4      ,'2015-04-15 00:44:38')
,('B00JKO4CHO',null      , null   ,'2015-09-17 00:41:40')
,('B00JKO4CHO',null      , null   ,'2015-09-19 00:41:47')
,('B00JKO4CHO',50        , 1      ,'2015-09-21 00:41:31');

编辑:

要更新旧数据,您可以这样做:

| product_id | reviewers | voting |                  created_at |
|------------|-----------|--------|-----------------------------|
| B0021ZFV9M |         4 |      3 |     March, 20 2015 00:34:09 |
| B0021ZFV9M |         4 |      3 |     March, 24 2015 00:34:09 |
| B0021ZFV9M |        30 |      4 |     April, 13 2015 00:55:51 |
| B0021ZFV9M |        30 |      4 |     April, 15 2015 00:44:38 |
| B00JKO4CHO |        50 |      1 | September, 17 2015 00:41:40 |
| B00JKO4CHO |        50 |      1 | September, 19 2015 00:41:47 |
| B00JKO4CHO |        50 |      1 | September, 21 2015 00:41:31 |

在尝试此操作之前备份测试(原始)表。

答案 1 :(得分:1)

select distinct on (a.product_id, a.created_at)
    a.product_id, 
    coalesce(a.reviewers, b.reviewers) reviewers,
    coalesce(a.voting, b.voting) voting,
    a.created_at
from a_table a
left join a_table b
    on a.product_id = b.product_id 
    and b.reviewers notnull
    and b.created_at > a.created_at
order by 1, 4;

SqlFiddle

注意:假设如果reviewersnot null,那么voting也是not null