【问题标题】:How to run a loop SQL with multiple children tables如何使用多个子表运行循环 SQL
【发布时间】:2020-10-29 15:19:53
【问题描述】:

我很难提出一个查询,该查询为我提供了从多个表中创建报告所需的信息。我正在尝试按属性获取列表,其中包含已配置的规则(属性、规则集、Ruleitem)并查看它们被应用了多少次(Propertyrule、Employeeset、Employeerule)

例如,如果我有:

          Table A (property), 
          Table B(Ruleset), 
          Table C(RuleItem), 
          Table D(Propertyrule)
          Table E(Employeeset)
          Table F(Employeerule). 

我希望查询从表 A 的第一行中选择 ID,然后根据从表 A 中提取的 ID 从表 B 中选择第一行,然后从表 B 的第一行中选择 ID,然后全选来自表 C 的返回值与表 B 中的相同 id。现在我想计算表 B(规则集)在表 D、E 和 F 各自单独列中出现的行数。

一旦为 C 列中的每一行运行,它就会返回到 B 列并再次循环。这将重复,直到表 A 中的每一行都完成为止。

这是我所拥有的,这似乎与我需要的相去甚远:

DECLARE @propid INT

DECLARE c1 CURSOR
FOR
SELECT ID
FROM property --This is the property to copy interfaces into

OPEN c1

FETCH NEXT
FROM c1
INTO @propid

WHILE @@fetch_status = 0
BEGIN
    SELECT @propid
        ,p.name
        ,rs.propertyid
        ,rs.name
        ,rs.ruletypecode
        ,ri.ruleclasscode
        ,ri.name
        ,esr.EmployeeSetID
        ,pr.rulesetid AS propertyrule
        ,(
            SELECT count(rulesetid)
            FROM employeerule
            )
    FROM ruleset rs
    JOIN ruleitem ri ON ri.RuleSetID = rs.id
    JOIN property p ON p.id = rs.PropertyID
    LEFT JOIN employeesetrule esr ON esr.rulesetid = rs.id
    LEFT JOIN propertyrule pr ON pr.RuleSetID = rs.id
    LEFT JOIN employeerule er ON er.RuleSetID = rs.id
    WHERE rs.id IN (
            SELECT rulesetid
            FROM employeesetrule
            )
        OR rs.id IN (
            SELECT rulesetid
            FROM propertyrule
            )
        OR rs.id IN (
            SELECT rulesetid
            FROM employeerule
            )

    FETCH NEXT
    FROM c1
    INTO @propid
END

CLOSE c1

DEALLOCATE c1

Example of what I want

【问题讨论】:

  • 不管问题的目标是什么,我强烈不建议您在此查询中使用游标,因为它会使获取此报告的速度非常慢。请提供输入数据示例,以便在您遇到复杂问题时更容易为您提供帮助。最后一件事,您可以在查询中使用标量函数吗?
  • 我并不完全认为此解决方案需要循环。此外,您不使用循环变量@propid 来过滤查询,仅作为SELECT 中的标量。所有相关表格中的示例数据可以帮助我们制定解决方案。

标签: sql-server loops tsql join


【解决方案1】:

不完全确定游标循环的需求,但假设property 表包含唯一的属性列表(即p.id),请考虑在聚合查询中加入单个查询以获取其他表中的计数。评论表明每个需求都可能得到满足(有细微变化的上限):

SELECT p.id,                          -- select EACH ID from Table A
       , p.name
       , rs.propertyid
       , rs.name AS ruleset_name
       , rs.ruletypecode
       , ri.ruleclasscode             -- select all the returns from table C
       , ri.name AS ruleitem_name
       , es_agg.employeeset_count     -- count how many rows the table B (Ruleset) appears in tables D in separate column
       , pr_agg.propertrule_count     -- count how many rows the table B (Ruleset) appears in tables E in separate column
       , er_agg.employeerule_count    -- count how many rows the table B (Ruleset) appears in tables F in separate column

FROM property p 
INNER JOIN ruleset rs
       ON p.id = rs.PropertyID        -- select EACH row from table B based on the ID pulled from table A
INNER JOIN ruleitem ri 
       ON ri.RuleSetID = rs.id         
INNER JOIN 
    (SELECT rulesetid, COUNT(*) AS employeeset_count  
     FROM employeesetrule
     GROUP BY rulesetid) es_agg
       ON rs.id = es_agg.rulesetid
INNER JOIN 
    (SELECT rulesetid, COUNT(*) AS propertrule_count
     FROM propertyrule
     GROUP BY rulesetid) pr_agg
       ON rs.id = pr_agg.rulesetid
INNER JOIN 
    (SELECT rulesetid, COUNT(*) AS employeerule_count
     FROM employeerule
     GROUP BY rulesetid) er_agg
       ON rs.id = er_agg.rulesetid

【讨论】:

    猜你喜欢
    • 2021-02-18
    • 2016-09-18
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 2017-11-09
    • 1970-01-01
    相关资源
    最近更新 更多