it-swarm.com.de

Verweisen auf einen Spaltenalias in einer WHERE-Klausel

SELECT logcount, logUserID, maxlogtm
   , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE daysdiff > 120

Ich bekomme

"ungültiger Spaltenname daysdiff".

Maxlogtm ist ein Datum/Uhrzeit-Feld. Es sind die kleinen Dinge, die mich verrückt machen.

148
user990016
SELECT
   logcount, logUserID, maxlogtm,
   DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE ( DATEDIFF(day, maxlogtm, GETDATE() > 120)

Normalerweise können Sie in der WHERE -Klausel nicht auf Feldaliase verweisen. (Betrachten Sie es als den gesamten SELECT einschließlich der Aliase, der nach der WHERE -Klausel angewendet wird.)

Wie in anderen Antworten erwähnt, können Sie jedoch erzwingen, dass SQL die Behandlung von SELECT vor der WHERE -Klausel durchführt. Dies geschieht normalerweise in Klammern, um die logische Reihenfolge der Operationen zu erzwingen, oder mit einem Common Table Expression (CTE):

Klammer/Unterauswahl:

SELECT
   *
FROM
(
   SELECT
      logcount, logUserID, maxlogtm,
      DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
   FROM statslogsummary   
) as innerTable
WHERE daysdiff > 120

Oder sehen Sie sich Adams Antwort für eine CTE-Version derselben an.

166
Jamie F

Wenn Sie den Alias ​​in Ihrer WHERE -Klausel verwenden möchten, müssen Sie ihn in eine Unterauswahl einschließen oder CTE :

WITH LogDateDiff AS
(
   SELECT logcount, logUserID, maxlogtm
      , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
   FROM statslogsummary
)
SELECT logCount, logUserId, maxlogtm, daysdiff
FROM LogDateDiff
WHERE daysdiff > 120
70
Adam Wenger

Der effektivste Weg, dies zu tun, ohne den Code zu wiederholen, ist die Verwendung von [~ # ~] mit [~ # ~] anstelle von [~ # ~] wobei [~ # ~]

SELECT logcount, logUserID, maxlogtm
   , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
HAVING daysdiff > 120
9
Pascal

Wenn Sie nicht alle Ihre Spalten in CTE auflisten möchten, können Sie auch outer apply :

select
    s.logcount, s.logUserID, s.maxlogtm,
    a.daysdiff
from statslogsummary as s
    outer apply (select datediff(day, s.maxlogtm, getdate()) as daysdiff) as a
where a.daysdiff > 120
8
Roman Pekar

Wie wäre es mit einer Unterabfrage (das hat bei mir in MySQL funktioniert)?

SELECT * from (SELECT logcount, logUserID, maxlogtm
   , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary) as 'your_alias'
WHERE daysdiff > 120
5
Shekhar Joshi

Sie können auf einen Spaltenalias verweisen, müssen diesen jedoch mit CROSS/OUTER APPLY Definieren:

SELECT s.logcount, s.logUserID, s.maxlogtm, c.daysdiff
FROM statslogsummary s
CROSS APPLY (SELECT DATEDIFF(day, s.maxlogtm, GETDATE()) AS daysdiff) c
WHERE c.daysdiff > 120;

DBFiddle Demo

Vorteile:

  • einzelne Definition des Ausdrucks (einfacher zu pflegen/keine Notwendigkeit des Kopierens-Einfügens)
  • die gesamte Abfrage muss nicht mit CTE/Outerquery umbrochen werden
  • referenzmöglichkeit in WHERE/GROUP BY/ORDER BY
  • möglicherweise bessere Leistung (einmalige Ausführung)
4
Lukasz Szozda

HAVING funktioniert in MySQL laut Dokumentation:

Die Klausel HAVING wurde zu SQL hinzugefügt, da das WHERE-Schlüsselwort nicht mit Aggregatfunktionen verwendet werden konnte.

4
roier.rdz