我已经搜索了这样做的方法,但我不确定如何在我的特定场景中应用建议,而且我也不知道哪种方法是考虑到数据上下文的最佳或最准确的方法。 / p>
我正在寻找从包含员工分数的表格中选择最佳表现者的最佳方式,针对特定测试多次给出相同的测量值。因此,随着时间的推移,员工可能会使用相同的测试/测量进行多次评估,并且我试图选择给定时期内的最佳表现者。在此示例中,度量记录在Question1和Question2列中,员工在EmployeeID列中指定。分数的比例因列而异,并且通过测试,但都是最小的0或1.在样本数据中,测试1000有列Question1(0-10)和Question2(1-7),但是你不要根据数据确定无误的比例,你只知道每列的最小值为0或1,并且可以为空,这意味着该值应从平均计算中排除。我希望能够说,给我测试1000的两个最佳表现者并根据该表现对它们进行相应的订购。
ID TestID Question1 Question2 Question3 EmployeeID
1 1000 10 null null 12
2 1000 10 7 null 12
3 1000 10 7 null 12
4 1000 10 7 null 12
5 1000 10 7 null 12
6 1000 10 7 null 5
7 1000 10 7 null 5
8 1000 10 7 null 5
9 1000 10 7 null 5
10 1000 10 7 null 5
11 1000 10 7 null 5
12 1000 10 7 null 5
13 1000 10 7 null 5
14 1000 10 null null 5
15 1000 10 7 null 5
16 2000 5 10 10 3
17 2000 5 0 3 3
18 2000 null 9 8 6
19 2000 5 10 9 6
20 2000 null 10 9 7
21 2000 null 10 9 7
在这个例子中,对于测试1000,如果我得到排名前两位的表现者,结果应该是员工5和员工12排名相同,因为虽然他们都有10和7并且每个都包含一个null,这应该是不予考虑。
这个SQL是向我建议的,但似乎并不像我想要的那样工作。由此产生的SumAve对于员工5最终为8.5789,对于员工12最终为8.6667,这似乎不正确,因为他们的记录得分具有相同的平均值,并且他们不应因为有任何空值而受到处罚。但即使他们是这样,这与我认为的情况正好相反,因为员工5有更多的记录(7s),我认为他们的平均值会受到缺失/低分的影响。
SELECT TOP 2
EmployeeID
,NoOfResults
,Question1
,Question2
,Question3
,SumAve
FROM (SELECT
[EmployeeID]
,COUNT(*) AS NoOfResults
,AVG([Question1]) AS Question1
,AVG([Question2]) AS Question2
,AVG([Question3]) AS Question3
,SUM(ISNULL([Question1], 0) + ISNULL([Question2], 0) + ISNULL([Question3], 0)) /
SUM(
CASE
WHEN Question1 IS NULL THEN 0
ELSE 1
END +
CASE
WHEN Question2 IS NULL THEN 0
ELSE 1
END +
CASE
WHEN Question3 IS NULL THEN 0
ELSE 1
END) AS SumAve
FROM Table1
WHERE TestID = '1000'
GROUP BY [EmployeeID] perform
ORDER BY SumAve DESC, EmployeeID ASC
另外,最后一个扳手,记录可能包含Question1,Question2和Question3的所有空值。意味着给出了测试,但没有记录得分(无论出于何种原因)。在这种情况下,同样应该忽略空值,如果这是他们唯一的记录,但是如果它们存在则使用其他记录,那么雇员没有等级或最低等级/不被包括在内。 而且我认为一个员工可能有多个记录但在所有记录的一列中都是空的,所以我也添加了这些记录。让我知道,如果这是打破骆驼背部的稻草,因为如果是这样的话,我可能能够在现有数据中改变一些东西。
感谢您的关注,非常感谢您的帮助。
更新 -
使用@scsimon建议的方法似乎并没有给我我想要的东西。似乎结果受到空值的影响,我之前提到的不应该用来惩罚员工的总体得分/排名。在以下示例中,员工10和5都具有最高分(10和7),但员工5缺少一个分数,这不应影响他们的排名。员工12的得分并不完美(一个得分为9而不是10),这应该反映的排名低于员工10和5,但正如您所看到的那样,员工5最终会降低,因此他们因缺失而受到处罚得分,他们不应该。测试1000的排名应该是员工10,5,11和13位于顶部,员工12位于其下方。
SQL for data
DECLARE @table TABLE (
ID INT IDENTITY(1,1) NOT NULL
,TestID INT
,Question1 INT
,Question2 INT
,Question3 INT
,EmployeeID INT
)
INSERT INTO @table
VALUES
(1000, 10, 7, NULL, 10),
(1000, 10, 7, NULL, 10),
(1000, 10, 7, NULL, 10),
(1000, 10, 7, NULL, 10),
(1000, 10, 7, NULL, 10),
(1000, 10, NULL, NULL, 11),
(1000, 10, 7, NULL, 11),
(1000, 10, 7, NULL, 11),
(1000, 10, 7, NULL, 11),
(1000, 10, 7, NULL, 11),
(1000, 10, 7, NULL, 12),
(1000, 9, 7, NULL, 12),
(1000, 10, 7, NULL, 12),
(1000, 10, 7, NULL, 12),
(1000, 10, 7, NULL, 12),
(1001, 10, 7, NULL, 12),
(1001, NULL, 6, NULL, 12),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, NULL, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 13),
(1000, 10, 7, NULL, 13)
数据
ID TestID Question1 Question2 Question3 EmployeeID
18 1000 10 7 null 5
19 1000 10 7 null 5
20 1000 10 7 null 5
21 1000 10 7 null 5
22 1000 10 7 null 5
23 1000 10 7 null 5
24 1000 10 7 null 5
25 1000 10 7 null 5
26 1000 10 null null 5
27 1000 10 7 null 5
1 1000 10 7 null 10
2 1000 10 7 null 10
3 1000 10 7 null 10
4 1000 10 7 null 10
5 1000 10 7 null 10
6 1000 10 null null 11
7 1000 10 7 null 11
8 1000 10 7 null 11
9 1000 10 7 null 11
10 1000 10 7 null 11
11 1000 10 7 null 12
12 1000 9 7 null 12
13 1000 10 7 null 12
14 1000 10 7 null 12
15 1000 10 7 null 12
16 1001 10 7 null 12
17 1001 null 6 null 12
28 1000 10 7 null 13
29 1000 10 7 null 13
建议1:结果的SQL
SELECT
t.EmployeeID
,t.TestID
,SUM(ISNULL(Question1, 0) + ISNULL(Question2, 0) + ISNULL(Question3, 0)) / (COUNT(t.TestID) * 1.00) AS Ranking
FROM @table t
GROUP BY t.EmployeeID
,t.TestID
ORDER BY t.TestID,
Ranking DESC
建议1:结果
EmployeeID TestID Ranking
10 1000 17.0
13 1000 17.0
12 1000 16.8
5 1000 16.3
11 1000 15.6
12 1001 11.5
关于另一个建议,它似乎没有输出我需要的东西 -
建议2:结果的SQL
SELECT
EmployeeID
,TestID
,SUM(ISNULL(Q1, 0) + ISNULL(Q2, 0) + ISNULL(Q3, 0)) / MIN(CASE
WHEN Q1 IS NULL THEN 0.0
ELSE 1.0
END +
CASE
WHEN Q2 IS NULL THEN 0.0
ELSE 1.0
END +
CASE
WHEN Q3 IS NULL THEN 0.0
ELSE 1.0
END) AS AverageScore
FROM cte
GROUP BY EmployeeID
,TestID
ORDER BY TestID
, AverageScore
建议2:结果
EmployeeID TestID AverageScore
5 1000 8.5
10 1000 8.5
11 1000 8.5
12 1000 8.5
13 1000 8.5
12 1001 8.5
答案 0 :(得分:1)
由于员工不应该因为没有回答问题而停靠,我认为应该这样做。
select
t.EmployeeID,
t.TestID,
Sum(isnull(Question1,0) + isnull(Question2,0) + isnull(Question3,0)) / (count(t.TestID) * 1.00)
from
@table t
group by
t.EmployeeID,
t.TestID
order by
t.TestID
或者,如果我在上面的假设中不正确,那么这个查询更像你想要的,这是基于他们个人尝试的每个employeeid的平均值。
function lcm(arr) {
arr = arr.sort(function(a, b) {
return a - b;
});
var j = 1;
var num = arr[0];
for (i = 1; i < arr.length; i++) {
while (num % arr[i] !== 0) {
j = j + 1;
num = j * arr[0];
}
arr[0] = num;
}
return num;
}
console.log(lcm([3, 5, 6, 10]));
答案 1 :(得分:0)
我找到了解决方案。希望其他人可以从中受益。原来这是一个简单的调整。基本上我得到每个问题的员工平均分数,并将它们加在一起创建一个索引,以便我可以对它们进行排名。我已经尝试了多个真实的数据场景,它似乎是一种测量和排序每个场景的准确方法。以下是一些示例数据,演示了一些场景。此外,在我的示例中,我将两个测试中的排名结合起来(在这种情况下,它们将是基本相同的测试,但是不同的修订)。
DECLARE @table1 TABLE (
ID INT IDENTITY (1, 1) NOT NULL
,TestID INT
,Question1 FLOAT
,Question2 FLOAT
,Question3 FLOAT
,EmployeeID INT
)
DECLARE @table2 TABLE (
EmployeeID INT
,Description VARCHAR(50)
)
INSERT INTO @table1
VALUES (1000, 10, 7, NULL, 10),
(1000, 10, 7, NULL, 10),
(1000, 10, 7, NULL, 10),
(1000, 10, 7, NULL, 10),
(1000, 10, 7, NULL, 10),
(1000, 10, NULL, NULL, 11),
(1000, 10, 7, NULL, 11),
(1000, 10, 7, NULL, 11),
(1000, 10, 7, NULL, 11),
(1000, 10, 7, NULL, 11),
(1000, 10, 7, NULL, 12),
(1000, 9, 7, NULL, 12),
(1000, 10, 7, NULL, 12),
(1000, 10, 7, NULL, 12),
(1000, 10, 7, NULL, 12),
(1001, 10, 7, NULL, 12),
(1001, NULL, 6, NULL, 12),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, NULL, NULL, 5),
(1000, 10, 7, NULL, 5),
(1000, 10, 7, NULL, 13),
(1000, 10, 7, NULL, 13),
(1000, NULL, NULL, NULL, 14)
INSERT INTO @table2
VALUES (10, 'peter (10s & 7s)')
,(11, 'michael (10s & 7s, x7)')
,(12, 'samir (mixed)')
,(13, 'milton (10s & 7s, <count)')
,(5, 'tom (10s & 7s, x7)')
,(14, 'bob (nulls)')
SELECT
t1.TestID
,t1.EmployeeID
,t1.Question1
,t1.Question2
,t1.Question3
FROM @table1 t1
INNER JOIN @table2 t2
ON t1.EmployeeID = t2.EmployeeID
ORDER BY t1.EmployeeID, TestID
SELECT
t1.EmployeeID
,t2.Description
,AVG(t1.Question1) AS Question1
,AVG(t1.Question2) AS Question2
,AVG(t1.Question3) AS Question3
,COUNT(t1.EmployeeID) AS NoOfTests
,ISNULL(AVG(t1.Question1), 0) + ISNULL(AVG(t1.Question2), 0) + ISNULL(AVG(t1.Question3), 0) AS Rank
FROM @table1 t1
INNER JOIN @table2 t2
ON t1.EmployeeID = t2.EmployeeID
WHERE t1.TestID = 1000
OR t1.TestID = 1001
GROUP BY t1.EmployeeID
,t2.Description
ORDER BY rank DESC, NoOfTests DESC
测试数据:
TestID EmployeeID Question1 Question2 Question3
1000 5 10.0 7.0 null
1000 5 10.0 7.0 null
1000 5 10.0 7.0 null
1000 5 10.0 7.0 null
1000 5 10.0 7.0 null
1000 5 10.0 7.0 null
1000 5 10.0 7.0 null
1000 5 10.0 7.0 null
1000 5 10.0 null null
1000 5 10.0 7.0 null
1000 10 10.0 7.0 null
1000 10 10.0 7.0 null
1000 10 10.0 7.0 null
1000 10 10.0 7.0 null
1000 10 10.0 7.0 null
1000 11 10.0 null null
1000 11 10.0 7.0 null
1000 11 10.0 7.0 null
1000 11 10.0 7.0 null
1000 11 10.0 7.0 null
1000 12 10.0 7.0 null
1000 12 9.0 7.0 null
1000 12 10.0 7.0 null
1000 12 10.0 7.0 null
1000 12 10.0 7.0 null
1001 12 10.0 7.0 null
1001 12 null 6.0 null
1000 13 10.0 7.0 null
1000 13 10.0 7.0 null
1000 14 null null null
结果数据:
EmployeeID Description Question1 Question2 Question3 NoOfTests Rank
5 tom (10s & 7s, x7) 10.0 7.0 null 10 17.0
10 peter (10s & 7s) 10.0 7.0 null 5 17.0
11 michael (10s & 7s, x7) 10.0 7.0 null 5 17.0
13 milton (10s & 7s, <count) 10.0 7.0 null 2 17.0
12 samir (mixed) 9.833 6.857 null 7 16.69
14 bob (nulls) null null null 1 0.0