【问题标题】:How do you count the related rows within a query如何计算查询中的相关行
【发布时间】:2009-02-26 20:21:27
【问题描述】:

我正在尝试进行查询,以提取特定公司的所有门票。 在该表中将有一个名为 [Repeat] 的列

我需要查询做的是检查在该票证的最后 30 天内是否有任何其他行具有匹配的 Circuit_ID。

"SELECT [MAIN_TICKET_ID], [CompID], [ActMTTR], [ActOTR], [DtCr], [DtRFC],
                CASE WHEN [PRIORITY] = 1 THEN '1' 
                     WHEN [PRIORITY] = 2 THEN '2' 
                     WHEN [PRIORITY] = 3 THEN '3' END AS [PRIORITY],
                CASE WHEN ([PRIORITY] = '1' AND [ActMTTR] >= '4' AND ([ResCd7] = 'Equipment (XX)' OR [ResCd7] = 'Lec Facilities (LEC)')) 
                       OR ([PRIORITY] = '1' AND [ActOTR] >= '14' AND ([ResCd7] = 'Equipment (XX)' OR [ResCd7] = 'Lec Facilities (LEC)')) 
                       OR ([PRIORITY] = '2' AND [ActMTTR] >= '6' AND ([ResCd7] = 'Equipment (XX)' OR [ResCd7] = 'Lec Facilities (LEC)')) 
                       OR ([PRIORITY] = '2' AND [ActOTR] >= '16' AND ([ResCd7] = 'Equipment (XX)' OR [ResCd7] = 'Lec Facilities (LEC)')) 
                       OR (([Rpt5] = '1' OR [Rpt30] = '1' OR [Chronic] = '1') AND ([ResCd7] = 'Equipment (XX)' OR [ResCd7] = 'Lec Facilities (LEC)')) THEN 'Yes' ELSE 'No' END AS [Measured],  
                CASE WHEN [Reviewed] = 1 THEN 'Yes' ELSE 'No' END AS [Reviewed],
                CASE WHEN [Rpt5] = 1 OR [Rpt30] = 1 THEN 'Yes' ELSE 'No' End As [Repeat],
                CASE WHEN [Chronic] = 1 THEN 'Yes' ELSE 'No' END AS [Chronic],
                CASE WHEN [ResCd7] = 'Equipment (XX)' THEN 'XX' 
                     WHEN [ResCd7] = 'Isolated to Customer (ITC)' THEN 'ITC' 
                     WHEN [ResCd7] = 'Information (INF)' THEN 'INF' 
                     WHEN [ResCd7] = 'Test OK (TOK)' THEN 'TOK' 
                     WHEN [ResCd7] = 'Lec Facilities (LEC)' THEN 'LEC' 
                     WHEN [ResCD7] = 'Dispatched No Trouble Found (NTF)' THEN 'NTF' 
                     WHEN [ResCD7] = 'Cleared While Testing (CWT)' THEN 'CWT' END AS [Resolution]
                FROM [SNA_Ticket_Detail] WHERE ([CompID] = @CompID)"

上面是当前查询,它依赖于表中的 0 或 1 标志。网上看到的 CASE WHEN [Rpt5] = 1 OR [Rpt30] = 1 THEN 'Yes' ELSE 'No' End As [Repeat],

我想要做的是用类似的东西替换它

CASE WHEN (SELECT COUNT([XX_CIRCUIT_ID]) FROM SNA_Ticket_Detail WHERE (CONVERT(CHAR(10), [DtRFC], 101) BETWEEN ([DtRFC] - 6) AND ([DtRFC])) AND (XX_CIRCUIT_ID = XX_CIRCUIT_ID)) > '1' THEN 'Yes' ELSE 'No' End As [Repeat],

这不起作用..它基本上计算所有行,而不仅仅是与当前行电路 id 匹配且属于上个月的行。

我不知道如何正确编码以使其正常工作。或者即使在查询中也是可能的。

【问题讨论】:

标签: asp.net sql sql-server


【解决方案1】:

如果您在外部查询中为 SNA_Ticket_Detail(例如 SNA_Ticket_Detail SNA)起别名,您可以在子查询中引用它

为简单起见,在子查询中还别名 SNA_Tick_Detail (SNA_Ticket_Detail SNA_sub)

然后,您当前的 (XX_CIRCUIT_ID = XX_CIRCUIT_ID) 将更改为 (SNA_sub.XX_CIRCUIT_ID = SNA.XX_CIRCUIT_ID)

【讨论】:

    【解决方案2】:

    为了对您的 SQL 进行最小的更改,请像这样更改您的子查询:

    SELECT ... FROM SNA_Ticket_Detail AS i WHERE ... AND i.XX_CIRCUIT_ID = [SNA_Ticket_Detail].[XX_CIRCUIT_ID]
    

    您必须以某种方式引用外部表,您不能只比较 XX_CIRCUIT_IDXX_CIRCUIT_ID 是否相等 - 这样比较总是正确的。 ;-)

    为了清楚起见,您必须将外部XX_CIRCUIT_ID(称为[SNA_Ticket_Detail].[XX_CIRCUIT_ID])与内部XX_CIRCUIT_ID(称为i.XX_CIRCUIT_ID)进行比较。

    【讨论】:

      【解决方案3】:

      您想对同一个表运行子查询,因此您需要为该表的两种用途(最近和下面的 td)设置别名。在查找感兴趣的行时,在这种情况下,具有相同电路 ID 且在一定范围内的行,您需要确保您查看的不是完全相同的行。因此检查 [MAIN_TICKET_ID]。你可以按照你的例子做一个 COUNT ,或者你可以做一个 EXISTS() 如下。

      SELECT [MAIN_TICKET_ID], [CompID], [ActMTTR], [ActOTR], [DtCr], [DtRFC],
                      CASE WHEN [PRIORITY] = 1 THEN '1' 
                           WHEN [PRIORITY] = 2 THEN '2' 
                           WHEN [PRIORITY] = 3 THEN '3' END AS [PRIORITY],
                      CASE WHEN ([PRIORITY] = '1' AND [ActMTTR] >= '4' AND ([ResCd7] = 'Equipment (XX)' OR [ResCd7] = 'Lec Facilities (LEC)')) 
                             OR ([PRIORITY] = '1' AND [ActOTR] >= '14' AND ([ResCd7] = 'Equipment (XX)' OR [ResCd7] = 'Lec Facilities (LEC)')) 
                             OR ([PRIORITY] = '2' AND [ActMTTR] >= '6' AND ([ResCd7] = 'Equipment (XX)' OR [ResCd7] = 'Lec Facilities (LEC)')) 
                             OR ([PRIORITY] = '2' AND [ActOTR] >= '16' AND ([ResCd7] = 'Equipment (XX)' OR [ResCd7] = 'Lec Facilities (LEC)')) 
                             OR (([Rpt5] = '1' OR [Rpt30] = '1' OR [Chronic] = '1') AND ([ResCd7] = 'Equipment (XX)' OR [ResCd7] = 'Lec Facilities (LEC)')) THEN 'Yes' ELSE 'No' END AS [Measured],  
                      CASE WHEN [Reviewed] = 1 THEN 'Yes' ELSE 'No' END AS [Reviewed],
                      CASE WHEN EXISTS ( select * from SNA_Ticket_Detail recent 
                             where recent.XX_CIRCUIT_ID = td.XX_CIRCUIT_ID
                             AND recent.[MAIN_TICKET_ID] <> td.[MAIN_TICKET_ID]
                             AND datediff( month, recent.[DtRFC], td.[DtRFC] ) < 1 
                            AND recent.[DtRFC] < td.[DtRFC]) 
                  THEN 'Yes' ELSE 'No' End As [Repeat],
                      CASE WHEN [Chronic] = 1 THEN 'Yes' ELSE 'No' END AS [Chronic],
                      CASE WHEN [ResCd7] = 'Equipment (XX)' THEN 'XX' 
                           WHEN [ResCd7] = 'Isolated to Customer (ITC)' THEN 'ITC' 
                           WHEN [ResCd7] = 'Information (INF)' THEN 'INF' 
                           WHEN [ResCd7] = 'Test OK (TOK)' THEN 'TOK' 
                           WHEN [ResCd7] = 'Lec Facilities (LEC)' THEN 'LEC' 
                           WHEN [ResCD7] = 'Dispatched No Trouble Found (NTF)' THEN 'NTF' 
                           WHEN [ResCD7] = 'Cleared While Testing (CWT)' THEN 'CWT' END AS [Resolution]
                      FROM [SNA_Ticket_Detail] td WHERE ([CompID] = @CompID)
      

      您应该检查 datediff 是否符合您的要求 - 只需使用一些测试数据即可。此外,您可能希望确保“最近”行实际上不在被检索的行之后,所以我添加了:

      AND recent.[DtRFC] < td.[DtRFC]
      

      虽然如果您知道您的票证 ID 是连续的,您可以用它们而不是日期字段来做同样的事情。

      【讨论】:

        【解决方案4】:

        试试

        SELECT(COUNT()...) > 1

        而不是

        SELECT(COUNT()...) > '1'

        【讨论】:

          【解决方案5】:

          这是一个混乱的查询...

          您需要将“内部”查询(也称为子查询)过滤到外部查询。该概念通常称为correlated subquery。请参阅 Rory 的解决方案。

          或者,您可以对包含聚合数据的视图(或派生表)使用 JOIN。一般来说,这是性能的最佳选择。

          【讨论】:

            猜你喜欢
            • 2019-05-29
            • 2011-04-18
            • 1970-01-01
            • 2011-10-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-08-21
            • 1970-01-01
            相关资源
            最近更新 更多