Search code examples
sqlsql-serversql-server-2008ssrs-2008

SQL Select within a select


I'm creating a dataset that will be displayed in an SSRS report.

I have a query in a job that puts a count into a table [dbo].[CountMetersDue] on a rolling basis on the 1st of every month; the value changes throughout the month so need to take a snapshot at beginning.

I have the report set up which uses a custom expression to produce a cumulative trend graph. Basically takes one value, divides by another to work out a percentage. Therefore I have two queries that need combining... Took me ages to get my head round all this!

I just need help with the last bit.

    SELECT (SELECT [Count] 
        FROM   [MXPTransferDev].[dbo].[CountMetersDue] 
        WHERE  [MXPTransferDev].[dbo].[CountMetersDue].[DateTime] = 
               [MXPTransferDev].[dbo].[Readings].[dateRead]) AS [MetersDue], 
       COUNT(readingid)                                      AS [TotalReadings], 
       CONVERT(DATE, dateread)                               AS [dateRead] 
FROM   [MXPTransferDev].[dbo].[Readings] 
WHERE  ( [MXPTransferDev].[dbo].[Readings].[dateRead] BETWEEN 
                '01-may-11' AND '31-may-11' ) 
       AND ( webcontactid IS NOT NULL ) 
       AND ( meter = 1 ) 
GROUP  BY CONVERT(DATE, [MXPTransferDev].[dbo].[Readings].[dateRead]) 

CREATE TABLE [dbo].[CountMetersDue](
    [Count] [int] NULL,
    [DateTime] [datetime] NULL
) ON [USER]

GO

ALTER TABLE [dbo].[CountMetersDue] 
ADD  CONSTRAINT [DF_CountMetersDue_DateTime]  DEFAULT (getdate()) FOR [DateTime]
GO

CREATE TABLE [dbo].[Readings](
    [readingId] [bigint] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
    [dateRead] [datetime] NOT NULL,
    [meter] [int] NOT NULL,
    [webcontactid] [bigint] NULL,

Readings

readingId   meter   reading dateRead            webcontactid
583089  4   3662    2011-05-25 15:00:33.040         479
583207  3   682     2011-05-25 15:00:33.027         479
583088  2   98064   2011-05-25 15:00:33.007         479

CountMetersDue

Count   DateTime
2793    2011-12-01 00:00:00.000
1057    2011-05-01 14:08:20.437
610     2011-03-01 00:00:00.000

Solution

  • Second stab at answering your question (will probably need some clarification from yourself before the answer is correct):

    /* DDL: 2 tables [CountMetersDue] & [Readings]
        [CountMetersDue]
            ([DateTime] datetime,
            [Count] int)
    
        [Readings]
            ([ReadingId] bigint,
            [dateRead] datetime,
            [webcontactid] bigint,
            [meter] int)
    
        [CountMetersDue] - contains 1 record on the first of every month, with count of the number of readings at that date
        [Readings] - contains all the individual readings
    
        ie: 
            [CountMetersDue]
            01-Jan-2011     1000
            01-Feb-2011     2357
            01-Mar-2011     3000
    
            [Readings]
            1   01-Jan-2011     11  1
            2   02-Jan-2011     12  1
            3   03-Jan-2011     13  1
            ...
    */
    
        SELECT
        CONVERT(DATE, [dbo].[Readings].[dateRead]) AS dateRead, 
        COUNT([dbo].[Readings].[readingId]) AS TotalReadings,
        [dbo].[CountMetersDue].[Count] AS MetersDue
    
    FROM
        [CountMetersDue]             /* get all count meters due */
        left join [Readings]           /* get any corresponding Reading records  
                                           where the dateRead in the same month as
                                           the CountMetersDue */
            on DATEPART(year, Readings.dateRead) = DATEPART(year, [CountMetersDue].[DateTime]) /* reading in same year as CountMetersDue */
            and DATEPART(month, Readings.dateRead) = DATEPART(month, [CountMetersDue].[DateTime]) /* reading in same month as CountMetersDue */
            WHERE  ([MXPTransferDev].[dbo].[Readings].[dateRead]) BETWEEN 
                   @StartDate AND @EndDate
           AND ( webcontactid IS NOT NULL ) 
           AND ( meter = 1 ) 
    GROUP BY
        [dbo].[CountMetersDue].[Count],CONVERT(DATE, [dbo].[Readings].[dateRead])