我需要重写SQL查询,以便它不包含任何子查询,因为将要执行它的第三方程序的要求。但是我只知道一点SQL,到目前为止还没有找到任何帮助我的东西。
我需要重写的子查询的一个例子是:
SELECT
DateAdd(millisecond
, ISnull((select RawOffset
from tbl_lms_TimeZoneData
where TimeZone_FK = (act.TimeZoneFK) ),0)
, DateAdd(millisecond
, ISnull((select Offset
from tbl_lms_ConvertTimeZoneData
where TimeZone_FK = (act.TimeZoneFK)
and act.StartDt between StartDate and EndDate),0) , act.StartDt))
as N'Activity Start Date'
FROM
etc...
act在FROM子句中定义。
查询按原样运行,但是我用CTE替换子查询的任何尝试都会破坏它。
在这种情况下是否可以替换子查询?
感谢您的帮助。
答案 0 :(得分:1)
你确定你甚至需要CTE吗?看起来你可以简单地使用外连接。
SELECT DateAdd(millisecond,
ISnull(tzd.RawOffset,0),
DateAdd(millisecond,
ISnull(ctzd.Offset,0),
Act.StartDt)) as N'Activity Start Date'
FROM Act
LEFT OUTER JOIN tbl_lms_TimeZoneData tzd
ON tzd.TimeZone_FK = act.TimeZoneFK
LEFT OUTER JOIN tbl_lms_ConvertTimeZoneData ctzd
ON ctzd.TimeZone_FK = act.TimeZoneFK
AND act.StartDt between ctzd.StartDate and ctzd.EndDate
不确定Act在子查询中做了什么条件来自tbl_lms_ConvertTimeZoneData,但我保留了它。
UPD:我猜,Start和End实际上属于tbl_lms_ConvertTimeZoneData。修改了查询。
答案 1 :(得分:0)
如果您最终不得不使用CTE,那么您应该能够像这样做:
WITH cte_TimeZoneData AS (
SELECT RawOffset, TimeZone_FK
FROM dbo.tbl_lms_TimeZoneData ),
cte_ConvertTimeZoneData AS (
SELECT Offset, TimeZone_FK, StartDate, EndDate
FROM dbo.tbl_lms_ConvertTimeZoneData )
SELECT [Activity Start Date] = DATEADD( MILLISECOND,
ISNULL( tzd.RawOffset, 0 ), DATEADD( MILLISECOND,
ISNULL( ctzd.Offset, 0 ), act.StartDt ) )
FROM dbo.Act act
LEFT JOIN cte_TimeZoneData tzd
ON act.TimeZoneFK = tzd.TimeZone_FK
LEFT JOIN cte_ConvertTimeZoneData ctzd
ON act.TimeZoneFK = ctzd.TimeZone_FK
AND act.StartDt >= ctzd.StartDate
AND act.StartDt < ctzd.EndDate;