tsql与子查询中的dateparts连接

时间:2012-06-14 13:03:47

标签: sql tsql join

我有两个查询,其中包含我想加入的dateparts的子查询。

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

我该怎么做?

3 个答案:

答案 0 :(得分: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 :(得分: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

答案 2 :(得分: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

我认为UNION的效果会比接受的答案中的JOIN好,因为MAX意味着每月有多行,而且因为月是唯一的共同字段所以它将最终交叉加入查询(即,如果在2012年6月查看了1000张优惠券,并且500个已兑换,则交叉连接意味着您将从50,000行而不是1500行中选择最大值)。我不确定架构和逻辑,所以这可能是不可能的,但如果FlurryCouponRedeemed中的日期不在FlurryCouponViewed中,那么这些日期将不会显示。

我也希望尽可能长时间地保留日期作为日期,以帮助优化者完成工作,这就是为什么我已经取代DATEPART(YEAR...& DATEPART(MONTH...CONVERT(VARCHAR(4), DateInsert...DATEADD(MONTH, DATEDIFF(MONTH, 0, DateInsert))