如何在MS-SQL Server中的别名列上执行GROUP BY?

时间:2009-01-30 21:05:35

标签: sql sql-server tsql syntax

我正在尝试在别名列上执行操作(下面的示例),但无法确定正确的语法。

SELECT       LastName + ', ' + FirstName AS 'FullName'
FROM         customers
GROUP BY     'FullName'

正确的语法是什么?

<小时/> 的修改

进一步扩展问题(我没想到我收到的答案)解决方案是否仍然适用于CASEed别名列?

SELECT       
    CASE
        WHEN LastName IS NULL THEN FirstName
        WHEN LastName IS NOT NULL THEN LastName + ', ' + FirstName
    END AS 'FullName'
FROM         customers
GROUP BY     
    LastName, FirstName

答案是肯定的,它仍然适用。

12 个答案:

答案 0 :(得分:66)

您传递要分组的表达式而不是别名

SELECT       LastName + ', ' + FirstName AS 'FullName'
FROM         customers
GROUP BY      LastName + ', ' + FirstName

答案 1 :(得分:36)

这就是我的工作。

SELECT FullName
FROM
(
  SELECT LastName + ', ' + FirstName AS FullName
  FROM customers
) as sub
GROUP BY FullName

此技术以直接的方式应用于您的“编辑”方案:

SELECT FullName
FROM
(
  SELECT
     CASE
       WHEN LastName IS NULL THEN FirstName
       WHEN LastName IS NOT NULL THEN LastName + ', ' + FirstName
     END AS FullName
  FROM customers
) as sub
GROUP BY FullName

答案 2 :(得分:8)

不幸的是,你不能在GROUP BY语句中引用你的别名,你必须再次编写逻辑,这看起来很神奇。

SELECT       LastName + ', ' + FirstName AS 'FullName'
FROM         customers
GROUP BY     LastName + ', ' + FirstName

或者,您可以将select放入子选择表或公用表表达式,之后您可以对列名称进行分组(不再是别名。)

答案 3 :(得分:5)

很抱歉,使用MS SQL Server是不可能的(虽然使用PostgreSQL可能):

select lastname + ', ' + firstname as fullname
from person
group by fullname

否则只需使用:

select x.fullname
from 
(
    select lastname + ', ' + firstname as fullname
    from person
) as x
group by x.fullname

或者这个:

select lastname + ', ' + firstname as fullname
from person
group by lastname, firstname  -- no need to put the ', '

上述查询更快,首先对字段进行分组,然后计算这些字段。

以下查询较慢(它首先尝试计算选择表达式,然后根据该计算对记录进行分组)。

select lastname + ', ' + firstname as fullname
from person
group by lastname + ', ' + firstname

答案 4 :(得分:3)

我的猜测是:

SELECT       LastName + ', ' + FirstName AS 'FullName'
FROM         customers
GROUP BY     LastName + ', ' + FirstName

Oracle有类似的限制,这很烦人。我很好奇是否有更好的解决方案。

要回答问题的后半部分,此限制也适用于更复杂的表达式,例如您的case语句。最好的建议我已经看到它使用子选择命名复杂表达式。

答案 5 :(得分:3)

根据您编辑的问题说明,我建议您使用COALESCE()代替那些笨拙的CASE表达式:

SELECT FullName
FROM (
  SELECT COALESCE(LastName+', '+FirstName, FirstName) AS FullName
  FROM customers
) c
GROUP BY FullName;

答案 6 :(得分:3)

您可以使用CROSS APPLY创建别名并在GROUP BY子句中使用它,如下所示:

SELECT       FullName
FROM         Customers
CROSS APPLY  (SELECT LastName + ', ' + FirstName AS FullName) Alias
GROUP BY     FullName

答案 7 :(得分:1)

SELECT       
    CASE
        WHEN LastName IS NULL THEN FirstName
        WHEN LastName IS NOT NULL THEN LastName + ', ' + FirstName
    END AS 'FullName'
FROM
    customers
GROUP BY     
    LastName,
    FirstName

这是有效的,因为您使用的公式(CASE语句)永远不会为两个不同的输入提供相同的答案。

如果您使用类似以下内容,则情况并非如此:

LEFT(FirstName, 1) + ' ' + LastName

在这种情况下,“詹姆斯泰勒”和“约翰泰勒”都会导致“J泰勒”。

如果您希望您的输出有两次“J Taylor”(每个人一个):

GROUP BY LastName, FirstName

但是,如果你只想要一行“J Taylor”,那么你需要:

GROUP BY LastName, LEFT(FirstName, 1)

答案 8 :(得分:0)

在旧的FoxPro(我从2.5版开始就没有使用它),你可以这样写:

SELECT       LastName + ', ' + FirstName AS 'FullName', Birthday, Title
FROM         customers
GROUP BY     1,3,2

我真的很喜欢这种语法。为什么不在其他任何地方实施?这是一个很好的捷径,但我认为它会导致其他问题吗?

答案 9 :(得分:0)

如果您想避免在查询中出现两次case语句的混乱,可能需要将其放在用户定义的函数中。

很抱歉,SQL Server不会在Group By子句之前呈现数据集,因此列别名不可用。您可以在Order By中使用它。

答案 10 :(得分:0)

SELECT 
CASE WHEN LastName IS NULL THEN FirstName         
     WHEN LastName IS NOT NULL THEN LastName + ', ' + FirstName     
END AS 'FullName' 
FROM  customers GROUP BY 1`

答案 11 :(得分:0)

对于发现自己存在以下问题的任何人(通过确保将零值和空值视为等于进行分组)......

SELECT AccountNumber, Amount AS MyAlias
FROM Transactions
GROUP BY AccountNumber, ISNULL(Amount, 0)

(即,SQL Server抱怨您没有在Group By或aggregate函数中包含字段数量)

...记得在SELECT ...中放置完全相同的功能

SELECT AccountNumber, ISNULL(Amount, 0) AS MyAlias
FROM Transactions
GROUP BY AccountNumber, ISNULL(Amount, 0)