I’ve got a database like this one:
I’m trying to create a query that would enable me to update the value of the status
attribute inside the incident
table whenever the values of all of these three attributes: tabor_vatrogasci
, tabor_policija
, and tabor_hitna
are contained inside the izvještaj_tabora
table as a value of the oznaka_tabora
attribute. If, for example, the values of the tabor_vatrogasci
, tabor_policija
, and tabor_hitna
attributes are 3, 4 and 5 respectively, the incident
table should be updated if (and only if) 3, 4, and 5 are contained inside the izvještaj_tabora
table.
This is what I tried, but it didn’t work:
UPDATE incident SET status='Otvoren' FROM tabor,izvjestaj_tabora WHERE (incident.tabor_policija=tabor.oznaka OR incident.tabor_vatrogasci=tabor.oznaka OR incident.tabor_hitna=tabor.oznaka) AND izvjestaj_tabora.oznaka_tabora=tabor.oznaka AND rezultat_izvjestaja='Riješen' AND ((SELECT EXISTS(SELECT DISTINCT oznaka_tabora FROM izvjestaj_tabora) WHERE oznaka_tabora=incident.tabor_policija) OR tabor_policija=NULL) AND ((SELECT EXISTS(SELECT DISTINCT oznaka_tabora FROM izvjestaj_tabora) WHERE oznaka_tabora=incident.tabor_vatrogasci) OR tabor_vatrogasci=NULL) AND ((SELECT EXISTS(SELECT DISTINCT oznaka_tabora FROM izvjestaj_tabora) WHERE oznaka_tabora=incident.tabor_hitna) OR tabor_hitna=NULL);
Does anyone have any idea on how to accomplish this?
Advertisement
Answer
According to your description the query should look something like this:
UPDATE incident i SET status = 'Otvoren' WHERE (tabor_policija IS NULL OR EXISTS ( SELECT 1 FROM izvjestaj_tabora t WHERE t.oznaka_tabora = i.tabor_policija ) ) AND (tabor_vatrogasci IS NULL OR EXISTS ( SELECT 1 FROM izvjestaj_tabora t WHERE t.oznaka_tabora = i.tabor_vatrogasci ) ) AND (tabor_hitna IS NULL OR EXISTS ( SELECT 1 FROM izvjestaj_tabora t WHERE t.oznaka_tabora = i.tabor_hitna ) )
I wonder though, why the connecting table tabor
is irrelevant to the operation.
Among other things you fell victim to two widespread misconceptions:
1)
tabor_policija=NULL
This expression aways results in NULL
. Since NULL
is considered “unknown”, if you compare it to anything, the outcome is “unknown” as well. I quote the manual on Comparison Operators:
Do not write expression = NULL because NULL is not “equal to” NULL. (The null value represents an unknown value, and it is not known whether two unknown values are equal.)
2)
EXISTS(SELECT DISTINCT oznaka_tabora FROM ...)
In an EXISTS
semi-join SELECT
items are completely irrelevant. (I use SELECT 1
instead). As the term implies, only existence is checked. The expression returns TRUE
or FALSE
, SELECT
items are ignored. It is particularly pointless to add a DISTINCT
clause there.