我的查询如下:
SELECT dbo.tablename.part_number,
DATEPART(year, dbo.tablename_test.test_date_time) as year,
DATEPART(month, dbo.tablename_test.test_date_time) as month,
COUNT(dbo.tablename_test.overall_pass) AS Count,
dbo.tablename_test.overall_pass
FROM dbo.tablename_test
INNER JOIN dbo.tablename
ON dbo.tablename_test.tablename_id = dbo.tablename.tablename_id
WHERE dbo.tablename_test.test_date_time BETWEEN '2003-01-01' AND '2013-06-01'
AND (dbo.tablename_test.resolution_code IS NULL
OR dbo.tablename_test.resolution_code = 'None')
AND dbo.tablename_test.operator IN ('Arlene Haselhorst','Trang Luong','Elena Viloria')
GROUP BY DATEPART(year, dbo.tablename_test.test_date_time),
DATEPART(month, dbo.tablename_test.test_date_time),
dbo.tablename.part_number,
dbo.tablename_test.overall_pass
ORDER BY DATEPART(year, dbo.tablename_test.test_date_time),
dbo.tablename.part_number,
dbo.tablename_test.overall_pass
此查询的输出为:
# part_number year month count overall_pass
#1 700-0376 2003 8 2 0
#2 700-0376 2003 11 1 0
#3 700-0376 2003 8 59 1
#4 700-0376 2003 10 34 1
#5 700-0376 2003 11 63 1
#6 700-0376 2004 2 12 0
#7 700-0376 2004 3 3 0
#8 700-0376 2004 5 13 0
#9 700-0376 2004 7 5 0
#10 700-0376 2004 11 3 0
#11 700-0376 2004 2 139 1
#12 700-0376 2004 3 150 1
#13 700-0376 2004 5 287 1
#. . . . . .
#. . . . . .
结果只显示一个数字的数据。有多个partnumber。 我需要找到每个partnumber,year,month
的总传递值的百分比我如何在SQL中执行此操作。在JAVA中执行此操作的最佳方法是什么。我需要有以下数据:
partnumber year month overallpass percentage
700-0376 2003 8 1 95.72
700-0376 2003 11 1 98.43
700-0376 2003 10 1 100.00
700-0376 2004 2 1 92.05
. . . . .
. . . . .
百分比计算为计数值(59)/61(59+2)*100=95.72
。我需要为同年和月份的所有部分编号执行此操作。
我必须从数据库中获取数据并使用谷歌图表将其绘制在图表上。对此最好的方法是什么?
答案 0 :(得分:0)
如果我已经将问题解释为OK,那么在计数传递时你需要在计数内部使用一个case表达式(例如得到59)但是对于除数不能这样做(得到61)并且你不希望整个传递
分组SELECT
dbo.tablename.part_number
, DATEPART(YEAR, dbo.tablename_test.test_date_time) AS year
, DATEPART(MONTH, dbo.tablename_test.test_date_time) AS month
, COUNT(CASE WHEN overall_pass = 1 THEN dbo.tablename_test.overall_pass END) AS Count_Passes
, COUNT(dbo.tablename_test.overall_pass) AS Count_All
, COUNT(CASE WHEN overall_pass = 1 THEN dbo.tablename_test.overall_pass END)
/ COUNT(dbo.tablename_test.overall_pass) AS Count_Percent
FROM dbo.tablename_test
INNER JOIN dbo.tablename
ON dbo.tablename_test.tablename_id = dbo.tablename.tablename_id
WHERE dbo.tablename_test.test_date_time BETWEEN '2003-01-01' AND '2013-06-01'
AND (dbo.tablename_test.resolution_code IS NULL
OR dbo.tablename_test.resolution_code = 'None')
AND dbo.tablename_test.operator IN ('Arlene Haselhorst', 'Trang Luong', 'Elena Viloria')
GROUP BY
DATEPART(YEAR, dbo.tablename_test.test_date_time)
, DATEPART(MONTH, dbo.tablename_test.test_date_time)
, dbo.tablename.part_number
ORDER BY
dbo.tablename.part_number
, DATEPART(YEAR, dbo.tablename_test.test_date_time)
, DATEPART(MONTH, dbo.tablename_test.test_date_time)
答案 1 :(得分:0)
首先,如果在SQL中处理日期/时间/时间戳,您不应该使用inclusive upper bound of BETWEEN
with positive contiguous-range types(其中日期/时间/时间戳是子集),尤其是服务器。就目前而言,你只是在六月的第一天(去年),我觉得很可疑。
此外,在表内数据中使用函数将使索引的使用无效,从而使对大型结果集的查询变慢。你想要一个范围表,看起来像这样:
range_start range_end year month
==========================================
'2003-01-01' '2003-02-01' 2003 1
'2003-02-01' '2003-03-01' 2003 2
..............
'2013-05-01' '2013-06-01' 2013 5
如果您有日历表,则应该可以在那里使用数据。否则,您可以使用递归CTE轻松生成一个:
WITH Calendar_Range AS (SELECT d AS range_start, DATEADD(month, 1, d) AS range_end,
DATEPART(year, d) AS year, DATEPART(month, d) AS month
FROM (VALUES(CAST('20030101' AS DATE))) t(d)
UNION ALL
SELECT range_end AS range_start, DATEADD(month, 1, range_end) AS range_end,
DATEPART(year, range_end) AS year, DATEPART(month, range_end) AS month
FROM Calendar_Range
WHERE range_end < CAST('20130601' AS DATE))
现在,COUNT(*)
和COUNT(<expression>)
之间的区别是什么?后者(第二个)将忽略(不计数)空行。我们可以使用简单的连接条件来计算行数...类似于以下
SELECT COUNT(p.didPass)
FROM tablename_test
LEFT JOIN (VALUES(1)) p(didPass)
ON p.didPass = tablename_test.overall_pass
...这基本上等同于CASE
- 计算行数(尽管优化程序可以能够更好地优化此行)
结果查询可能如下所示:
WITH Calendar_Range AS (SELECT d AS range_start, DATEADD(month, 1, d) AS range_end,
DATEPART(year, d) AS year, DATEPART(month, d) AS month
FROM (VALUES(CAST('20030101' AS DATE))) t(d)
UNION ALL
SELECT range_end AS range_start, DATEADD(month, 1, range_end) AS range_end,
DATEPART(year, range_end) AS year, DATEPART(month, range_end) AS month
FROM Calendar_Range
WHERE range_end < CAST('20130601' AS DATE))
SELECT Calendar_Range.year, Calendar_Range.month, Part.part_number,
100.0 * COUNT(Pass.didPass) / COUNT(*) AS percentage
FROM dbo.tablename Part
JOIN dbo.tablename_test Test
ON Test.tablename_id = Part.tablename_id
AND Test.operator IN('Arlene Haselhorst','Trang Luong','Elena Viloria')
AND (Test.resolution_code IS NULL OR Test.resolution_code = 'None')
JOIN Calendar_Range
ON Test.test_date_time >= Calendar_Range.range_start
AND Test.test_date_time < Calendar_Range.range_end
LEFT JOIN (VALUES(1)) Pass(didPass)
ON Pass.didPass = Test.overall_pass
GROUP BY Calendar_Range.year, Calendar_Range.month, Part.part_number
ORDER BY Calendar_Range.year, Calendar_Range.month, Part.part_number
(未经测试,因为未提供样本起始数据)
我从最终结果集中删除了overall_pass
,因为常量列并没有真正告诉你任何事情(当值已知时)。为了避免混淆,我将SELECT
中的列顺序与ORDER BY
进行了匹配(我还切换了GROUP BY
中的列,但这实际上并没有改变结果)。我调整了操作的顺序,并使用浮点值来计算percentage
,或者你最终会得到整数除法(即获得100
或0
,但不是介于两者之间的任何事情。)