[英]Use String_AGG to query with condition in SQL?
我有 3 个表,关系是 Policy (N) -> PolicyService <- Service (N):
DXBusinessPolicy_Policy
ID | 代码 | 名称 |
---|---|---|
1个 | COMBO.2103001 | [Giá nền] T9/2020 #1 |
2个 | IPTV-0121.002 | [Giá nền] T8/2020 #1 |
3个 | INT.2103001 | Chính sách 2 |
DXBusinessPolicy_Service
ID | 代码 | 名称 |
---|---|---|
1个 | 情报局 | 因特网 |
2个 | 网络电视 | 网络电视 |
DXBusinessPolicy_PolicyService
ID | 政策编号 | 服务编号 |
---|---|---|
1个 | 1个 | 1个 |
2个 | 1个 | 2个 |
3个 | 2个 | 2个 |
4个 | 3个 | 1个 |
问题:输入服务(ServiceCode),output分别是PolicyID、PolicyCode、PolicyName和该策略的服务列表(ServiceCode列表的字符串用“,”连接)。
例如:我的输入是:“INT”。 结果预期:
政策代码 | 政策名称 | 服务 |
---|---|---|
COMBO.2103001 | [Giá nền] T9/2020 #1 | 国际网络电视 |
INT.2103001 | Chính sách 2 | 情报局 |
我试图按如下方式解决这个问题:
ALTER PROC FindPolicyByService
@ServiceCode varchar(200)
AS
BEGIN
SELECT dbo.DXBusinessPolicy_Policy.ID AS PolicyID,
dbo.DXBusinessPolicy_Policy.Code AS PolicyCode,
dbo.DXBusinessPolicy_Policy.Name AS PolicyName,
STRING_AGG(dbo.DXBusinessPolicy_Service.Code, ',')
FROM dbo.DXBusinessPolicy_Policy
join dbo.DXBusinessPolicy_PolicyService ON dbo.DXBusinessPolicy_Policy.ID = dbo.DXBusinessPolicy_PolicyService.PolicyID
join dbo.DXBusinessPolicy_Service ON dbo.DXBusinessPolicy_PolicyService.ServiceID = dbo.DXBusinessPolicy_Service.ID
WHERE dbo.DXBusinessPolicy_Service.Code = @ServiceCode
GROUP by dbo.DXBusinessPolicy_Policy.ID, dbo.DXBusinessPolicy_Policy.Code, dbo.DXBusinessPolicy_Policy.Name
END
exec FindPolicyByService "INT"
但是结果不是我所期望的
政策代码 | 政策名称 | 服务 |
---|---|---|
COMBO.2103001 | [Giá nền] T9/2020 #1 | 情报局 |
INT.2103001 | Chính sách 2 | 情报局 |
我终于找到了对我的问题最准确的答案。 谢谢大家:最好的解决方案是:
ALTER PROC FindPolicyByService
@codes varchar(200)
AS
BEGIN
SELECT p.ID AS PolicyID,
p.Code AS PolicyCode,
p.Name AS PolicyName,
STRING_AGG(s.Code, ',') AS ServiceCode
FROM dbo.DXBusinessPolicy_Policy AS p
JOIN dbo.DXBusinessPolicy_PolicyService AS ps ON p.ID = ps.PolicyID
JOIN dbo.DXBusinessPolicy_Service AS s ON ps.ServiceID = s.ID
WHERE p.ID IN
(
SELECT subps.PolicyID
FROM dbo.DXBusinessPolicy_PolicyService AS subps
JOIN dbo.DXBusinessPolicy_Service AS subs ON subps.ServiceID = subs.ID
WHERE subs.Code = @ServiceCode
)
GROUP by p.ID, p.Code, p.Name
END
或其他解决方案:
ALTER PROC FindPolicyByService
@ServiceCode varchar(200)
AS
BEGIN
SELECT DIstinct policy.ID AS PolicyID,
policy.Code AS PolicyCode,
policy.Name AS PolicyName,
(SELECT STRING_AGG(tempService.Code, ',') FROM dbo.DXBusinessPolicy_Policy tempPolicy
JOIN dbo.DXBusinessPolicy_PolicyService tempPolicyService
ON tempPolicy.ID = tempPolicyService.PolicyID
JOIN dbo.DXBusinessPolicy_Service tempService
ON tempPolicyService.ServiceID = tempService.ID
WHERE policyservice.PolicyID = PolicyID) AS ServiceCode
FROM dbo.DXBusinessPolicy_Policy policy
JOIN dbo.DXBusinessPolicy_PolicyService policyservice
ON policy.ID = policyservice.PolicyID
JOIN dbo.DXBusinessPolicy_Service service
ON policyservice.ServiceID = service.ID AND service.Code = @ServiceCode
GROUP BY
policy.ID,
policyservice.PolicyID,
policy.Code,
policy.Name
END
这一切都给了我预期的结果:
政策代码 | 政策名称 | 服务 |
---|---|---|
COMBO.2103001 | [Giá nền] T9/2020 #1 | INT,IPTV |
INT.2103001 | Chính sách 2 | INT |
使用左连接并将WHERE
子句中的逻辑移动到相应连接的ON
子句:
ALTER PROC FindPolicyByService
@ServiceCode varchar(200)
AS
BEGIN
SELECT policy.ID AS PolicyID,
policy.Code AS PolicyCode,
policy.Name AS PolicyName,
STRING_AGG(service.Code, ',')
FROM dbo.DXBusinessPolicy_Policy policy
LEFT JOIN dbo.DXBusinessPolicy_PolicyService policyservice
ON policy.ID = policyservice.PolicyID
LEFT JOIN dbo.DXBusinessPolicy_Service service
ON policyservice.ServiceID = service.ID AND
service.Code = @ServiceCode
GROUP BY
policy.ID,
policy.Code,
policy.Name
END
exec FindPolicyByService "INT"
当前的WHERE
子句过早地过滤掉应该由STRING_AGG
的记录。 另请注意,我在查询中引入了更具可读性的别名。
我试图像这样更新我的商店:
ALTER PROC FindPolicyByService
@ServiceCode varchar(200)
AS
BEGIN
SELECT policy.ID AS PolicyID,
policy.Code AS PolicyCode,
policy.Name AS PolicyName,
STRING_AGG(service.Code, ',')
FROM dbo.DXBusinessPolicy_Policy policy
LEFT JOIN dbo.DXBusinessPolicy_PolicyService policyservice
ON policy.ID = policyservice.PolicyID
LEFT JOIN dbo.DXBusinessPolicy_Service service
ON policyservice.ServiceID = service.ID AND
service.Code = @ServiceCode
GROUP BY
policy.ID,
policy.Code,
policy.Name
END
exec FindPolicyByService "INT"
我得到的结果:
策略ID | 政策代码 | 政策名称 | 服务 |
---|---|---|---|
1 | COMBO.2103001 | [Giá nền] T9/2020 #1 | INT |
2 | IPTV-0121.002 | [Giá nền] T8/2020 #1 | NULL |
3 | INT.2103001 | Chính sách 2 | INT |
看起来service.Code = @codes
条件不起作用。
我预期的结果:
政策代码 | 政策名称 | 服务 |
---|---|---|
COMBO.2103001 | [Giá nền] T9/2020 #1 | INT,IPTV |
INT.2103001 | Chính sách 2 | INT |
我也尝试不使用service.Code = @codes
条件
策略ID | 政策代码 | 政策名称 | 服务 |
---|---|---|---|
1 | COMBO.2103001 | [Giá nền] T9/2020 #1 | INT,IPTV |
2 | IPTV-0121.002 | [Giá nền] T8/2020 #1 | 网络电视 |
3 | INT.2103001 | Chính sách 2 | INT |
这个结果接近我的预期,rest 我只想得到包含INT
的服务
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.