Как вы подсчитываете связанные строки в запросе - PullRequest
0 голосов
/ 26 февраля 2009

Я пытаюсь сделать запрос, который извлекает все Билеты для определенной компании. В этой таблице будет столбец с именем [Repeat]

Мне нужен запрос, чтобы проверить, есть ли другие строки с соответствующим Circuit_ID в течение последних 30 дней этого билета.

"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, затем «Да», иначе «Нет», завершается как [повтор],

Что я хочу сделать, это заменить это чем-то вроде

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],

Это не работает .. По сути, он считает все строки, а не только те строки, которые соответствуют текущему идентификатору цепочки строк и попадают в последний месяц.

Я не знаю, как правильно это кодировать, чтобы заставить его работать. или даже если это возможно в запросе.

Ответы [ 5 ]

1 голос
/ 26 февраля 2009

Для минимального изменения вашего SQL измените свой подзапрос следующим образом:

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

Вы должны как-то ссылаться на внешнюю таблицу, вы не можете просто сравнить XX_CIRCUIT_ID и XX_CIRCUIT_ID на равенство - это сравнение всегда будет верным. ; -)

Вместо этого вы должны сравнить внешний XX_CIRCUIT_ID, обозначенный [SNA_Ticket_Detail].[XX_CIRCUIT_ID], с внутренним XX_CIRCUIT_ID, обозначенный i.XX_CIRCUIT_ID для ясности.

1 голос
/ 26 февраля 2009

Если вы используете псевдоним 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)

1 голос
/ 26 февраля 2009

Вы хотите запустить подзапрос для одной и той же таблицы, поэтому вам необходимо связать псевдонимы двух использований таблицы (последние и т. Д. Ниже). При поиске интересующих строк, в данном случае с одинаковым идентификатором канала в пределах определенного диапазона, необходимо убедиться, что вы не смотрите на одну и ту же строку. Отсюда проверка на [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)

Вы должны проверить, выполняет ли датировка то, что вы хотите - просто поиграйте с некоторыми тестовыми данными. Также вы, вероятно, хотите убедиться, что «недавняя» строка на самом деле не после полученной, поэтому я добавил:

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

Хотя, если вы знаете, что ваши идентификаторы билетов являются последовательными, вы можете сделать то же самое с ними вместо поля даты.

0 голосов
/ 26 февраля 2009

Это один грязный запрос ...

Вам нужно будет отфильтровать ваш «внутренний» запрос (a.k.a. подзапрос) к внешнему запросу. Эта концепция обычно называется коррелированным подзапросом . Смотрите решение Рори.

Или вы можете использовать JOIN для представления (или производной таблицы), которое содержит агрегированные данные. Как правило, это лучший выбор для производительности.

0 голосов
/ 26 февраля 2009

попробуй

SELECT (COUNT () ...)> 1

вместо

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...