如何计算查询中的相关行

时间:2009-02-26 20:21:27

标签: asp.net sql sql-server

我正在尝试进行查询以获取特定公司的所有票证。 在该表中将是一个名为[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标志。在网上看到了 情况[Rpt5] = 1或[Rpt30] = 1那么'是'ELSE'否'结束为[重复],

我想要做的是用

的内容替换它
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匹配的行,并且在上个月内。

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

5 个答案:

答案 0 :(得分:1)

您希望针对同一个表运行子查询,因此您需要对表的两种用法进行别名(next和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是连续的,你可以用它们而不是日期字段做同样的事情。

答案 1 :(得分: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 :(得分:1)

对于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 :(得分:0)

尝试

SELECT(COUNT()...)&gt; 1

而不是

SELECT(COUNT()...)&gt; '1'

答案 4 :(得分:0)

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

您需要将“内部”查询(a.k.a.子查询)过滤到外部查询。这个概念通常称为correlated subquery。见罗里的解决方案。

或者,您可以将JOIN用于包含聚合数据的视图(或派生表)。通常,这是性能的最佳选择。