postgreSQL重复计算连接的行

时间:2012-10-22 10:33:24

标签: sql postgresql

我有一个复杂的问题。我将尝试用例子解释它:

有一个表有主键,我想加入其他表那里第一个表的主键是外键,我想要在第二个表中有重复的外键来选择重复次数。例如:

1-table表:

  id    name 
  ---  -----
  1     Greg
  2     Alan 
  3    George 
  4     John 
  5     Peter   

2-nd table

 id       aid        data   
 ---     -----      -------
 1        2          CCCV   
 2        2          VVVV 
 3        3          DDDDD 
 4        3          SSSS 
 5        4          PPPPP 

我希望联接的结果是:

 id(1st table)  aid   name    Data   Number
 -----------    ----  -----   -----  -----
 1               null  Greg    null   1
 2                1    Alan    CCCV   1
 2                2    Alan    VVVV   2
 3                3    George  DDDDD  1
 3                4    George  SSSS   2
 4                5    John    PPPPP  1
 5               null  Peter   null   1

我搜索了很多,我找不到任何东西。也许我不知道如何搜索,或者没有我想做的事情。

3 个答案:

答案 0 :(得分:2)

根据我的评论,你已经标记了MySQL和PostgreSQL。

这个答案适用于PostgreSQL。

SELECT
  table1.id,
  table2.aid,
  table1.name,
  table2.data,
  ROW_NUMBER() OVER (PARTITION BY table1.id ORDER BY table2.aid) AS number
FROM
  table1
LEFT JOIN
  table2
    ON table1.id = table2.aid

答案 1 :(得分:2)

SELECT Table1.id, Table2.id as aid, Table1.name, Table2.data,
GREATEST(1, (SELECT COUNT(*)
             FROM Table2 t2
             WHERE t2.aid = Table1.id
             AND t2.id <= Table2.id))
AS number
FROM Table1
LEFT JOIN Table2
ON Table2.aid = Table1.id
ORDER BY id, aid;

适用于MySQL和PostgreSQL。

答案 2 :(得分:0)

查询没有窗口函数的PostgreSQL 8.3。
使用更大的表,使用JOIN代替correlated sub-query通常要快得多。
第一个查询在加入Table2之前聚合Table1 的值,这也应该更快:

SELECT t1.id, t2.aid, t1.name, t2.data, COALESCE(t2.ct, 1) AS number
FROM   Table1 t1
LEFT   JOIN  (
    SELECT x.aid, x.data, count(y.aid) + 1 AS ct
    FROM   Table2 x
    LEFT   JOIN Table2 y ON x.aid = y.aid AND x.id > y.id
    GROUP  BY x.aid, x.data
    ) t2 ON t2.aid = t1.id
ORDER  BY t1.id, t2.ct;

ORDER BY应该修复。

没有子查询的备选方案。可能会更快,但是:

SELECT t1.id, t2.aid, t1.name, t2.data, count(*) + count(t3.id) AS number
FROM   Table1 t1
LEFT   JOIN Table2 t2 ON t2.aid = t1.id
LEFT   JOIN Table2 t3 ON t3.aid = t2.aid AND t3.id < t2.id
GROUP  BY t1.id, t2.aid, t1.name, t2.data
ORDER  BY t1.id, count(t3.id);

不确定,没用更大的套装进行测试。使用EXPLAIN ANALYZE测试性能。你能报告一下你的结果吗?