Reputation: 1237
I have below query. But it is not bringing the results how i want.
In case if UPPER(PCK.Keyid) = 'TLMAPICONFIGMGR.USEDB' AND UPPER(PCK.DEFAULTKEYIDVALUE) = 'FALSE' then, it should bring only this record. If PCK.DEFAULTKEYIDVALUE is not False, it should bring all other records back.
Though it is false in the database, it is bringing all records including this one.
How to fix this where Clause?
SELECT
COALESCE(Cast(PCBS.keyId as VarChar2(255)), cast(PC.Keyid as varchar2(255)), cast(PCK.KeyId as varchar2(255))) as Key,
COALESCE(Cast(PCBS.KeyIdValue as VarChar2(255)), cast(PC.KeyIdValue as varchar2(255)), cast(PCK.DefaultKeyIdValue as varchar2(255))) as value
FROM
PodServer_Tab PS
JOIN PodConfigKey_tab PCK
ON PCK.KeyId = PCK.KEYID
LEFT OUTER JOIN PodConfig_Tab PC
ON PS.PodId = PC.PodId
LEFT JOIN PodConfigByServer_Tab PCBS
ON PS.PODID = PCBS.PODID
AND PS.ServerName = PCBS.ServerName
AND PCBS.KeyId = PC.KeyId
WHERE PS.PodId = p_podId
AND PS.Servername = p_serverName
AND (
(UPPER(PCK.Keyid) = 'TLMAPICONFIGMGR.USEDB' AND UPPER(PCK.DEFAULTKEYIDVALUE) = 'FALSE')
OR
(UPPER(PCK.Keyid) != 'TLMAPICONFIGMGR.USEDB')
);
Upvotes: 0
Views: 66
Reputation: 191235
The filter is applied against each row.
AND (
(UPPER(PCK.Keyid) = 'TLMAPICONFIGMGR.USEDB' AND UPPER(PCK.DEFAULTKEYIDVALUE) = 'FALSE')
OR
(UPPER(PCK.Keyid) != 'TLMAPICONFIGMGR.USEDB')
);
For every row, UPPER(PCK.Keyid)
either does or does not match 'TLMAPICONFIGMGR.USEDB'
. Every row that does not match will always be returned, because there is nothing saying it shouldn't be.
The only time anything will be excluded is if UPPER(PCK.DEFAULTKEYIDVALUE)
does not equal 'FALSE'
, in which case only that row will be excluded. It has no effect on rows which don't match the Keyid
, only on those that do.
Whatever that default is set to, all other Keyid
values will always match.
If you want to only see a single row or everything except that row, then you need to look wider than one row at a time. You could add an exists
clause, something like:
AND (
(UPPER(PCK.Keyid) = 'TLMAPICONFIGMGR.USEDB' AND UPPER(PCK.DEFAULTKEYIDVALUE) = 'FALSE')
OR
(UPPER(PCK.Keyid) != 'TLMAPICONFIGMGR.USEDB'
AND NOT EXISTS (
SELECT 1 FROM PodConfigKey_tab PCK2
WHERE PCK2.KeyId = PCK.KEYID
AND UPPER(PCK2.Keyid) = 'TLMAPICONFIGMGR.USEDB'
AND UPPER(PCK2.DEFAULTKEYIDVALUE) = 'FALSE'
)
)
);
You could use a subquery with analytic functions but it you're looking up a single value there may not be much benefit and the correlated self-join won't be too expensive.
I don't think this is relevant to the issue you're describing, but at the moment you have what appears to be a broken join condition too:
JOIN PodConfigKey_tab PCK
ON PCK.KeyId = PCK.KEYID
should presumably be:
JOIN PodConfigKey_tab PCK
ON PS.KeyId = PCK.KEYID
otherwise it is a cross-join rather than an inner join; in which case it would be clearer to use:
CROSS JOIN PodConfigKey_tab PCK
(with no ON
clause, since a cross join doesn't allow one) to make it clear that is the intention.
Upvotes: 2
Reputation: 2115
OR
(UPPER(PCK.Keyid) != 'TLMAPICONFIGMGR.USEDB')
well the above is saying show me everything where keyid != 'TLMAPICONFIGMGR.USEDB', so you will get everything (assuming the servername matches)
Upvotes: 1