Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在左联接和where表达式中未使用检索行的CTE_Sql_Null_Amazon Redshift_Common Table Expression - Fatal编程技术网

Sql 在左联接和where表达式中未使用检索行的CTE

Sql 在左联接和where表达式中未使用检索行的CTE,sql,null,amazon-redshift,common-table-expression,Sql,Null,Amazon Redshift,Common Table Expression,我已经在AmazonRedshift上编写了一个SQL查询,我面临一个CTE不返回行的问题 查询正在从CTE No1检索id和时间戳,并在比较CTE No1的时间戳字段与CTE No2,3,4,5,5的时间戳字段后,返回CTE No2,3,4,6的字段。更准确地说,下面是我的SQL查询的伪代码,我希望它是可以理解的。请不要太注意超前和滞后函数。查询问题本质上比可能出现的问题简单得多,并且是关于CTE的0行,但它们用于最终查询的where条件,如何解释这些情况 with CTE1 AS (SEL

我已经在AmazonRedshift上编写了一个SQL查询,我面临一个CTE不返回行的问题

查询正在从CTE No1检索id和时间戳,并在比较CTE No1的时间戳字段与CTE No2,3,4,5,5的时间戳字段后,返回CTE No2,3,4,6的字段。更准确地说,下面是我的SQL查询的伪代码,我希望它是可以理解的。请不要太注意超前和滞后函数。查询问题本质上比可能出现的问题简单得多,并且是关于CTE的0行,但它们用于最终查询的where条件,如何解释这些情况

with CTE1 AS 
(SELECT timestamp1, id
from table1
where ...
...
...)

, CTE2 as 
(select timestamp2, 
        id,  
        field1, 
        field2, 
        LAG(timestamp2,1) over partition by id order by timestamp2 as timestamp2_previous, 
        LEAD(timestamp2,1) over partition by id order by timestamp2 as timestamp2_next 
        from table2)

, CTE3 as 
(select timestamp3, 
        id, 
        field1, 
        field2, 
        LAG(timestamp3,1) over partition by id order by timestamp3 as timestamp3_previous, 
        LEAD(timestamp3,1) over partition by id order by timestamp3 as timestamp3_next 
       from table3)

, CTE4 as 
(select timestamp4, 
        id, 
        field1, 
        field2, 
        LAG(timestamp4,1) over partition by id order by timestamp4 as timestamp4_previous, 
        LEAD(timestamp4,1) over partition by id order by timestamp4 as timestamp4_next 
        from table4)

, CTE5 as 
(select timestamp5, 
        id, 
        field1, 
        field2, 
        LAG(timestamp5,1) over partition by id order by timestamp5 as timestamp5_previous, 
        LEAD(timestamp5,1) over partition by id order by timestamp5 as timestamp5_next 
        from table5)

, CTE6 as 
(select timestamp6, 
        id, 
        field1, 
        field2, 
        LAG(timestamp6,1) over partition by id order by timestamp6 as timestamp6_previous, 
        LEAD(timestamp6,1) over partition by id order by timestamp6 as timestamp6_next 
        from table6)

select cte1.id, 
       cte1.timestamp1, 
       case when cte1.timestamp1<cte2.timestamp2 and cte2.timestamp2_previous is null then cte2.field1 else cte2.field2, 
case when cte1.timestamp1<cte3.timestamp3 and cte3.timestamp3_previous is null then cte3.field1 else cte3.field2, 
case when cte1.timestamp1<cte4.timestamp4 and cte4.timestamp4_previous is null then cte4.field1 else cte4.field2, 
case when cte1.timestamp1<cte5.timestamp5 and cte5.timestamp5_previous is null then cte5.field1 else cte5.field2, 
case when cte1.timestamp1<cte6.timestamp6 and cte6.timestamp6_previous is null then cte6.field1 else cte6.field2

from cte1
left join cte2 on cte1.id=cte2.id
left join cte3 on cte1.id=cte3.id
left join cte4 on cte1.id=cte4.id
left join cte5 on cte1.id=cte5.id
left join cte6 on cte1.id=cte6.id
where 1 

and 

-- conditions for CTE2

( case when cte1.timestamp1 < cte2.timestamp2 and cte2.timestamp2_previous is null then 1=1
         else cte1.timestamp1 > cte2.timestamp2 end
and
        CASE
                WHEN cte2.timestamp2_next is not null THEN cte1.timestamp1 < cte2.timestamp2_next ELSE 1=1
        END
)

-- conditions for CTE3

( case when cte1.timestamp1 < cte3.timestamp3 and cte3.timestamp3_previous is null then 1=1
         else cte1.timestamp1 > cte3.timestamp3 end
and
        CASE
                WHEN cte3.timestamp3_next is not null THEN cte1.timestamp1 < cte3.timestamp3_next ELSE 1=1
        END
)

-- conditions for CTE4

( case when cte1.timestamp1 < cte4.timestamp4 and cte4.timestamp4_previous is null then 1=1
         else cte1.timestamp1 > cte4.timestamp4 end
and
        CASE
                WHEN cte4.timestamp4_next is not null THEN cte1.timestamp1 < cte4.timestamp4_next ELSE 1=1
        END
)


-- conditions for CTE5

( case when cte1.timestamp1 < cte5.timestamp5 and cte5.timestamp5_previous is null then 1=1
         else cte1.timestamp1 > cte5.timestamp5 end
and
        CASE
                WHEN cte5.timestamp5_next is not null THEN cte1.timestamp1 < cte5.timestamp5_next ELSE 1=1
        END
)


-- conditions for CTE6

( case when cte1.timestamp1 < cte6.timestamp6 and cte6.timestamp6_previous is null then 1=1
         else cte1.timestamp1 > cte6.timestamp6 end
and
        CASE
                WHEN cte6.timestamp6_next is not null THEN cte1.timestamp1 < cte6.timestamp6_next ELSE 1=1
        END
)
问题是,在第一个之后的一些CTE没有返回特定id的记录。我测试了特定id的代码,而CTE3没有返回该id的行。 在这些情况下,最终的where条件(都与AND连接)将评估其中没有记录的CTE,并返回0行,因为操作为TRUE和NULL,即使所有其他CTE都有该id的数据,并且查询结果应该检索它们的数据


如何检索此类情况的结果,并在引用带now行的CTE的结果字段中获取NULL?

正如@JNevill所说,答案是将where条件移动到联接。为了让您了解其工作原理,cte1和cte2之间的连接变成:
在cte1.id=cte2.id和cte1.timestampcte2.timestamp和cte2.timestamp_next为NULL或cte1.timestamp我必须在这里做一些假设,因为您的伪代码不包含您在段落中编写的属性,如where最后的条件都与和有关,但是。。。您可以将最终查询中的WHERE条件移动到ON子句中,这些CTE将留在该子句中并加入查询。通过这种方式,这些记录在加入之前会被过滤。非常感谢@JNevill您的提议奏效了!非常感谢@JNevill你的提议奏效了!如果您的问题现在已解决,请将问题标记为已回答。这有助于其他用户。您可以通过单击答案旁边的复选框来完成此操作。