SQL:从同一查询中联合多个单行结果集

时间:2016-11-21 22:37:34

标签: sql-server tsql

我有一个查询,当给定一个特定日期时,检查一个大型数据集(大约36米并且正在增长)并返回一个聚合。一切都按预期工作......但是,我的最终目标是能够确定这些值的年平均值。也许我的大脑是空的,但我试图动态地这样做,我不必运行365次查询然后平均......

我需要找到365个结果的年平均值, per @inst, per @program。

任何指向正确方向的人都会非常感激。

查询:

USE HCODS
GO

DECLARE @user_date DATETIME
DECLARE @inst VARCHAR(4)
DECLARE @program VARCHAR(4)
SELECT @user_date = '9/30/2016'
SELECT @inst = 'SAC'
SELECT @program = 'PSU';

WITH T AS (
    SELECT
         B.OFFENDERID
        ,Institution = I.ORGCOMMONID
        ,BedUse = B.BEDUSE
        ,BeginEffectiveDtTm = CAST(B.BEDASSIGNMENTDATE AS DATETIME) + CAST(B.BEDASSIGNMENTTIME AS DATETIME)
        ,EndEffectiveDtTm = CASE WHEN B.BEDASSIGNMENTSTATUS = 'U' THEN 
            (CAST(B.INMBEDSTATUSDATE AS DATETIME) + CAST(B.INMBEDSTATUSTIME AS DATETIME)) ELSE NULL END

    FROM ODS.BEDASSIGNMENT (NOLOCK) B

    INNER JOIN (
        SELECT F.PARTYID, I.ORGCOMMONID
        FROM ODS.ORGANIZATIONPROF (NOLOCK) AS F
        INNER JOIN ODS.ORGANIZATIONPROF (NOLOCK) AS I ON F.ORGAREACODE = I.PARTYID
        ) AS I ON B.FACILITYWHEREBEDLOCATED = I.PARTYID

    WHERE B.BEDASSIGNMENTDATE BETWEEN '1/1/2016' AND '12/31/2016'
        AND B.BEDASSIGNMENTSTATUS IN ('U','M')
        )

SELECT CAST(@user_date AS DATE)
    ,T.INSTITUTION
    ,T.BEDUSE
    ,COUNT(*)

FROM T

WHERE
    ( 
        (
        T.BEGINEFFECTIVEDTTM <= DATEADD(second,-1,(@user_date+1))
        AND
        T.ENDEFFECTIVEDTTM >= @user_date
        )
    OR T.ENDEFFECTIVEDTTM IS NULL
    )
    AND T.INSTITUTION = @inst
    AND T.BedUse = @program

GROUP BY
     T.Institution
    ,T.BedUse

结果集(通过单次运行查询获得的每个结果集)

Date       |Institution |BedUse |Count
-----------|------------|-------|-------
2016-09-30 |SAC         |PSU    |446
2016-10-01 |SAC         |PSU    |421
2016-10-02 |SAC         |PSU    |423

etc......

1 个答案:

答案 0 :(得分:3)

虽然很难在没有看到数据的情况下回答您的数据问题。我可以把你转变为窗口函数的SQL概念。在本质上,这是在进行内联分组以聚合数据。如果我有一套但想要在其上设置多个语句以查看不同的内容,那么这个陈述是完美的。

所以在一个例子中,我本质上是从2015年1月1日到今天(动态,因为这可能是任何一天,甚至在我发布之后)。然后我选择1到100的随机数来填充我的临时集中的数据行。然后,我可以对此进行集合操作。

DECLARE @Data TABLE ( Id INT IDENTITY, val INT, dt DATETIME)

DECLARE @Start DATETIME = '1-1-2015'

SET NOCOUNT ON;

WHILE @Start <= GETDATE()
BEGIN
    INSERT INTO @Data VALUES (ABS(CHECKSUM(NewId())) % 100, @Start)

        SELECT @Start = DATEADD(DAY, 1, @STart)
END

SELECT DISTINCT
    SUM(Val) OVER() AS TotalValues
,   COUNT(*) OVER() AS rowCounts
,   DATEADD(YEAR, DATEDIFF(YEAR, 0, Dt), 0) AS YearDate
,   COUNT(*) OVER(PARTITION BY DATEADD(YEAR, DATEDIFF(YEAR, 0, Dt), 0)) AS DaysInYear
,   SUM(Val) OVER(PARTITION BY DATEADD(YEAR, DATEDIFF(YEAR, 0, Dt), 0)) AS ValsByYear
,   AVG(Val) OVER(PARTITION BY DATEADD(YEAR, DATEDIFF(YEAR, 0, Dt), 0)) AS AVGByYear
,   DATEADD(Month, DATEDIFF(Month, 0, Dt), 0) AS MonthDate
,   COUNT(*) OVER(PARTITION BY DATEADD(Month, DATEDIFF(Month, 0, Dt), 0)) AS DaysInMonth
,   SUM(Val) OVER(PARTITION BY DATEADD(Month, DATEDIFF(Month, 0, Dt), 0)) AS ValsByMonth
,   AVG(Val) OVER(PARTITION BY DATEADD(Month, DATEDIFF(MOnth, 0, Dt), 0)) AS AVGByMonth
From @Data