将 T-SQL INNER JOIN 语句翻译成 DAX
Translating T-SQL INNER JOIN statement into DAX
我在 T-SQL 中有以下代码,它根据特定条件计算 [C-Services] table 的不同 [ClientID],并加入 [[=24] =]] table 在多个字段上:
SELECT
cs.[ProgramName] AS [Program]
,COUNT(DISTINCT cs.[ClientID]) AS [# Clients Served]
FROM
[C_Services] cs
INNER JOIN [C_Episodes] epi ON (
(epi.[ProgramID] = cs.[ProgramID])
AND (epi.[ClientID] = cs.[ClientID])
AND (epi.[AdmissionDate] <= cs.[ServiceMonth])
AND (epi.[DischargeDate] >= cs.[ServiceMonth])
)
WHERE
(cs.[ClientID] > 0)
AND (cs.[IsNoShow] = 0)
AND (cs.[IsCancellation] = 0)
AND (cs.[IsNonClaimable] = 0)
GROUP BY
cs.[ProgramName]
此外,我还有与上述代码关联的 DAX 度量,但没有 INNER JOIN [C 集] table:
VAR countClients =
CALCULATE (
DISTINCTCOUNT ( 'C_Services'[ClientID] ),
FILTER (
'C_Services',
[ClientID] > 0
&& [Is Non-Claimable] = FALSE ()
&& [Is No-show] = FALSE ()
&& [Is Cancellation] = FALSE ()
)
)
RETURN
countClients
我的问题是——
我必须如何修改 DAX 度量才能添加 INNER JOIN [C_Episodes] table(在 T-SQL 代码中规定的三个条件下加入)?
我试图为第一个 JOIN ON ProgramID 列添加
NATURALINNERJOIN('C_Services'[ProgramID], 'C_Episodes'[ProgramID])
但它给出了一个错误 - “需要分组”,并且在我尝试将我的计算更改为 Summarize 或 Summarizecolumns 之后 - 它仍然给出了一个错误。
SQL可以改写成这样:
SELECT
cs.[ProgramName] AS [Program]
,COUNT(
DISTINCT
CASE WHEN EXISTS (
SELECT *
FROM [C_Episodes] epi
WHERE (epi.[ProgramID] = cs.[ProgramID])
AND (epi.[ClientID] = cs.[ClientID])
AND (epi.[AdmissionDate] <= cs.[ServiceMonth])
AND (epi.[DischargeDate] >= cs.[ServiceMonth])
) THEN cs.[ClientID] ELSE NULL END
) AS [# Clients Served]
FROM
[C_Services] cs
WHERE
(cs.[ClientID] > 0)
AND (cs.[IsNoShow] = 0)
AND (cs.[IsCancellation] = 0)
AND (cs.[IsNonClaimable] = 0)
GROUP BY
cs.[ProgramName]
这更符合 DAX 以衡量为中心的世界观。
如果我们
- 关注
[# Clients Served]
措施
- 假设 ProgramName 分组依据将由可视化处理
- 假设您现有的过滤器可以重复使用
那么您应该可以将其用于 C_Episodes
table:
中的 列 计算
ClientMatched =
IF(
ISEMPTY(
FILTER(
'C_Episodes',
'C_Episodes'[ProgramID] = 'C_Services'[ProgramID] &&
'C_Episodes'[ClientID] = 'C_Services'[ClientID] &&
'C_Episodes'[AdmissionDate] <= 'C_Services'[ServiceMonth] &&
'C_Episodes'[DischargeDate] >= 'C_Services'[ServiceMonth]
)
),
BLANK(),
[ClientID]
)
如果 C_Episodes 中有匹配的记录,该列将包含 ClientID,否则将为空白。
这也可以通过您的其他过滤器进行扩展。
现在你可以使用这个措施了:
DistinctClientCount = DISTINCTCOUNTNOBLANK(Services[ClientMatched])
我不确定这有多有效,但试试看
为了完整起见,这些是创建我用来测试的 tables 的 DAX 表达式:
C_Services
C_Services = UNION(
ROW("ProgramId", 1, "ClientId", 1,"ServiceMonth",DATE(2021,2,1)),
ROW("ProgramId", 1, "ClientId", 1,"ServiceMonth",DATE(2021,3,1)),
ROW("ProgramId", 1, "ClientId", 1,"ServiceMonth",DATE(2021,4,1)),
ROW("ProgramId", 1, "ClientId", 2,"ServiceMonth",DATE(2021,2,1)),
ROW("ProgramId", 1, "ClientId", 2,"ServiceMonth",DATE(2021,3,1)),
ROW("ProgramId", 1, "ClientId", 2,"ServiceMonth",DATE(2021,4,1)),
ROW("ProgramId", 2, "ClientId", 1,"ServiceMonth",DATE(2021,2,1)),
ROW("ProgramId", 2, "ClientId", 1,"ServiceMonth",DATE(2021,3,1)),
ROW("ProgramId", 2, "ClientId", 1,"ServiceMonth",DATE(2021,4,1))
)
C_Episodes
C_Episodes = UNION(
ROW("ProgramId", 1, "ClientId", 1,"AdmissionDate",DATE(2021,1,15),"DischargeDate",DATE(2021,2,15)),
ROW("ProgramId", 1, "ClientId", 2,"AdmissionDate",DATE(2022,5,15),"DischargeDate",DATE(2022,6,15)),
ROW("ProgramId", 4, "ClientId", 1,"AdmissionDate",DATE(2021,2,15),"DischargeDate",DATE(2021,3,15)),
ROW("ProgramId", 1, "ClientId", 2,"AdmissionDate",DATE(2021,2,15),"DischargeDate",DATE(2021,3,15))
)
我在 T-SQL 中有以下代码,它根据特定条件计算 [C-Services] table 的不同 [ClientID],并加入 [[=24] =]] table 在多个字段上:
SELECT
cs.[ProgramName] AS [Program]
,COUNT(DISTINCT cs.[ClientID]) AS [# Clients Served]
FROM
[C_Services] cs
INNER JOIN [C_Episodes] epi ON (
(epi.[ProgramID] = cs.[ProgramID])
AND (epi.[ClientID] = cs.[ClientID])
AND (epi.[AdmissionDate] <= cs.[ServiceMonth])
AND (epi.[DischargeDate] >= cs.[ServiceMonth])
)
WHERE
(cs.[ClientID] > 0)
AND (cs.[IsNoShow] = 0)
AND (cs.[IsCancellation] = 0)
AND (cs.[IsNonClaimable] = 0)
GROUP BY
cs.[ProgramName]
此外,我还有与上述代码关联的 DAX 度量,但没有 INNER JOIN [C 集] table:
VAR countClients =
CALCULATE (
DISTINCTCOUNT ( 'C_Services'[ClientID] ),
FILTER (
'C_Services',
[ClientID] > 0
&& [Is Non-Claimable] = FALSE ()
&& [Is No-show] = FALSE ()
&& [Is Cancellation] = FALSE ()
)
)
RETURN
countClients
我的问题是—— 我必须如何修改 DAX 度量才能添加 INNER JOIN [C_Episodes] table(在 T-SQL 代码中规定的三个条件下加入)?
我试图为第一个 JOIN ON ProgramID 列添加
NATURALINNERJOIN('C_Services'[ProgramID], 'C_Episodes'[ProgramID])
但它给出了一个错误 - “需要分组”,并且在我尝试将我的计算更改为 Summarize 或 Summarizecolumns 之后 - 它仍然给出了一个错误。
SQL可以改写成这样:
SELECT
cs.[ProgramName] AS [Program]
,COUNT(
DISTINCT
CASE WHEN EXISTS (
SELECT *
FROM [C_Episodes] epi
WHERE (epi.[ProgramID] = cs.[ProgramID])
AND (epi.[ClientID] = cs.[ClientID])
AND (epi.[AdmissionDate] <= cs.[ServiceMonth])
AND (epi.[DischargeDate] >= cs.[ServiceMonth])
) THEN cs.[ClientID] ELSE NULL END
) AS [# Clients Served]
FROM
[C_Services] cs
WHERE
(cs.[ClientID] > 0)
AND (cs.[IsNoShow] = 0)
AND (cs.[IsCancellation] = 0)
AND (cs.[IsNonClaimable] = 0)
GROUP BY
cs.[ProgramName]
这更符合 DAX 以衡量为中心的世界观。
如果我们
- 关注
[# Clients Served]
措施 - 假设 ProgramName 分组依据将由可视化处理
- 假设您现有的过滤器可以重复使用
那么您应该可以将其用于 C_Episodes
table:
ClientMatched =
IF(
ISEMPTY(
FILTER(
'C_Episodes',
'C_Episodes'[ProgramID] = 'C_Services'[ProgramID] &&
'C_Episodes'[ClientID] = 'C_Services'[ClientID] &&
'C_Episodes'[AdmissionDate] <= 'C_Services'[ServiceMonth] &&
'C_Episodes'[DischargeDate] >= 'C_Services'[ServiceMonth]
)
),
BLANK(),
[ClientID]
)
如果 C_Episodes 中有匹配的记录,该列将包含 ClientID,否则将为空白。
这也可以通过您的其他过滤器进行扩展。
现在你可以使用这个措施了:
DistinctClientCount = DISTINCTCOUNTNOBLANK(Services[ClientMatched])
我不确定这有多有效,但试试看
为了完整起见,这些是创建我用来测试的 tables 的 DAX 表达式:
C_Services
C_Services = UNION(
ROW("ProgramId", 1, "ClientId", 1,"ServiceMonth",DATE(2021,2,1)),
ROW("ProgramId", 1, "ClientId", 1,"ServiceMonth",DATE(2021,3,1)),
ROW("ProgramId", 1, "ClientId", 1,"ServiceMonth",DATE(2021,4,1)),
ROW("ProgramId", 1, "ClientId", 2,"ServiceMonth",DATE(2021,2,1)),
ROW("ProgramId", 1, "ClientId", 2,"ServiceMonth",DATE(2021,3,1)),
ROW("ProgramId", 1, "ClientId", 2,"ServiceMonth",DATE(2021,4,1)),
ROW("ProgramId", 2, "ClientId", 1,"ServiceMonth",DATE(2021,2,1)),
ROW("ProgramId", 2, "ClientId", 1,"ServiceMonth",DATE(2021,3,1)),
ROW("ProgramId", 2, "ClientId", 1,"ServiceMonth",DATE(2021,4,1))
)
C_Episodes
C_Episodes = UNION(
ROW("ProgramId", 1, "ClientId", 1,"AdmissionDate",DATE(2021,1,15),"DischargeDate",DATE(2021,2,15)),
ROW("ProgramId", 1, "ClientId", 2,"AdmissionDate",DATE(2022,5,15),"DischargeDate",DATE(2022,6,15)),
ROW("ProgramId", 4, "ClientId", 1,"AdmissionDate",DATE(2021,2,15),"DischargeDate",DATE(2021,3,15)),
ROW("ProgramId", 1, "ClientId", 2,"AdmissionDate",DATE(2021,2,15),"DischargeDate",DATE(2021,3,15))
)