SQL 内联视图的语法帮助
Syntax assistance for SQL inline view
我仍在学习 SQL 并且正在努力处理内联视图。我一直在做一个项目,在这个项目中我需要考虑某些事情的滞后,因此需要依赖嵌套的东西。但是我对内联视图的语法还不是很好,它一直在括号、逗号等上抛出错误。有人可以帮我清理它以便它运行吗?
SELECT *
, SiteName
, VentCount AS 'Number Of Vents'
, ROUND(PumpAHours,1) AS 'Pump A Hours'
, ROUND(PumpBHours,1) AS 'Pump B Hours'
, ROUND(PumpAStarts, 1) AS 'Pump A Starts'
, ROUND(PumpBStarts, 1) AS 'Pump B Starts'
FROM (
SELECT * , SiteName
, SUM(CASE WHEN ECV36_Open_Count_Lifetime - Lag_ECV36_Open_Count_Lifetime Between 1 AND 5 THEN ECV36_Open_Count_Lifetime - Lag_ECV36_Open_Count_Lifetime ELSE 0 END) AS 'VentCount'
, CASE WHEN NULLIF(SUM(CASE WHEN PumpAStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT),0) < MAX(Pump_A_Hours) - MIN(Pump_A_Hours)
THEN SUM(CASE WHEN PumpAStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT)
ELSE MAX(Pump_A_Hours) - MIN(Pump_A_Hours) END AS 'PumpAHours'
, CASE WHEN NULLIF(SUM(CASE WHEN PumpBStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT),0) < MAX(Pump_B_Hours) - MIN(Pump_B_Hours)
THEN SUM(CASE WHEN PumpBStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT)
ELSE MAX(Pump_B_Hours) - MIN(Pump_B_Hours) END AS 'PumpBHours'
,COUNT(CASE WHEN Pump_A_StateId = 12 OR Pump_A_StateId = 14 OR Pump_A_StateId = 9 OR Pump_A_StateId = 1837 OR Pump_A_StateId = 1839 THEN 1 END) AS PumpAStarts
,COUNT(CASE WHEN Pump_B_StateId = 12 OR Pump_B_StateId = 14 OR Pump_B_StateId = 9 OR Pump_B_StateId = 1837 OR Pump_B_StateId = 1839 THEN 1 END) AS PumpBStarts
FROM (
SELECT * , SiteName
, LAG([ECV36_Open_Count_Lifetime],1,NULL) OVER(PARTITION BY R.SiteId ORDER BY RecordDateTime ASC) AS 'Lag_ECV36_Open_Count_Lifetime'
FROM (
[Cryo].[dbo].[Record] R
Cryo.dbo.Site S on S.SiteId = R.RecordId
Cryo.dbo.pad P on P.RecordId = R.RecordId
Cryo.dbo.Pump PP on PP.RecordId = R.RecordId
)a
)a
WHERE RecordDateTime BETWEEN DATEADD(DD,-1,CONVERT(DATE,GETDATE())) AND DATEADD(DD, 0,CONVERT(DATE,GETDATE()))
)a
编辑:我重新格式化了代码并修复了一些标注。事情仍然无法正常工作,但给出的唯一错误是我猜子查询别名,如果那是他们所说的?。对于 )a 和 )c 我有语法错误,并且 )b 说 SiteName 被指定了多次,尽管我只能找到一个。我不确定如何解决该问题。再次,对于所有混乱的代码,我感到很抱歉,我真的很新鲜。
SELECT * ,
sitename ,
ventcount AS 'Number Of Vents' ,
Round(pumpahours,1) AS 'Pump A Hours' ,
Round(pumpbhours,1) AS 'Pump B Hours' ,
Round(pumpastarts, 1) AS 'Pump A Starts' ,
Round(pumpbstarts, 1) AS 'Pump B Starts'
FROM (
SELECT * ,
sitename ,
Sum(
CASE
WHEN ecv36_open_count_lifetime - lag_ecv36_open_count_lifetime BETWEEN 1 AND 5 THEN ecv36_open_count_lifetime - lag_ecv36_open_count_lifetime
ELSE 0
END) AS 'VentCount' ,
CASE
WHEN NULLIF(Sum(
CASE
WHEN pumpastatus LIKE '%Running%' THEN 1
ELSE 0
END) / Cast(20 AS FLOAT),0) < Max(pump_a_hours) - Min(pump_a_hours) THEN Sum(
CASE
WHEN pumpastatus LIKE '%Running%' THEN 1
ELSE 0
END) / Cast(20 AS FLOAT)
ELSE Max(pump_a_hours) - Min(pump_a_hours)
END AS 'PumpAHours' ,
CASE
WHEN NULLIF(Sum(
CASE
WHEN pumpbstatus LIKE '%Running%' THEN 1
ELSE 0
END) / Cast(20 AS FLOAT),0) < Max(pump_b_hours) - Min(pump_b_hours) THEN Sum(
CASE
WHEN pumpbstatus LIKE '%Running%' THEN 1
ELSE 0
END) / Cast(20 AS FLOAT)
ELSE Max(pump_b_hours) - Min(pump_b_hours)
END AS 'PumpBHours' ,
Count(
CASE
WHEN pump_a_stateid = 12
OR pump_a_stateid = 14
OR pump_a_stateid = 9
OR pump_a_stateid = 1837
OR pump_a_stateid = 1839 THEN 1
END) AS pumpastarts ,
Count(
CASE
WHEN pump_b_stateid = 12
OR pump_b_stateid = 14
OR pump_b_stateid = 9
OR pump_b_stateid = 1837
OR pump_b_stateid = 1839 THEN 1
END) AS pumpbstarts
FROM (
SELECT * ,
s.SiteName ,
Lag([ECV36_Open_Count_Lifetime],1,NULL) OVER(partition BY r.siteid ORDER BY recorddatetime ASC) AS 'Lag_ECV36_Open_Count_Lifetime'
FROM ( [Cryo].[dbo].[Record] R JOIN cryo.dbo.site s ON s.siteid = r.recordid JOIN cryo.dbo.pad p ON p.recordid = r.recordid JOIN cryo.dbo.pump pp ON pp.recordid = r.recordid )a
WHERE recorddatetime BETWEEN dateadd(dd,-1,CONVERT(date,getdate())) AND dateadd(dd, 0,CONVERT(date,getdate())) )b )c
我必须从改进缩进开始。这使得更容易查看事情是如何排列的:
SELECT *
, SiteName
, VentCount AS 'Number Of Vents'
, ROUND(PumpAHours,1) AS 'Pump A Hours'
, ROUND(PumpBHours,1) AS 'Pump B Hours'
, ROUND(PumpAStarts, 1) AS 'Pump A Starts'
, ROUND(PumpBStarts, 1) AS 'Pump B Starts'
FROM (
SELECT * , SiteName
, SUM(CASE WHEN ECV36_Open_Count_Lifetime - Lag_ECV36_Open_Count_Lifetime Between 1 AND 5 THEN ECV36_Open_Count_Lifetime - Lag_ECV36_Open_Count_Lifetime ELSE 0 END) AS 'VentCount'
, CASE WHEN NULLIF(SUM(CASE WHEN PumpAStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT),0) < MAX(Pump_A_Hours) - MIN(Pump_A_Hours)
THEN SUM(CASE WHEN PumpAStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT)
ELSE MAX(Pump_A_Hours) - MIN(Pump_A_Hours) END AS 'PumpAHours'
, CASE WHEN NULLIF(SUM(CASE WHEN PumpBStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT),0) < MAX(Pump_B_Hours) - MIN(Pump_B_Hours)
THEN SUM(CASE WHEN PumpBStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT)
ELSE MAX(Pump_B_Hours) - MIN(Pump_B_Hours) END AS 'PumpBHours'
,COUNT(CASE WHEN Pump_A_StateId = 12 OR Pump_A_StateId = 14 OR Pump_A_StateId = 9 OR Pump_A_StateId = 1837 OR Pump_A_StateId = 1839 THEN 1 END) AS PumpAStarts
,COUNT(CASE WHEN Pump_B_StateId = 12 OR Pump_B_StateId = 14 OR Pump_B_StateId = 9 OR Pump_B_StateId = 1837 OR Pump_B_StateId = 1839 THEN 1 END) AS PumpBStarts
FROM (
SELECT * , SiteName
, LAG([ECV36_Open_Count_Lifetime],1,NULL) OVER(PARTITION BY R.SiteId ORDER BY RecordDateTime ASC) AS 'Lag_ECV36_Open_Count_Lifetime'
FROM (
[Cryo].[dbo].[Record] R
Cryo.dbo.Site S on S.SiteId = R.RecordId
Cryo.dbo.Pad P on P.RecordId = R.RecordId
Cryo.dbo.Pump PP on PP.RecordId = R.RecordId
)a
)a
WHERE RecordDateTime BETWEEN DATEADD(DD,-1,CONVERT(DATE,GETDATE())) AND DATEADD(DD, 0,CONVERT(DATE,GETDATE()))
)a
请注意,我不太在意 SELECT 区域中的项目看起来是否漂亮,而是确保每个嵌套级别的缩进正确。完成后,这部分突然出现在我面前:
FROM (
[Cryo].[dbo].[Record] R
Cryo.dbo.Site S on S.SiteId = R.RecordId
Cryo.dbo.Pad P on P.RecordId = R.RecordId
Cryo.dbo.Pump PP on PP.RecordId = R.RecordId
您似乎在这里遗漏了一些 JOIN。不幸的是,我不能只为你解决这个问题,因为我们无法知道你是否想要 INNER JOIN、LEFT JOIN、CROSS JOIN 等。它还怀疑这个查询在 [=14] 中有一个 *
=] 子句。
我注意到的另一件事是下一层的聚合函数。您不能使用 SUM()
之类的聚合函数,除非它们是 SELECT 子句中的唯一字段,您有 GROUP BY 子句,或者它们位于带有 PARTITION BY 的窗口函数(OVER 表达式)中部分。
最后,为了帮助以后更容易管理,我建议将每个级别都写成 CTE(通用 Table 表达式)。这将减少缩进,并且(以我的经验)使查询更容易在心理上进行推理。无需重写 所有内容,这里有一个简短的概述:
WITH LaggedSiteLifetime AS (
SELECT * , SiteName
, LAG(....)
FROM Record...
), PumpCounts AS (
SELECT *, SiteName, COUNT(.....)
FROM LaggedSiteLifetime
)
SELECT SiteName,
ROUND(...)
FROM PumpCounts
这是我的偏好。有些人更喜欢您已有的嵌套视图,因为它允许他们只突出显示一个部分并在 Management Studio 中按 F5 到 运行 该部分,这会使 运行 变得更难,比如说,只是PumpCounts
部分。但是,我发现这有助于减少嵌套并使缩进更加一致(所有 SELECT/FROM/WHERE/etc 可以处于同一级别)。最重要的是,这让我们可以按照您需要阅读的顺序编写查询以便能够理解它,而另一种方式您必须从内到外阅读内容。
我仍在学习 SQL 并且正在努力处理内联视图。我一直在做一个项目,在这个项目中我需要考虑某些事情的滞后,因此需要依赖嵌套的东西。但是我对内联视图的语法还不是很好,它一直在括号、逗号等上抛出错误。有人可以帮我清理它以便它运行吗?
SELECT *
, SiteName
, VentCount AS 'Number Of Vents'
, ROUND(PumpAHours,1) AS 'Pump A Hours'
, ROUND(PumpBHours,1) AS 'Pump B Hours'
, ROUND(PumpAStarts, 1) AS 'Pump A Starts'
, ROUND(PumpBStarts, 1) AS 'Pump B Starts'
FROM (
SELECT * , SiteName
, SUM(CASE WHEN ECV36_Open_Count_Lifetime - Lag_ECV36_Open_Count_Lifetime Between 1 AND 5 THEN ECV36_Open_Count_Lifetime - Lag_ECV36_Open_Count_Lifetime ELSE 0 END) AS 'VentCount'
, CASE WHEN NULLIF(SUM(CASE WHEN PumpAStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT),0) < MAX(Pump_A_Hours) - MIN(Pump_A_Hours)
THEN SUM(CASE WHEN PumpAStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT)
ELSE MAX(Pump_A_Hours) - MIN(Pump_A_Hours) END AS 'PumpAHours'
, CASE WHEN NULLIF(SUM(CASE WHEN PumpBStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT),0) < MAX(Pump_B_Hours) - MIN(Pump_B_Hours)
THEN SUM(CASE WHEN PumpBStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT)
ELSE MAX(Pump_B_Hours) - MIN(Pump_B_Hours) END AS 'PumpBHours'
,COUNT(CASE WHEN Pump_A_StateId = 12 OR Pump_A_StateId = 14 OR Pump_A_StateId = 9 OR Pump_A_StateId = 1837 OR Pump_A_StateId = 1839 THEN 1 END) AS PumpAStarts
,COUNT(CASE WHEN Pump_B_StateId = 12 OR Pump_B_StateId = 14 OR Pump_B_StateId = 9 OR Pump_B_StateId = 1837 OR Pump_B_StateId = 1839 THEN 1 END) AS PumpBStarts
FROM (
SELECT * , SiteName
, LAG([ECV36_Open_Count_Lifetime],1,NULL) OVER(PARTITION BY R.SiteId ORDER BY RecordDateTime ASC) AS 'Lag_ECV36_Open_Count_Lifetime'
FROM (
[Cryo].[dbo].[Record] R
Cryo.dbo.Site S on S.SiteId = R.RecordId
Cryo.dbo.pad P on P.RecordId = R.RecordId
Cryo.dbo.Pump PP on PP.RecordId = R.RecordId
)a
)a
WHERE RecordDateTime BETWEEN DATEADD(DD,-1,CONVERT(DATE,GETDATE())) AND DATEADD(DD, 0,CONVERT(DATE,GETDATE()))
)a
编辑:我重新格式化了代码并修复了一些标注。事情仍然无法正常工作,但给出的唯一错误是我猜子查询别名,如果那是他们所说的?。对于 )a 和 )c 我有语法错误,并且 )b 说 SiteName 被指定了多次,尽管我只能找到一个。我不确定如何解决该问题。再次,对于所有混乱的代码,我感到很抱歉,我真的很新鲜。
SELECT * ,
sitename ,
ventcount AS 'Number Of Vents' ,
Round(pumpahours,1) AS 'Pump A Hours' ,
Round(pumpbhours,1) AS 'Pump B Hours' ,
Round(pumpastarts, 1) AS 'Pump A Starts' ,
Round(pumpbstarts, 1) AS 'Pump B Starts'
FROM (
SELECT * ,
sitename ,
Sum(
CASE
WHEN ecv36_open_count_lifetime - lag_ecv36_open_count_lifetime BETWEEN 1 AND 5 THEN ecv36_open_count_lifetime - lag_ecv36_open_count_lifetime
ELSE 0
END) AS 'VentCount' ,
CASE
WHEN NULLIF(Sum(
CASE
WHEN pumpastatus LIKE '%Running%' THEN 1
ELSE 0
END) / Cast(20 AS FLOAT),0) < Max(pump_a_hours) - Min(pump_a_hours) THEN Sum(
CASE
WHEN pumpastatus LIKE '%Running%' THEN 1
ELSE 0
END) / Cast(20 AS FLOAT)
ELSE Max(pump_a_hours) - Min(pump_a_hours)
END AS 'PumpAHours' ,
CASE
WHEN NULLIF(Sum(
CASE
WHEN pumpbstatus LIKE '%Running%' THEN 1
ELSE 0
END) / Cast(20 AS FLOAT),0) < Max(pump_b_hours) - Min(pump_b_hours) THEN Sum(
CASE
WHEN pumpbstatus LIKE '%Running%' THEN 1
ELSE 0
END) / Cast(20 AS FLOAT)
ELSE Max(pump_b_hours) - Min(pump_b_hours)
END AS 'PumpBHours' ,
Count(
CASE
WHEN pump_a_stateid = 12
OR pump_a_stateid = 14
OR pump_a_stateid = 9
OR pump_a_stateid = 1837
OR pump_a_stateid = 1839 THEN 1
END) AS pumpastarts ,
Count(
CASE
WHEN pump_b_stateid = 12
OR pump_b_stateid = 14
OR pump_b_stateid = 9
OR pump_b_stateid = 1837
OR pump_b_stateid = 1839 THEN 1
END) AS pumpbstarts
FROM (
SELECT * ,
s.SiteName ,
Lag([ECV36_Open_Count_Lifetime],1,NULL) OVER(partition BY r.siteid ORDER BY recorddatetime ASC) AS 'Lag_ECV36_Open_Count_Lifetime'
FROM ( [Cryo].[dbo].[Record] R JOIN cryo.dbo.site s ON s.siteid = r.recordid JOIN cryo.dbo.pad p ON p.recordid = r.recordid JOIN cryo.dbo.pump pp ON pp.recordid = r.recordid )a
WHERE recorddatetime BETWEEN dateadd(dd,-1,CONVERT(date,getdate())) AND dateadd(dd, 0,CONVERT(date,getdate())) )b )c
我必须从改进缩进开始。这使得更容易查看事情是如何排列的:
SELECT *
, SiteName
, VentCount AS 'Number Of Vents'
, ROUND(PumpAHours,1) AS 'Pump A Hours'
, ROUND(PumpBHours,1) AS 'Pump B Hours'
, ROUND(PumpAStarts, 1) AS 'Pump A Starts'
, ROUND(PumpBStarts, 1) AS 'Pump B Starts'
FROM (
SELECT * , SiteName
, SUM(CASE WHEN ECV36_Open_Count_Lifetime - Lag_ECV36_Open_Count_Lifetime Between 1 AND 5 THEN ECV36_Open_Count_Lifetime - Lag_ECV36_Open_Count_Lifetime ELSE 0 END) AS 'VentCount'
, CASE WHEN NULLIF(SUM(CASE WHEN PumpAStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT),0) < MAX(Pump_A_Hours) - MIN(Pump_A_Hours)
THEN SUM(CASE WHEN PumpAStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT)
ELSE MAX(Pump_A_Hours) - MIN(Pump_A_Hours) END AS 'PumpAHours'
, CASE WHEN NULLIF(SUM(CASE WHEN PumpBStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT),0) < MAX(Pump_B_Hours) - MIN(Pump_B_Hours)
THEN SUM(CASE WHEN PumpBStatus LIKE '%Running%' THEN 1 ELSE 0 END) / CAST(20 AS FLOAT)
ELSE MAX(Pump_B_Hours) - MIN(Pump_B_Hours) END AS 'PumpBHours'
,COUNT(CASE WHEN Pump_A_StateId = 12 OR Pump_A_StateId = 14 OR Pump_A_StateId = 9 OR Pump_A_StateId = 1837 OR Pump_A_StateId = 1839 THEN 1 END) AS PumpAStarts
,COUNT(CASE WHEN Pump_B_StateId = 12 OR Pump_B_StateId = 14 OR Pump_B_StateId = 9 OR Pump_B_StateId = 1837 OR Pump_B_StateId = 1839 THEN 1 END) AS PumpBStarts
FROM (
SELECT * , SiteName
, LAG([ECV36_Open_Count_Lifetime],1,NULL) OVER(PARTITION BY R.SiteId ORDER BY RecordDateTime ASC) AS 'Lag_ECV36_Open_Count_Lifetime'
FROM (
[Cryo].[dbo].[Record] R
Cryo.dbo.Site S on S.SiteId = R.RecordId
Cryo.dbo.Pad P on P.RecordId = R.RecordId
Cryo.dbo.Pump PP on PP.RecordId = R.RecordId
)a
)a
WHERE RecordDateTime BETWEEN DATEADD(DD,-1,CONVERT(DATE,GETDATE())) AND DATEADD(DD, 0,CONVERT(DATE,GETDATE()))
)a
请注意,我不太在意 SELECT 区域中的项目看起来是否漂亮,而是确保每个嵌套级别的缩进正确。完成后,这部分突然出现在我面前:
FROM (
[Cryo].[dbo].[Record] R
Cryo.dbo.Site S on S.SiteId = R.RecordId
Cryo.dbo.Pad P on P.RecordId = R.RecordId
Cryo.dbo.Pump PP on PP.RecordId = R.RecordId
您似乎在这里遗漏了一些 JOIN。不幸的是,我不能只为你解决这个问题,因为我们无法知道你是否想要 INNER JOIN、LEFT JOIN、CROSS JOIN 等。它还怀疑这个查询在 [=14] 中有一个 *
=] 子句。
我注意到的另一件事是下一层的聚合函数。您不能使用 SUM()
之类的聚合函数,除非它们是 SELECT 子句中的唯一字段,您有 GROUP BY 子句,或者它们位于带有 PARTITION BY 的窗口函数(OVER 表达式)中部分。
最后,为了帮助以后更容易管理,我建议将每个级别都写成 CTE(通用 Table 表达式)。这将减少缩进,并且(以我的经验)使查询更容易在心理上进行推理。无需重写 所有内容,这里有一个简短的概述:
WITH LaggedSiteLifetime AS (
SELECT * , SiteName
, LAG(....)
FROM Record...
), PumpCounts AS (
SELECT *, SiteName, COUNT(.....)
FROM LaggedSiteLifetime
)
SELECT SiteName,
ROUND(...)
FROM PumpCounts
这是我的偏好。有些人更喜欢您已有的嵌套视图,因为它允许他们只突出显示一个部分并在 Management Studio 中按 F5 到 运行 该部分,这会使 运行 变得更难,比如说,只是PumpCounts
部分。但是,我发现这有助于减少嵌套并使缩进更加一致(所有 SELECT/FROM/WHERE/etc 可以处于同一级别)。最重要的是,这让我们可以按照您需要阅读的顺序编写查询以便能够理解它,而另一种方式您必须从内到外阅读内容。