开发者

need help writing a date sensitive T-SQL query

I need help writing a T-SQL query that will generate 52 rows of data per franchise from a table that will often contain gaps in the 52 week sequence per franchise (i.e., the franchise may have reported data bi-weekly or has not been in business for a full year).

The table I'm querying against looks something like this:

FranchiseId | Date | ContractHours | PrivateHours

and I need to join it to a table similar to this:

FranchiseId | Name

The output of the query needs to look like t开发者_高级运维his:

Name | Date       | ContractHours | PrivateHours
----   ----------   -------------   ------------
AZ1    08-02-2011             292            897
AZ1    07-26-2011               0              0 -- default to 0's for gaps in sequence
...
AZ1    08-03-2010              45            125 -- row 52 for AZ1
AZ2    08-02-2011             382            239
...
AZ2    07-26-2011               0              0 -- row 52 for AZ2

I need this style of output for every franchise, i.e., 52 rows of data with default rows for any gaps in the 52 week sequence, in a single result set. Thus, if there are 100 franchises, the result set should be 5200 rows.

What I've Tried

I've tried the typical suggestions of:

  • Create a table with all possible dates
  • LEFT OUTER JOIN this to the table of data needed

The problems I'm running into are

  1. ensuring that for every franchise their are 52 rows and
  2. filling in gaps with the franchise name and 0 for hours, I can't have the following in the result set:

    Name | Date       | ContractHours | PrivateHours
    ----   ----------   -------------   ------------
    NULL   08-02-2011            NULL           NULL
    

I don't know where to go from here? Is there an efficient way to write a T-SQL query that will produce the required output?


The bare bones is this

  • Generate 52 week ranges
  • Cross join with Franchise
  • LEFT JOIN the actual date
  • ISNULL to substitute zeroes

So, like this, untested

;WITH cDATE AS
(
    SELECT
        CAST('20100101' AS date /*smalldatetime*/) AS StartOfWeek, 
        CAST('20100101' AS date /*smalldatetime*/) + 6 AS EndOfWeek
    UNION ALL
    SELECT StartOfWeek + 7, EndOfWeek + 7
    FROM cDATE WHERE StartOfWeek + 7 < '20110101'
), Possibles AS
(
    SELECT
        StartOfWeek, FranchiseID
    FROM
        cDATE CROSS JOIN Franchise
)
SELECT
    P.FranchiseID,
    P.StartOfWeek, 
    ISNULL(SUM(O.ContractHours), 0), 
    ISNULL(SUM(O.PrivateHours), 0)
FROM
    Possibles P
    LEFT JOIN
    TheOtherTable O ON P.FranchiseID = O.FranchiseID AND 
                    O.Date BETWEEN P.StartOfWeek AND P.EndOfWeek
GROUP BY
    P.FranchiseID
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜