SQL 案例逻辑问题
SQL CASE Logic Issue
有人可以帮助我吗?示例:我遇到的问题是当一个帐户有 AV.Query='PN4'、AV.Response = 'Y'、AV.Query='FL1' 和 AV.Response='Y',结果需要
PStatus IStatus
4 2
但是,我得到了
PStatus IStatus
4 5
5 2
它总是在对面的列上选择“5”。
SELECT distinct A.AcctNum,
CASE
WHEN O.Order = 'NEI2' THEN '1'
WHEN AV.Query IN ('PNE1','PNE2') AND AV.Response = 'Y' THEN '2'
WHEN AV.Query = 'PN20' AND AV.Response = 'Y' THEN '3'
WHEN AV.Query = 'PN4' AND AV.Response = 'Y' THEN '4'
ELSE '5'
END AS [PStatus],
CASE
WHEN O.Order IN ('DO2','FL25','VACHP') THEN '1'
WHEN AV.Query = 'FL1' AND AV.Response = 'Y' THEN '2'
WHEN AV.Query = 'REF' AND AV.Response = 'Y' THEN '3'
WHEN AV.Query IN ('FL2','FL6','NEU.G','HE.B') AND AV.Response = 'Y' THEN '4'
WHEN AV.Query = 'NOA' AND AV.Response = 'Y' THEN '6'
ELSE '5'
END AS [IStatus]
FROM AData AS AD
INNER JOIN AVisit AS AV
ON AD.Visit = AV.Visit
AND AV.QueryID IN ('PNE1','PNE2','PN20','PN4','FL1','REF','FL2','FL6','NEU.G','HE.B','NOA')
LEFT JOIN Order AS O
ON AD.Visit = O.Visit
AND O.Order IN ('NEI2','DO2','FL25','VACHP');
您的查询结果似乎是正确的。
首先考虑连接的行
AV.Query='PN4', AV.Response = 'Y',
这匹配 [PStatus]
的 CASE
表达式中的最后一个 WHEN
条件,但不匹配 CASE
中的任何 WHEN
条件] [IStatus]
的表达式。结果:
4 5
现在考虑具有
的连接行
AV.Query='FL1' and AV.Response='Y'
这不匹配 [PStatus]
的 CASE
表达式中的任何 WHEN
条件,但它匹配 CASE
表达式中的第二个 WHEN
条件[IStatus]
。结果:
5 2
我可以为您的查询提供一个变体,以生成您为您提供的特定数据指定的结果,但我没有这样做,因为有很多选择,而且您没有给我们确定的信息哪一个正确回答了其他数据的问题。
更新:
要将多个结果行合并为一个,您需要聚合查询。实现此类查询以为给定数据提供值为 4、2 的单行的一种可能方法是
SELECT
AcctNum,
MIN(
CASE
WHEN O.Order = 'NEI2' THEN '1'
WHEN AV.Query IN ('PNE1','PNE2') AND AV.Response = 'Y' THEN '2'
WHEN AV.Query = 'PN20' AND AV.Response = 'Y' THEN '3'
WHEN AV.Query = 'PN4' AND AV.Response = 'Y' THEN '4'
ELSE NULL
END
) AS [Pstatus],
MIN(
CASE
WHEN O.Order IN ('DO2','FL25','VACHP') THEN '1'
WHEN AV.Query = 'FL1' AND AV.Response = 'Y' THEN '2'
WHEN AV.Query = 'REF' AND AV.Response = 'Y' THEN '3'
WHEN AV.Query IN ('FL2','FL6','NEU.G','HE.B') AND AV.Response = 'Y' THEN '4'
WHEN AV.Query = 'NOA' AND AV.Response = 'Y' THEN '6'
ELSE NULL
END
) AS [IStatus]
FROM
AData AS AD
INNER JOIN AVisit AS AV
ON AD.Visit = AV.Visit
AND AV.QueryID IN ('PNE1','PNE2','PN20','PN4','FL1','REF','FL2','FL6','NEU.G','HE.B','NOA')
LEFT JOIN Order AS O
ON AD.Visit = O.Visit
AND O.Order IN ('NEI2','DO2','FL25','VACHP');
GROUP BY AcctNum
这是有效的,因为 COUNT()
以外的聚合函数会忽略 NULL
s。但是,它很可能不会为不同的数据模式提供所需的答案——尤其是同一帐户有两个以上 AVisit
的模式。
结果正确。
您的价值观是:
第一行 - AV.Query='PN4'
、AV.Response = 'Y'
第二行 - AV.Query='FL1', AV.Response='Y'
第一个 CASE PStatus:结果如您所料为 4。
下一个案例,Istatus。这可能是误会,因为 SQL 仍将处理相同的值(第一行)。此 CASE
将检查值:从第一行开始的 AV.Query='PN4'
、AV.Response = 'Y'
。不反对你的第二个价值观(AV.Query='FL1' and AV.Response='Y'
)。
值'PN4' and 'FL1'
不能在同一行的同一列中!一列只能有一个值,不能有两个。您可能期望在第二种情况下 SQL 将开始获取另一(第二)行数据。但事实并非如此。
第二种情况结果是正确的因为在CASE中没有条件值PN4
,所以它最终是ELSE = 5
OK 编辑,像这样做,这个蛮力,但会奏效 ;-)
SELECT A.AcctNum,
COALESCE(MAX( CASE
WHEN O.Order = 'NEI2' THEN '1'
WHEN AV.Query IN ('PNE1','PNE2') AND AV.Response = 'Y' THEN '2'
WHEN AV.Query = 'PN20' AND AV.Response = 'Y' THEN '3'
WHEN AV.Query = 'PN4' AND AV.Response = 'Y' THEN '4'
ELSE NULL
END),5) AS [PStatus],
COALESCE(MAX(CASE
WHEN O.Order IN ('DO2','FL25','VACHP') THEN '1'
WHEN AV.Query = 'FL1' AND AV.Response = 'Y' THEN '2'
WHEN AV.Query = 'REF' AND AV.Response = 'Y' THEN '3'
WHEN AV.Query IN ('FL2','FL6','NEU.G','HE.B') AND AV.Response = 'Y' THEN '4'
WHEN AV.Query = 'NOA' AND AV.Response = 'Y' THEN '6'
ELSE NULL
END),5) AS [IStatus]
有人可以帮助我吗?示例:我遇到的问题是当一个帐户有 AV.Query='PN4'、AV.Response = 'Y'、AV.Query='FL1' 和 AV.Response='Y',结果需要
PStatus IStatus
4 2
但是,我得到了
PStatus IStatus
4 5
5 2
它总是在对面的列上选择“5”。
SELECT distinct A.AcctNum,
CASE
WHEN O.Order = 'NEI2' THEN '1'
WHEN AV.Query IN ('PNE1','PNE2') AND AV.Response = 'Y' THEN '2'
WHEN AV.Query = 'PN20' AND AV.Response = 'Y' THEN '3'
WHEN AV.Query = 'PN4' AND AV.Response = 'Y' THEN '4'
ELSE '5'
END AS [PStatus],
CASE
WHEN O.Order IN ('DO2','FL25','VACHP') THEN '1'
WHEN AV.Query = 'FL1' AND AV.Response = 'Y' THEN '2'
WHEN AV.Query = 'REF' AND AV.Response = 'Y' THEN '3'
WHEN AV.Query IN ('FL2','FL6','NEU.G','HE.B') AND AV.Response = 'Y' THEN '4'
WHEN AV.Query = 'NOA' AND AV.Response = 'Y' THEN '6'
ELSE '5'
END AS [IStatus]
FROM AData AS AD
INNER JOIN AVisit AS AV
ON AD.Visit = AV.Visit
AND AV.QueryID IN ('PNE1','PNE2','PN20','PN4','FL1','REF','FL2','FL6','NEU.G','HE.B','NOA')
LEFT JOIN Order AS O
ON AD.Visit = O.Visit
AND O.Order IN ('NEI2','DO2','FL25','VACHP');
您的查询结果似乎是正确的。
首先考虑连接的行
AV.Query='PN4', AV.Response = 'Y',
这匹配 [PStatus]
的 CASE
表达式中的最后一个 WHEN
条件,但不匹配 CASE
中的任何 WHEN
条件] [IStatus]
的表达式。结果:
4 5
现在考虑具有
的连接行AV.Query='FL1' and AV.Response='Y'
这不匹配 [PStatus]
的 CASE
表达式中的任何 WHEN
条件,但它匹配 CASE
表达式中的第二个 WHEN
条件[IStatus]
。结果:
5 2
我可以为您的查询提供一个变体,以生成您为您提供的特定数据指定的结果,但我没有这样做,因为有很多选择,而且您没有给我们确定的信息哪一个正确回答了其他数据的问题。
更新:
要将多个结果行合并为一个,您需要聚合查询。实现此类查询以为给定数据提供值为 4、2 的单行的一种可能方法是
SELECT
AcctNum,
MIN(
CASE
WHEN O.Order = 'NEI2' THEN '1'
WHEN AV.Query IN ('PNE1','PNE2') AND AV.Response = 'Y' THEN '2'
WHEN AV.Query = 'PN20' AND AV.Response = 'Y' THEN '3'
WHEN AV.Query = 'PN4' AND AV.Response = 'Y' THEN '4'
ELSE NULL
END
) AS [Pstatus],
MIN(
CASE
WHEN O.Order IN ('DO2','FL25','VACHP') THEN '1'
WHEN AV.Query = 'FL1' AND AV.Response = 'Y' THEN '2'
WHEN AV.Query = 'REF' AND AV.Response = 'Y' THEN '3'
WHEN AV.Query IN ('FL2','FL6','NEU.G','HE.B') AND AV.Response = 'Y' THEN '4'
WHEN AV.Query = 'NOA' AND AV.Response = 'Y' THEN '6'
ELSE NULL
END
) AS [IStatus]
FROM
AData AS AD
INNER JOIN AVisit AS AV
ON AD.Visit = AV.Visit
AND AV.QueryID IN ('PNE1','PNE2','PN20','PN4','FL1','REF','FL2','FL6','NEU.G','HE.B','NOA')
LEFT JOIN Order AS O
ON AD.Visit = O.Visit
AND O.Order IN ('NEI2','DO2','FL25','VACHP');
GROUP BY AcctNum
这是有效的,因为 COUNT()
以外的聚合函数会忽略 NULL
s。但是,它很可能不会为不同的数据模式提供所需的答案——尤其是同一帐户有两个以上 AVisit
的模式。
结果正确。
您的价值观是:
第一行 - AV.Query='PN4'
、AV.Response = 'Y'
第二行 - AV.Query='FL1', AV.Response='Y'
第一个 CASE PStatus:结果如您所料为 4。
下一个案例,Istatus。这可能是误会,因为 SQL 仍将处理相同的值(第一行)。此 CASE
将检查值:从第一行开始的 AV.Query='PN4'
、AV.Response = 'Y'
。不反对你的第二个价值观(AV.Query='FL1' and AV.Response='Y'
)。
值'PN4' and 'FL1'
不能在同一行的同一列中!一列只能有一个值,不能有两个。您可能期望在第二种情况下 SQL 将开始获取另一(第二)行数据。但事实并非如此。
第二种情况结果是正确的因为在CASE中没有条件值PN4
,所以它最终是ELSE = 5
OK 编辑,像这样做,这个蛮力,但会奏效 ;-)
SELECT A.AcctNum,
COALESCE(MAX( CASE
WHEN O.Order = 'NEI2' THEN '1'
WHEN AV.Query IN ('PNE1','PNE2') AND AV.Response = 'Y' THEN '2'
WHEN AV.Query = 'PN20' AND AV.Response = 'Y' THEN '3'
WHEN AV.Query = 'PN4' AND AV.Response = 'Y' THEN '4'
ELSE NULL
END),5) AS [PStatus],
COALESCE(MAX(CASE
WHEN O.Order IN ('DO2','FL25','VACHP') THEN '1'
WHEN AV.Query = 'FL1' AND AV.Response = 'Y' THEN '2'
WHEN AV.Query = 'REF' AND AV.Response = 'Y' THEN '3'
WHEN AV.Query IN ('FL2','FL6','NEU.G','HE.B') AND AV.Response = 'Y' THEN '4'
WHEN AV.Query = 'NOA' AND AV.Response = 'Y' THEN '6'
ELSE NULL
END),5) AS [IStatus]