簡體   English   中英

SQL 查詢在嵌套 select 中使用別名時引發錯誤

[英]SQL query throws error while using Alias in nested select

我今天發布了一個問題,但這太寬泛了。 所以,我在這方面工作,現在縮小到一些部分。 但是,我的查詢返回語法錯誤,而只是復制粘貼相同的文本。

(
SELECT
   TOP (100) PERCENT v_UpdateComplianceStatus.ResourceID, v_UpdateComplianceStatus.Status, CAST(DATEPART(yyyy, v_UpdateInfo.DatePosted) AS varchar(255)) + '-' + RIGHT('0' + CAST(DATEPART(mm, v_UpdateInfo.DatePosted) AS VARCHAR(255)), 2) AS MonthPosted, COUNT(1) AS Count 
FROM
   v_UpdateComplianceStatus 
   INNER JOIN
      v_UpdateInfo 
      ON v_UpdateComplianceStatus.CI_ID = v_UpdateInfo.CI_ID 
   INNER JOIN
      v_R_System 
      ON v_UpdateComplianceStatus.ResourceID = v_R_System.ResourceID 
   inner join
      v_FullCollectionMembership fcm 
      on v_UpdateComplianceStatus.ResourceID = fcm.ResourceID 
WHERE
   (
      v_R_System.Operating_System_Name_and0 like '%Workstation 6.1%' 
      and v_R_System.Obsolete0 = 0
   )
   AND 
   (
      v_UpdateInfo.Severity IN 
      (
         8,
         10
      )
   )
   AND 
   (
      v_UpdateInfo.IsSuperseded = 0
   )
   AND 
   (
      v_UpdateInfo.IsEnabled = 1
   )
   and fcm.CollectionID = 'ABC00328' 
GROUP BY
   v_UpdateComplianceStatus.ResourceID, v_UpdateComplianceStatus.Status, CAST(DATEPART(yyyy, v_UpdateInfo.DatePosted) AS varchar(255)) + '-' + RIGHT('0' + CAST(DATEPART(mm, v_UpdateInfo.DatePosted) AS VARCHAR(255)), 2)) FF
where Status =2
Group By MonthPosted ) E
where E.MonthPosted = E.MonthPosted
order by MonthPosted Desc

如果我運行上面的查詢,它會拋出錯誤

Group By MonthPosted ) EE 

不知道為什么它給出錯誤。

Msg 102, Level 15, State 1, Line 123
Incorrect syntax near 'EE'.

我發現的一些重要的事情。

如果我運行它的某些部分,這個查詢就可以正常工作。

(SELECT TOP (100) PERCENT v_UpdateComplianceStatus.ResourceID, v_UpdateComplianceStatus.Status, CAST(DATEPART(yyyy,
v_UpdateInfo.DatePosted) AS varchar(255)) + '-' + RIGHT('0' + CAST(DATEPART(mm, v_UpdateInfo.DatePosted) AS VARCHAR(255)), 2)
AS MonthPosted, COUNT(1) AS Count
FROM v_UpdateComplianceStatus INNER JOIN
v_UpdateInfo ON v_UpdateComplianceStatus.CI_ID = v_UpdateInfo.CI_ID INNER JOIN
v_R_System ON v_UpdateComplianceStatus.ResourceID = v_R_System.ResourceID
inner join v_FullCollectionMembership fcm on v_UpdateComplianceStatus.ResourceID=fcm.ResourceID
WHERE (v_R_System.Operating_System_Name_and0 like '%Workstation 6.1%' and v_R_System.Obsolete0 = 0) AND (v_UpdateInfo.Severity IN (8, 10)) AND (v_UpdateInfo.IsSuperseded = 0) AND (v_UpdateInfo.IsEnabled = 1)
and fcm.CollectionID='ABC00328'
GROUP BY v_UpdateComplianceStatus.ResourceID, v_UpdateComplianceStatus.Status, CAST(DATEPART(yyyy,
v_UpdateInfo.DatePosted) AS varchar(255)) + '-' + RIGHT('0' + CAST(DATEPART(mm, v_UpdateInfo.DatePosted) AS VARCHAR(255)), 2))

但是,如果我輸入別名 (FF),則會引發語法錯誤。

評論太長了。 這是您的第一個片段濃縮成可讀的東西。 注意 - 學習編寫和發布可讀代碼。 您已經使用了 FAR 太多的行距、縮進和空白,任何人都無法輕松閱讀您的代碼。 越難讀,就越難理解。 我已盡力將您的第一個查詢濃縮為基本元素。

(
   SELECT blah blah,  
          CAST(DATEPART(yyyy, v_UpdateInfo.DatePosted) AS varchar(255)) + '-' + 
               RIGHT('0' + CAST(DATEPART(mm, v_UpdateInfo.DatePosted) AS VARCHAR(255)), 2) AS MonthPosted, 
          <aggregated column> 
    GROUP BY blah blah) as FF

where Status =2
Group By MonthPosted 
) as E

where E.MonthPosted = E.MonthPosted
order by MonthPosted Desc

那么在這里看到了什么錯誤。 where 子句毫無意義——沒有任何用處。 您可能在所有編輯中都引入了該錯誤。 顯然,您無緣無故地將數字轉換為大字符串。 那只是草率。 令人擔憂的是,您首先需要將數字轉換為零填充字符串 - 這可能是一種低效的方法。 如果您確實需要這樣做,請查看 convert 的文檔。 樣式 112 可以滿足您的需求 - 您需要做的就是獲取轉換后的字符串的前 6 個字符。 注意 6 個字符,而不是 255 個字符或 MAX 個字符。 這將顯着整理您的代碼。

現在你已經多次編輯了你的帖子,這在邏輯上是沒有意義的。 您的第一個查詢中根本沒有“EE”別名 - 因此您發布的錯誤不能來自該片段。 問題很可能來自您遺漏的代碼。

所以現在是分而治之的時候了——一種可以用來構建復雜查詢的技術。 只關注那個片段。 把它寫成一個完整的查詢並運行它,測試它,驗證它是否有效。 當它執行時沒有錯誤並返回正確的結果(您已經實際驗證的結果,而不僅僅是查看數字/值是否看起來“合理”),然后您可以根據需要添加其他邏輯。 通常最好是逐個添加連接,以避免產生難以理解和診斷的怪物問題。 通常使用 CTE 會有所幫助。 將您的起始查詢放在 cte 中,讓它正常工作。 例子:

with cte1 as (...)
select * from cte1 
order by ...;

然后在第一個 cte 中添加另一個 cte 並編寫它以使用第一個,讓它工作。 例子:

with cte1 as (...), 
cte2 as (select ... from cte1 inner join ...)
select * from cte2 
order by ...; 

根據需要重復。 一旦一切正常,您可以嘗試將它們組合在一起並在需要時“美化”它。

並開始考慮您的代碼。 使用適當的數據類型,不要試圖過早地優化事物,學習和理解你的模式,停止使用技巧。 正如我所提到的,“選擇前 100%”通常是沒有意義的。 反問——你為什么認為這是這個派生表的一部分。 並使用有意義的別名。 “E”和“EE”沒有意義。 請記住,有人需要維護此代碼,甚至可能對其進行修改。 當然,為每個表/視圖創建一個別名並使用它。 簡短(但不是太短)但有意義的東西。 這將極大地提高可讀性——尤其是對於那些非常長的視圖(大概)名稱。

最后,您說“如果我運行它的某些部分,這個查詢就可以正常工作。” 那只是沒有用的東西,因為它對讀者沒有任何意義。 哪一部分? 所有的? 第一行? 只有第 2 到 5 行? 很難進行技術討論——不要使用不精確的術語來增加混淆。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM