Firebird 2.5: Выбор данных при NULL

Модератор: Модераторы

Аватара пользователя
Unvictis
новенький
Сообщения: 48
Зарегистрирован: 17.07.2015 17:59:12
Откуда: Kokshetau, Kazakshtan
Контактная информация:

Firebird 2.5: Выбор данных при NULL

Сообщение Unvictis »

Привет ребята! Столкнулся с такой вот проблемой: у меня в БД есть 2 таблицы: EMPLOYEES и CLIENTS. Таблица CLIENTS имеет поля CREATOR и EDITOR - внешние ключи на записи из таблицы EMPLOYEES - создатель и редактор записи соответственно. Создатель записи присваивается при добавлении новой записи в таблицу CLIENTS и по этому в принципе не может содержать NULL, а редактор после первого редактирования - а до этого соответственно NULL. Теперь самое интересное: в TSQLQuery делаю запрос:

Код: Выделить всё

SELECT CLIENTS.CLIENT_ID,
       CLIENTS.CREATOR,
       EMPLOYEES.EMPLOYEE AS "CREATORLOOKUP",
       CLIENTS.EDITOR,
       EMPLOYEES.EMPLOYEE AS "EDITORLOOKUP",
       CLIENTS.EDITED,
       CLIENTS.CLIENT,
       CLIENTS.PHONE,
       CLIENTS.ADDRESS,
       CLIENTS.E-MAIL,
       CLIENTS.ANGRY,
       CLIENTS.NOTES
FROM CLIENTS,
     EMPLOYEES
WHERE EMPLOYEES.EMPLOYEE_ID = CLIENTS.CREATOR
  AND EMPLOYEES.EMPLOYEE_ID = CLIENTS.EDITOR
ORDER BY CLIENT ASC;


.. и мне отображаются только записи в которых поле EDITOR не равно NULL. А мне надо что-бы отображались все записи что есть в таблице CLIENTS, а там где в поле EDITOR установлен NULL была просто пустая строка. Как такое реализовать?
Аватара пользователя
vitaly_l
долгожитель
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41
Контактная информация:

Сообщение vitaly_l »

Код: Выделить всё

WHERE 
(EMPLOYEES.EMPLOYEE_ID = CLIENTS.CREATOR  AND EMPLOYEES.EMPLOYEE_ID = CLIENTS.EDITOR)
OR CLIENTS.EDITOR = null
Аватара пользователя
Unvictis
новенький
Сообщения: 48
Зарегистрирован: 17.07.2015 17:59:12
Откуда: Kokshetau, Kazakshtan
Контактная информация:

Сообщение Unvictis »

vitaly_l писал(а):

Код: Выделить всё

WHERE 
(EMPLOYEES.EMPLOYEE_ID = CLIENTS.CREATOR  AND EMPLOYEES.EMPLOYEE_ID = CLIENTS.EDITOR)
OR CLIENTS.EDITOR = null

Увы не работает - только что проверил - возвращает те же записи которые возвращала и без вставки OR CLIENTS.EDITOR = null, скобки и пр. поставил и ещё раз всё проверил.
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Сообщение Cheb »

http://www.1keydata.com/sql/sql-isnull.html

Добавлено спустя 1 минуту 8 секунд:
http://www.1keydata.com/sql/sql-ifnull.html
kosteek
постоялец
Сообщения: 203
Зарегистрирован: 24.07.2008 14:57:09
Откуда: Украина, г.Славянск

Сообщение kosteek »

Код: Выделить всё

WHERE EMPLOYEES.EMPLOYEE_ID = CLIENTS.CREATOR AND (EMPLOYEES.EMPLOYEE_ID = CLIENTS.EDITOR OR CLIENTS.EDITOR IS NULL)
Аватара пользователя
Unvictis
новенький
Сообщения: 48
Зарегистрирован: 17.07.2015 17:59:12
Откуда: Kokshetau, Kazakshtan
Контактная информация:

Сообщение Unvictis »

kosteek писал(а):

Код: Выделить всё

WHERE EMPLOYEES.EMPLOYEE_ID = CLIENTS.CREATOR AND (EMPLOYEES.EMPLOYEE_ID = CLIENTS.EDITOR OR CLIENTS.EDITOR IS NULL)

Вот теперь работает! Спасибо большое! Вопрос решён!

Добавлено спустя 1 час 41 секунду:
Хотя нет, всё равно отображаются не все записи - 29 из 34, не пойму почему.

Изображение
olegy123
долгожитель
Сообщения: 1643
Зарегистрирован: 25.02.2016 11:10:20

Сообщение olegy123 »

Почему не используешь LEFT JOIN / RIGHT JOIN / INNER JOIN ?

Код: Выделить всё

SELECT CLIENTS.*,
 CREATOR.*,
 EDITOR.*
FROM
    CLIENTS AS C
LEFT JOIN EMPLOYEES AS CREATOR ON CREATOR.EMPLOYEE_ID=C.CREATOR
LEFT JOIN EMPLOYEES AS EDITOR ON EDITOR.EMPLOYEE_ID=C.EDITOR


по логике [.. FROM CLIENTS, EMPLOYEES] = [..INNER JOIN..]

Добавлено спустя 4 минуты 32 секунды:
http://www.skillz.ru/dev/php/article-Ob ... OUTER.html

Добавлено спустя 42 минуты 10 секунд:
Для полного понимания:

LEFT vs Right Outer Join in SQL.png
kosteek
постоялец
Сообщения: 203
Зарегистрирован: 24.07.2008 14:57:09
Откуда: Украина, г.Славянск

Сообщение kosteek »

Unvictis писал(а):Хотя нет, всё равно отображаются не все записи - 29 из 34, не пойму почему.


Похоже что такой запрос не прокатит, т.к. будет выбирать записи, где creator и editor одинаковые или editor = null. Нужно делать join`ом.
Аватара пользователя
vitaly_l
долгожитель
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41
Контактная информация:

Сообщение vitaly_l »

kosteek писал(а):Похоже что такой запрос не прокатит, т.к. будет выбирать записи, где creator и editor одинаковые или editor = null. Нужно делать join`ом

join - может ничего не поменять.
Лучше вначале разобраться, почему editor != null, но при этом creator и editor - получается разные?
В смысле, найдите те записи, которые не отображаются и поймите причину: "Почему их нет после запроса"?
olegy123
долгожитель
Сообщения: 1643
Зарегистрирован: 25.02.2016 11:10:20

Сообщение olegy123 »

vitaly_l потому что

Код: Выделить всё

WHERE EMPLOYEES.EMPLOYEE_ID = CLIENTS.CREATOR AND (EMPLOYEES.EMPLOYEE_ID = CLIENTS.EDITOR OR CLIENTS.EDITOR IS NULL)

эти позиции могут взаимоисключатся. а брать итог нужно в одном EMPLOYEES
поэтому нужно на два поля (CLIENTS.EDITOR , CLIENTS.EDITOR) брать данные с двух EMPLOYEES
Аватара пользователя
vitaly_l
долгожитель
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41
Контактная информация:

Сообщение vitaly_l »

olegy123 писал(а):эти позиции могут взаимоисключатся

Какие эти? (кстати там нужно брать INNER JOIN (или просо JOIN), а не LEFT)
В программировании - чудес не бывает, либо они все вазаимоисключаются, либо у исчезнувших трёх строк: "что-то иначе", чем у остальных 333.
И вот это: "что-то иначе" - явно ТС нужно прояснить в БД.
Последний раз редактировалось vitaly_l 15.06.2017 09:46:21, всего редактировалось 1 раз.
kosteek
постоялец
Сообщения: 203
Зарегистрирован: 24.07.2008 14:57:09
Откуда: Украина, г.Славянск

Сообщение kosteek »

Тогда что-то такое получается:

Код: Выделить всё

SELECT CLIENTS.CLIENT_ID,
       CLIENTS.CREATOR,
       CREATOR_EMPL.EMPLOYEE AS "CREATORLOOKUP",
       CLIENTS.EDITOR,
       EDITOR_EMPL.EMPLOYEE AS "EDITORLOOKUP",
       CLIENTS.EDITED,
       CLIENTS.CLIENT,
       CLIENTS.PHONE,
       CLIENTS.ADDRESS,
       CLIENTS.E-MAIL,
       CLIENTS.ANGRY,
       CLIENTS.NOTES
FROM CLIENTS,
     (select * from EMPLOYEES) as CREATOR_EMPL,
     (select * from EMPLOYEES) as EDITOR_EMPL
WHERE CREATOR_EMPL.EMPLOYEE_ID = CLIENTS.CREATOR AND (EDITOR_EMPL.EMPLOYEE_ID = CLIENTS.EDITOR OR CLIENTS.EDITOR IS NULL)
ORDER BY CLIENT ASC;
Аватара пользователя
vitaly_l
долгожитель
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41
Контактная информация:

Сообщение vitaly_l »

kosteek писал(а):Тогда что-то такое получается:

У него скорее всего вот это значение не равно друг другу: CREATOR_EMPL.EMPLOYEE_ID = CLIENTS.CREATOR, т.к. оно всегда должно быть равно. Либо, EDITOR_EMPL.EMPLOYEE_ID = CLIENTS.EDITOR, больше null, но опять таки не равны друг-другу. Соответственно такие строки после запроса - 100% не показываются. Но заниматься вангинацией - бессмысленно, т.к. нам невидно самой БД.
olegy123
долгожитель
Сообщения: 1643
Зарегистрирован: 25.02.2016 11:10:20

Сообщение olegy123 »

Это конвейер - там все операции поделены построенной логикой от запроса поэтому когда в

Код: Выделить всё

SELECT
..
       EMPLOYEES.EMPLOYEE AS "CREATORLOOKUP",
       EMPLOYEES.EMPLOYEE AS "EDITORLOOKUP",
..

он выплевывает, что есть как итог EMPLOYEES.EMPLOYEE.. Еще весело будет если EMPLOYEES.EMPLOYEE - будет содержать более 1 позиции на одну позицию из CLIENTS.
EMPLOYEES.EMPLOYEE AS "CREATORLOOKUP", EMPLOYEES.EMPLOYEE AS "EDITORLOOKUP" - это один и тот же Raw из таблицы EMPLOYEES.
kosteek
постоялец
Сообщения: 203
Зарегистрирован: 24.07.2008 14:57:09
Откуда: Украина, г.Славянск

Сообщение kosteek »

olegy123 писал(а):Это конвейер - там все операции поделены поэтому когда в

Не совсем понял что подразумевается под конвейером.
Автор вроде писал
Unvictis писал(а):из таблицы EMPLOYEES - создатель и редактор записи
Ответить