Как подсчитать или суммировать значения столбцов String - PullRequest
1 голос
/ 21 февраля 2011

У меня есть таблица посещаемости сотрудников с даты 1 по 31 с именами столбцов, такими как 1, 2, 3, 4 5 ..... 31 и тип данных nVarchar (5)

Я добавляю значения в этихстолбцы (P, H, A), например:

P = присутствует A = отсутствует H = выходной

Теперь я хочу вычислить итоговое значение (P = Present) в последнем столбце, который является [TotalPresnets] работника.Как рассчитать (подсчитать) строковые значения.

Ответы [ 5 ]

4 голосов
/ 21 февраля 2011

Поскольку вы создали 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 голос
/ 22 февраля 2011

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

UNPIVOT

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
0 голосов
/ 21 февраля 2011

Я написал как комментарий, но думаю, что он может быть лучше в качестве ответа.

Создайте вид вашей таблицы:

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
0 голосов
/ 21 февраля 2011

Я знаю, что сказанное людьми - правда. Тем не менее, вам, скорее всего, придется доставить проект довольно скоро, поэтому я подумал, что помогу вам

<?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, а какой-то другой язык, но идея проста. Переберите все столбцы, пропустив только столбцы, которые не являются днями, суммируя каждую отдельную букву и сохраняя ее в массиве.

Надеюсь, это вам пригодится.

С уважением, Pedro

0 голосов
/ 21 февраля 2011

Я должен согласиться с Марком здесь. Ваш текущий дизайн делает очень сложным запрос по дате. Я рекомендую использовать поле даты и поле статуса. У вас будет по одной строке на сотрудника в день, но будет гораздо проще получить результаты, которые вы ищете.

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