【问题标题】:Use String_AGG to query with condition in SQL?使用 String_AGG 查询 SQL 中的条件?
【发布时间】:2022-01-24 05:50:16
【问题描述】:

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

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

【问题讨论】:

  • @lptr 好答案,我认为如果您使用“DISTINCT”(SELECT DISTINCT subps.PolicyID)会更好

标签: sql sql-server tsql stored-procedures string-aggregation


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2019-02-25
    • 2016-02-03
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    相关资源
    最近更新 更多