Reputation: 11
I have this query:
SELECT
s.id AS id,
s.item_id,
i.type_id AS type_id,
i.description AS description,
i.owner_id,
s.buyer_id,
i.receivedate,
i.statusdate,
i.baseprice,
i.salepercentage,
i.status_id,
s.posteddate,
s.closingdate,
s.discountdate,
s.discountrate,
t.description AS type_description,
st.description AS status_description
FROM
sale s
LEFT JOIN item i ON s.item_id=i.id
LEFT JOIN TYPE t ON i.type_id=t.id
LEFT JOIN STATUS st ON i.status_id=st.id
WHERE s.flag_id != 2
GROUP BY s.id
ORDER BY s.closingdate;
It works fine, but as a final step I need to pull in the concatenated firstname and lastname fields from yet another table called customer
for both the i.owner_id
and s.buyer_id
fields.
I've got close using the following:
SELECT
s.id AS id,
s.item_id,
i.type_id AS type_id,
i.description AS description,
i.owner_id,
s.buyer_id,
i.receivedate,
i.statusdate,
i.baseprice,
i.salepercentage,
i.status_id,
s.posteddate,
s.closingdate,
s.discountdate,
s.discountrate,
t.description AS type_description,
st.description AS status_description,
GROUP_CONCAT(CONCAT(c.firstname, ' ', c.lastname) ORDER BY i.owner_id, s.buyer_id)
FROM
sale s
LEFT JOIN item i ON s.item_id=i.id
LEFT JOIN TYPE t ON i.type_id=t.id
LEFT JOIN STATUS st ON i.status_id=st.id
LEFT JOIN CUSTOMER c ON i.owner_id=c.id OR s.buyer_id=c.id
WHERE s.flag_id != 2
GROUP BY s.id
ORDER BY s.closingdate;
When I test it using entries in the customer table like the following:
id=3, firstname="John", lastname="Doe"
id=10, firstname="Jane", lastname="Do"
And the items from the sale table have:
owner_id=3, buyer_id=10
owner_id=10, buyer_id=3
The GROUP_CONCAT()
column returns
Jane Do,John Doe
Jane Do,John Doe
I have no way of knowing which is the owner and which is the buyer purely off the comma separated position as the results I was hoping for were
John Doe,Jane Do
Jane Do,John Doe
for the sale items.
Is it possible to ensure that the result set returned will have the GROUP_CONCAT()
list returned in a controlled order (i.e. the first customer will be associated with the owner_id
and the 2nd customer with the buyer_id
)?
Upvotes: 1
Views: 639
Reputation: 360702
I'd suggest joining the customer table twice. once for buyer, once for owner:
SELECT ...
GROUP_CONCAT(CONCAT(buyer.firstname, ' ', buyer.lastname) AS buyers,
GROUP_CONCAT(CONCAT(owner.firstname, ' ', owner.lastname) AS owners
...
LEFT JOIN customer AS buyer ON s.buyer_id=buyer.id
LEFT JOIN customer AS owner ON i.owner_id=owner.id
If you need data to be kept separate, then keep it separate.
Upvotes: 3
Reputation: 76567
The problem is that you are mixing owners and buyers.
Just join them separately;
it's no problem joining on the same table twice as long as you use a different alias for each instance.
SELECT
s.id AS id, s.item_id
, i.type_id AS type_id, i.description AS description, i.owner_id
, s.buyer_id
, i.receivedate, i.statusdate, i.baseprice, i.salepercentage, i.status_id
, s.posteddate, s.closingdate, s.discountdate, s.discountrate
, t.description AS type_description
, st.description AS status_description
, GROUP_CONCAT(
CONCAT(co.firstname, ' ', co.lastname,',',cb.firstname,' ',cb.lastname)
ORDER BY co.id,cb.id) as first_owner_than_buyer
FROM sale s
LEFT JOIN item i ON s.item_id=i.id
LEFT JOIN TYPE t ON i.type_id=t.id
LEFT JOIN STATUS st ON i.status_id=st.id
LEFT JOIN CUSTOMER co ON (i.owner_id=co.id)
LEFT JOIN CUSTOMER cb ON (s.buyer_id=cb.id)
WHERE s.flag_id != 2
GROUP BY s.id
ORDER BY s.closingdate;
Upvotes: 1