开发者

MySQL ordering SELECT by associated column

I'd like to select some Addresses from a MySQL DB. Addresses can have a Contact, an Organization, or both. (A Contact can have many Addresses. So can an Organization.)

Let's say I want to get all of an Organization's Addresses. That's no big deal. But what if I want to ORDER them by Contact.last_name? Some of the Addresses don't have a Contact.

I did some experimenting and discovere开发者_开发问答d that if you ORDER BY contacts.last_name, then only those Addresses that have a Contact will be returned. I tried ORDER BY contacts.last_name, addresses.street1, but still only Addresses that had an associated Contact were returned.

Is there a query that will find Addresses by Organization.id, order the results by Contact.last_name, and include all the Organization's Addresses, even ones that don't have a Contact?


Table structure

addresses
---------
id
contact_id
organization_id
street1

contacts
--------
id
last_name

organizations
-------------
id
name

Solution:

Returns all the Organization's Addresses:

SELECT a.*
FROM addresses a
LEFT JOIN contacts c
ON a.contact_id = c.id
WHERE a.organization_id = '8283'
ORDER BY c.last_name

OK, great the above query solved it.


The problem is probably the join and not the order-by clause. As soon as you join the Addresses table with the Contacts table, the join condition will eliminate all tuples with NULL values.

To avoid this, you have to use an OUTER JOIN instead of an INNER JOIN (the default). The idea behind an OUTER JOIN is simply to extend the missing table rows with NULL values for processing/ordering and so on.


You could use the MySQL IFNULL function to return an empty string when there is no associated contact. That way, if there is no associated contact for an address, you still get a record with an empty string in the contact column if there is no contact.

For example:

SELECT a.*,
IFNULL(c.last_name, '') AS last_name
FROM Addresses a
LEFT JOIN Contacts c
ON a.contact_id = c.id
ORDER BY IFNULL(c.last_name, '')

As others have pointed out, ORDER BY does not filter out missing records. Ensure you have the proper join in your query and it will return records even if there is no associated contact. I have added the IFNULL to return an empty string instead of a NULL, but that is only for aesthetics and doesn't actually change the number of records returned.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜