所以,我发现自己不得不扮演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';
我想要的是一个查询,它使我可以从今天的值机表中获取所有行,并且还可以从今天的结果集的同一结果集中提取所有表中的行。
有没有办法为做,还是我只是将不得不使用两个查询,直到我可以得到存储在一个表中这些数据?
答案 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-For
和check_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
来收集数据,因为这可能会使行数成倍增加。您将希望对数据中的内容有个更好的了解,而不必乘以任何一个表中的行。