【问题标题】:How to join multiple sub queries as a single one without 'with'?如何在没有'with'的情况下将多个子查询合并为一个?
【发布时间】:2019-08-20 19:53:21
【问题描述】:

我有一个由多个子查询组成的查询。我使用'join',因为我不允许使用'with'。子查询有 'from' 子句,这会产生问题。

我必须显示两列,每列包含要显示的某些逻辑。为了打印这两列,我需要使用需要“from”子句的子查询。我不确定如何编写“from”子句以适应整个查询并使其可运行。我检查了各个查询,它们都工作正常。


select lead(dt) over 
(partition by t1.id_user order by f.topup_date desc rows between 0 
preceding and unbounded following )
from 
  (select *,    
  (max(case when f.topup_value >= 20 then f.topup_date  end) over (partition 
   by f.id_user order by f.topup_date desc rows between 0 preceding and 
   unbounded following )) as dt 
   from topups f) as f, //(<-I think this is incorrect) 

CAST(f.topup_value as float)/CAST(t1.topup_value as float) from 
(SELECT t1.seq,t1.id_user,t1.topup_value,row_number() 
over (partition by t1.id_user order by t1.topup_date ) 
as rowrank from topups t1) as t1 
inner join topups f on f.id_user=t1.id_user 
inner join topups t2 on t1.seq=t2.seq

【问题讨论】:

  • 如果“个人查询”有效,您可以发布它们和一些示例数据,以及预期的输出吗?为什么不能使用WITH

标签: sql postgresql window-functions


【解决方案1】:

您遇到语法错误,因为查询只能有一个 FROM 子句。很难说出您想要达到的结果,但是将第一个查询转换为不相关的子查询并将其用于列 f 可能是您正在寻找的:

select
    (select lead(dt) over (partition by t1.id_user order by f.topup_date desc rows between 0 preceding and unbounded following )
    from (
        select *,    
            (max(case when f.topup_value >= 20 then f.topup_date  end) over (partition by f.id_user order by f.topup_date desc rows between 0 preceding and unbounded following )) as dt 
        from topups f
    ) x) as f,
    CAST(f.topup_value as float)/CAST(t1.topup_value as float) 
    from (
        SELECT t1.seq, t1.id_user, t1.topup_value, row_number() over (partition by t1.id_user order by t1.topup_date ) as rowrank 
        from topups t1
    ) as t1 
    inner join topups f on f.id_user=t1.id_user 
    inner join topups t2 on t1.seq=t2.seq

【讨论】:

  • 这会返回“多于一行由用作表达式的子查询返回”的错误,这会导致连接的替代。我被卡住了:(
  • 这是因为用于获取列 f 的查询返回多个值。如果没有 1. 数据集和 2. 查询的目的,就不可能提出正确的解决方案
【解决方案2】:

真的很难阅读该查询。您标记为可能不正确的内容是错误的,因为您试图在原始 FROM 子句之后添加看起来像另一个 SELECT 的内容。那是不正确的语法。将您的 FROM 子查询视为临时表。你不能说这样的话:

SELECT some_column
FROM a_table, some_other_column

这是交叉连接语法。 some_other_column 需要是一个表格才能有效。

考虑添加CREATE TABLE 和样本数据,以便我们进行测试。

您可能正在寻找类似以下内容的内容:

SELECT  LEAD(temp.dt) OVER(PARTITION BY temp.id_user ORDER BY temp.topup_date DESC ROWS BETWEEN 0 PRECEDING AND UNBOUNDED FOLLOWING)
        , temp.division
FROM
(
    SELECT  (max(CASE WHEN f.topup_value >= 20 THEN f.topup_date  END) OVER(PARTITION BY f.id_user ORDER BY f.topup_date DESC ROWS BETWEEN 0 PRECEDING AND UNBOUNDED FOLLOWING )) AS dt
            , f.topup_value::float / t1.topup_value::float AS division
            , t1.id_user
            , f.topup_date
    FROM topups t1
        JOIN topups f USING (id_user)
) temp
; 

只是一个意见,但使用:: 运算符来转换变量的噪音较小。而不是CAST(f.topup_value as float),只需使用f.topup_value::float

【讨论】:

  • 第三个'FROM'子句有错误,我回到正题
  • 很难说你想在这里实现什么。有了样本数据和样本表,我们可以尝试进行测试。什么错误?
  • 这是一个语法错误。对不起,这太令人困惑了。这些只是显示两列的两个子查询。我需要把它写成一个查询,但正如我所说的,我不能,因为'FROM'太多
  • 我忘记了 sub-SELECT 周围的一组括号。编辑了答案
  • 这会返回“多于一行由用作表达式的子查询返回”错误,这会导致连接的替代。我被卡住了:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-09
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 2012-05-31
相关资源
最近更新 更多