2017-12-16 13 views
0

아래 "이벤트"테이블과 "영화"테이블에 합류 한 모든 영화 등급을 얻는 간단한 쿼리가 있습니다.datetime 값을 기반으로 한 동일한 테이블에서 효율적인 SQL 하위 쿼리

Select e.*, m.moviename 
From Event e, movie m 
Where e.eventdate >= DATEADD(day, -1, GETDATE()) 
    and e.moviekey = m.moviekey 
order by e.Ratings desc; 

당신이 1 주 전, 그리고 1 개월 전에서 평가를 검색 할 방법 위의 예에서

질문

. 따라서 쿼리는 RatingOneMonthAgo, RatingsOneWeekAgo 등 2 개의 추가 열을 반환합니다.

하위 쿼리를 살펴본 결과 어떤 도움도받지 못하면 감사하겠습니다.

감사

+0

[나쁜 습관을 걷어차 : 이전 스타일을 사용하여 조인 (http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old ANSI - ** 92 ** SQL 표준 (* 25 년 * *)에서 구식 * 쉼표로 구분 된 테이블 * 스타일 목록이 * 적절한 * ANSI'JOIN' 구문으로 대체되었습니다. * 예전의) 그리고 그 사용은 권장하지 않는다. –

답변

1

당신은 (하위 쿼리를 사용하는 것과 비슷합니다)에이 정보를 끌어 CTEs를 사용할 수 있습니다.

WITH cteOneWeekAgo 
AS 
(
    SELECT 
     moviekey 
     , Ratings 
    FROM Event 
    WHERE CAST(eventdate AS date) = DATEADD(WEEK, -1, CAST(GETDATE() AS date)) 
) 
, 

cteOneMonthAgo 
AS 
(
    SELECT 
     moviekey 
     , Ratings 
    FROM Event 
    WHERE CAST(eventdate AS date) = DATEADD(MONTH, -1, CAST(GETDATE() AS date)) 
) 

SELECT 
    e.* 
    , m.moviename 
    , w.Ratings Ratings_OneWeekAgo 
    , mth.Ratings Ratings_OneMonthAgo 
FROM 
    Event e 
    JOIN movie m ON e.moviekey = m.moviekey 
    LEFT JOIN cteOneWeekAgo w ON e.moviekey = w.moviekey 
    LEFT JOIN cteOneMonthAgo mth ON e.moviekey = mth.moviekey 
WHERE e.eventdate >= DATEADD(DAY, -1, GETDATE()) 
ORDER BY e.Ratings DESC 

가 나는 또한 끌어 더 복잡한 쿼리를 썼다 :

다음 쿼리는 (같은 날 같은 영화에 대해 여러 등급) 매일에 대한 평가가없는, 어떤 중복 된 것으로 가정 해당 날짜에 대한 평가가 존재하지 않으면 찾고있는 날짜 이전의 영화에 대한 가장 최근 등급으로 표시됩니다.

WITH cteOneWeekAgo 
AS 
(
    SELECT 
     moviekey 
     , Ratings 
     , eventdate 
    FROM 
     (
      SELECT 
       moviekey 
       , Ratings 
       , eventdate 
       , ROW_NUMBER() OVER (PARTITION BY moviekey ORDER BY eventdate DESC) R 
      FROM Event 
      WHERE CAST(eventdate AS date) <= DATEADD(WEEK, -1, CAST(GETDATE() AS date)) 
     ) Q 
    WHERE R = 1 
) 
, 

cteOneMonthAgo 
AS 
(
    SELECT 
     moviekey 
     , Ratings 
     , eventdate 
    FROM 
     (
      SELECT 
       moviekey 
       , Ratings 
       , eventdate 
       , ROW_NUMBER() OVER (PARTITION BY moviekey ORDER BY eventdate DESC) R 
      FROM Event 
      WHERE CAST(eventdate AS date) <= DATEADD(MONTH, -1, CAST(GETDATE() AS date)) 
     ) Q 
    WHERE R = 1 
) 

SELECT 
    e.* 
    , m.moviename 
    , w.eventdate Ratings_OneWeekAgo_MostRecentDate 
    , w.Ratings Ratings_OneWeekAgo 
    , mth.eventdate Ratings_OneMonthAgo_MostRecentDate 
    , mth.Ratings Ratings_OneMonthAgo 
FROM 
    Event e 
    JOIN movie m ON e.moviekey = m.moviekey 
    LEFT JOIN cteOneWeekAgo w ON e.moviekey = w.moviekey 
    LEFT JOIN cteOneMonthAgo mth ON e.moviekey = mth.moviekey 
WHERE e.eventdate >= DATEADD(DAY, -1, GETDATE()) 
ORDER BY e.Ratings DESC 
+0

새벽 트랜잭션의 누락을 막기 위해'getdate()'를'cast (getdate() as date) '로 바꾸고 싶을 것이다. –

+0

당신은 맞습니다 -'='진술에 대해서 - 고마워요! –

+0

감사합니다. 하나의 사소한 잘라 내기 및 붙여 넣기 실수가 있습니다. 두 번째 왼쪽 결합에 cteOneWeekAgo 대신 cteOneMonthAgo가 있어야합니다. 다시 한 번 감사드립니다. –