问题描述
我有以下架构
CREATE TABLE QUOTE (id int,amount int);
CREATE TABLE QUOTE_LINE (id int,quote_id int,line_amount int);
INSERT INTO QUOTE VALUES(1,100);
INSERT INTO QUOTE VALUES(2,200);
INSERT INTO QUOTE VALUES(3,100);
INSERT INTO QUOTE VALUES(4,300);
INSERT INTO QUOTE_LINE VALUES(1,1,5);
INSERT INTO QUOTE_LINE VALUES(2,6);
INSERT INTO QUOTE_LINE VALUES(3,4);
INSERT INTO QUOTE_LINE VALUES(4,2);
INSERT INTO QUOTE_LINE VALUES(1,2,5);
INSERT INTO QUOTE_LINE VALUES(3,5);
INSERT INTO QUOTE_LINE VALUES(4,5);
我需要运行以下查询:
SELECT QUOTE.id,line_amount*12 AS amount,amount*2 as amount_doubled
from QUOTE_LINE
LEFT JOIN QUOTE ON QUOTE_LINE.quote_id=QUOTE.id;
查询 amount*2 as amount_double
中的第 3 行需要引用前一行中计算出的金额,即 line_amount*12 AS amount
。
但是,如果我运行此查询,它会从 QUOTE 表中选择 amount
而不是计算出的 amount
。如何让我的查询使用计算的 amount
而不更改计算字段的名称?
这是用于此的sqlfiddle: http://sqlfiddle.com/#!17/914b2/1
注意:我知道我可以创建子查询、CTE 或横向联接,但我正在处理的表是非常宽的表,并且查询有许多联接。因此,我需要保留 LEFT INNER JOINS,而且我并不总是知道计算字段是否会在 JOINed 表中重复。表结构发生变化。
解决方法
使用 FROM
将定义移动到 LATERAL JOIN
子句:
select q.id,v.amount,v.amount * 2 as as amount_doubled
from QUOTE_LINE ql left join
QUOTE q
on ql.quote_id = q.id CROSS JOIN LATERAL
(values (line_amount*12)) v(amount);
您也可以使用子查询或 CTE,但我喜欢横向连接方法。
注意:我希望 QUOTE
是 LEFT JOIN
中的第一个表。
使用表名限定所有列名并使用子查询:
SELECT q.id,q.amount,q.amount * 2 AS amount_doubled
FROM (SELECT quote.id,quote_line.line_amount * 12 AS amount,FROM quote_line
LEFT JOIN quite
ON quote_line.quote_id = quote.id
) AS q;
,
只要一点点简单的代数就可以很容易地解决这个问题。很明显,计算量是 line_amount 的 12 倍,amount_doubles 是它的 2 倍。所以
select q.id,ql.line_amount*12 as amount,ql.line_amount*12*2 as amount_doubled
from quote_line ql
left join quote q
on ql.quote_id = q.id;
然而,child left join parent 似乎很奇怪,因为它基本上是在说“给我没有引用的引用行数量”。人们希望从行到引用的 FK 可以防止这种情况发生。 如果是这样,那么内部联接就足够了。此外,如果 id 是引用中的唯一列,则可以通过从 quote_line 中获取 quote_id 来删除连接。所以也许减少到:
select ql.quote_id as id,ql.line_amount*12 as amount,ql.line_amount*24 as amount_doubled
from quote_line ql;