WHERE 절에서 열 별명 참조


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

나는 얻다

"잘못된 열 이름 daysdiff".

Maxlogtm은 날짜 / 시간 필드입니다. 나를 미치게하는 작은 것들입니다.


mysql에 대해서는 확실하지 않지만 별명은 ticks로 감싸 야 `daysdiff`합니다.
Ash Burlaczenko

답변:


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

일반적으로 WHERE절 에서 필드 별명을 참조 할 수 없습니다 . ( SELECT별명을 포함 하여 전체 를 생각 하면 WHERE절 뒤에 적용됩니다 .)

그러나 다른 답변에서 언급했듯이 SQL SELECTWHERE절 보다 먼저 처리 되도록 강제 할 수 있습니다 . 이것은 일반적으로 논리 연산 순서를 강제하기 위해 괄호 나 CTE (Common Table Expression)로 수행됩니다.

괄호 / 하위 선택 :

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

또는 CTE 버전에 대한 Adam의 답변을 참조하십시오.


16
연대순으로 WHERE가 SELECT 이전에 발생하기 때문에 실행 체인에서 항상 마지막 단계이므로 직접 수행 할 수 없습니다. - REFER stackoverflow.com/questions/356675/...
데이비드 블레인

선택의 별칭이 상관 하위 쿼리 인 경우 CTE 솔루션이 작동하지 않는 동안 작동합니다.
Răzvan Flavius ​​Panda

Pascal이 그의 답변 here stackoverflow.com/a/38822328/282887 에서 언급했듯이 하위 쿼리보다 빠르게 작동하는 HAVING 절을 사용할 수 있습니다.
Bakhtiyor

@Bakhtiyor HAVING이 질문에 대한 MS-SQL을 포함한 대부분의 SQL 환경에서는 답이 작동하지 않습니다. (T-SQL에서는 HAVING집계 함수가 필요합니다.)
Jamie F

72

WHERE절 에서 별칭을 사용하려면 하위 선택 또는 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

2
이 박람회 효율이 어떻게 현명한 지 아십니까? CTE를 사용하여 추가 오버 헤드가 있습니까?
제임스

5
CTE는 하위 쿼리에 대한 더 예쁜 구문이므로 성능은 비슷합니다. 내 경험상 성능 차이는 이와 같은 작업과 관련이 없었지만 환경에서 테스트하여 특정 테이블 / 쿼리가 이것에 부정적인 영향을 미치는지 확인하는 것이 매우 간단합니다. where 절에서 구체적으로 수식. 나는 당신이 차이를 느끼지 못할 것이라고 생각합니다.
Adam Wenger

CTE는 하위 쿼리로 CTE를 사용하려고 할 때까지 훌륭합니다. 나는 그들을 중첩보기로 작성해야했습니다. 나는이에게 심각한 SQL의 단점을 고려
공생

10

코드를 반복하지 않고 가장 효과적인 방법 은 WHERE 대신 HAVING을 사용하는 것입니다.

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

1
HAVING별칭 사용은 표준이 아니라고 생각 합니다 (MySQL에서는 작동합니다). 특히 SQL Server에서는 작동하지 않는다고 생각합니다.
tokland

2
SQL Server :[S0001][207] Invalid column name 'daysdiff'
Vadzim

3
SQL Server :[S0001][8121] Column 'day' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.
Vadzim

9

CTE에 모든 열을 나열하지 않으려면 다른 방법으로 다음을 사용하십시오 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

6

하위 쿼리를 사용하는 것은 어떻습니까 (Mysql에서 저에게 효과적이었습니다)?

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

4

HAVING은 설명서에 따라 MySQL에서 작동합니다.

HAVING 를 Where 키워드 집계 함수와 함께 사용할 수 없기 때문에 절은 SQL에 추가되었습니다.


4

컬럼 별명을 참조 할 수 있지만 다음을 사용하여 정의해야합니다 CROSS/OUTER APPLY.

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 데모

장점 :

  • 표현의 단일 정의 (복사-붙여 넣기를 유지하기가 더 쉬움)
  • CTE / 외부 쿼리로 전체 쿼리를 래핑 할 필요가 없습니다.
  • 언급 가능성 WHERE/GROUP BY/ORDER BY
  • 더 나은 성능 (단일 실행)

1
그것은 단지 SQL 서버에서 작동하는지 언급에 그 가치
마틴 Zinovsky

1
@MartinZinovsky Question 태그로 설정 됨 sql-servert-sql:
루카스 Szozda

0

여기에 온 것과 유사한 무언가를 찾고 있지만, CASE와 언제, 어디서이 같은를 사용 끝났다 : WHERE (CASE WHEN COLUMN1=COLUMN2 THEN '1' ELSE '0' END) = 0어쩌면 당신이 사용할 수 DATEDIFF에서 WHERE직접. 다음과 같은 것 :

SELECT logcount, logUserID, maxlogtm
FROM statslogsummary
WHERE (DATEDIFF(day, maxlogtm, GETDATE())) > 120
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.