开发者

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 [Meter开发者_运维知识库sDue], 
       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


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])


This would be the query you are looking for then?
Subqueries, as they are called, can be included by enclosing them in parentheses '()'.

SELECT (SELECT [Count] FROM [xxxxx].[dbo].[CountMetersDue] AS tabA WHERE tabA.[datefield] = tabB.dateRead) AS [MetersDue], COUNT(readingId) AS [TotalReadings], CONVERT(DATE, dateRead) AS [dateRead]
FROM         [xxxxx] AS tabB
WHERE     (dateRead BETWEEN @StartDate AND @EndDate) AND (webcontactid IS NOT NULL) AND (meter = 1)
GROUP BY CONVERT(DATE, dateRead)
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜