0

I want to create a table with a subset of records from a master table. for example, I have:

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

I want to store peter and carl but not jack because has same peter's code. I need the max ref!

I try this:

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

but it doesn't work.

4

4 回答 4

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 ║
╚════╩═══════╩══════╩═════╝

看到这个 SQLFiddle

于 2013-07-16T10:48:15.047 回答
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 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;
于 2013-07-16T10:51:27.833 回答
1

尝试类似:

SELECT DISTINCT ON (code) id, name, code
FROM old_tab
WHERE conditions
ORDER BY code, ref DESC
于 2013-07-16T10:50:09.667 回答
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项目作为 tiebrekaer 来决定返回哪一行。或者 Postgres 会选择一个任意的,因为每个表达式DISTINCT ON总是返回一行。DISTINCT

在这个密切相关的答案中比较这些样式的解释、链接和基准:
选择每个 GROUP BY 组中的第一行?

另一种快速的方法是:

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
   )

小的区别:这个不会打破关系。如果每个code(和conditions)多行共享最高ref,则将返回多行。

CREATE TABLE AS

对于从 a 创建新表SELECT,推荐的形式是CREATE TABLE AS。在这里引用手册

此命令在功能上类似于SELECT INTO,但它是首选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;
于 2013-07-16T15:55:20.073 回答