2012-06-14 2 views
1

У меня есть два запроса с подзапросами для дат, к которым я хочу присоединиться.tsql присоединяется к датам в подзапросах

SELECT DateMonth, DateYear, Datestring, 
    MAX(CouponTotalCount) NoOfCouponsViewed 
FROM (
     SELECT *, DATEPART(MONTH, DateInsert) DateMonth, DATEPART(YEAR, DateInsert) DateYear, 
     CONVERT(CHAR(4), DateInsert, 100) + CONVERT(CHAR(4), DateInsert, 120) Datestring 
     FROM FlurryCouponViewed 
    ) sub 
where couponID=249 
GROUP BY DateMonth, DateYear, Datestring 

SELECT DateMonth, DateYear, Datestring, 
    MAX(CouponTotalCount) NoOfCouponsRedeemed 
FROM (
     SELECT *, DATEPART(MONTH, DateInsert) DateMonth, DATEPART(YEAR, DateInsert) DateYear, 
     CONVERT(CHAR(4), DateInsert, 100) + CONVERT(CHAR(4), DateInsert, 120) Datestring 
     FROM FlurryCouponRedeemed 
    ) sub 

where couponID=249 
GROUP BY DateMonth, DateYear, Datestring 

Выход из двух запросов является:

DateMonth DateYear Datestring NoOfCouponsViewed 
----------- ----------- ---------- ----------------- 
2   2012  Feb 2012 5 
3   2012  Mar 2012 12 
4   2012  Apr 2012 25 
5   2012  May 2012 25 



DateMonth DateYear Datestring NoOfCouponsRedeemed 
----------- ----------- ---------- ------------------- 
2   2012  Feb 2012 3 
3   2012  Mar 2012 4 
4   2012  Apr 2012 5 
5   2012  May 2012 11 

Что мне нравится для того чтобы достигнуть в два еще один присоединился запрос дает мне:

DateMonth DateYear Datestring NoOfCouponsViewed NoOfCouponsRedeemed 
----------- ----------- ---------- ----------------- ------------------- 
2   2012  Feb 2012 5     3 
3   2012  Mar 2012 12    4 
4   2012  Apr 2012 25    5 
5   2012  May 2012 25    11 

Как я могу это сделать?

+1

Так же, как вы делаете в запросах уже , вы можете использовать запрос в виде таблицы. Ну, вы можете сделать это для многих слоев (хотя его трудно прочитать). – Limey

ответ

1

Сделать внутреннее соединение между двумя запросами, и он должен работать:

SELECT sub.DateMonth, sub.DateYear, sub.Datestring, 
    MAX(sub.CouponTotalCount) NoOfCouponsViewed, 
    MAX(sub2.CouponTotalCount) NoOfCouponsViewed 
FROM (
     SELECT *, DATEPART(MONTH, DateInsert) DateMonth, DATEPART(YEAR, DateInsert) DateYear, 
     CONVERT(CHAR(4), DateInsert, 100) + CONVERT(CHAR(4), DateInsert, 120) Datestring 
     FROM FlurryCouponViewed 
    ) sub 
INNER JOIN 
    ( SELECT *, DATEPART(MONTH, DateInsert) DateMonth, DATEPART(YEAR, DateInsert) DateYear, 
     CONVERT(CHAR(4), DateInsert, 100) + CONVERT(CHAR(4), DateInsert, 120) Datestring 
     FROM FlurryCouponRedeemed 
    ) sub2 on sub.DateMonth = sub2.DateMonth and sub.DateYear = sub2.DateYear and sub.Datestring = sub2.Datestring 
where sub.couponID=249 and sub2.couponID=249 
GROUP BY sub.DateMonth, sub.DateYear, sub.Datestring 
1

или ее UNION:

SELECT u.DateMonth, u.DateYear, u.Datestring, MAX(u.NoOfCouponsViewed), MAX(u.NoOfCouponsRedeemed) 
    FROM (
     SELECT DateMonth, DateYear, Datestring, 
      MAX(CouponTotalCount) NoOfCouponsViewed, 0 AS NoOfCouponsRedeemed 
     FROM (
      SELECT *, DATEPART(MONTH, DateInsert) DateMonth, DATEPART(YEAR, DateInsert) DateYear, 
      CONVERT(CHAR(4), DateInsert, 100) + CONVERT(CHAR(4), DateInsert, 120) Datestring 
      FROM FlurryCouponViewed 
      ) sub 
     where couponID=249 
     GROUP BY DateMonth, DateYear, Datestring 
    UNION 
     SELECT DateMonth, DateYear, Datestring, 0 AS NoOfCouponsViewed, 
      MAX(CouponTotalCount) NoOfCouponsRedeemed 
     FROM (
      SELECT *, DATEPART(MONTH, DateInsert) DateMonth, DATEPART(YEAR, DateInsert) DateYear, 
      CONVERT(CHAR(4), DateInsert, 100) + CONVERT(CHAR(4), DateInsert, 120) Datestring 
      FROM FlurryCouponRedeemed 
      ) sub 

     where couponID=249 
     GROUP BY DateMonth, DateYear, Datestring 
    ) u 
GROUP BY u.DateMonth, u.DateYear, u.Datestring 
+1

@aF. спасибо за редактирование –

0

я хотел бы использовать UNION вместо JOIN

SELECT MonthInserted, 
     LEFT(DATENAME(MONTH, Datestring), 3) + ' ' + DATENAME(YEAR, MonthInserted) AS DateString 
     MAX(Viewed) NoOfCouponsViewed, 
     MAX(Redeemed) NoOfCouponsRedeemed 
FROM ( SELECT CouponID, 
        DATEADD(MONTH, DATEDIFF(MONTH, 0, DateInsert)) [MonthInserted], 
        CouponTotalCount AS Viewed, 
        0 AS Redeemed 
      FROM FlurryCouponViewed 
      UNION ALL 
      SELECT CouponID, 
        DATEADD(MONTH, DATEDIFF(MONTH, 0, DateInsert)), 
        0, 
        CouponTotalCount 
      FROM FlurryCouponRedeemed 
     ) sub 
WHERE couponID = 249 
GROUP BY MonthInserted 

I думаю, UNION woul d работают лучше, чем JOIN в принятом ответе, так как MAX подразумевает, что существует несколько строк в месяц, а так как месяц является единственным общим полем, поэтому он будет заканчиваться перекрестными связями (т. если в июне 2012 года ожидается 1000 купонов, а 500 выкуплены, то перекрестное соединение означает, что вы выберете максимум от 50 000 строк вместо 1500). Я не уверен в схеме и логике, поэтому это может быть невозможно, но если в FlurryCouponRedeemed есть даты, которые не находятся в FlurryCouponViewed, то они не будут отображаться.

Я также хотел бы сохранить даты в качестве даты для как можно дольше, чтобы помочь оптимизатору сделать его работу, поэтому я заменил DATEPART(YEAR... & DATEPART(MONTH... И CONVERT(VARCHAR(4), DateInsert... с DATEADD(MONTH, DATEDIFF(MONTH, 0, DateInsert))

Смежные вопросы