tags:

views:

214

answers:

1
+3  Q: 

A strange SQL join

Simplified for example, I have two tables, groups and items.

items (
    id,
    groupId,
    title
)

groups (
    id,
    groupTitle,
    externalURL
)

The regular query I'm goes something like this:

SELECT
    i.`id`,
    i.`title`,
    g.`id` as 'groupId',
    g.`groupTitle`,
    g.`externalURL`
FROM
    items i INNER JOIN groups g ON (i.`groupId` = g.`id`)

However I need to modify this now, because all the groups which specify an externalURL will not have any corresponding records in the items table (since they're stored externally). Is it possible to do some sort of join so that the output looks kinda like this:

items:
id    title    groupId
----------------------
1     Item 1   1
2     Item 2   1

groups
id    groupTitle    externalURL
-------------------------------
1     Group 1       NULL
2     Group 2       something
3     Group 3       NULL

Query output:
id    title    groupId    groupTitle    externalURL
---------------------------------------------------
1     Item 1   1          Group 1       NULL
2     Item 2   1          Group 1       NULL
NULL  NULL     2          Group 2       something

-- note that group 3 didn't show up because it had no items OR externalURL

Is that possible in one SQL query?

+10  A: 

This is exactly what an outer join is for: return all the rows from one table, whether or not there is a matching row in the other table. In those cases, return NULL for all the columns of the other table.

The other condition you can take care of in the WHERE clause.

SELECT
    i.`id`,
    i.`title`,
    g.`id` as 'groupId',
    g.`groupTitle`,
    g.`externalURL`
FROM
    items i RIGHT OUTER JOIN groups g ON (i.`groupId` = g.`id`)
WHERE i.`id` IS NOT NULL OR g.`externalURL` IS NOT NULL;

Only if both i.id and g.externalURL are NULL, then the whole row of the joined result set should be excluded.

Bill Karwin
I guess I should have listened more in Databases 101, hey? Cheers.
nickf