繁体   English   中英

在SQL中使用String_AGG条件查询?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM