Поиск процента по подзапросу с разными предложениями where - PullRequest
0 голосов
/ 25 мая 2019

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

SELECT (        
CAST((SELECT COUNT(WO.[WORK_ORDER_ID]) 
FROM [NCH].[nch].[WORK_ORDER] WO JOIN [NCH].[nch].[TASK] T ON WO.[TASK_ID] = T.[TASK_ID] 
WHERE WO.[LOT_ID] = 501 AND WO.[DRY_RUN_FLAG] != 1 
AND WO.[COMPLETED_DATE] IS NOT NULL AND T.[TASK_TYPE_ID] = 2) AS float) 
/ 
(CAST((SELECT COUNT(WO.[WORK_ORDER_ID]) 
FROM [NCH].[nch].[WORK_ORDER] WO JOIN [NCH].[nch].[TASK] T ON WO.[TASK_ID] = T.[TASK_ID] 
WHERE WO.[LOT_ID] = 501 AND T.[TASK_TYPE_ID] = 2) as Float))
) * 100 AS PERCENT_ROUGH_COMPLETED

В частности, моя проблема заключается в том,в пункте, где.Я повторяю точно такой же запрос за исключением условий где.Может ли это быть достигнуто с помощью JOIN на одном столе?Многочисленные объединения сбивают меня с толку, и SQL - один из моих самых слабых навыков.Я чувствую, что этот запрос может быть ужесточен, потому что мне придется повторить его в гораздо большем запросе.

EDIT

Используя CASE, я смог правильно настроить больший запрос SQL,Я никогда раньше не писал такой комплексный запрос, поэтому простите, если он выглядит слишком сложным:

 SELECT L.[LOT_ID]
 ,L.[LOT_NUMBER]
 ,L.[JOBSITE_ID]
 ,L.[PHASE_ID]
 ,L.[MODEL_ID]
 ,M.[SQUARE_FOOTAGE]
 ,M.[MODEL_NAME]
 ,P.[PHASE_NAME]

 -- Case 1
 ,CASE 
    WHEN P.[ROUGH_SCHEDULE_FLAG] != 0 
  THEN 
(SELECT (SELECT AVG(CASE WHEN WO.[DRY_RUN_FLAG] <> 1 AND WO.[COMPLETED_DATE] IS NOT NULL THEN 1.0 ELSE 0 END)
FROM [NCH].[nch].[WORK_ORDER] WO 
JOIN [NCH].[nch].[TASK] T ON WO.[TASK_ID] = T.[TASK_ID] 
WHERE WO.[LOT_ID] = L.[LOT_ID] AND T.[TASK_TYPE_ID] = 1) * 100)
  ELSE 0 
  END AS ROUGH_PERCENT_COMPLETED,

  -- Case 2
  CASE 
    WHEN P.[INTERIOR_SCHEDULE_FLAG] != 0 
  THEN 
(SELECT (SELECT AVG(CASE WHEN WO.[DRY_RUN_FLAG] <> 1 AND WO.[COMPLETED_DATE] IS NOT NULL THEN 1.0 ELSE 0 END)
FROM [NCH].[nch].[WORK_ORDER] WO 
JOIN [NCH].[nch].[TASK] T ON WO.[TASK_ID] = T.[TASK_ID] 
WHERE WO.[LOT_ID] = L.[LOT_ID] AND T.[TASK_TYPE_ID] = 2) * 100)
  ELSE 0 
  END AS INTERIOR_PERCENT_COMPLETED,

  -- Case 3
  CASE 
    WHEN P.[WASH_SCHEDULE_FLAG] != 0 
  THEN 
(SELECT (SELECT AVG(CASE WHEN WO.[DRY_RUN_FLAG] <> 1 AND WO.[COMPLETED_DATE] IS NOT NULL THEN 1.0 ELSE 0 END)
FROM [NCH].[nch].[WORK_ORDER] WO 
JOIN [NCH].[nch].[TASK] T ON WO.[TASK_ID] = T.[TASK_ID] 
WHERE WO.[LOT_ID] = L.[LOT_ID] AND T.[TASK_TYPE_ID] = 3) * 100)
  ELSE 0 
  END AS WASH_PERCENT_COMPLETED  

 FROM [NCH].[nch].[LOT] L
 JOIN [NCH].[nch].[MODEL] M ON L.[MODEL_ID] = M.[MODEL_ID]
 JOIN [NCH].[nch].[PHASE] P ON L.[PHASE_ID] = P.[PHASE_ID]

ГДЕ L. [JOBSITE_ID] = 1502

result set

Ответы [ 2 ]

2 голосов
/ 26 мая 2019

Я бы упростил это до:

select avg(case when wo.dry_run_flalg <> 1 and
                     wo.completed_date is not null
                then 1.0 else 0
           end) as ratio
from [NCH].[nch].[WORK_ORDER] wo join
     [NCH].[nch].[TASK] t
     on wo.[TASK_ID] = t.[TASK_ID] 
where wo.lot_id = 501 and
      wo.work_order_id is not null and
      t.task_type_id = 2
1 голос
/ 25 мая 2019

Вы можете сделать это, используя CASE.На мой взгляд, лучше использовать числовой (десятичный) вместо float.float - приблизительный тип данных, который может привести к неверным результатам.Вы можете прочитать больше об этом здесь .

WITH calculations as
(
    SELECT
        CASE 
            WHEN WO.[LOT_ID] = 501 
            AND WO.[DRY_RUN_FLAG] != 1 
            AND WO.[COMPLETED_DATE] IS NOT NULL 
            AND T.[TASK_TYPE_ID] = 2 
            AND WO.[WORK_ORDER_ID] IS NOT NULL THEN 1 --the last condition is to simulate COUNT(WO.[WORK_ORDER_ID])
        ELSE 0
        END AS part1
       ,CASE
            WHEN WO.[LOT_ID] = 501 
            AND T.[TASK_TYPE_ID] = 2
            AND WO.[WORK_ORDER_ID] IS NOT NULL THEN 1 --the last condition is to simulate COUNT(WO.[WORK_ORDER_ID])
        ELSE 0
        END AS part2
    FROM [NCH].[nch].[WORK_ORDER] WO 
    JOIN [NCH].[nch].[TASK] T 
        ON WO.[TASK_ID] = T.[TASK_ID] 
)
SELECT
    (cast(sum(part1) as numeric(18,6)) / cast(sum(part2) as numeric(18,6))) * 100 as calculation
from calculations
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...