如何获得每日正确的平均约会数?

时间:2017-06-09 19:48:05

标签: sql sql-server

我想知道每种约会类型的平均约会数是多少。基本上我有以下表格和列:

Table 1 - Dates
-----------
Date date (primary key)

Table 2 - Appointments
-----------
AppointmentStart Datetime
ApptId Numeric
FacilityId Numeric
ApptKind Numeric
Appointmentid Numeric

Table 3 AppointmentType
-----------
ApptTypeId Numeric
Name Varchar


Sample Data
============

Table 1 Date
--------------- 
date
1/1/2017
1/2/2017
...

Table 2 Appointment
----------------  
ApptStart        |  ApptTypeId   | FacilityId   |  ApptKind |  ApptId
2017-1-1 9:00:00    1              2               1           2385525
2017-1-1 9:15:00    3              2               1           2385526
2017-1-1 9:30:00    2              2               1           2385527
...


Table 3 ApptType
-----------------
ApptTypeId  |  Name
1              Walk-in
2              MAT
3              Acute
...

大约有30种不同的约会类型,并非所有约会都是每天都有。到目前为止,我已经创建了一个表,列出了我想要的时间范围内的每个日期,然后我使用约会计数进行左连接(空值等于0)。我也删除星期六和星期日。这适用于一种约会类型,但当我使用多种约会类型执行此操作时,零只显示没有约会的日期。

我的解决方案:
以某种方式在每天旁边插入每个约会类型然后使用NULL = 0部分进行左连接,尽管我不知道如何让列表在表格中的每一天重复。

示例:

最后我想要

EndResult
----------
Average(Count(appts)) |  ApptType.Name    

OR

EndResult
---------
Count(apptid)  |  ApptType.Name  |  Date
5                 Acute             1/1/2017
0                 MAT               1/1/2017
4                 Walk-in           1/1/2017
0                 Other             1/1/2017

然后使用相同的约会类型名称重复第二天

3 个答案:

答案 0 :(得分:0)

这就是我编写一个可以帮助您的查询的方法 最终结果#2:

SELECT IsNull(B.ApptCount, 0) AS ApptCount, C.Name AS ApptTypeName, A.Date
FROM (
    SELECT Table1.Date, Table3.ApptTypeID
    FROM Table1, Table3
) AS A LEFT JOIN (
    SELECT Convert(Date, ApptStart) AS ApptDate, ApptTypeID, COUNT(ApptID) AS ApptCount 
    FROM Table2
    GROUP BY Date(ApptStart), ApptTypeID
) AS B ON A.Date = B.ApptDate AND A.ApptTypeID = B.ApptTypeID
LEFT JOIN Table3 AS C ON B.ApptTypeID = C.ApptTypeID

这假设ApptTypeID确实是Table2的一部分。您可以进一步包装此结果以获得最终结果#1:

SELECT Avg(D.ApptCount), D.ApptTypeName 
FROM (
    SELECT IsNull(B.ApptCount, 0) AS ApptCount, C.Name AS ApptTypeName, A.Date
    FROM (
        SELECT Table1.Date, Table3.ApptID
        FROM Table1, Table3
    ) AS A LEFT JOIN (
        SELECT Convert(Date, ApptStart) AS ApptDate, ApptTypeID, COUNT(ApptID) AS ApptCount 
        FROM Table2
        GROUP BY Date(ApptStart), ApptTypeID
    ) AS B ON A.Date = B.ApptDate AND A.ApptTypeID = B.ApptTypeID
    LEFT JOIN Table3 AS C ON B.ApptTypeID = C.ApptTypeID
) AS D
GROUP BY D.ApptTypeName

答案 1 :(得分:0)

首先,我们声明并填充表变量以获取示例数据。

DECLARE @Dates TABLE (
    Date DATE
)

INSERT @Dates
VALUES
    ('2017-01-01')
    ,('2017-01-02')

DECLARE @Appointments TABLE (
    AppointmentStart DATETIME
    ,ApptId INT
    ,FacilityId INT
    ,ApptKind INT
    ,Appointmentid INT
)

INSERT @Appointments
VALUES
    ('2017-01-01 09:00:00.000', 1, 2, 1, 2385525)
    ,('2017-01-01 09:15:00.000', 3, 2, 1, 2385526)
    ,('2017-01-01 09:30:00.000', 2, 2, 1, 2385527)

DECLARE @ApptType TABLE (
    ApptTypeId INT
    ,Name VARCHAR(32)   
)

INSERT @ApptType
VALUES
    (1, 'Walk-in')
    ,(2, 'MAT')
    ,(3, 'Acute')

这向我们展示了Dates和ApptType的完全外连接的笛卡尔积。

SELECT
    [Dates].[Date]
    ,[ApptType].[ApptTypeID]
    ,[ApptType].[Name]
FROM @Dates AS [Dates]
FULL OUTER JOIN @ApptType AS [ApptType]
    ON 1 = 1

我们可以使用笛卡尔积作为左侧数据集,并计算右侧数据集中的项目数(@Appointments)。通过左连接执行此操作,我们确保包含每个日期/约会类型组合,即使该日期没有该类型的约会。

SELECT
    A.[Date]
    ,A.[Name]
    ,COUNT(B.Appointmentid)
FROM (
    SELECT
        [Dates].[Date]
        ,[ApptType].[ApptTypeID]
        ,[ApptType].[Name]
    FROM @Dates AS [Dates]
    FULL OUTER JOIN @ApptType AS [ApptType]
        ON 1 = 1) AS A
LEFT JOIN @Appointments AS B
    ON A.[ApptTypeId] = B.[ApptId]
    AND A.[Date] = CAST(B.[AppointmentStart] AS DATE)
GROUP BY
    A.[Date]
    ,A.[Name]
ORDER BY
    A.[Date]
    ,A.[Name]

答案 2 :(得分:0)

使用正确的联接和交叉申请。

select count(a.ApptId) as Appointments, at.Name, d.[Date]
from [Appointment] a
right join (
    [ApptType] at 
    cross apply [Date] d
) on (a.ApptTypeId = at.ApptTypeId and cast(a.ApptStart as date) = d.[Date])
group by d.[Date], at.ApptTypeId, at.Name;

为什么正确加入?嗯,外连接不必一直留下。