【发布时间】:2011-04-22 19:09:28
【问题描述】:
我正在尝试开发一个 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
如果 B 不等于 0,我当前的逻辑只会将 A/B 相除。你能帮我解决这个问题吗? p.s.以上所有字段均来自同一个表 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。
好主意,康拉德!我测试了您的解决方案,如果我只想要一个值,它就可以工作。但我没有告诉你的是,我需要从同一个查询中返回其他值。当我尝试添加其他值计算时,出现语法错误。所以这是我当前的查询。请问htis应该怎么改写?
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
【问题讨论】:
-
您可以添加表架构吗?如果 t.VarA 和 t.VarB 的数据类型为 INT,它将返回 INT(从不给你小数)。问题:您是要汇总并仅返回 1 行,还是应该对每一行执行百分比计算?
-
好吧,你有两个 From 子句,所以看起来不太好......试试这个从 Batch_Records 和 QC_CODES 中放入几行数据。然后把它写成你的输出应该是什么样子。
-
总共只有 1 行(总结)。 MFG、MFG2、QC、QC2、Group 都是数据库中的 NVARCHAR(MAX)。 Date_completed 是日期时间。这能回答你的问题吗?
-
@Conrad,我刚刚从您下面的答案中复制了两个 FROM 语句。我误会你了吗?而且我不确定你对几行数据的意思。你的意思是你想看看这些值是什么样的,还是我需要填充数据?
-
@salvationishere 如果你看看这个question。 Eric H. 提供脚本来创建临时表并插入测试数据。然后他还包括预期的输出。这使人们更容易提供帮助。
标签: tsql