如何在PostgreSQL中插入许多记录,不包括一些记录

时间:2013-07-16 10:43:14

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

我想创建一个包含主表中记录子集的表。 例如,我有:

id  name   code  ref
1   peter  73    2.5
2   carl   84    3.6
3   jack   73    1.1

我想存储peter和carl但不是jack,因为它有相同的peter代码。 我需要最大参考!

我试试这个:

SELECT id, name, DISTINCT(code) INTO new_tab
FROM old_tab 
WHERE (conditions)

但它不起作用。

4 个答案:

答案 0 :(得分:3)

您可以尝试这样的子查询:

SELECT ot.* FROM old_tab ot
JOIN
(
   SELECT "code", MAX("ref") AS "MaxRef"
   FROM old_tab
   GROUP BY "code"
) tbl
ON ot."code" = tbl."code"
AND ot."ref" = tbl."MaxRef"

输出:

╔════╦═══════╦══════╦═════╗
║ ID ║ NAME  ║ CODE ║ REF ║
╠════╬═══════╬══════╬═════╣
║  1 ║ peter ║   73 ║ 2.5 ║
║  2 ║ carl  ║   84 ║ 3.6 ║
╚════╩═══════╩══════╩═════╝

请参阅this SQLFiddle

答案 1 :(得分:3)

您可以使用窗口函数:

select t.id, t.name, t.code, t.ref
from (select t.*,
             row_number() over (partition by code order by ref desc) as seqnum
      from old_tab t
     ) t
where seqnum = 1;

insert语句只包围insert

insert into new_tab(id, name, code)
    select t.id, t.name, t.code
    from (select t.*,
                 row_number() over (partition by code order by ref desc) as seqnum
          from old_tab t
         ) t
    where seqnum = 1;

答案 2 :(得分:1)

尝试类似:

SELECT DISTINCT ON (code) id, name, code
FROM old_tab
WHERE conditions
ORDER BY code, ref DESC

答案 3 :(得分:0)

正确查询

由于您need the max ref! DISTINCT ON正确表单为SELECT DISTINCT ON (code) id, name, code FROM old_tab WHERE (conditions) ORDER BY code, ref DESC,所以

ref

这通常比具有子查询和窗口函数或聚合函数的解决方案更快,更简单,更短 如果可以有多个行共享最高ORDER BY,请添加更多DISTINCT ON项作为tiebrekaer以决定返回哪一行。或者Postgres会选择任意一个,因为DISTINCT始终会为每个SELECT id, name, code, ref FROM old_tab t WHERE (conditions) AND NOT EXISTS ( SELECT 1 FROM old_tab t2 WHERE (conditions) AND t2.code = t.code AND t2.ref > t.ref ) 表达式返回单行

在这个密切相关的答案中,比较这些风格的解释,链接和基准:
Select first row in each GROUP BY group?

另一种快速方式是:

code

小差异:这个没有打破关系。如果每个conditions(和ref)的多行共享最高CREATE TABLE AS,则会返回多行。

SELECT

要从CREATE TABLE AS创建新表格,建议的格式为SELECT INTO。引用the manual here

  

此命令在功能上与SELECT INTO类似,但确实如此   首选,因为它不太可能与其他用途混淆   CREATE TABLE AS语法。此外,SELECT INTO提供了一个超集   CREATE TABLE new_tab AS SELECT DISTINCT ON (code) id, name, code FROM old_tab WHERE (conditions) ORDER BY code, ref DESC; 提供的功能。

大胆强调我的 所以使用:

{{1}}