Backstory :
This is the output I was getting at this point. The ? are null values.
Name DataID LastName FirstName
File10 1290 ? Jane
File10 1290 Doe ?
I was able to include one statement or the other but could not add in both. Instead of getting an error I just got a horrifically long run time with no foreseeable result (note that I am using software which lets you input oracle queries within the interface to query the database). It works if I run the query up until the ** (see code) but as soon as I add in the OR condition, it doesn't work anymore. I think this is because I have multiple WHERE conditions. In all cases I want the directory ID and general stringval conditions to apply but I want to have a third condition where either lastname is not null or first name is not null. I'm not sure if I'm missing something obvious- please help?
Here is my current query:
SELECT directory.name, directory.dataid,
(SELECT max(stringval) FROM attribute2table WHERE attribute1table.attrid = 2) as LastName,
(SELECT max(stringval) FROM attribute2table WHERE attribute1table.attrid = 3) as FirstName
FROM attribute2table
JOIN directory ON directory.dataid = attribute2table.id
JOIN attribute1table ON attribute1table.id = directory.dataid
WHERE directory.dataid = 1290
AND stringval IS NOT NULL
AND (SELECT max(valstr) FROM attribute1table WHERE attribute1table.attrid = 2) IS NOT NULL
**OR (SELECT max(valstr) FROM attribute1table WHERE attribute1table.attrid = 3) IS NOT NULL**
Basically I just need to get rid of the null values and want my table to look like....
Name DataID LastName FirstName
File10 1290 Doe Jane
This appears to be a parenthesization issue. If I understand the issue, you need to put the two IS NOT NULL conditions in parentheses:
SELECT directory.name,
directory.dataid,
m2.LastName,
m3.FirstName
FROM attribute2table
INNER JOIN directory
ON directory.dataid = attribute2table.id
INNER JOIN attribute1table
ON attribute1table.id = directory.dataid
LEFT OUTER JOIN (SELECT max(valstr) AS LASTNAME
FROM attribute1table
WHERE attribute1table.attrid = 2) m2
ON 1 = 1
LEFT OUTER JOIN (SELECT max(valstr) AS FIRSTNAME
FROM attribute1table
WHERE attribute1table.attrid = 3) m3
ON 1 = 1
WHERE directory.dataid = 1290 AND
stringval IS NOT NULL AND
(m2.LASTNAME IS NOT NULL OR
m3.FIRSTNAME IS NOT NULL)
I also rewrote the query using joins instead of subselects as I think it's a bit clearer.
Note also that in the M2
and M3
joins I used LEFT OUTER
with a condition of 1 = 1
rather than using CROSS JOIN
, because I've noticed that CROSS JOIN
acts like an INNER JOIN
if the query being cross-joined returns no rows - that is, it causes the entire SELECT to return no data. dbfiddle demonstrating this situation here
I'm pretty sure you just need conditional aggregation:
SELECT d.name, d.dataid,
MAX(CASE WHEN a1.attrid = 2 THEN a2.stringval END) as LastName,
MAX(CASE WHEN a1.attrid = 3 THEN a2.stringval END) as FirstName
FROM directory d JOIN
attribute2table a2
ON a2.id = d.dataid JOIN
attribute1table a1
ON a1.id = d.dataid
WHERE d.dataid = 1290
GROUP BY d.name, d.dataid
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.