简体   繁体   English

引用 SQL 语句中的计算字段

[英]Referencing a calculated field in SQL statement

I have the following schema我有以下架构

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, 1, 6);
INSERT INTO QUOTE_LINE VALUES(3, 1, 4);
INSERT INTO QUOTE_LINE VALUES(4, 1, 2);
INSERT INTO QUOTE_LINE VALUES(1, 2, 5);
INSERT INTO QUOTE_LINE VALUES(2, 2, 5);
INSERT INTO QUOTE_LINE VALUES(3, 2, 5);
INSERT INTO QUOTE_LINE VALUES(4, 2, 5);

And I need to run the following query:我需要运行以下查询:

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;

The 3rd line in the query amount*2 as amount_double needs to reference the amount calculated in the prior line ie line_amount*12 AS amount .查询amount*2 as amount_double中的第 3 行需要参考上一行计算的金额,即line_amount*12 AS amount

However if I run this query, it picks the amount from the QUOTE table instead the amount that was calculated.但是,如果我运行此查询,它会从 QUOTE 表中选择amount ,而不是计算出的amount How can I make my query use the calculated amount without changing the name of the calculated field?如何在不更改计算字段名称的情况下使我的查询使用计算的amount

Here is the sqlfiddle for this: http://sqlfiddle.com/#!17/914b2/1这是 sqlfiddle: http://sqlfiddle.com/#!17/914b2/1

Note: I understand that I can create a sub-query, CTE or a lateral join, but the tables I am working are very very wide tables, and the queries have many many joins.注意:我知道我可以创建子查询、CTE 或横向连接,但我正在处理的表是非常宽的表,并且查询有很多连接。 As such, I need to keep the LEFT INNER JOINS and also I don't always know if a calculated field will be duplicated in JOINed table or not.因此,我需要保留 LEFT INNER JOINS,而且我并不总是知道计算字段是否会在 JOINed 表中重复。 Table structures change.表结构发生变化。

Move the definition to the FROM clause using a LATERAL JOIN :使用LATERAL JOIN将定义移动到FROM子句:

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);

You can also use a subquery or CTE, but I like the lateral join method.您也可以使用子查询或 CTE,但我喜欢横向连接方法。

Note: I would expect QUOTE to be the first table in the LEFT JOIN .注意:我希望QUOTELEFT JOIN中的第一个表。

Qualify all column names with the table name and use a subquery:用表名限定所有列名并使用子查询:

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;

Just a little simple algebra resolves the issue quite easily.只需一点简单的代数就可以很容易地解决这个问题。 It is clear that calculated amount is 12 times the line_amount and that amount_doubles is 2 times that.很明显,计算出的金额是 line_amount 的 12 倍,而 amount_doubles 是该金额的 2 倍。 So所以

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; 

 

However, child left join parent seems strange as it basically says "Give me the quote line amounts where there is no quote".然而,child left join parent 似乎很奇怪,因为它基本上说“给我没有报价的报价行金额”。 One would hope a FK from line to quote would prevent that from happening.人们希望从行到引用的 FK 可以防止这种情况发生。 If so then a inner join would suffice.如果是这样,那么内部连接就足够了。 Further if the id is the only column from quote the join can removed by taking quote_id from quote_line.此外,如果 id 是quote 中的唯一列,则可以通过从quote_line 中获取quote_id 来删除连接。 So perhaps reducing to:所以也许减少到:

select ql.quote_id        as id
     , ql.line_amount*12  as amount 
     , ql.line_amount*24  as amount_doubled  
  from quote_line ql;  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM