如何更有效地编写这个SQL查询

时间:2014-05-09 08:16:00

标签: sql database sql-server-2008 tsql

这里我有一个查询,我在哪里选择14天后范围内的值

DECLARE @DATETIMENOW DATETIME  
SET @DATETIMENOW = GETDATE()

SELECT
        B.WEEK AS PREVIOUSWEEKACCIDENTS
    FROM BKA.CHILDINFORMATION CI
    LEFT OUTER JOIN 
    (
        SELECT Distinct
                CHINFO.CHILDID,
                COUNT(*) as week
            FROM
                BKA.CHILDINFORMATION CHINFO               
            JOIN 
                BKA.CHILDEVENTS CHE 
                    ON CHE.CHILDID = CHINFO.CHILDID
            JOIN
                BKA.CHILDEVENTPROPERITIES CHEP 
                    ON  CHE.EVENTID = CHEP.EVENTID                         
            WHERE 
            (
                   CHE.TYPE = 'ACCIDENT'
                OR 
               (
                       CHE.TYPE = 'POTTYBREAK'
                   AND 
                       CHEP.PROPERTY = 'SUCCESS' 
                   AND
                       CHEP.PROPERTYVALUE = 'FALSE'
               )
            )  
            AND 
                CHE.ADDDATE BETWEEN 
                        DATEADD(
                            DD,
                            -(DATEPART(DW, @DATETIMENOW-14)-1),
                             @DATETIMENOW-14) 
                    AND  
                        DATEADD(
                            DD,
                            7-(DATEPART(DW, @DATETIMENOW-14)),
                            @DATETIMENOW-14)
        group by
            CHINFO.CHILDID
    ) b
        on CI.ChildID = b.ChildID

我需要的是选择相同的值,这些值在7天之内,即@ DATETIMENOW-7是唯一的更改,它必须是单个查询。任何建议?

3 个答案:

答案 0 :(得分:1)

好的,声明中有一些计算总是给出相同的值。

DECLARE @now DateTime;
DECLARE @start DateTime;
DECLARE @end DateTime;

SET @now = getDate();
SET @start = DATEADD(
                 DD,
                 -(DATEPART(DW, @now - 14) - 1),
                 @now - 14); 
SET @end = DATEADD(
               DD,
               7 - (DATEPART(DW, @now - 14)),
               @now - 14);

如果你这样做,那么它显然会避免为每一行重复它们,并使你的TSQL更具可读性。


接下来,除了更改集合中的列名称

之外,外部选择不会执行任何操作
SELECT
        COUNT(*) PREVIOUSWEEKSACCIDENTS
    FROM [BKA].[CHILDINFORMATION] ci               
    JOIN [BKA].[CHILDEVENTS] ce 
        ON ce.[CHILDID] = ci.[CHILDID]
    JOIN [BKA].[CHILDEVENTPROPERITIES] ce 
        ON  ce.[EVENTID] = ce.[EVENTID]                         
    WHERE 
            (
                ce.[TYPE] = 'ACCIDENT'
            OR 
                (
                    ce.[TYPE] = 'POTTYBREAK'
                AND 
                    ce.[PROPERTY] = 'SUCCESS' 
                AND
                    cep.[PROPERTYVALUE] = 'FALSE'
                )
            )  
        AND 
            CHE.ADDDATE BETWEEN @start AND @end 
    GROUP BY
        ci.[CHILDID];

所以,这个陈述会达到同样的结果。

答案 1 :(得分:1)

试试这个:

DECLARE @DATETIMENOW DATETIME = GETDATE();
DECLARE @StartDate DATETIME = DATEADD(DD, -( DATEPART(DW, @DATETIMENOW - 14) - 1 ), @DATETIMENOW - 14);
DECLARE @EndDate DATETIME = DATEADD(DD, 7 - ( DATEPART(DW, @DATETIMENOW - 14) ), @DATETIMENOW - 14);

SELECT  COUNT(*) AS PREVIOUSWEEKACCIDENTS
FROM    BKA.CHILDINFORMATION CHINFO
        JOIN BKA.CHILDEVENTS CHE ON CHE.CHILDID = CHINFO.CHILDID
        JOIN BKA.CHILDEVENTPROPERITIES CHEP ON CHE.EVENTID = CHEP.EVENTID
WHERE   (
          CHE.TYPE = 'ACCIDENT'
          OR (
               CHE.TYPE = 'POTTYBREAK'
               AND CHEP.PROPERTY = 'SUCCESS'
               AND CHEP.PROPERTYVALUE = 'FALSE'
             )
        )
        AND CHE.ADDDATE BETWEEN StartDate AND @EndDate
GROUP BY CHINFO.CHILDID

答案 2 :(得分:1)

@Rooney just check if this helps you:

    DECLARE @DATETIMENOW DATETIME = GETDATE();
    DECLARE @StartDate7 DATETIME = DATEADD(DD, -( DATEPART(DW, @DATETIMENOW - 7) - 1 ), @DATETIMENOW - 7);
    DECLARE @StartDate14 DATETIME = DATEADD(DD, -( DATEPART(DW, @DATETIMENOW - 14) - 1 ), @DATETIMENOW - 14);
    DECLARE @EndDate DATETIME = DATEADD(DD, 7 - ( DATEPART(DW, @DATETIMENOW - 14) ), @DATETIMENOW - 14);

    SELECT  CHE.Category,
            COUNT(*) AS PREVIOUSWEEKACCIDENTS
            FROM BKA.CHILDINFORMATION CHINFO
            JOIN (
                    SELECT ADDDATE,
                           'Last7Days' Category
                        FROM BKA.CHILDEVENTS
                        WHERE CHE.ADDDATE BETWEEN @StartDate7 AND @EndDate

                    UNION ALL

                    SELECT ADDDATE,
                           'Last14Days' Category
                        FROM BKA.CHILDEVENTS
                        WHERE CHE.ADDDATE BETWEEN @StartDate14 AND @EndDate

                 ) CHE 
                ON CHINFO.CHILDID = CHE.CHILDID
                    AND CHINFO.ADDDATE = CHE.ADDDATE 
            JOIN BKA.CHILDEVENTPROPERITIES CHEP 
                ON CHE.EVENTID = CHEP.EVENTID
            WHERE   (
                        CHE.TYPE = 'ACCIDENT'
                      OR (
                           CHE.TYPE = 'POTTYBREAK'
                           AND CHEP.PROPERTY = 'SUCCESS'
                           AND CHEP.PROPERTYVALUE = 'FALSE'
                         )
                    )
            GROUP BY CHE.Category,
                     CHINFO.CHILDID