我想根据派生列的值对SQL数据进行排序,如下所示:
SELECT DISTINCT sp.ID
, sp.Status
, sp.Rank
, sp.Price
, sp.SalePrice
, sp.Width
, sp.Height
, sp.QOH
, (sp.SalePrice*sp.QOH) As 'sp.Value'
, (sp.Price*sp.QOH) As 'sp.StandardValue'
FROM table
WHERE -- Conditions
ORDER BY
CASE WHEN 'sp.SalePrice' > 0 THEN 'sp.Value' END DESC,
CASE WHEN 'sp.SalePrice' = 0 THEN 'sp.StandardValue' END DESC
发现此错误:
Msg 145,Level 15,State 1,Line 1
如果指定了SELECT DISTINCT,则ORDER BY项必须出现在选择列表中。
如果我尝试
ORDER BY
CASE WHEN sp.SalePrice > 0 THEN (sp.SalePrice*sp.QOH) As "sp.Value" END DESC,
CASE WHEN sp.SalePrice = 0 THEN (sp.Price*sp.QOH) As sp.StandardValue" END DESC
给出错误:
关键字“As”附近的语法不正确。
如果我试图通过cluase& amp;来尝试删除别名*,它会开始给出相同的选择明显错误只留下乘法部分
答案 0 :(得分:2)
我将在下面添加一些关于一般约定的建议,但是对于主要问题,请考虑您尝试使用此示例做什么:
MY_TABLE:
id value
1 1
2 2
3 1
现在,尝试按ID显示不同的value
排序。它应该是什么?
value
1
2
或
value
2
1
所以,你要求SQL Server做一些可能不可能或至少不清楚的事情。
现在,关于约定......也许其中一些就是你在这里发布的内容,但我会为你的代码提出以下建议:
避免对名称使用保留和SQL语言单词。这包括table
,rank
和status
。
避免在名称中使用特殊字符。这将包括sp.value
。当然,您可以使用带引号的标识符来执行此操作,但是某些前端等可能不支持它们,即使SQL确实如此,并且在大多数情况下您并没有真正购买任何东西。
必须引用名称时使用带引号的标识符。如果您绝对必须违反上述两个建议之一,请使用标准的SQL Server引用标识符,即[
和]
。如果你想引用别名,也可以使用它们(你不应该通常引用别名BTW)。这有助于避免Mark B指出的问题。
您的CASE
语句可以更好地写为一个排序列。此外,在大多数情况下,您应该包括ELSE以避免未处理的条件。只要您不能在任何相关列中包含NULL或负值,就可能不需要这样做。
CASE
WHEN sp.SalePrice > 0 THEN (sp.SalePrice*sp.QOH)
WHEN sp.SalePrice = 0 THEN (sp.Price*sp.QOH)
END
我个人会避免使用表别名(看起来你不小心忽略了查询)作为列别名的一部分。它使IMO更加混乱,因为它使得看起来像别名列实际上是表中的一列。
答案 1 :(得分:1)
在字段名称周围使用'
将它们转换为字符串。完全删除引号,或使用"
代替。
答案 2 :(得分:1)
您的第二个示例最接近,因为它正确指定了列。但是,您不能按顺序对列进行别名。这可行:
ORDER BY
CASE WHEN sp.SalePrice > 0 THEN sp.SalePrice*sp.QOH END DESC,
CASE WHEN sp.SalePrice = 0 THEN sp.Price*sp.QOH END DESC
或者只是使用您在结果集中定义的别名:
ORDER BY
CASE WHEN sp.SalePrice > 0 THEN [sp.Value] END DESC,
CASE WHEN sp.SalePrice = 0 THEN [sp.StandardValue] END DESC
注意括号[] ....这是定义列名所必需的,因为在别名中使用了带点名称...否则sp.Value将被视为sp表中的Value列。 / p>