从第1天到第31天,我有员工出勤表,列名为1,2,3,4 5 ..... 31 和数据类型是nVarchar(5)
我在这些列(P,H,A)中添加值,例如:
P =现在 A =缺席 H =假期
现在我想计算最后一列中的Total(P = Present),即Employee的[TotalPresnets]。 如何计算(计算)字符串值。
答案 0 :(得分:4)
因为您创建了31列,所以每种类型的操作都涉及获取所有31列。这是为什么这个设计会给你带来很多痛苦的一百万个原因之一。所以,我不得不说你需要考虑改变这个设计!
如果你必须坚持这一点,你将得到类似这样的代码:
select
EmployeeID,
(
case when Day0 = 'P' then 1 else 0 end
+ case when Day1 = 'P' then 1 else 0 end
+ case when Day2 = 'P' then 1 else 0 end
...
+ case when Day31 = 'P' then 1 else 0 end
) as TotalPresent
from
Attendance
另一个丑陋的解决方案是使用动态SQL生成上面的查询。
一般来说,当你被迫陷入如此丑陋的解决方案时,这是一个很好的迹象表明你正在接近这个问题。
另请注意,对于单行的非常基本的操作,这是大约40行代码。将此技术应用到您的应用程序的其余部分将导致更多的麻烦。想象一下,如果你必须改变这里的任何逻辑;什么应该是一行现在31。
更好的设计将产生更直观/可维护/可读的代码:
select
EmployeeID,
count(*) TotalPresent
from
EmployeeDailyAttendance eda
inner join Days d on d.ID = eda.DayID
where
eda.Code = 'p'
group by
EmployeeID
答案 1 :(得分:1)
SQL Server 2008非常棒。看看这个例子:
讨论表
create table attendance(
empid int,
[1] char(1), [2] char(1), [3] char(1), [4] char(1),
[5] char(1), [6] char(1), [7] char(1), [8] char(1));
insert attendance values
(1,'P','P','H','A','A','P','P','P'),
(2,'P','P','P','P','P','P','P',null),
(3,'P','P','H','P','P','P',null,null);
您的选择语句选项(根据需要扩展为31天)
select empid,
(select COUNT(*)
from (values([1]),([2]),([3]),([4]),([5]),([6]),([7]),([8])) t(Day)
where Day='P')
from attendance
select empid, count(day)
from attendance
unpivot (type for day in ([1],[2],[3],[4],[5],[6],[7],[8])) unp
where type='P'
group by empid
答案 2 :(得分:0)
我必须同意马克的意见。您当前的设计使得按日期查询非常困难。我建议使用日期字段和状态字段。每个员工每天都会有一行,但是要获得您正在寻找的结果会更容易。
答案 3 :(得分:0)
我知道人们所说的是真的。尽管如此,你很可能很快就会完成这个项目,所以我想我会帮你一把。
<?php
$result = mysql_query("SELECT * FROM table WHERE month = '$month'");
// loop through rows.
while(false !== ($row = mysql_fetch_object())) {
// loop through cols
foreach($row as $key => $col) {
if($key != $userID)
$split = str_split($col);
// loop through letters
foreach($split as $letter) {
$final_results[$row->userID][$letter]++;
}
}
}
print_r($final_results);
/*
* outputs something like
* array(
* '15' => array(
* 'P' => 19,
* 'A' => 4,
* 'H' => 1
* )
* '13' => array(
* 'P' => 19,
* 'A' => 4,
* 'H' => 1
* )
* );
*/
很可能你不使用PHP而是使用其他语言,但这个想法很简单。循环遍历所有列,仅跳过非天数的列,将每个字母相加并将其存储到数组中。
希望这对你有用。
此致 佩德罗
答案 4 :(得分:0)
我发表了评论,但认为答案可能会更好。
创建表格视图:
SELECT EmployeeID, '1' As DayOfMonth, Day1 As AttendanceValue FROM TableName
UNION
SELECT EmployeeID, '2', Day2 FROM TableName
....
SELECT EmployeeID, '31', Day31 FromTableName
现在您可以使用类似于tenfour的查询:
SELECT AttendanceValue, COUNT(AttendanceValue) FROM ViewName GORUP BY AttendanceValue