简体   繁体   English

SQL 查询在嵌套 select 中使用别名时引发错误

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

I posted one question today but that was too broad.我今天发布了一个问题,但这太宽泛了。 So, I worked on that and now narrow down to some of parts.所以,我在这方面工作,现在缩小到一些部分。 However, my query is returning syntax error while just copy paste the same text.但是,我的查询返回语法错误,而只是复制粘贴相同的文本。

(
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

If I run the above query it is throwing error at如果我运行上面的查询,它会抛出错误

Group By MonthPosted ) EE 

Not sure why it is giving error.不知道为什么它给出错误。

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

Some Important things which I discover.我发现的一些重要的事情。

This query works fine if I run some part of it.如果我运行它的某些部分,这个查询就可以正常工作。

(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))

But if I Put Alias (FF) then it is throwing a syntax error.但是,如果我输入别名 (FF),则会引发语法错误。

Too long for a comment.评论太长了。 Here is your first snippet condensed into something readable.这是您的第一个片段浓缩成可读的东西。 Note - learn to write and post readable code.注意 - 学习编写和发布可读代码。 You have gone with FAR too much line spacing, indentation, and white space for anyone to easily read your code.您已经使用了 FAR 太多的行距、缩进和空白,任何人都无法轻松阅读您的代码。 The harder it is to read, the harder it is to understand.越难读,就越难理解。 I've done my best to condense your first query into the essential elements.我已尽力将您的第一个查询浓缩为基本元素。

(
   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

So what do YOU see wrong here.那么在这里看到了什么错误。 The where clause is pointless - does nothing useful. where 子句毫无意义——没有任何用处。 You probably introduced that error with all the editing.您可能在所有编辑中都引入了该错误。 And apparently you cast numbers to large strings for no reason.显然,您无缘无故地将数字转换为大字符串。 That is just sloppy.那只是草率。 It is concerning that you feel a need to cast a number to zero-filled string in the first place - that is probably an inefficient approach.令人担忧的是,您首先需要将数字转换为零填充字符串 - 这可能是一种低效的方法。 If you really need to do that, look up the documentation for convert.如果您确实需要这样做,请查看 convert 的文档。 Style 112 does what you need - all you need to do is take the first 6 characters of the converted string.样式 112 可以满足您的需求 - 您需要做的就是获取转换后的字符串的前 6 个字符。 Note 6 characters, not 255 characters or MAX characters.注意 6 个字符,而不是 255 个字符或 MAX 个字符。 That will declutter your code significantly.这将显着整理您的代码。

And now that you have edited your post multiple times, it logically makes no sense.现在你已经多次编辑了你的帖子,这在逻辑上是没有意义的。 There is no "EE" alias in your first query at all - so the error you posted cannot come from that snippet.您的第一个查询中根本没有“EE”别名 - 因此您发布的错误不能来自该片段。 Most likely the problem comes from the code you left out.问题很可能来自您遗漏的代码。

So now it is time to divide and conquer - a technique you can use to build complicated queries.所以现在是分而治之的时候了——一种可以用来构建复杂查询的技术。 Focus on that snippet ONLY.只关注那个片段。 Write it as a complete query and run it, test it, validate that it works.把它写成一个完整的查询并运行它,测试它,验证它是否有效。 When it does execute without errors and returns the correct results (results that you have actually verified and not just glanced at to see if numbers/values look "reasonable"), you can then add additional logic as needed.当它执行时没有错误并返回正确的结果(您已经实际验证的结果,而不仅仅是查看数字/值是否看起来“合理”),然后您可以根据需要添加其他逻辑。 Usually it is best to add joins 1 by 1 to avoid creating a monster problem that is difficult to understand and diagnose.通常最好是逐个添加连接,以避免产生难以理解和诊断的怪物问题。 Often the use of CTEs can help.通常使用 CTE 会有所帮助。 Put your starting query in a cte, get it working correctly.将您的起始查询放在 cte 中,让它正常工作。 Example:例子:

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

Then add another cte to this first one and write it to use the first one, get it working.然后在第一个 cte 中添加另一个 cte 并编写它以使用第一个,让它工作。 Example:例子:

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

Repeat that as needed.根据需要重复。 Once everything works you can try to bring it all together and "beautify" it if needed.一旦一切正常,您可以尝试将它们组合在一起并在需要时“美化”它。

And start thinking about your code.并开始考虑您的代码。 Use the appropriate datatypes, do NOT try to prematurely optimize things, learn and understand your schema, and stop using tricks.使用适当的数据类型,不要试图过早地优化事物,学习和理解你的模式,停止使用技巧。 As I mentioned, "select top 100 percent" is generally pointless.正如我所提到的,“选择前 100%”通常是没有意义的。 Rhetorical question - why do you think this is needed as a part of this derived table.反问——你为什么认为这是这个派生表的一部分。 And use meaningful alias names.并使用有意义的别名。 "E" and "EE" are not meaningful. “E”和“EE”没有意义。 Remember that someone will need to maintain this code, perhaps even modify it.请记住,有人需要维护此代码,甚至可能对其进行修改。 And, of course, create an alias for every table/view and use it.当然,为每个表/视图创建一个别名并使用它。 Something short (but not too short) but meaningful.简短(但不是太短)但有意义的东西。 This will vastly improve readability - especially with those very long view (presumably) names.这将极大地提高可读性——尤其是对于那些非常长的视图(大概)名称。

Lastly, You said "This query works fine if i run some part of it."最后,您说“如果我运行它的某些部分,这个查询就可以正常工作。” That just is not a useful thing to write since it means nothing to the reader.那只是没有用的东西,因为它对读者没有任何意义。 Which part?哪一部分? All of it?所有的? The first line?第一行? Just lines 2 through 5?只有第 2 到 5 行? It is difficult to have a technical discussion - do not add confusion by using terms that are imprecise.很难进行技术讨论——不要使用不精确的术语来增加混淆。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM