NOT EXISTS() predicate sometimes return NULL instead True or False ------------------------------------------------------------------
Key: CORE-6120 URL: http://tracker.firebirdsql.org/browse/CORE-6120 Project: Firebird Core Issue Type: Bug Components: Engine Affects Versions: 3.0.4, 3.0.5 Reporter: Karol Bieniaszewski In below query second column rerurn "NULL" instead of "TRUE". If you remove "NOT" then result is "FALSE". Run it against database from CORE-6106 SELECT K.ID , ( NOT EXISTS (WITH KWARTALY AS (SELECT * FROM KWARTAL KW WHERE KW.CKWARTAL BETWEEN '2019.I' AND '2019.I'), KWARTALY_DATY AS (SELECT MIN(KW.ZALICZAJ_OD) AS MIN_ZALICZAJ_OD , MAX(KW.ZALICZAJ_DO) AS MAX_ZALICZAJ_DO , MIN(KW.D_OD) AS MIN_D_OD , MAX(KW.D_DO) AS MAX_D_DO , MIN(KW.CKWARTAL) AS MIN_KWARTAL , MAX(KW.CKWARTAL) AS MAX_KWARTAL FROM KWARTALY KW) SELECT 1 FROM KWARTALY_DATY KW WHERE /* jest jakakolwiek deklaracja w zadanym przedziale to znaczy, ze jest platnikiem */ EXISTS (SELECT * FROM SPR S INNER JOIN KWARTAL SKW ON S.ID_KWARTAL = SKW.ID WHERE S.ID_KONTRAHENT = K.ID AND SKW.CKWARTAL BETWEEN KW.MIN_KWARTAL AND KW.MAX_KWARTAL ) OR /* jesli ma wpis o statusie dzialnosci za zadany okres (z data pozyaskania nie z przyszlosci) to tez jest platnikiem */ EXISTS (SELECT * FROM STATUS_PLATNIKA SP INNER JOIN STATUS_PLATNIKA_TYP SPT ON SP.ID_STATUS_PLATNIKA_TYP = SPT.ID WHERE SP.ID_KONTRAHENT = K.ID AND SP.DATA_POZYSKANIA <= KW.MAX_ZALICZAJ_DO AND (SPT.FLAGA_SYS IN(1) AND ((SP.DATA_OD <= KW.MAX_D_DO) AND (SP.DATA_DO IS NULL OR (SP.DATA_DO >= KW.MIN_D_OD)))) ) UNION ALL SELECT 1 FROM KWARTALY_DATY KD INNER JOIN URZADZENIE U ON 1 = 1 /* robimy liste kwartalow w ktorych obowiazuje status dzialalnosci kontrahenta i szukamy brakow deklaracji */ INNER JOIN KWARTALY KW ON EXISTS (SELECT * FROM STATUS_PLATNIKA SP INNER JOIN STATUS_PLATNIKA_TYP SPT ON SP.ID_STATUS_PLATNIKA_TYP = SPT.ID WHERE SP.ID_KONTRAHENT = K.ID AND SP.DATA_POZYSKANIA <= KD.MAX_ZALICZAJ_DO AND (SPT.FLAGA_SYS IN(1) AND ((SP.DATA_OD <= KW.D_DO) AND (SP.DATA_DO IS NULL OR (SP.DATA_DO >= KW.D_OD)))) ) WHERE NOT EXISTS (SELECT * FROM SPR S WHERE S.ID_KONTRAHENT = K.ID AND S.ID_URZADZENIE = U.ID AND ((EXTRACT(YEAR FROM S.DATA_OD)*12+EXTRACT(MONTH FROM S.DATA_OD)) BETWEEN(KW.ROK*12+KW.MIESIAC_OD) AND (KW.ROK*12+KW.MIESIAC_DO) OR (EXTRACT(YEAR FROM S.DATA_DO)*12+EXTRACT(MONTH FROM S.DATA_DO)) BETWEEN(KW.ROK*12+KW.MIESIAC_OD) AND (KW.ROK*12+KW.MIESIAC_DO)) ) ) AND (WITH KWARTALY AS (SELECT * FROM KWARTAL KW WHERE KW.CKWARTAL BETWEEN '2019.I' AND '2019.I'), KWARTALY_DATY AS (SELECT MIN(KW.ZALICZAJ_OD) AS MIN_ZALICZAJ_OD , MAX(KW.ZALICZAJ_DO) AS MAX_ZALICZAJ_DO , MIN(KW.D_OD) AS MIN_D_OD , MAX(KW.D_DO) AS MAX_D_DO , MIN(KW.CKWARTAL) AS MIN_KWARTAL , MAX(KW.CKWARTAL) AS MAX_KWARTAL FROM KWARTALY KW) SELECT DATEDIFF(DAY, KD.MIN_D_OD, KD.MAX_D_DO) FROM KWARTALY_DATY KD) =(WITH KWARTALY AS (SELECT * FROM KWARTAL KW WHERE KW.CKWARTAL BETWEEN '2019.I' AND '2019.I'), KWARTALY_DATY AS (SELECT MIN(KW.ZALICZAJ_OD) AS MIN_ZALICZAJ_OD , MAX(KW.ZALICZAJ_DO) AS MAX_ZALICZAJ_DO , MIN(KW.D_OD) AS MIN_D_OD , MAX(KW.D_DO) AS MAX_D_DO , MIN(KW.CKWARTAL) AS MIN_KWARTAL , MAX(KW.CKWARTAL) AS MAX_KWARTAL FROM KWARTALY KW) SELECT SUM(DATEDIFF(DAY, CASE WHEN SP.DATA_OD < KD.MIN_D_OD THEN KD.MIN_D_OD ELSE SP.DATA_OD END, CASE WHEN COALESCE(SP.DATA_DO, KD.MAX_D_DO) > KD.MAX_D_DO THEN KD.MAX_ZALICZAJ_DO ELSE COALESCE(SP.DATA_DO, KD.MAX_D_DO) END)) FROM KWARTALY_DATY KD INNER JOIN STATUS_PLATNIKA SP ON 1 = 1 INNER JOIN STATUS_PLATNIKA_TYP SPT ON SP.ID_STATUS_PLATNIKA_TYP = SPT.ID WHERE SP.ID_KONTRAHENT = K.ID AND SP.DATA_POZYSKANIA <= KD.MAX_ZALICZAJ_DO AND (SPT.FLAGA_SYS IN(2) AND SP.DATA_OD <= KD.MAX_D_DO AND (SP.DATA_DO IS NULL OR SP.DATA_DO >= KD.MIN_D_OD)))) FROM KONTRAHENT K WHERE (( /* PP platnik */ CASE WHEN ( EXISTS (WITH KWARTALY AS (SELECT * FROM KWARTAL KW WHERE KW.CKWARTAL BETWEEN '2019.I' AND '2019.I'), KWARTALY_DATY AS (SELECT MIN(KW.ZALICZAJ_OD) AS MIN_ZALICZAJ_OD , MAX(KW.ZALICZAJ_DO) AS MAX_ZALICZAJ_DO , MIN(KW.D_OD) AS MIN_D_OD , MAX(KW.D_DO) AS MAX_D_DO , MIN(KW.CKWARTAL) AS MIN_KWARTAL , MAX(KW.CKWARTAL) AS MAX_KWARTAL FROM KWARTALY KW) SELECT 1 FROM KWARTALY_DATY KW WHERE /* jest jakakolwiek deklaracja w zadanym przedziale to znaczy, ze jest platnikiem */ EXISTS (SELECT * FROM SPR S INNER JOIN KWARTAL SKW ON S.ID_KWARTAL = SKW.ID WHERE S.ID_KONTRAHENT = K.ID AND SKW.CKWARTAL BETWEEN KW.MIN_KWARTAL AND KW.MAX_KWARTAL ) OR /* jesli ma wpis o statusie dzialnosci za zadany okres (z data pozyaskania nie z przyszlosci) to tez jest platnikiem */ EXISTS (SELECT * FROM STATUS_PLATNIKA SP INNER JOIN STATUS_PLATNIKA_TYP SPT ON SP.ID_STATUS_PLATNIKA_TYP = SPT.ID WHERE SP.ID_KONTRAHENT = K.ID AND SP.DATA_POZYSKANIA <= KW.MAX_ZALICZAJ_DO AND (SPT.FLAGA_SYS IN(1) AND ((SP.DATA_OD <= KW.MAX_D_DO) AND (SP.DATA_DO IS NULL OR (SP.DATA_DO >= KW.MIN_D_OD)))) ) UNION ALL SELECT 1 FROM KWARTALY_DATY KD INNER JOIN URZADZENIE U ON 1 = 1 /* robimy liste kwartalow w ktorych obowiazuje status dzialalnosci kontrahenta i szukamy brakow deklaracji */ INNER JOIN KWARTALY KW ON EXISTS (SELECT * FROM STATUS_PLATNIKA SP INNER JOIN STATUS_PLATNIKA_TYP SPT ON SP.ID_STATUS_PLATNIKA_TYP = SPT.ID WHERE SP.ID_KONTRAHENT = K.ID AND SP.DATA_POZYSKANIA <= KD.MAX_ZALICZAJ_DO AND (SPT.FLAGA_SYS IN(1) AND ((SP.DATA_OD <= KW.D_DO) AND (SP.DATA_DO IS NULL OR (SP.DATA_DO >= KW.D_OD)))) ) WHERE NOT EXISTS (SELECT * FROM SPR S WHERE S.ID_KONTRAHENT = K.ID AND S.ID_URZADZENIE = U.ID AND ((EXTRACT(YEAR FROM S.DATA_OD)*12+EXTRACT(MONTH FROM S.DATA_OD)) BETWEEN(KW.ROK*12+KW.MIESIAC_OD) AND (KW.ROK*12+KW.MIESIAC_DO) OR (EXTRACT(YEAR FROM S.DATA_DO)*12+EXTRACT(MONTH FROM S.DATA_DO)) BETWEEN(KW.ROK*12+KW.MIESIAC_OD) AND (KW.ROK*12+KW.MIESIAC_DO)) ) )) IS NULL THEN -1 ELSE 0 END /* PP platnik koniec */ + /* PP nieplatnik */ CASE WHEN ( NOT EXISTS (WITH KWARTALY AS (SELECT * FROM KWARTAL KW WHERE KW.CKWARTAL BETWEEN '2019.I' AND '2019.I'), KWARTALY_DATY AS (SELECT MIN(KW.ZALICZAJ_OD) AS MIN_ZALICZAJ_OD , MAX(KW.ZALICZAJ_DO) AS MAX_ZALICZAJ_DO , MIN(KW.D_OD) AS MIN_D_OD , MAX(KW.D_DO) AS MAX_D_DO , MIN(KW.CKWARTAL) AS MIN_KWARTAL , MAX(KW.CKWARTAL) AS MAX_KWARTAL FROM KWARTALY KW) SELECT 1 FROM KWARTALY_DATY KW WHERE /* jest jakakolwiek deklaracja w zadanym przedziale to znaczy, ze jest platnikiem */ EXISTS (SELECT * FROM SPR S INNER JOIN KWARTAL SKW ON S.ID_KWARTAL = SKW.ID WHERE S.ID_KONTRAHENT = K.ID AND SKW.CKWARTAL BETWEEN KW.MIN_KWARTAL AND KW.MAX_KWARTAL ) OR /* jesli ma wpis o statusie dzialnosci za zadany okres (z data pozyaskania nie z przyszlosci) to tez jest platnikiem */ EXISTS (SELECT * FROM STATUS_PLATNIKA SP INNER JOIN STATUS_PLATNIKA_TYP SPT ON SP.ID_STATUS_PLATNIKA_TYP = SPT.ID WHERE SP.ID_KONTRAHENT = K.ID AND SP.DATA_POZYSKANIA <= KW.MAX_ZALICZAJ_DO AND (SPT.FLAGA_SYS IN(1) AND ((SP.DATA_OD <= KW.MAX_D_DO) AND (SP.DATA_DO IS NULL OR (SP.DATA_DO >= KW.MIN_D_OD)))) ) UNION ALL SELECT 1 FROM KWARTALY_DATY KD INNER JOIN URZADZENIE U ON 1 = 1 /* robimy liste kwartalow w ktorych obowiazuje status dzialalnosci kontrahenta i szukamy brakow deklaracji */ INNER JOIN KWARTALY KW ON EXISTS (SELECT * FROM STATUS_PLATNIKA SP INNER JOIN STATUS_PLATNIKA_TYP SPT ON SP.ID_STATUS_PLATNIKA_TYP = SPT.ID WHERE SP.ID_KONTRAHENT = K.ID AND SP.DATA_POZYSKANIA <= KD.MAX_ZALICZAJ_DO AND (SPT.FLAGA_SYS IN(1) AND ((SP.DATA_OD <= KW.D_DO) AND (SP.DATA_DO IS NULL OR (SP.DATA_DO >= KW.D_OD)))) ) WHERE NOT EXISTS (SELECT * FROM SPR S WHERE S.ID_KONTRAHENT = K.ID AND S.ID_URZADZENIE = U.ID AND ((EXTRACT(YEAR FROM S.DATA_OD)*12+EXTRACT(MONTH FROM S.DATA_OD)) BETWEEN(KW.ROK*12+KW.MIESIAC_OD) AND (KW.ROK*12+KW.MIESIAC_DO) OR (EXTRACT(YEAR FROM S.DATA_DO)*12+EXTRACT(MONTH FROM S.DATA_DO)) BETWEEN(KW.ROK*12+KW.MIESIAC_OD) AND (KW.ROK*12+KW.MIESIAC_DO)) ) ) AND (WITH KWARTALY AS (SELECT * FROM KWARTAL KW WHERE KW.CKWARTAL BETWEEN '2019.I' AND '2019.I'), KWARTALY_DATY AS (SELECT MIN(KW.ZALICZAJ_OD) AS MIN_ZALICZAJ_OD , MAX(KW.ZALICZAJ_DO) AS MAX_ZALICZAJ_DO , MIN(KW.D_OD) AS MIN_D_OD , MAX(KW.D_DO) AS MAX_D_DO , MIN(KW.CKWARTAL) AS MIN_KWARTAL , MAX(KW.CKWARTAL) AS MAX_KWARTAL FROM KWARTALY KW) SELECT DATEDIFF(DAY, KD.MIN_D_OD, KD.MAX_D_DO) FROM KWARTALY_DATY KD) =(WITH KWARTALY AS (SELECT * FROM KWARTAL KW WHERE KW.CKWARTAL BETWEEN '2019.I' AND '2019.I'), KWARTALY_DATY AS (SELECT MIN(KW.ZALICZAJ_OD) AS MIN_ZALICZAJ_OD , MAX(KW.ZALICZAJ_DO) AS MAX_ZALICZAJ_DO , MIN(KW.D_OD) AS MIN_D_OD , MAX(KW.D_DO) AS MAX_D_DO , MIN(KW.CKWARTAL) AS MIN_KWARTAL , MAX(KW.CKWARTAL) AS MAX_KWARTAL FROM KWARTALY KW) SELECT SUM(DATEDIFF(DAY, CASE WHEN SP.DATA_OD < KD.MIN_D_OD THEN KD.MIN_D_OD ELSE SP.DATA_OD END, CASE WHEN COALESCE(SP.DATA_DO, KD.MAX_D_DO) > KD.MAX_D_DO THEN KD.MAX_ZALICZAJ_DO ELSE COALESCE(SP.DATA_DO, KD.MAX_D_DO) END)) FROM KWARTALY_DATY KD INNER JOIN STATUS_PLATNIKA SP ON 1 = 1 INNER JOIN STATUS_PLATNIKA_TYP SPT ON SP.ID_STATUS_PLATNIKA_TYP = SPT.ID WHERE SP.ID_KONTRAHENT = K.ID AND SP.DATA_POZYSKANIA <= KD.MAX_ZALICZAJ_DO AND (SPT.FLAGA_SYS IN(2) AND SP.DATA_OD <= KD.MAX_D_DO AND (SP.DATA_DO IS NULL OR SP.DATA_DO >= KD.MIN_D_OD)))) IS NULL THEN -1 ELSE 0 END /* PP nieplatnik koniec */ ) < 0 AND K.KONT_NR+0 > 0) ORDER BY 1 -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://tracker.firebirdsql.org/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira Firebird-Devel mailing list, web interface at https://lists.sourceforge.net/lists/listinfo/firebird-devel