Postgres集团

时间:2017-04-14 00:51:55

标签: sql postgresql

当我运行查询时,这些是呈现给我的结果:

id  account_id  score  active  item_id
5    78          9      true    4
6    78          1      true    4
7    78          9      true    6
8    78          5      true    7
9    78          5      true    8
10   78          5      true    8

我希望通过根据得分合并item_id&#39来使输出看起来像这样:

id  account_id  score  active  item_id
*    78          10      true    4
7    78          9      true    6
8    78          5      true    7
*    78          10      true    8 

我的返回该信息的查询如下所示:

SELECT item.id, item.account_id, itemaudit.score, itemrevision.active, itemaudit.item_id
from item 
left join itemrevision on item.id = itemrevision.id 
join itemaudit on item.id = itemaudit.id 
where itemrevision.active = true 
;

我错过的位是' item_id'并不明显,将“得分”的值组合/总和。我不知道该怎么做。

架构如下所示:

 CREATE TABLE item
(id integer, account_id integer);

CREATE TABLE itemaudit
(id integer, item_id integer, score integer);

CREATE TABLE itemrevision
(id int, active boolean, item_id int);


INSERT INTO item 
  (id, account_id)
VALUES
    (5, 78),
    (6, 78),
    (7, 78),
    (8, 78),
    (9, 78),
    (10, 78)    
;


INSERT INTO itemaudit
    (id, item_id, score)
VALUES
    (5, 4, 5),
    (6, 4, 1),
    (7, 6, 9),
    (8, 7, 10),
    (9, 8, 1),
    (10, 8, 9)  
;

INSERT INTO itemrevision
    (id, active, item_id)
VALUES
    (5, true, 4),
    (6, true, 4),
    (7, true, 6),
    (8, true, 7),
    (9, true, 7),
    (10, true, 8)
;

2 个答案:

答案 0 :(得分:1)

如果我理解正确,您只需要一个聚合查询:

select ia.item_id, sum(ia.score) as score
from item i join  -- the `where` clause turns this into an inner join
     itemrevision ir
     on i.id = ir.id  join
     itemaudit ia
     on i.id = ia.id 
where ir.active = true 
group by ia.item_id;

注意:

  • 我将left join更改为inner join,因为where子句无论如何都会产生这种影响。
  • 表别名使查询更易于编写和阅读。
  • 在聚合查询中,其他列不合适。

答案 1 :(得分:1)

我想你想要这样的事情......

SELECT
  CASE
    WHEN array_length(array_agg(id),1) = 1
      THEN (array_agg(id))[1]::text
    ELSE '*'
  END AS id,
  account_id,
  sum(score) AS score,
  item_id
FROM item
GROUP BY account_id, item_id
ORDER BY account_id, item_id;

 id | account_id | score | item_id 
----+------------+-------+---------
 *  |         78 |    10 |       4
 7  |         78 |     9 |       6
 8  |         78 |     5 |       7
 *  |         78 |    10 |       8
(4 rows)

虽然这是你想要的,但更简单的版本更加详细和更好。

SELECT
  array_agg(id) AS id,
  account_id,
  sum(score) AS score,
  item_id
FROM item
GROUP BY account_id, item_id
ORDER BY account_id, item_id;

   id   | account_id | score | item_id 
--------+------------+-------+---------
 {5,6}  |         78 |    10 |       4
 {7}    |         78 |     9 |       6
 {8}    |         78 |     5 |       7
 {9,10} |         78 |    10 |       8
(4 rows)