Reputation: 8414
I'm trying to pull in data from several tables, one of which has a one-to-many relationship. My SQL looks like this:
SELECT
VU.*,
UI.UserImg,
COALESCE(CI.Interests, 0) as NumInterests
FROM [vw_tmpUsers] VU
LEFT JOIN (
SELECT
[tmpUserPhotos].UserID,
CASE WHEN MAX([tmpUserPhotos].uFileName) = NULL
THEN 'dflt.jpg'
ELSE Max([tmpUserPhotos].uFileName)
END as UserImg
FROM [tmpUserPhotos]
GROUP BY UserID) UI
ON VU.UserID = UI.UserID
I've excluded a bunch of LEFT JOINS which follows this, because they're all working properly.
My trouble is, I only want to pull in one image name from the table which has a one-to-many relationship. In order to do this, I've used the MAX function.
My desired result would look like this:
UserID UserName UserState UserZip UserIncome UserHeight UserImg
1 Jimbo NY 10012 2 64 1[Blue hills.jpg
2 Jack MA 06902 3 66 dflt.jpg
3 Lisa CT 06820 4 64 dflt.jpg
4 Mary CT 06791 6 67 4[Natalie.jpg
5 Wanda CT 06791 6 67 dflt.jpg
but instead it looks like this:
UserID UserName UserState UserZip UserIncome UserHeight UserImg
1 Jimbo NY 10012 2 64 1[Blue hills.jpg
2 Jack MA 06902 3 66 NULL
3 Lisa CT 06820 4 64 NULL
4 Mary CT 06791 6 67 4[Natalie.jpg
5 Wanda CT 06791 6 67 NULL
It's got to be something wonky in my CASE statement, but I'm not very good with them. I've tried using IS NULL, = NULL, ='NULL', all to no avail.
Can anyone spot what I'm doing wrong? One little tidbit that might shed light; MAX(tmpUserPhotos.uFileName) will only return NULL if there is no matching record in tmpUserPhotos.
Upvotes: 2
Views: 54
Reputation:
The reason your CASE
expression is returning nulls even though you have included a check for them is that the expression WHEN MAX([tmpUserPhotos].uFileName) = NULL
will never evaluate as true, even when MAX([tmpUserPhotos].uFileName)
is null.
This is because nulls are a special type of value in SQL, one which means "value is not known" - almost any comparison with a null value evaluates as null, not true or false.
For this reason, you need to use a function such as coalesce
or isnull
to check whether the expression evaluates as null; alternately, you could amend your case condition to test whether the expression is null
, like so:
CASE WHEN MAX([tmpUserPhotos].uFileName) IS NULL
THEN 'dflt.jpg'
ELSE Max([tmpUserPhotos].uFileName)
END as UserImg
Upvotes: 1
Reputation: 1263
Look at the using of TOP
operator and subquery
.
SELECT
VU.*,
ISNULL((SELECT TOP 1 UP.uFileName FROM tmpUserPhotos AS UP
WHERE UP.userid = VU.userID), 'dflt.jpg') AS userImg
FROM [vw_tmpUsers] VU
Upvotes: 1
Reputation: 3312
Instead of the case statement, try the 'isnull' function...
isnull(MAX([tmpUserPhotos].uFileName),'dflt.jpg') as UserImg
Upvotes: 2
Reputation: 1271241
You need to check for NULL
in the outer query:
SELECT VU.*,
COALESCE(UI.UserImg, 'dflt.jpg') as UserImg,
COALESCE(CI.Interests, 0) as NumInterests
FROM [vw_tmpUsers] VU LEFT JOIN
(SELECT [tmpUserPhotos].UserID, MAX([tmpUserPhotos].uFileName) as UserImg
FROM [tmpUserPhotos]
GROUP BY UserID
) UI
ON VU.UserID = UI.UserID ;
You are getting NULL
values because the LEFT JOIN
has no matches. No matches means that the SELECT
is not being executed on any data.
I'll also note that if you have a preference for the priority of the images, then OUTER APPLY
is easier than LEFT JOIN
. However, that would be another question.
Upvotes: 3