postgreDifference 单个 SQL SELECT 语句中的两行



我有一个数据库表

,其结构如下所示:
CREATE TABLE dated_records (
              recdate DATE NOT NULL
              col1    DOUBLE NOT NULL,
              col2    DOUBLE NOT NULL,
              col3    DOUBLE NOT NULL,
              col4    DOUBLE NOT NULL,
              col5    DOUBLE NOT NULL,
              col6    DOUBLE NOT NULL,
              col7    DOUBLE NOT NULL,
              col8    DOUBLE NOT NULL
              );

我想编写一个 SQL 语句,该语句将允许我返回一条记录,其中包含指定列的两个提供日期之间的更改 - 例如 col1、col2 和 col3

例如,如果我想查看 col1、col2 和 col3 中的值在两个日期之间的间隔内发生了多少变化。一种愚蠢的方法是为每个日期选择行(单独(,然后区分数据库服务器外部的字段 -

SQL1 = "SELECT col1, col2 col3 FROM dated_records WHERE recdate='2001-01-01'";
SQL1 = "SELECT col1, col2 col3 FROM dated_records WHERE recdate='2001-02-01'";

但是,我确信有一种方法可以使用纯SQL执行差异的更智能的方法。我这将涉及使用自连接(可能还有一个嵌套子查询(,但我可能过于复杂 - 我决定最好问问这里的 SQL 专家,看看他们将如何以最有效的方式解决这个问题。

理想情况下,SQL应该是与数据库无关的,但是如果需要将其绑定为特定的数据库,那么它必须是PostgreSQL。

只需选择两行,将它们合并为一行,然后减去值:

select d1.recdate, d2.recdate,
       (d2.col1 - d1.col1) as delta_col1,
       (d2.col2 - d1.col2) as delta_col2,
       ...
from (select *
      from dated_records
      where recdate = <date1>
     ) d1 cross join
     (select *
      from dated_records
      where recdate = <date2>
     ) d2
我认为,

如果您要做的是在不与两个选择查询相交的结果集行中获取,则可以使用EXCEPT 运算符:

EXCEPT 运算符返回第一个结果集中的行 但不是在第二个。

因此,您的两个查询将成为一个查询,其中 except 运算符将它们连接起来:

SELECT col1, col2 col3 FROM dated_records WHERE recdate='2001-01-01'
EXCEPT
SELECT col1, col2 col3 FROM dated_records WHERE recdate='2001-02-01'
SELECT
COALESCE
(a.col1 -
  (
    SELECT b.col1
    FROM dated_records b
    WHERE b.id = a.id + 1
  ),
a.col1)
FROM dated_records a
WHERE recdate='2001-01-01';

您可以使用窗口函数DISTINCT

SELECT DISTINCT
       first_value(recdate) OVER () AS date1
      ,last_value(recdate)  OVER () AS date2
      ,last_value(col1)     OVER () - first_value(col1) OVER () AS delta1
      ,last_value(col2)     OVER () - first_value(col2) OVER () AS delta2
       ...
FROM   dated_records
WHERE  recdate IN ('2001-01-01', '2001-01-03')

任何两天。使用单个索引或表扫描,因此应该很快。

我没有对窗口进行排序,但所有计算都使用相同的窗口,因此值是一致的。

此解决方案可以很容易地推广到 n 行之间的计算中。在这种情况下,您可能希望使用Windows函数的Postgres库中的nth_value()

如果您正在寻找一个简单的增量,这似乎是一种更快的编写方法。

SELECT first(col1) - last(col1) AS delta_col1
, first(col2) - last(col2) AS delta_col2
FROM dated_records WHERE recdate IN ('2001-02-01', '2001-01-01')

你可能不知道第一行还是第二行先来,但你总是可以用abs(first(col1)-last(col1))来包装答案

最新更新