在MySQL中对相同的行字段进行分组?

时间:2013-04-25 05:37:28

标签: mysql select grouping

我需要将员工姓名分组在一起。我尝试使用“Order By”但它不适用于空单元格。

enter image description here

顶部的表格是我当前的表格,我希望结果像底部的表格一样。这是我当前的选择查询。

SELECT 
    DAYNAME(calendar.DATE) AS DAY,
    DATE_FORMAT(calendar.DATE, '%d %b %Y') AS Date,
    t2.Department,
    t2.Name,
    TIME(t2.time_enter) AS 'Time In',
    TIME(t2.time_exit) AS 'Time Out'
FROM
    calendar
        LEFT JOIN
    (SELECT 
        employee_hr_id,
            time_enter,
            time_exit,
            department.NAME As Department,
            CONCAT(employee.F_NAME, ' ', employee.L_NAME) As Name
    from
        entry_log
    Inner Join employee ON entry_log.EMPLOYEE_HR_ID = employee.HR_ID
    Inner Join department ON employee.DEPARTMENT_ID = department.ID
    where
        CONCAT(employee.F_NAME, ' ', employee.L_NAME) LIKE @NAME) t2 ON date(t2.time_enter) = calendar.date
where
    calendar.DATE >= @TIME_ENTER
        AND calendar.DATE <= @TIME_EXIT

2 个答案:

答案 0 :(得分:2)

您应该使用以下子查询,而不仅仅是CALENDAR表。

select calendar.DATE,employee.HR_ID,employee.DEPARTMENT_ID 
  from calendar,employee 
  where
    calendar.DATE >= @TIME_ENTER
        AND calendar.DATE <= @TIME_EXIT

在这种情况下,您将获得DATE和EMPLOYEE的所有可能组合。然后从此表中按DEPARTMENT_ID, HR_ID, DATE排序。

所以你的查询应该是这样的:

SELECT 
    DAYNAME(NEW_calendar.DATE) AS DAY,
    DATE_FORMAT(NEW_calendar.DATE, '%d %b %Y') AS Date,
    t2.Department,
    t2.Name,
    TIME(t2.time_enter) AS 'Time In',
    TIME(t2.time_exit) AS 'Time Out'
FROM
    (
       select calendar.DATE as DATE,
              employee.HR_ID as HR_ID,
              employee.DEPARTMENT_ID as DEPARTMENT_ID
            from calendar,employee 
            where
              calendar.DATE >= @TIME_ENTER
                AND calendar.DATE <= @TIME_EXIT
     ) NEW_calendar
        LEFT JOIN
    (SELECT 
        employee_hr_id,
            time_enter,
            time_exit,
            department.NAME As Department,
            CONCAT(employee.F_NAME, ' ', employee.L_NAME) As Name
    from
        entry_log
    Inner Join employee ON entry_log.EMPLOYEE_HR_ID = employee.HR_ID
    Inner Join department ON employee.DEPARTMENT_ID = department.ID
    where
        CONCAT(employee.F_NAME, ' ', employee.L_NAME) LIKE @NAME) t2 

        ON date(t2.time_enter) = NEW_calendar.date
           and (t2.EMPLOYEE_HR_ID=NEW_calendar.HR_ID)
where
    calendar.DATE >= @TIME_ENTER
        AND calendar.DATE <= @TIME_EXIT

order by NEW_calendar.DEPARTMENT_ID,NEW_calendar.HR_ID,NEW_calendar.Date

答案 1 :(得分:1)

空行中没有任何内容表明您与他们关联的员工。事实上,它们根本不应该是重复的。要做的就是加入三个表(或子查询):一个用于日期,第二个用于所有(相关)员工,第三个用于实际分配。然后,即使您选择不打印名称,也可以使用所有员工的第二个表来排序行。前两个表之间的完全交叉连接为您提供日期和员工之间的所有组合,然后可以将具有日志条目的组合保持连接到该组合。

我创建了an example on SQLFiddle。它使用员工姓名而不是ID来匹配事物,并将t2作为表而不是更复杂的子查询,但这个想法应该是干净的。这是来自那个小提琴的查询:

SELECT …
FROM
    (calendar,
     (SELECT DISTINCT Name FROM t2) AS employees)
    LEFT JOIN t2 ON DATE(t2.time_enter) = calendar.date
                AND t2.Name = employees.Name
ORDER BY employees.Name, calendar.date