Подтвердить что ты не робот

Как выполнить GROUP BY в столбце с псевдонимом в MS-SQL Server?

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

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

И ответ да, он все еще применяется.

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

Извините, это невозможно в 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

Ответ 5

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

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

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

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

Ответ 6

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

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

Ответ 7

В старом FoxPro (я не использовал его с версии 2.5), вы могли бы написать что-то вроде этого:

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

Мне очень понравился этот синтаксис. Почему это не реализовано нигде? Это хороший ярлык, но я полагаю, что это вызывает другие проблемы?

Ответ 8

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" .

Если вы хотите, чтобы ваш результат имел "J Taylor" дважды (по одному для каждого человека):

GROUP BY LastName, FirstName

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

GROUP BY LastName, LEFT(FirstName, 1)

Ответ 9

Если вы хотите избежать беспорядка оператора case в вашем запросе дважды, вы можете поместить его в пользовательскую функцию.

Извините, но SQL Server не будет отображать набор данных перед предложением Group By, поэтому псевдоним столбца недоступен. Вы можете использовать его в Order By.

Ответ 10

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

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

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

(I.e. SQL Server жалуется, что вы не включили поле "Сумма" в функцию "Группировать по" или "заполнить" )

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

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

Ответ 12

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

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