有没有更简洁的方法来编写这个SQL查询而不是一遍又一遍地使用sum?

时间:2013-04-30 19:32:32

标签: php sql

似乎非常多余。我正在做的是为特定的员工和他们所在的部门执行任务,并根据dateiff和后续日期相等的时间分配他们的任务两周,分配1是真实的,并总计在结束。

$_2weeks = "select
        isnull(b.employee, 'Event Total') as Employee,
        sum(case when DATEDIFF(dd,cast(GETDATE() as date),cast(a.follow_up as date))<='-2' then 1 else 0 end) '2+ Days Behind',
        sum(case when DATEDIFF(dd,cast(GETDATE() as date),cast(a.follow_up as date))='-1' then 1 else 0 end) '1 Day Behind',
        sum(case when cast(a.follow_up as date)=cast(GETDATE() as date) then 1 else 0 end) 'Today<br>&nbsp;" . date('m/d') . "',
        sum(case when DATEDIFF(dd,cast(GETDATE() as date),cast(a.follow_up as date))='1' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+1 day')), 0, 1).'<br>' . date('m/d', strtotime('+1 day')) . "',
        sum(case when DATEDIFF(dd,cast(GETDATE() as date),cast(a.follow_up as date))='2' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+2 day')), 0, 2).'<br>' . date('m/d', strtotime('+2 day')) . "',
        sum(case when DATEDIFF(dd,cast(GETDATE() as date),cast(a.follow_up as date))='3' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+3 day')), 0, 1).'<br>' . date('m/d', strtotime('+3 day')) . "',
        sum(case when DATEDIFF(dd,cast(GETDATE() as date),cast(a.follow_up as date))='4' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+6 day')), 0, 1).'<br>' . date('m/d', strtotime('+6 day')) . "',
        sum(case when DATEDIFF(dd,cast(GETDATE() as date),cast(a.follow_up as date))='5' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+7 day')), 0, 1).'<br>' . date('m/d', strtotime('+7 day')) . "',
        sum(case when DATEDIFF(dd,cast(GETDATE() as date),cast(a.follow_up as date))='6' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+8 day')), 0, 1).'<br>' . date('m/d', strtotime('+8 day')) . "',
        sum(case when DATEDIFF(dd,cast(GETDATE() as date),cast(a.follow_up as date))='7' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+9 day')), 0, 2).'<br>' . date('m/d', strtotime('+9 day')) . "',
        sum(case when DATEDIFF(dd,cast(GETDATE() as date),cast(a.follow_up as date))='8' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+10 day')), 0, 1).'<br>' . date('m/d', strtotime('+10 day')) . "',
        sum(case when DATEDIFF(dd,cast(GETDATE() as date),cast(a.follow_up as date))='9' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+13 day')), 0, 1).'<br>' . date('m/d', strtotime('+13 day')) . "',
        sum(1) AS 'Total'
    from " . event_table('event') . " a
    left outer join " . event_table('employee') . " b on a.employee_id=b.id
    where a.task_id like '%$task_id%'
    and b.department_id like '$dept_id'
    and a.status=1
    and a.task_id<>''
    group by b.employee with rollup";

还有一个更简洁的substr和strtotime php函数的方法?任何帮助将不胜感激。提前谢谢。

3 个答案:

答案 0 :(得分:1)

您可以展开group by以包含日差。例如:

select  b.employee
,       datediff(dd,cast(getdate() as date),cast(a.follow_up as date)) as DaysInPast
,       count(a.task_id) as TaskCount
group by
        b.employee
,       datediff(dd,cast(getdate() as date),cast(a.follow_up as date))

您必须生成列名称客户端,并可能转动结果。最后,这可能比您当前的解决方案更复杂(当然在代码行方面)。

答案 1 :(得分:0)

。 。如果你只需要避免这种重复的“视觉问题”,你可以创建一个php函数来输出正确的字符串,比如......

    function sqlline($i, $n) {
        $timestr = strtotime('+'. $i .' day');
        $d = date('l/m/d', $timestr);
        $d2 = date('m/d', $timestr);

        return 'SUM '.
            '(CASE WHEN '.
                'DATEDIFF (dd, cast(GETDATE() as date), cast(a.follow_up as date)) = "'. $i .'" '.
            'THEN 1 ELSE 0 END) '.
            '"'. substr($d, 0, $n) .'<br>'. $d2 .
            ', '
    }

。 。并使用sqlline(1, 1) . sqlline(2, 1) (...)调用它。

。 。但我认为你应该更多地考虑一下代码的目标,以及其中一些可以自动完成。

答案 2 :(得分:0)

不一定是你要求的(简化PHP部分),但我认为如果你的数据库支持这样的子表,你可以减少SQL代码的“视觉混乱”:

select
        isnull(b.employee, 'Event Total') as Employee,
        sum(case when sub.dat_diff<='-2' then 1 else 0 end) '2+ Days Behind',
        sum(case when sub.dat_diff='-1' then 1 else 0 end) '1 Day Behind',
        sum(case when cast(a.follow_up as date)=cast(GETDATE() as date) then 1 else 0 end) 'Today<br>&nbsp;" . date('m/d') . "',
        sum(case when sub.dat_diff='1' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+1 day')), 0, 1).'<br>' . date('m/d', strtotime('+1 day')) . "',
        sum(case when sub.dat_diff='2' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+2 day')), 0, 2).'<br>' . date('m/d', strtotime('+2 day')) . "',
        sum(case when sub.dat_diff='3' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+3 day')), 0, 1).'<br>' . date('m/d', strtotime('+3 day')) . "',
        sum(case when sub.dat_diff='4' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+6 day')), 0, 1).'<br>' . date('m/d', strtotime('+6 day')) . "',
        sum(case when sub.dat_diff='5' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+7 day')), 0, 1).'<br>' . date('m/d', strtotime('+7 day')) . "',
        sum(case when sub.dat_diff='6' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+8 day')), 0, 1).'<br>' . date('m/d', strtotime('+8 day')) . "',
        sum(case when sub.dat_diff='7' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+9 day')), 0, 2).'<br>' . date('m/d', strtotime('+9 day')) . "',
        sum(case when sub.dat_diff='8' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+10 day')), 0, 1).'<br>' . date('m/d', strtotime('+10 day')) . "',
        sum(case when sub.dat_diff='9' then 1 else 0 end) '" . substr(date('l/m/d', strtotime('+13 day')), 0, 1).'<br>' . date('m/d', strtotime('+13 day')) . "',
        sum(1) AS 'Total'
FROM (
SELECT a.employee_id, a.task_id, DATEDIFF(dd,cast(GETDATE() as date),cast(a.follow_up as date)) as dat_diff
FROM " . event_table('event') . " a
WHERE a.status=1
) sub
LEFT JOIN ... (etc.)

此外,您应该避免多次调用“getdate” - 最有可能调用一次,将值存储在变量中并将其粘贴到代码中就足够了,而且速度稍快。

我的2美分;)