使用 String_AGG 来查询 SQL 中的条件?

Use String_AGG to query with condition in SQL?

我有 3 个表,关系是 Policy (N) -> PolicyService <- Service (N):

DXBusinessPolicy_Policy

ID Code Name
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 Code Name
1 INT Internet
2 IPTV IPTV

DXBusinessPolicy_PolicyService

ID PolicyID ServiceID
1 1 1
2 1 2
3 2 2
4 3 1

问题:输入服务(ServiceCode),输出为PolicyID、PolicyCode、PolicyName和该策略的服务列表(列表ServiceCode用","连接的字符串)。

例如:我的输入是:“INT”。 结果预期:

PolicyCode PolicyName Services
COMBO.2103001 [Giá nền] T9/2020 #1 INT,IPTV
INT.2103001 Chính sách 2 INT

我尝试解决这个问题如下:

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"

但是结果不是我想的那样

PolicyCode PolicyName Services
COMBO.2103001 [Giá nền] T9/2020 #1 INT
INT.2103001 Chính sách 2 INT

我终于找到了我问题的最准确答案。谢谢大家! 最好的解决方案是:

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

这一切都给了我预期的相同结果:

PolicyCode PolicyName Services
COMBO.2103001 [Giá nền] T9/2020 #1 INT,IPTV
INT.2103001 Chính sách 2 INT