it-swarm.com.de

Wie führe ich eine GROUP BY in einer Alias-Spalte in MS-SQL Server aus?

Ich versuche, eine group by -Aktion für eine Alias-Spalte auszuführen (Beispiel unten), kann jedoch nicht die richtige Syntax ermitteln.

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

Was ist die richtige Syntax?


EDIT

Wenn Sie die Frage weiter ausdehnen (ich hatte nicht erwartet, dass die Antworten, die ich erhalten hatte), würde die Lösung immer noch für eine Spalte mit CASEed-Alias ​​gelten?

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

Und die Antwort lautet: Ja, es trifft immer noch zu.

51
Gavin Miller

Sie übergeben den Ausdruck, den Sie gruppieren möchten, anstelle des Alias 

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

Das ist was ich mache.

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

Diese Technik lässt sich einfach auf Ihr "Bearbeiten" -Szenario anwenden:

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
32
Amy B

Leider können Sie Ihren Alias ​​nicht in der GROUP BY-Anweisung referenzieren, Sie müssen die Logik erneut schreiben, erstaunlich, wie es scheint.

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

Alternativ können Sie select in einen Subselect-Ausdruck oder einen allgemeinen Tabellenausdruck setzen und danach nach dem Spaltennamen gruppieren (kein Alias ​​mehr).

8
James Orr

Leider ist dies mit MS SQL Server nicht möglich (jedoch mit PostgreSQL möglich):

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

Ansonsten benutzen Sie einfach folgendes:

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

Oder dieses:

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

Die obige Abfrage ist schneller, gruppiert zuerst die Felder und dann compute diese Felder.

Die folgende Abfrage ist langsamer (versucht zuerst compute den select-Ausdruck und dann die Datensätze nach dieser Berechnung zu gruppieren). 

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

Meine Vermutung ist:

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

Oracle hat eine ähnliche Einschränkung, die ärgerlich ist. Ich bin gespannt, ob es eine bessere Lösung gibt.

Um die zweite Hälfte der Frage zu beantworten, gilt diese Einschränkung auch für komplexere Ausdrücke wie Ihre Fallaussage. Der beste Vorschlag, den ich gesehen habe, ist die Verwendung eines Sub-Selects, um den komplexen Ausdruck zu benennen.

3
Jon Ericson

Angesichts Ihrer bearbeiteten Problembeschreibung würde ich vorschlagen, anstelle des unhandlichen Ausdrucks CASECOALESCE() zu verwenden:

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

Sie können CROSS APPLY verwenden, um einen Alias ​​zu erstellen und ihn in der GROUP BY-Klausel zu verwenden.

SELECT       FullName
FROM         Customers
CROSS APPLY  (SELECT LastName + ', ' + FirstName AS FullName) Alias
GROUP BY     FullName
1
Ricardo
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

Dies funktioniert, weil die von Ihnen verwendete Formel (die CASE-Anweisung) niemals die gleiche Antwort für zwei verschiedene Eingaben geben kann.

Dies ist nicht der Fall, wenn Sie Folgendes verwendet haben:

LEFT(FirstName, 1) + ' ' + LastName

In einem solchen Fall würden "James Taylor" und "John Taylor" beide zu "J Taylor" führen.

Wenn Sie möchten, dass Ihre Ausgabe zweimal "J Taylor" enthält (eine für jede Person):

GROUP BY LastName, FirstName

Wenn Sie jedoch nur eine Reihe von "J Taylor" wünschen, möchten Sie:

GROUP BY LastName, LEFT(FirstName, 1)
1
MatBailie

Wenn Sie vermeiden möchten, dass sich die case-Anweisung zweimal in Ihrer Abfrage befindet, können Sie sie in einer benutzerdefinierten Funktion platzieren.

Es tut uns leid, aber SQL Server würde die Datenmenge nicht vor der Group By-Klausel wiedergeben, sodass der Spaltenalias nicht verfügbar ist. Sie könnten es in der Order By verwenden.

0
JeffO

In der alten FoxPro (die ich seit Version 2.5 nicht mehr verwendet habe) könnte man so etwas schreiben:

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

Diese Syntax hat mir sehr gut gefallen. Warum wird es nicht woanders implementiert? Es ist eine schöne Verknüpfung, aber ich nehme an, dass es andere Probleme verursacht?

0
E.J. Brennan

Für alle, die sich mit dem folgenden Problem befinden (Gruppierung durch Sicherstellung, dass Null- und Nullwerte als gleichwertig behandelt werden) ...

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

(SQL-Server beschwert sich, dass Sie das Feld Amount nicht in Ihre Group By- oder Aggregat-Funktion aufgenommen haben)

... denken Sie daran, genau dieselbe Funktion in Ihrem SELECT zu platzieren ...

SELECT AccountNumber, ISNULL(Amount, 0) AS MyAlias
FROM Transactions
GROUP BY AccountNumber, ISNULL(Amount, 0)
0
41st
SELECT 
CASE WHEN LastName IS NULL THEN FirstName         
     WHEN LastName IS NOT NULL THEN LastName + ', ' + FirstName     
END AS 'FullName' 
FROM  customers GROUP BY 1`
0
Deepak Pathak