Как выполнить GROUP BY для столбца с псевдонимами в MS-SQL Server? - PullRequest
57 голосов
/ 31 января 2009

Я пытаюсь выполнить действие group by для столбца с псевдонимом (пример ниже), но не могу определить правильный синтаксис.

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

Какой правильный синтаксис?

<ч /> EDIT

Если продолжить вопрос (я не ожидал получить ответы), будет ли решение по-прежнему применяться для столбца с псевдонимом 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 ]

66 голосов
/ 31 января 2009

Вы передаете выражение, по которому хотите группировать, а не псевдоним

SELECT       LastName + ', ' + FirstName AS 'FullName'
FROM         customers
GROUP BY      LastName + ', ' + FirstName
36 голосов
/ 31 января 2009

Это то, что я делаю.

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
8 голосов
/ 31 января 2009

К сожалению, вы не можете ссылаться на свой псевдоним в выражении GROUP BY, вам придется снова написать логику, как это ни удивительно.

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

В качестве альтернативы вы можете поместить выбор в подвыбор или общее табличное выражение, после чего вы можете сгруппировать по имени столбца (больше не псевдоним).

5 голосов
/ 31 января 2009

Извините, это невозможно с 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, затем он группирует записи на основе этого вычисления).

select lastname + ', ' + firstname as fullname
from person
group by lastname + ', ' + firstname
3 голосов
/ 13 декабря 2016

Вы можете использовать CROSS APPLY для создания псевдонима и использовать его в предложении GROUP BY, например:

SELECT       FullName
FROM         Customers
CROSS APPLY  (SELECT LastName + ', ' + FirstName AS FullName) Alias
GROUP BY     FullName
3 голосов
/ 31 января 2009

Учитывая ваше отредактированное описание проблемы, я бы предложил использовать COALESCE() вместо этого громоздкого CASE выражения:

SELECT FullName
FROM (
  SELECT COALESCE(LastName+', '+FirstName, FirstName) AS FullName
  FROM customers
) c
GROUP BY FullName;
3 голосов
/ 31 января 2009

Мое предположение:

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

Oracle имеет аналогичное ограничение, что раздражает. Мне любопытно, если есть лучшее решение.

Чтобы ответить на вторую половину вопроса, это ограничение относится и к более сложным выражениям, таким как ваше утверждение case. Лучшее предложение, которое я видел, это использовать подвыбор для именования сложного выражения.

1 голос
/ 31 января 2009
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 Taylor» (по одному на каждого человека):

GROUP BY LastName, FirstName

Если, однако, вам нужен был только один ряд "J Taylor", вы бы хотели:

GROUP BY LastName, LEFT(FirstName, 1)
0 голосов
/ 22 сентября 2014

Для тех, кто сталкивается со следующей проблемой (группировка по нулевым и нулевым значениям рассматривается как равные) ...

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

(т. Е. SQL Server жалуется на то, что вы не включили поле «Сумма» в функцию Group By или статистическую функцию)

... не забудьте поместить точно такую ​​же функцию в ваш SELECT ...

SELECT AccountNumber, ISNULL(Amount, 0) AS MyAlias
FROM Transactions
GROUP BY AccountNumber, ISNULL(Amount, 0)
0 голосов
/ 11 сентября 2012
SELECT 
CASE WHEN LastName IS NULL THEN FirstName         
     WHEN LastName IS NOT NULL THEN LastName + ', ' + FirstName     
END AS 'FullName' 
FROM  customers GROUP BY 1`
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...