简体   繁体   中英

LEFT JOIN with right table criteria

I would like to join table A and B with the following criteria to get the result table.

TABLE A is the Starting TIME TABLE B consist of both TIME IN and TIME OUT USER need to clock in (TIME IN), start machine (TIME START), clock out (TIME OUT)

  1. TIME IN >= TIME START
  2. TIME START >= TIME OUT
  3. MAX TIME IN/OUT
  4. DISTINCT Results based on ID

I tried left join but couldn't get the result that I want. I tried using CASE but the are lots of redundant result. Please advise.

在此处输入图像描述

SELECT a.ID     as id,
       GROUP_CONCAT(CASE
                        WHEN b.Code = 'In'
                            THEN b.Time
           end) as `Time In`,
       `TIME START`,
       GROUP_CONCAT(CASE
                        WHEN b.Code = 'Out'
                            THEN b.Time
           end) as `Time Out`
FROM `Table A` a
JOIN `Table B` b on a.ID = b.ID
WHERE 1
  AND ((b.Code = 'In' && b.`TIME` <= a.`TIME START`) OR
       (b.Code = 'Out' && b.`TIME` >= a.`TIME START`))
GROUP BY a.ID, a.`Time Start`

query doesn`t handle Code='In/Out' you need to split this explict

You can do this with a couple of LEFT JOINs :

SELECT 
  ts.ID, 
  MAX(ti.Time) AS Time, 
  MAX(ts.TimeStart) AS TimeStart, 
  MAX(tto.Time) AS TimeOut
FROM tableA ts
LEFT JOIN tableB ti ON ts.ID = ti.ID AND ti.Code IN ('IN','IN/OUT') -- "Time IN"
LEFT JOIN tableB tto ON ts.ID = tto.ID AND tto.Code IN ('Out','IN/OUT') -- "Time OUT"
GROUP BY ts.ID
ORDER BY ts.ID

Like Impaler mentioned, your description of IN/OUT and the desired result you provided don't seem to be in sync. The example above assumes IN/OUT is both IN and OUT . This will also give you the max TimeIn/TimeOut values if there are duplicate entries.

DB Fiddle (Postgres)

Try aggregating table B before the join:

WITH cte AS 
 ( -- pivot into in/out time
   SELECT
      ID
     ,Max(CASE WHEN Code IN ('IN', 'IN/OUT') THEN Time END) AS TimeIn
     ,Max(CASE WHEN Code IN ('Out','IN/OUT') THEN Time END) AS TimeOut
   FROM tableB
   GROUP BY ID
 ) 
SELECT
   a.ID
  ,CASE WHEN TimeStart >= TimeIn THEN TimeIn END AS TimeIn
  ,TimeStart                                                                                                                          
  ,CASE WHEN TimeStart <= TimeOut THEN TimeIn END AS TimeIn
FROM tableA AS a
LEFT JOIN cte AS b
  ON a.ID = b.ID

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM