Нужно выбрать все строки из 2 таблиц с общим полем даты - PullRequest
0 голосов
/ 29 января 2019

Итак, я оказался в незавидном положении, когда мне нужно играть в DBA (обычно я системный администратор), и у меня возникает следующая проблема:

У меня есть два стола, один для людейзаписывать, когда они прибывают на сайт, и другую таблицу, когда они уходят.

В идеале, данные между двумя таблицами должны просто совпадать, и я должен иметь возможность использовать внутренний JOIN для них, чтобы получить представлениеЯ хочу.Но то, что мы видели, это то, что люди не регистрируются и выходят, как должны.Таким образом, это означает, что у меня может быть несколько человек в таблице регистрации, которых не будет в таблице контроля, и наоборот.

Я пробовал левый JOIN между двумя таблицами, но он по-прежнему дублирует некоторые строки таблицы регистрации в выходных данных ...

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 голосов
/ 29 января 2019

Используйте 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 для объединения данных, потому что это может умножить количество строк.Вы хотите получить лучшее представление о том, что находится в данных, не умножая строки из любой таблицы.

0 голосов
/ 29 января 2019

Звучит так, как будто вы хотите полное внешнее соединение, но вам нужно соединиться по общему идентификатору между таблицами.В данный момент вы присоединяетесь к дате, которая объединит все строки в check_in для даты со всеми строками из check_out для даты (т. Е. Если у вас было 5 человек, зарегистрировавшихся и вышедших в день примера, вы 'вернул 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 всегда будет иметь имя.

Тогда вы можете взять это оттуда, как вы хотите получить.

0 голосов
/ 29 января 2019

Полное внешнее объединение будет получать строки как из check_in, так и check_out, если хотя бы одна из дат совпадает с той, которую вы ищете.Простого OR в предложении WHERE должно быть достаточно, чтобы получить все нужные вам записи.

SELECT a.name, a.timein, a.signature, b.timeout, b.signature 
FROM check_in a
FULL OUTER JOIN check_out b
ON a.datein = b.dateout AND a.name = b.name
WHERE a.datein = '2019-01-28' OR b.dateout = '2019-01-28';
0 голосов
/ 29 января 2019

Звучит так, как будто вы хотите, чтобы строки, в которых дата заезда совпадала с датой выписки или , дата заезда отсутствует или , дата выписки отсутствует, поэтому я бы написал запроскак:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...