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.