SQL Server语言 - 包含聚合或子查询的表达式的聚合函数的替代方法



首先,对于令人困惑的代码示例,简化我的问题被证明是棘手的。

select [...]
SUM(case when 
(select [CustID] from [Source3] S3
where (S3.[CustID] = S1.[StaffID1] or S3.[CustID] = S1.[StaffID2])
and substring(datename(dw,S1.[AppDateTime]),1,3)=substring(S3.[DoW],1,3)) is not null
then 1 else 0 end), [...]
from [Source 1] S1
left join [Source 2] S2
on S2.[SbSpcID]=S1.[SbSpcID]
group by S1.[Condition1], S1.[Condition2]

基本上,我需要抓取(在此查询中只有 1 个字段(一个数字,指示我的 Source 3 表包含与我的连接表的行匹配的行的次数(在本例中源 1 和 2 连接在一起(。

只要源 3 的 [CustID] 字段等于源 1 的 StaffID1 或 StaffID2 字段,并且源 3 的 [DoW] 字段的星期几与源 1 的 AppDateTime 字段的星期几匹配,就需要此联接。

子字符串(日期名称(dw,S1.[AppDateTime](,1,3( 返回诸如"星期一"、"星期二"等内容。我之所以使用,是因为日期在源 3 中存储为名称("星期四"、"星期三"(。

我收到"无法对包含聚合或子查询的表达式执行聚合函数"错误。通常为了解决这个问题,我会将源 3 连接到包含源 2 和 1 的表中,但是因为我预计有多个匹配项,这意味着行数会增加,这将破坏此查询的其他(当前工作正常(结果的结果。

..

.

帮助!我的脑子疼。

---------------------编辑:---------------------

示例数据:

来源1和2:

[Condition1]  [Condition2]  [SbSpcID]  [StaffID1]  [StaffID2]  [AppDateTime]
Hosp          Doc           xxx        Con123       NULL       2018-02-10 16:00
Hosp          Nur           xxx        NULL         Con123     2018-03-15 21:05
Clin          Doc           xxx        Con125       NULL       2018-04-12 18:30
Hosp          DIT           xxx        NULL         NULL       2018-02-25 16:01
Hosp          Reg           xxx        NULL         Con126     2018-06-30 09:45
Hosp          Doc           xxx        Con321       NULL       2018-03-11 11:55
Hosp          Nur           xxx        NULL         Con125     2018-01-01 06:29
Hosp          Doc           xxx        Con125       NULL       2018-02-01 17:00

来源 3:

[CustID]  [Dow]
Con123    Wed
Con123    Thurs
Con123    Fri
Con123    Sunday
Con125    Mon
Con125    Tues
Con126    Sat
Con321    Mon

结果:

[Condition1]  [Condition2]  [Query]
Hosp          Doc           0
Hosp          Nur           2
Clin          Doc           0
Hosp          DIT           0
Hosp          Reg           1

尽管有很多 [Hosp] [Doc] 条目,但它们与源 3 中的条目中的星期几不匹配。而两个 [Hosp][Nur] 条目都与星期几匹配,因此它们都计算在内。

您仍然可以将源 3LEFT JOIN到源 1 和 2。您的联接将很奇怪且效率低下,因为您将工作日存储为文本,而不是它们的整数值。

使用您的样本数据(我将来源 1 和 2 合并为 1 CTE(:

-- sample data
WITH 
Source_1_2(Condition1, Condition2, StaffID1, StaffID2, AppDateTime)
AS
(
SELECT * FROM
(
VALUES
('Hosp',          'Doc',    'Con123',   NULL,       '2018-02-10 16:00'),
('Hosp',          'Nur',    NULL,       'Con123',   '2018-03-15 21:05'),
('Clin',          'Doc',    'Con125',   NULL,       '2018-04-12 18:30'),
('Hosp',          'DIT',    NULL,       NULL,       '2018-02-25 16:01'),
('Hosp',          'Reg',    NULL,       'Con126',   '2018-06-30 09:45'),
('Hosp',          'Doc',    'Con321',   NULL,       '2018-03-11 11:55'),
('Hosp',          'Nur',    NULL,       'Con125',   '2018-01-01 06:29'),
('Hosp',          'Doc',    'Con125',   NULL,       '2018-02-01 17:00')
) v(c1, c2, c3, c4, c5)
)
,Source_3(CustID, Dow) AS
(
SELECT * FROM
(
VALUES
('Con123',    'Wed'),
('Con123',    'Thurs'),
('Con123',    'Fri'),
('Con123',    'Sunday'),
('Con125',    'Mon'),
('Con125',    'Tues'),
('Con126',    'Sat'),
('Con321',    'Mon')
) v(c1, c2)
)
-- actual query
SELECT
Source_1_2.Condition1,
Source_1_2.Condition2,
COUNT(Source_3.CustID) AS [Count]
FROM Source_1_2
LEFT JOIN Source_3 ON
(Source_3.CustID = Source_1_2.StaffID1 OR Source_3.CustID = Source_1_2.StaffID2)
AND LEFT(Source_3.Dow, 3) = LEFT(DATENAME(WEEKDAY, Source_1_2.AppDateTime), 3)
GROUP BY 
Source_1_2.Condition1, 
Source_1_2.Condition2

给你这个结果:

+------------+------------+-------+
| Condition1 | Condition2 | Count |
+------------+------------+-------+
| Hosp       | DIT        |     0 |
| Clin       | Doc        |     0 |
| Hosp       | Doc        |     0 |
| Hosp       | Nur        |     2 |
| Hosp       | Reg        |     1 |
+------------+------------+-------+

最新更新