ОБЪЕДИНЕНИЕ в КОЛИЧЕСТВЕ хранимых процедур

#stored-procedures

#хранимые процедуры

Вопрос:

Я создаю хранимую процедуру, которая будет возвращать результаты открытых обращений на основе введенного времени — я хочу вернуть количество обращений, но на основе разных офисов. После редактирования моего кода я также переформулирую свой вопрос по-другому — каким способом лучше всего возвращать подсчет вместо фактических результатов, которые я получаю сейчас.

Ниже приведена моя хранимая процедура:

 SELECT C.CaseId
FROM [Case] C
WHERE C.DateCreated <= @BeginDate
    AND C.CaseId NOT IN (SELECT CaseId FROM CaseStatusChange CSC WHERE CSC.DateClosed < @BeginDate)

UNION

-- Also need the cases that reopened and are currently open
SELECT ReOpened.CaseId FROM
(
                SELECT C.CaseId, MAX(CSC.DateReopened) AS DateReOpened 
                FROM [Case] C 
                INNER JOIN [CaseStatusChange] CSC ON C.CaseId = CSC.CaseId
                WHERE CSC.DateReopened <= @BeginDate
                GROUP BY C.CaseId
) ReOpened 
WHERE ReOpened.CaseId NOT IN 
(
                SELECT CaseId FROM CaseStatusChange 
                WHERE CaseId = ReOpened.CaseId AND 
                CaseStatusChange.DateClosed BETWEEN ReOpened.DateReopened AND @BeginDate
)
  

Ответ №1:

Это означает, что количество столбцов в SELECT списках должно совпадать. И их типы данных тоже.

Вот так:

 select
   col1, col2, col3
from
   t1
union
select
   col1, col2, col3
from
   t2
  

В вашем конкретном случае вам необходимо добавить идентификатор OfficeId и количество во второй SELECT список.

Комментарии:

1. Да, в примере операционной системы, похоже, выбираются два варианта: ВЫБЕРИТЕ C.CaseID, O.OfficeId и ВЫБЕРИТЕ Повторно открыто. CaseID, которые имеют разное количество аргументов.

2. Во вложенном выборе также есть скрытый COUNT().

3. Я отредактировал свой код и начал по-другому, надеюсь, это приведет к потере некоторых узлов

Ответ №2:

Обновление: Включить OfficeId в соответствии с запросом:

 SELECT  OfficeId, SUM(CaseCount)
FROM    (
            SELECT  COUNT(C.CaseId) AS CaseCount,
                    C.OfficeId
            FROM    [Case] C
            WHERE   C.DateCreated <= @BeginDate
                AND C.CaseId NOT IN (SELECT CaseId FROM CaseStatusChange CSC WHERE CSC.DateClosed < @BeginDate)
            GROUP BY C.OfficeId

            UNION ALL

            -- Also need the cases that reopened and are currently open
            SELECT  COUNT(ReOpened.CaseId) As CaseCount,
                    ReOpened.OfficeID
            FROM
                (
                    SELECT C.CaseId, MAX(CSC.DateReopened) AS DateReOpened, C.OfficeId 
                    FROM [Case] C 
                    INNER JOIN [CaseStatusChange] CSC ON C.CaseId = CSC.CaseId
                    WHERE CSC.DateReopened <= @BeginDate
                    GROUP BY C.CaseId, C.OfficeID
                ) ReOpened 
            WHERE ReOpened.CaseId NOT IN 
                    (
                        SELECT CaseId FROM CaseStatusChange 
                        WHERE CaseId = ReOpened.CaseId AND 
                        CaseStatusChange.DateClosed BETWEEN ReOpened.DateReopened AND @BeginDate
                    )
            GROUP BY OfficeID
        ) AS OpenCasesCount
GROUP BY OfficeId
  

Вам нужно обернуть весь ваш запрос во внутренний запрос, как показано ниже:

 SELECT  SUM(CaseCount)
FROM    (
            SELECT  COUNT(C.CaseId) AS CaseCount
            FROM    [Case] C
            WHERE   C.DateCreated <= @BeginDate
                AND C.CaseId NOT IN (SELECT CaseId FROM CaseStatusChange CSC WHERE CSC.DateClosed < @BeginDate)

            UNION ALL

            -- Also need the cases that reopened and are currently open
            SELECT  COUNT(ReOpened.CaseId) As CaseCount 
            FROM
                (
                    SELECT C.CaseId, MAX(CSC.DateReopened) AS DateReOpened 
                    FROM [Case] C 
                    INNER JOIN [CaseStatusChange] CSC ON C.CaseId = CSC.CaseId
                    WHERE CSC.DateReopened <= @BeginDate
                    GROUP BY C.CaseId
                ) ReOpened 
            WHERE ReOpened.CaseId NOT IN 
                    (
                        SELECT CaseId FROM CaseStatusChange 
                        WHERE CaseId = ReOpened.CaseId AND 
                        CaseStatusChange.DateClosed BETWEEN ReOpened.DateReopened AND @BeginDate
                    )
        ) AS OpenCasesCount
  

Комментарии:

1. Спасибо! И снова ты лучший.

2. Мне жаль, я знаю, что я заноза, но я хотел также добавить параметр для OfficeId, чтобы я мог узнать, сколько открытых обращений имеется для каждого офиса. Добавил бы я их во внутренние инструкции select?

3. в этом случае вам нужно использовать GROUP BY, например, ВЫБРАТЬ COUNT(C.CaseID) В КАЧЕСТВЕ CaseCount, OfficeId … ГРУППИРУЙТЕ ПО идентификатору OfficeId .. таким образом, вашими результатами будут пары OfficeId и Count.

4. является ли OfficeId столбцом в вашей таблице «Case»? или для его получения вам нужно объединение?

5. Это выглядит великолепно, но когда я пытаюсь выполнить процедуру, я получаю, что она снова открыта. OfficeId недопустим и не содержится ни в агрегатной функции, ни в предложении Group By. Я переделаю то, что у меня есть, и посмотрю, что я мог бы также сделать. Спасибо!