Как спроектировать T-SQL запрос для расчета суммы за один проход? - PullRequest
3 голосов
/ 22 апреля 2011

Я пытаюсь разработать запрос T-SQL, который будет выполнять следующее:

ROUND(100 * A / B, 1)

Прост в концепции, но это сложно из-за возможного знаменателя B = 0, а также из-за переменных A и B,То, что я ожидаю, это процентное значение, например, 93,2 (дано в этом формате без%).Или даже 932 будет приемлемо, так как я мог бы преобразовать его позже.

Но вместо этого я в настоящее время получаю 151, что является количеством записей.

A = CASE WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN 1 ELSE 0 END
B = CASE WHEN [Date_Completed] IS NOT NULL THEN 1 ELSE 0 END

Моя текущая логика делит A / B, только если B не равно нулю.Можете ли вы помочь мне исправить это?ps все поля выше взяты из одной и той же таблицы A.

Я пытался:

SELECT CASE WHEN t.VarB<>0 THEN ROUND(100 * t.VarA / t.VarB, 1) 
ELSE 0 /* or whatever you'd want to return in this case */ 
END 
FROM (SELECT CASE WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN 1 
ELSE 0 
END AS VarA, 
CASE WHEN [Date_Completed] IS NOT NULL THEN 1 
ELSE 0 
END AS VarB 
FROM EXCEL.Batch_Records A) t

Но я получил 33000 строк, а не одну, где каждая строка = 100 или 0.

Хорошая идея, Конрад!Я проверил ваше решение, и оно работает, если я просто хочу это одно значение.Но я не сказал вам, что есть дополнительные значения, которые мне нужно вернуть из того же запроса.Когда я попытался добавить другие вычисления значений, я получил синтаксические ошибки.Итак, вот мой текущий запрос.Как его следует переписать, пожалуйста?

select 
SUM(CASE WHEN A.DATE_RECEIVED IS NOT NULL THEN 1 ELSE 0 END) AS NUM_RECEIVED,
SUM(CASE WHEN [Date_Completed] IS NOT NULL THEN 1 ELSE 0 END) AS NUM_COMPLETE_OF_OPENED,
SUM(CASE WHEN A.DATE_COMPLETED IS NOT NULL THEN 1 ELSE 0 END) AS NUM_COMPLETED_IN_MONTH,
SUM(CASE WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN 1 ELSE 0 END) AS NUM_WITHOUT_ERROR,

round(100 * a/b , 1) 
from 
(select 
    sum(CASE  
        WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN  
            1.0  
        ELSE 0.0 END) A, 
    sum(CASE WHEN [Date_Completed] IS NOT NULL THEN 

1.0 ELSE 0.0 END) B 

FROM EXCEL.Batch_Records a 
LEFT JOIN EXCEL.QC_CODES d ON a.Part_Number = d.CODE_ID    
WHERE (a.[Group] = @GROUP or @GROUP = '' OR @GROUP IS NULL) AND A.Date_Received >= @STARTDATE AND A.Date_Received <= @ENDDATE

Конрад правильно посоветовал мне, что # TEMP1 - пустая таблица.Но теперь я заполнил его и успешно разработал этот запрос с его помощью:

SET @STARTDATE = '1/1/11'
SET @ENDDATE = '1/31/11'
SET @GROUP = 'INTERMEDIATES_FISH'
--SET @TABLE_TITLE = 'BATCH RECORD SUCCESS RATE'
--SET @DEPT = 'QC'     

IF EXISTS(SELECT * FROM TEMPDB.INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '#TEMP1%')
DROP TABLE #TEMP1

--CREATE TABLE #TEMP1 (     MFG int ,      MFG2 int ,     QC int,      QC2 INT ,      [Group] NVARCHAR(MAX),     [Date_Completed] datetime,     Date_Received datetime)
SELECT
MFG, MFG2, QC, QC2, [GROUP], [DATE_COMPLETED], [DATE_RECEIVED]
INTO #TEMP1
FROM EXCEL.Batch_Records a 
WHERE (a.[Group] = @GROUP or @GROUP = '' OR @GROUP IS NULL) AND A.Date_Received >= @STARTDATE AND A.Date_Received <= @ENDDATE

------------------------------------------  
;WITH CTE AS 
( 
SELECT 
CASE 
WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN 
1.0 
ELSE 0.0 END A, 
CASE WHEN [Date_Completed] IS NOT NULL THEN 1.0 ELSE 0.0 END B, 
CASE WHEN A.Date_Received IS NOT NULL THEN 1 ELSE 0 END NUM_RECEIVED, 
CASE WHEN [Date_Completed] IS NOT NULL THEN 1 ELSE 0 END NUM_COMPLETE_OF_OPENED, 
CASE WHEN A.DATE_COMPLETED IS NOT NULL THEN 1 ELSE 0 END NUM_COMPLETED_IN_MONTH, 
CASE WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN 1 ELSE 0 END AS NUM_WITHOUT_ERROR 
FROM 
#TEMP1 a 
--WHERE (a.[Group] = @GROUP or @GROUP = '' OR @GROUP IS NULL) AND A.Date_Received >= @STARTDATE AND A.Date_Received <= @ENDDATE
) 

select 
round(100 * SUM(A)/SUM(b) , 1) , 
SUM(NUM_RECEIVED) NUM_RECEIVED, 
SUM(NUM_COMPLETE_OF_OPENED) NUM_COMPLETE_OF_OPENED, 
SUM(NUM_COMPLETED_IN_MONTH) NUM_COMPLETED_IN_MONTH, 
SUM(NUM_WITHOUT_ERROR) NUM_WITHOUT_ERROR 


FROM CTE 

1 Ответ

1 голос
/ 22 апреля 2011

В основном вам нужно использовать SUM (), чтобы получить сумму.Вы также должны использовать 1,0 и 0,0, чтобы получить десятичные значения.

Вы также должны сделать СУММУ до деления

ОБНОВЛЕНИЕ Поскольку вы добавляете числоSUM(CASE операторы, вероятно, более читабельно перемещают статистику CASE в CTE.

CREATE TABLE #Batch_Records (
    MFG int , 
    MFG2 int ,
    QC int, 
    QC2 INT , 
    [Group] int,
    [Date_Completed] datetime,
    Date_Received datetime)




INSERT INTO #Batch_Records (MFG ,   MFG2 ,  QC ,    QC2  ,  [Group] ,   [Date_Completed] ,  Date_Received )
VALUES (1,null,null,null,1,'1/4/2011','2/4/2011'),
       (null,null,null,null,1,'2/2/2011','3/4/2011'),
       (1,null,null,null,1,'3/6/2011','4/3/2011'),
       (null,null,null,null,1,NULL,'5/4/2011'),
       (1,null,null,null,1,'5/4/2011','6/6/2011'),
       (1,null,null,null,1,NULL,'7/4/2011')


DECLARE @GROUP int
DECLARE @STARTDATE DateTime
DECLARE @ENDDATE DateTime

SET @GROUP = 1
SET @STARTDATE = '1/1/2001'
SET @ENDDATE = '1/1/2012'

;WITH CTE AS
(
    SELECT
        CASE  
            WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN  
                1.0  
            ELSE 0.0 END A, 
        CASE WHEN [Date_Completed] IS NOT NULL THEN 
        1.0 ELSE 0.0 END B,
        CASE WHEN A.Date_Received IS NOT NULL THEN 1 ELSE 0 END  NUM_RECEIVED,
        CASE WHEN [Date_Completed] IS NOT NULL THEN 1 ELSE 0 END  NUM_COMPLETE_OF_OPENED,   
        CASE WHEN A.DATE_COMPLETED IS NOT NULL THEN 1 ELSE 0 END  NUM_COMPLETED_IN_MONTH,
        CASE WHEN A.MFG IS NULL AND A.MFG2 IS NULL AND A.QC IS NULL AND A.QC2 IS NULL THEN 1 ELSE 0 END AS NUM_WITHOUT_ERROR
    FROM 
        #Batch_Records a 
    WHERE 
        (a.[Group] = @GROUP or @GROUP = '' OR @GROUP IS NULL) 
        AND A.Date_Received >= @STARTDATE AND A.Date_Received <= @ENDDATE
)

select 
    round(100 * SUM(A)/SUM(b) , 1) ,
    SUM(NUM_RECEIVED) NUM_RECEIVED,
    SUM(NUM_COMPLETE_OF_OPENED) NUM_COMPLETE_OF_OPENED,
    SUM(NUM_COMPLETED_IN_MONTH) NUM_COMPLETED_IN_MONTH,
    SUM(NUM_WITHOUT_ERROR) NUM_WITHOUT_ERROR


 FROM CTE

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