tags:

views:

42

answers:

3

I am having trouble with a mysql query. I want to get a unique pairing of names that share the same tenant_group_id number. All you need to know is that each tenant has a unique individual_tenant_id and up to two individual tenants share the same tenant_group_id.

   SELECT t1.first_name, t2.first_name  
     FROM individualtenant t1  
LEFT JOIN individualtenant t2 ON t1.tenant_group_id = t2.tenant_group_id
                             AND t1.individual_tenant_id != t2.individual_tenant_id

Right now this is giving me pairs but both ways, for example, it would return "John", "Melissa" and "Melissa", "John" but I only need a unique pairing.

EDIT: And if the individualtenant does not have a partner I need to have NULL in the second column.

+1  A: 

Try:

SELECT t1.first_name, t2.first_name
FROM individualtenant t1
LEFT JOIN individualtenant t2
ON t1.tenant_group_id = t2.tenant_group_id 
WHERE t1.individual_tenant_id < t2.individual_tenant_id 
    or t2.individual_tenant_id is null;
RedFilter
Still gives me the same number of pairs, but the second pairing has NULL since left join preserves everything on the left. How should I form this to throw those out?
MCH
Ok, just switched to Inner Join and it worked :P Though I would like to know how to do it with a variable amount of tenants as well, and I do need to add a NULL if the tenant does not have a partner.
MCH
Try my updated version.
RedFilter
I added one thing to make it work ON t1.tenant_group_id = t2.tenant_group_id AND t1.individual_tenant_id != t2.individual_tenant_id
MCH
And I am trying to do a count on the query result but get an error I do SELECT COUNT(*) FROM (aforementionedQuery); And I get every derived table must have its own alias.
MCH
Nevermind, I fixed it by adding an AS NAME
MCH
A: 

Doing it with a LEFT JOIN where a NULL could be either 'no second tenant' or 'matched on previous ordering of tenants' could be quite tricky, and I'm not sure how to handle those. However, if this is all the data you need, and there's no need to fetch further data from other tables, we could cheat a little bit (which would be a separated list of N values, 1 or more):

SELECT GROUP_CONCAT(first_name)
FROM individualtenant
GROUP BY tenant_group_id;

Another dirty, dirty cheat would be (with only 1 or 2 tenants):

SELECT MIN(first_name), IF(COUNt(*) > 1,MAX(first_name),NULL)
FROM individualtenant
GROUP BY tenant_group_id;
Wrikken
Great success! Now what if I wanted to COUNT those pairings. Seems you can't wrap GROUP_CONCAT(first_name) with a COUNT(), how would I do that for the second one. And also what's a good way to concat those two names into one column with a separating space? (Sorry for all the requests)
MCH
FOr the first one, if you want to count the amount of members in the result, you'd just have a second column `COUNT(*)` (or any particular unique field). I wouldn't recommend separating names with a space, as that could be a legitimate content of a name, I'd recommend choosing a `SEPARATOR` that is a non-printable character (look at the manual how `group_concat` works), so it's more or less expected never to be in a `first_name` column, unless there was some input error. Be aware this is 'hackish' though: choose your separator carefully and always be vigilant/suspicious.
Wrikken
A: 

Is this what you seek?

SELECT
t1.first_name AS 'first_tenant',
t2.first_name AS 'second_tenant'
FROM
individualtenant t1,
individualtenant t2
WHERE
    t1.tenant_group_id = t2.tenant_group_id
AND t1.individual_tenant_id < t2.individual_tenant_id
UNION
SELECT
t1.first_name,
"No Match"
FROM
individualtenant t1
WHERE NOT EXISTS (
SELECT *
FROM individualtenant t2
WHERE
    t2.individual_tenant_id <> t1.individual_tenant_id
AND t2.tenant_group_id = t1.tenant_group_id
)
KMW