【问题标题】:Select rows based on comparison with other rows in same view根据与同一视图中其他行的比较来选择行
【发布时间】:2017-05-18 12:25:50
【问题描述】:

我有一个x, y 点的表,我需要找到表中其他行少于三行且具有更高x 值或更高y 值的点。

  x  |  y  
-----+-----
  85 | 996
 109 | 989
 116 | 987
 164 | 983

         create or replace function sk(tableName text)
             returns integer
         as $$
         declare
            count integer;
            r record;

         begin
            count :=3;
            for r in execute 'select * from TABLE'
            if
                  loop
                  count := count - 1;

                  end loop;
                  return count;

         end
         $$ language plpgsql;

预期结果是一个新视图,其中只有那些小于 3 且大于 xy 的点。

【问题讨论】:

  • 编辑您的问题并显示您想要的结果。
  • "psql" 不是 Postgres 的有效名称,这是标准命令行界面的名称。而且您不需要“循环”,您需要解决问题。循环是一种可能的技术,在任何 RDBMS 中很少是一种有效的方法。我冒昧地澄清一下。

标签: sql postgresql plpgsql


【解决方案1】:

为什么要在函数中这样做?您可以使用单个查询来执行此操作,例如:

select t.x, t.y, count(t2.x) as numBiggerXY
from t left join
     t2
     on t2.x > t.x or t2.y > t.y
group by t.x, t.y;

你可以把它变成一个标志:

select t.x, t.y, (count(t2.x) < 3) as biggerFlag
from t left join
     t2
     on t2.x > t.x or t2.y > t.y
group by t.x, t.y;

【讨论】:

  • 您使用 2 张桌子,但问题只提到了一张。 GROUP BY 丢失,即使您添加它,查询也不适合(x,y) 上可能的重复项,除非您执行更多操作。最后,是&lt; 3 而不是&lt;= 3
【解决方案2】:

假设一个PK列id,所以这是测试用例:

CREATE TABLE tbl (id serial PRIMARY KEY, x int, y int);
INSERT INTO tbl(x,y) VALUES
  ( 85, 996)
, (109, 989)
, (116, 987)
, (164, 983);

如果您没有 PK,请创建一个。否则,您必须在查询中使用其他技术来区分 (x,y) 上可能的重复项 - 尚未排除。

SELECT t.*, count(t2.x) AS ct_greater
FROM        tbl t
LEFT   JOIN tbl t2 ON t2.x > t.x OR t2.y > t.y
GROUP  BY t.id
HAVING count(t2.x) < 3;

测试用例的结果为空,因为总是有 3 行具有更大的x 或更大的y

【讨论】:

    猜你喜欢
    • 2018-03-16
    • 1970-01-01
    • 2020-11-12
    • 2019-10-17
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 2021-07-15
    相关资源
    最近更新 更多