SQL JOIN在同一个表上返回重复的结果

时间:2015-01-13 18:45:26

标签: php mysql sql

我正在尝试使用连接从同一个表中提取此数据。基本上我需要创建一个时间表报告,以查看员工是否在同一天提交了正常的可计费小时和休假时间。可计费小时数为1,2,5和6类,休假时间为4类。这是我到目前为止的情况。

SELECT
 a.attendant_id,
 a.date,
 a.start_time,
 a.end_time,
 a.hours AS HoursBilled,
 a.type AS TypeBilled,
 t.start_time,
 t.end_time,
 t.hours AS HoursVacation
FROM
 timesheet_lines AS a
INNER JOIN (
SELECT
    b.date,
    b.attendant_id,
    b.hours,
    b.start_time,
    b.end_time
FROM
    timesheet_lines AS b
WHERE
    b.date >= '2014-10-01'
AND b.date <= '2014-12-31'
AND b.type = 4
) AS t ON a.attendant_id = t.attendant_id
WHERE
a.date = t.date
AND a.type IN (1, 2, 5, 6)

我正在获取我需要的数据,唯一的问题是我得到像这样的重复数据:

atten_id   date         start_time  end_time    HB  TB  s_t1        e_t1        HV
4584       2014-10-03   10:00:00    12:00:00    2   1   05:30:00    06:30:00    1
4584       2014-10-03   10:00:00    12:00:00    2   1   18:00:00    21:00:00    3
6139       2014-10-04   14:00:00    17:00:00    3   2   09:00:00    13:30:00    4.5
6842       2014-10-06   00:00:00    08:00:00    8   1   17:00:00    20:00:00    3

我缩写了房间的字段标题。前两行复制到第6列。最后3列包含良好的数据。反过来也是可能的,其中最后3列包含重复,前6列是好数据。

有没有办法只用“NULL”填充重复数据?我打算尝试过滤PHP方面的重复项,但必须有一个更好的解决方案。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

您所撰写的查询似乎正在回答这个问题:对于同一个人,同时记录了正常工作时间和休假时间的每一天的时间表详情是什么?

如果您确实想回答问题,&#34;员工在同一天提交了休假时间和正常时间的日期?&#34;,请尝试以下方式:

SELECT 
    a.attendant_id, 
    a.[date]
FROM timesheet_lines a
WHERE a.[type] IN (1, 2, 5, 6)
AND EXISTS (
    SELECT 1 
    FROM timesheet_lines b 
    WHERE b.[type] = 4 AND 
        b.attendant_id = a.attendant_id AND 
        b.[date] = a.[date])
GROUP BY attendant_id, [date]

或者,如果您需要了解员工在同一天提交的每种类型的小时数,请尝试以下操作:

SELECT  
    a.attendant_id, 
    a.[date], 
    SUM(a.[hours]) AS TotalHoursBilled, 
    MAX(VacationHoursBilled) VacationHoursBilled --MAX because we're already joining on the     fields we're grouping on, so there can be at most one result
FROM timesheet_lines a
INNER JOIN (
    SELECT attendant_id, [date], SUM([hours]) AS VacationHoursBilled
    FROM timesheet_lines
    WHERE [type] = 4
    GROUP BY attendant_id, [date]) b ON b.attendant_id = a.attendant_id AND b.[date] = a.[date]
WHERE a.[type] IN (1, 2, 5, 6)
GROUP BY a.attendant_id, a.[date]

根据您的更新,如果存在正常时间,您似乎需要休假时间详细信息。在这种情况下,您可以使用:

SELECT attendant_id, [date], start_time, end_time, [hours]
FROM timesheet_lines a
WHERE a.[type] = 4
AND EXISTS (
    SELECT 1 
    FROM timesheet_lines b 
    WHERE b.[type] IN (1, 2, 5, 6) AND
        b.attendant_id = a.attendant_id AND 
        b.[date] = a.[date])

答案 1 :(得分:0)

我总是发现自己加入表格的过程充满了意想不到的,不方便的复杂性。您可以考虑以下不同的方法:

SELECT CONCAT(attendant_id,"|",date) AS query_key,
       GROUP_CONCAT(DISTINCT IF(`type` in (1,2,5,6),`type`,NULL)     AS n_hours,
       GROUP_CONCAT(DISTINCT IF(`type` in (1,2,5,6),start_time,NULL) AS n_start, 
       GROUP_CONCAT(DISTINCT IF(`type` in (1,2,5,6),end_time,NULL)   AS n_end, 
       GROUP_CONCAT(DISTINCT IF(`type` in (4),`type`,NULL)           AS v_hours,
       GROUP_CONCAT(DISTINCT IF(`type` in (4),start_time,NULL)       AS v_start, 
       GROUP_CONCAT(DISTINCT IF(`type` in (4),end_time,NULL)         AS v_end       
FROM timesheet_lines
GROUP BY query_key
HAVING (v_hours IS NOT NULL) AND (n_hours IS NOT NULL)
;

这里的想法是编写一个字段(查询键),它结合了报告所需的所有唯一性标准。一旦可用,就可以在不需要自联接的情况下获得报告。

我对这些类型的查询运气不错。通常,它们比自连接更快,因为表只需要扫描一次。