So, i have this problem in my hands.
I have to get multiples records from differents tables in inner join and get in a UNION or UNION ALL and use the limit to make one pagination, the following code is for get all the records and count. Here's my nemesis:
(SELECT pp.id as id, pp.*, i.name, p.name as plans_name, u.username,u.email,u.phone, DATE_ADD(pp.init_date, INTERVAL pp.avaliable_days DAY) as end_date FROM property_purchase pp
inner join users u ON pp.users_id $username
inner join inn_oficial i ON i.photo_id = pp.property_id
left join plans p ON pp.plans_id = p.id
WHERE (pp.type = 1 or pp.type = 2)
$where )
UNION
(SELECT pp.id as id, pp.*, i.model as name, p.name as plans_name, u.username,u.email,u.phone, DATE_ADD(pp.init_date, INTERVAL pp.avaliable_days DAY) as end_date FROM property_purchase pp
inner join users u ON pp.users_id $username
inner join rent_oficial i ON i.photo_id = pp.property_id
left join plans p ON pp.plans_id = p.id
WHERE pp.type = 3
$where)
UNION
(SELECT pp.id as id, pp.*, i.name, p.name as plans_name, u.username,u.email,u.phone, DATE_ADD(pp.init_date, INTERVAL pp.avaliable_days DAY) as end_date FROM property_purchase pp
inner join users u ON pp.users_id $username
inner join fish_pay_oficial i ON i.photo_id = pp.property_id
left join plans p ON pp.plans_id = p.id
WHERE pp.type = 4
$where )
UNION
(SELECT pp.id as id, pp.*, i.name, p.name as plans_name, u.username,u.email,u.phone, DATE_ADD(pp.init_date, INTERVAL pp.avaliable_days DAY) as end_date FROM property_purchase pp
inner join users u ON pp.users_id $username
inner join stores_oficial i ON i.photo_id = pp.property_id
left join plans p ON pp.plans_id = p.id
WHERE pp.type = 5
$where)
UNION
(SELECT pp.id as id, pp.*, i.name, p.name as plans_name, u.username,u.email,u.phone, DATE_ADD(pp.init_date, INTERVAL pp.avaliable_days DAY) as end_date FROM property_purchase pp
inner join users u ON pp.users_id $username
inner join transfer_oficial i ON i.photo_id = pp.property_id
inner join plans p ON pp.plans_id = p.id
WHERE pp.type = 6
$where)
GROUP BY pp.id
ORDER BY pp.id
I get this example from 13.2.9.3 UNION Clause and tried on script
When I try to run the code it gives an error
You have a syntax error in your SQL next to 'GROUP BY id ORDER BY id LIMIT 0.25' on line 1
Sorry for my horrible english, it's not my first language
CodePudding user response:
I solved kskskskks, just add the pp id column as id_p and then ordered by that
(SELECT pp.id as id_p, pp.*, i.name, p.name as plans_name, u.username,u.email,u.phone, DATE_ADD(pp.init_date, INTERVAL pp.avaliable_days DAY) as end_date FROM property_purchase pp
inner join users u ON pp.users_id $username
inner join inn_oficial i ON i.photo_id = pp.property_id
left join plans p ON pp.plans_id = p.id
WHERE (pp.type = 1 or pp.type = 2)
$where )
UNION
(SELECT pp.id as id_p, pp.*, i.model as name, p.name as plans_name, u.username,u.email,u.phone, DATE_ADD(pp.init_date, INTERVAL pp.avaliable_days DAY) as end_date FROM property_purchase pp
inner join users u ON pp.users_id $username
inner join rent_oficial i ON i.photo_id = pp.property_id
left join plans p ON pp.plans_id = p.id
WHERE pp.type = 3
$where)
UNION
(SELECT pp.id as id_p, pp.*, i.name, p.name as plans_name, u.username,u.email,u.phone, DATE_ADD(pp.init_date, INTERVAL pp.avaliable_days DAY) as end_date FROM property_purchase pp
inner join users u ON pp.users_id $username
inner join fish_pay_oficial i ON i.photo_id = pp.property_id
left join plans p ON pp.plans_id = p.id
WHERE pp.type = 4
$where )
UNION
(SELECT pp.id as id_p, pp.*, i.name, p.name as plans_name, u.username,u.email,u.phone, DATE_ADD(pp.init_date, INTERVAL pp.avaliable_days DAY) as end_date FROM property_purchase pp
inner join users u ON pp.users_id $username
inner join stores_oficial i ON i.photo_id = pp.property_id
left join plans p ON pp.plans_id = p.id
WHERE pp.type = 5
$where)
UNION
(SELECT pp.id as id_p, pp.*, i.name, p.name as plans_name, u.username,u.email,u.phone, DATE_ADD(pp.init_date, INTERVAL pp.avaliable_days DAY) as end_date FROM property_purchase pp
inner join users u ON pp.users_id $username
inner join transfer_oficial i ON i.photo_id = pp.property_id
inner join plans p ON pp.plans_id = p.id
WHERE pp.type = 6
$where)
ORDER BY id_p $pagination
CodePudding user response:
LIMIT 0.25
raises my suspicion because this clause is not represented in your provided query.
That doesn't really matter because this looks like an XY Problem -- I don't see any need to use any UNION clauses or GROUP BY. You are forcing your server to do too much work by scanning whole tables multiple times, not to mention the developer eye strain of having to read such a verbose and repetitive query.
I don't know what is inside of $where
, but my crystal ball tells me that it's not secure query practices. I'd want to be using a prepared statement if there are any variables being passed in.
If you need individualized control of the column values SELECTed based on the pp.type
, then you can use CASE
expressions in your SELECT.
I reckon your query can boil down to something like this:
SELECT pp.*,
i.name,
p.name AS plans_name,
u.username,
u.email,
u.phone,
DATE_ADD(pp.init_date, INTERVAL pp.avaliable_days DAY) AS end_date
FROM property_purchase pp
JOIN users u ON pp.users_id = u.id
JOIN inn_oficial i ON pp.property_id = i.photo_id
LEFT JOIN plans p ON pp.plans_id = p.id
WHERE pp.user_id = ?
AND pp.type BETWEEN 1 AND 6
$where
ORDER BY pp.id