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

时间:2010-05-25 02:50:23

标签: sql where-clause

我是SQL的全新人,但是我要说StackExchange Data Explorer,我只想按名誉列出前15名用户,我写了这样的话:

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轻松解决这个问题,基本上重复这个公式。

所以问题是:

  • 我可以在RepInK子句中实际使用WHERE“列”吗?
    • 我是否需要使用此列创建虚拟表/视图,然后对其进行SELECT/WHERE查询?
  • 我可以命名一个表达式,例如Reputation/1000,所以我只需要在几个地方重复这些名字而不是公式?
    • 你怎么称呼这个?替换宏?一个功能?存储过程?
  • 是否有SQL快速表,术语表,语言规范,以及我可以用来快速获取语言的语法和语义的任何内容?
    • 我明白有不同的“味道”?

5 个答案:

答案 0 :(得分:9)

  

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

不,但您可以放心,即使您在(Reputation / 1000)字段和SELECT子句中都使用了数据库,您的数据库也会评估WHERE一次。

  

我是否需要使用此列创建虚拟表/视图,然后对其执行SELECT / WHERE查询?

是的,视图是简化复杂查询的一种选择。

  

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

您可以创建一个用户定义的函数,您可以调用类似convertToK的函数,它会将rep值作为参数接收并返回该参数除以1000.但是,对于像这样的小案例,它通常是不实用的你的例子中的一个。

  

是否有SQL快速表,术语表,语言规范,以及我可以用来快速获取语言的语法和语义的任何内容?

我建议练习。您可能希望开始关注Stack Overflow上的mysql标记,其中每天都会询问许多初学者问题。 Download MySQL,当您认为可以达到问题时,请尝试寻求解决方案。我认为这将有助于您提高速度,以及对语言功能的认识。起初没有必要发布答案,因为这里的主题有一些相当快的枪支,但通过一些练习我相信你能够带回家一些点:)

  

我明白有不同的“味道”?

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

答案 1 :(得分:7)

您可以简单地重写WHERE子句

where reputation > 10000

这并不总是方便的。作为替代方案,您可以使用内联视图:

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 

答案 2 :(得分:2)

关于命名表达式之类的东西,虽然有几种可能的选择,但查询优化器最好只写出公式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提供了几个主要数据库的标准形式和偏差。

答案 3 :(得分:1)

CAN Order By子句中引用RepInK,但在Where子句中,您必须重复该表达式。但是,正如其他人所说,它只会被执行一次。

答案 4 :(得分:1)

技术问题已有很好的答案,所以我只会解决其余的一些问题。

如果您只是使用DataExplorer,那么您将需要熟悉SQL Server语法,因为它正在运行。当然,找到它的最佳位置是MSDN's reference

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