初学者SQL部分:避免重复表达

初学者SQL部分:避免重复表达

问题描述:

我在SQL全新的,但让我们说,在StackExchange Data Explorer,我只是想列出前15名用户通过口碑,我写的是这样的:初学者SQL部分:避免重复表达

SELECT TOP 15 
    DisplayName, Id, Reputation, Reputation/1000 As RepInK 
FROM 
    Users 
WHERE 
    RepInK > 10 
ORDER BY Reputation DESC 

目前这给出了Error: Invalid column name 'RepInK',我认为这是合理的,因为RepInK不是Users中的一列。我可以通过说WHERE Reputation/1000 > 10很容易解决这个问题,基本上重复这个公式。

所以问题是:

  • 我能实际上是WHERE子句中使用RepInK “列”?
    • 我是否需要创建一个虚拟表/视图与此列,然后对其执行SELECT/WHERE查询?
  • 我可以命名一个表达式,例如: Reputation/1000,所以我只需要在几个地方重复名称而不是公式?
    • 你叫什么?一个替代宏?一个函数?存储过程?
  • 是否有SQL快速表,术语词汇表,语言规范,我可以用来快速获取语言的语法和语义的任何东西?
    • 我知道有不同的“口味”?
+1

你不能使用'SELECT'语句作为'WHERE'条件,在你的情况下'RepInk',因为t他们会在WHERE之后解决,这是一个悖论,服务器将与整个建筑一起爆炸。 – Ben 2010-05-25 03:07:25

我可以实际使用的RepInK “列” 在WHERE子句中?

没有,但你可以放心,你的数据库将评估(Reputation/1000)一次,即使你在SELECT领域和WHERE子句中使用这两种。

我是否需要用这个列创建一个虚拟表/视图,然后对它做一个SELECT/WHERE查询?

是的,视图是简化复杂查询的一个选项。

我可以命名一个表达式,例如:名誉/ 1000,所以我只需要在几个地方重复名称而不是公式?

您可以创建一个用户定义的函数,你可以调用像convertToK,这将收到代表值作为参数,但它往往是像一个微不足道的情况下,不实际返回一个参数,以1000分一个在你的例子中。

是否有SQL快速表,术语词汇表,语言规范,我可以用来快速选择语言的语法和语义的任何东西?

我建议的做法。您可能想要在Stack Overflow上开始关注mysql标签,每天都会询问很多初学者问题。 Download MySQL,当您认为您的范围内存在问题时,请尝试寻求解决方案。我认为这会帮助你提高速度以及语言功能的意识。一开始没有必要张贴答案,因为这里的主题有一些相当快的枪支,但有一些练习,我相信你可以带回家一些观点:)

I明白有不同的“口味”?

风味实际上是ANSI SQL的扩展。数据库供应商通常通过扩展来扩充SQL语言,如Transact-SQLPL/SQL

+0

你会建议不要通过查询Stack Exchange Data Explorer来学习SQL吗?因为那是我的计划。没有必要安装任何东西,很多人已经查询过,所以我可以查看其他人的查询,我熟悉和关心的真实数据等。 – polygenelubricants 2010-05-25 03:46:19

+1

@polygenelubricants:根本没有。这当然是一种好的做法,尤其是如果你有一些特别的好奇心,你想从SE数据转储中满足:) ......我建议遵循SO问题,因为真正的问题通常会为实际的SQL工具揭示更多的情况。另外,你还会看到专家如何回应,从中学到很多东西。 mysql标签通常会比sql-server标签或其他标签收集更简单的问题。语法并非完全不同:大多数查询将在所有数据库上运行。 – 2010-05-25 04:10:17

+1

@polygenelubricants:看起来你不是唯一一个[有兴趣从Stack Exchange Data Exporer学习SQL](http://meta.stackexchange.com/questions/51395/can-we-become-ourown -northwind-for-teaching-sql-databases):) – 2010-05-27 14:09:34

你可以简单地重新写在WHERE子句

where reputation > 10000 

这并不总是很方便。作为alternativly,您可以使用内嵌视图:

SELECT 
    a.DisplayName, a.Id, a.Reputation, a.RepInK 
FROM 
    (
     SELECT TOP 15 
      DisplayName, Id, Reputation, Reputation/1000 As RepInK 
     FROM 
      Users 
     ORDER BY Reputation DESC 
    ) a 
WHERE 
    a.RepInK > 10 

CAN指RepInK的Order By子句中,但Where子句中你必须重复的表达。但是,正如其他人所说,它只会执行一次。

有对已经解决的技术问题很好的答案,所以我只能解决大家的一些问题,其余的。

如果你只是用DataExplorer的工作,你要熟悉SQL Server语法,因为这就是它的运行。当然,最好的地方是MSDN's reference

是的,有在SQL语法不同的变化。例如,您提供的查询中的TOP子句是特定于SQL Server的;在MySQL中,您将使用LIMIT子句(而且这些关键字不一定出现在查询中的同一位置!)。

关于类似命名表达式,虽然有多种可能的选择,查询优化器会做最好的只是写出来的公式Reputation/1000长手。如果您确实需要使用相同的评估值运行一组完整的查询,那么最好的办法是使用定义的字段创建视图,但您不希望为一次性查询做到这一点。

作为替代,(并且在性能没有太大的问题的情况下),你可以尝试像:

SELECT TOP 15 
    DisplayName, Id, Reputation, RepInk 
FROM (
    SELECT DisplayName, Id, Reputation, Reputation/1000 as RepInk 
    FROM Users 
) AS table 
WHERE table.RepInk > 10 
ORDER BY Reputation DESC 

虽然我不相信这是所有SQL方言的支持,并再次,优化器很可能会做这种事情更糟糕的工作(因为它将针对完整的Users表运行SELECT,然后过滤该结果)。尽管如此,在某些情况下,这种查询是合适的(这里有个名字......我现在正在画一个空白)。

个人而言,当我开始用SQL,我发现the W3 schools参考是我的固定停靠点。它符合我的风格,因为我可以浏览一下以找到快速答案并继续前进。但是,最终要真正利用数据库,有必要深入研究供应商文档。

虽然SQL是“标化”,不幸的是(虽然,在一定程度上,幸运的),每个数据库供应商实现他们自己的版本与自己的扩展,这可能会导致完全不同的语法是最合适的(为的讨论各个数据库在一个问题上的不兼容性见SQLite documentation on NULL handling。特别是,标准函数(例如用于处理DATE和TIME的标准函数)在每个供应商中倾向于不同,并且还有其他更大的差异(特别是在不支持子查询或正确处理JOIN时) 。如果你关心一些细节,this document提供了几个主要数据库的标准格式和偏差。

+0

(回复:命名查询和优化器)在这一点上我关心编写好可读的查询;我稍后会担心优化/性能。我认为这是学习大多数语言的更好方式;我希望对于SQL也是如此。 – polygenelubricants 2010-05-25 03:49:51