需要选择具有一个共同的日期字段从2个表中的所有行

时间:2019-01-29 02:59:21

标签: mysql sql

所以,我发现自己不得不扮演DBA(通常是系统管理员),这是我的问题,而我的问题是:

我有两个桌子,一个桌子供人们在他们到达现场时记录,另一个桌子则用于他们离开时。

理想情况下,两个表之间的数据应该恰好匹配,并且我应该能够对它们使用内部的JOIN来获取所需的视图。但是,我们已经看到的是,人们不进出应该像他们检查。因此,这意味着我可以有一些人在签表中,将不会在结账台,反之亦然。

我已经尝试了两个表之间的Left JOIN,但是仍然会在输出中复制checkin表的某些行...

SELECT a.name,a.timein,a.signature,b.timeout,b.signature 
FROM check_in a
LEFT JOIN check_out b ON a.datein = b.dateout
WHERE a.datein = '2019-01-28';

我想要的是一个查询,它使我可以从今天的值机表中获取所有行,并且还可以从今天的结果集的同一结果集中提取所有表中的行。

有没有办法为做,还是我只是将不得不使用两个查询,直到我可以得到存储在一个表中这些数据?

4 个答案:

答案 0 :(得分:2)

听起来您想要一个完整的外部联接,但是您需要在表之间的公共标识符上联接。目前,您要加入日期,这会将日期check_in中的所有行与日期中的check_out中的所有行进行合并(即,如果您有5个人在示例日期进行检入并检出,则您d返回25行)。因此,假设name是标识符,您将执行以下操作:

SELECT a.name,a.timein,a.signature,b.timeout,b.signature, b.name 
FROM check_in a
FULL OUTER JOIN check_out b ON a.name = b.name
    and a.datein = b.dateout
WHERE a.datein = '2019-01-28' 
OR b.dateout = '2019-01-28';

我在结果中包括了b.name,因为如果有人签出了,但没有签出,那么您将不会获得a.name的值。

另一种选择可能是进行联合,所以可以使用类似这样的方法:

SELECT a.name,a.timein,a.signature,b.timeout,b.signature
FROM check_in a
LEFT OUTER JOIN check_out b ON a.name = b.name
    and a.datein = b.dateout
WHERE a.datein = '2019-01-28' 
UNION
SELECT co.name, '', '', co.timeout, co.signature
FROM check_out co
where not exists (SELECT 1 
    FROM check_in ci
    WHERE ci.name = co.name 
    AND ci.datein = co.dateout)
AND co.dateout = '2019-01-28'

因此查询的上半部分将返回匹配项以及具有签入和签出的项,以及具有签入但未签出的项,而下半部分将选择具有签出但没有匹配的签入项的匹配项,但是它在第一列中返回check_out名称,因此列1将始终具有该名称。

然后,您可以从那里得到想要的花式。

答案 1 :(得分:0)

听起来像您想要入住日期与结帐日期相匹配的行,没有入住日期没有结帐日期,所以我会写查询类似:

SELECT a.name, a.timein, a.signature, b.timeout, b.signature
FROM check_in a, check_out b,
WHERE a.user = b.user
AND a.datein = ‘2019-01-28’
AND (a.datein = b.dateout OR a.datein IS NULL OR b.dateout IS NULL);

答案 2 :(得分:0)

完全外部联接将从X-Forwarded-Forcheck_in中获得行,只要其中一个日期中的至少一个与您要查找的日期匹配即可。 check_out子句中的简单OR应该足以获取所需的所有记录。

WHERE

答案 3 :(得分:0)

使用union all

select c.*
from ((select ci.name, ci.timein, ci.signature as in_signature,
              null as timeout, null as out_signature
       from check_in ci
       where ci.check_in = '2019-01-28'
      ) union all
      (select co.name, null, null,
              co.timeout, co.signature as out_signature
       from check_out co
       where ci.check_in = '2019-01-28'
      )
     ) c;

我强烈建议您不要使用join来收集数据,因为这可能会使行数成倍增加。您将希望对数据中的内容有个更好的了解,而不必乘以任何一个表中的行。