我有一个一定很常见的查询模式,但我不知道如何为它编写有效的查询。我想查找与“最近日期不晚于”另一个表的行相对应的表的行。
inventory
比如说,我有一张表格,它代表了我在某一天持有的库存。
date | good | quantity
------------------------------
2013-08-09 | egg | 5
2013-08-09 | pear | 7
2013-08-02 | egg | 1
2013-08-02 | pear | 2
Run Code Online (Sandbox Code Playgroud)
和一张表,“价格”说,它保存了某一天的商品价格
date | good | price
--------------------------
2013-08-07 | egg | 120
2013-08-06 | pear | 200
2013-08-01 | egg | 110
2013-07-30 | pear | 220
Run Code Online (Sandbox Code Playgroud)
如何有效地获得库存表每一行的“最新”价格,即
date | pricing date | good | quantity | price
----------------------------------------------------
2013-08-09 | 2013-08-07 | egg | 5 | 120
2013-08-09 …
Run Code Online (Sandbox Code Playgroud) postgresql performance greatest-n-per-group query-performance
假设我有表 a(列 a1)和 b(列 b1 和 b2)并且我执行左外连接
SELECT *
FROM a LEFT OUTER JOIN b
ON a.a1 = b.b1
Run Code Online (Sandbox Code Playgroud)
然后 b1 和 b2 将为 NULL,其中 a1 的值没有 b1 的匹配值。
我可以为 b2 提供默认值而不是 NULL 吗?需要注意的是COALESCE不会在这里工作,因为我不希望默认值来覆盖潜在的NULL在B2那里是B1匹配A1的值。
也就是说,将 a 和 b 作为
CREATE TABLE a (a1)
AS VALUES (1),
(2),
(3) ;
CREATE TABLE b (b1,b2)
AS VALUES (1, 10),
(3, null) ;
a1 b1 | b2
--- --------
1 1 | 10
2 3 | NULL
3
Run Code Online (Sandbox Code Playgroud)
和 …
前者给我错误消息“在其自己的查询级别的 FROM 子句中不允许聚合函数”,而后者是允许的。除非我弄错了,后者等同于前者,因为它只是为v
.
我正在编写一个代码生成器,因此将前者的自然形式重写为后者的人工形式有点繁琐。
但禁止前者的理由是什么?
SELECT * FROM
((SELECT 0 as "v") as "T1"
INNER JOIN LATERAL
(SELECT
SUM("v") as "r"
FROM (SELECT 0) as "T1") as "T2"
ON TRUE) as "T1"
Run Code Online (Sandbox Code Playgroud)
SELECT * FROM
((SELECT 0 as "v") as "T1"
INNER JOIN LATERAL
(SELECT
SUM("v_again") as "r"
FROM (SELECT "v" as "v_again") as "T1") as "T2"
ON TRUE) as "T1"
Run Code Online (Sandbox Code Playgroud) 我想执行以下操作:
SELECT person, MAX( (date, priority) ) FROM table GROUP BY person;
Run Code Online (Sandbox Code Playgroud)
它将为列中的每个不同值返回一个person
,date
和priority
行person
。的date
和priority
被选择为使得所述date
值被最大化,且最大priority
发生在该日期被选择。
例如,在此表上运行查询
person | date | priority
---------------------------------
1 | '2014-01-01' | 10
1 | '2014-01-02' | 2
1 | '2014-01-02' | 3
Run Code Online (Sandbox Code Playgroud)
应该导致
person | date | priority
---------------------------------
1 | '2014-01-02' | 3
Run Code Online (Sandbox Code Playgroud)
Postgres 抱怨这种特殊的尝试:
ERROR: function max(record) does not exist
HINT: No function matches the given name …
Run Code Online (Sandbox Code Playgroud) 在 PostgreSQL 中我可以创建匿名行或复合类型
postgres=# SELECT ROW(1,'Hello',false) as r;
r
-------------
(1,Hello,f)
(1 row)
Run Code Online (Sandbox Code Playgroud)
但我怎样才能把这些田地重新拿出来呢?没有以下工作
postgres=# SELECT (r).* from (SELECT ROW(1,'Hello',false) as r) as T;
ERROR: record type has not been registered
postgres=# SELECT (r).column0 from (SELECT ROW(1,'Hello',false) as r) as T;
ERROR: record type has not been registered
Run Code Online (Sandbox Code Playgroud)