Mysql join with group by and order by - php

I am using this mysql query
SELECT `p`.`id` AS product_id, `p`.`title` , `i`.`image` , `u`.`user_username` , `m`.`id` AS message_id, `m`.`date` , `m`.`from` , `m`.`to` , `m`.`message` , `m`.`read`
FROM (`messages` AS m)
JOIN `products` AS p ON `m`.`product_id` = `p`.`id`
JOIN `users` AS u ON `m`.`from` = `u`.`user_id`
JOIN `product_images` AS i ON `p`.`id` = `i`.`product_id`
WHERE `i`.`type` = 'FRONT'
AND (m.to = '1171' OR m.from = '1171)
GROUP BY `m`.`therad_user` , `m`.`product_id`
ORDER BY `m`.`id` DESC
In message table it shows message with oldest message id, I want to return latest message. but it show oldest message. how I solve this.

Try ORDER BY first, then only GROUP BY
SELECT * FROM
(
SELECT `p`.`id` AS product_id, `p`.`title` , `i`.`image` , `u`.`user_username` , `m`.`id` AS message_id, `m`.`date` , `m`.`from` , `m`.`to` , `m`.`message` , `m`.`read`
FROM (`messages` AS m)
JOIN `products` AS p ON `m`.`product_id` = `p`.`id`
JOIN `users` AS u ON `m`.`from` = `u`.`user_id`
JOIN `product_images` AS i ON `p`.`id` = `i`.`product_id`
WHERE `i`.`type` = 'FRONT'
AND (m.to = '1171' OR m.from = '1171)
ORDER BY `m`.`id` DESC
) tmp
GROUP BY `m`.`therad_user` , `m`.`product_id`

Related

LIMIT results on specific table when using LEFT JOIN

Below is my query. I would like to get only 10 posts from post table. However it LIMIT 10 below doesn't limit the results in posts table but it does on another table.
Can anyone help me to fix the query? I really appreicate your help.
SELECT posts.id , posts.cat_id , posts.school_id , posts.campus_id , posts.status , posts.priority , posts.title , posts.content , posts.phone , posts.email , posts.tags , posts.zip , posts.price_new , posts.price_old , posts.reviewed_by , posts.reviewed_date , posts.updated_date , posts.posted_date , posts.expired_date , posts.ip_address , schools.school_name, campuses.campus_name , meta.meta_key , meta_value , images.img_name
FROM posts LEFT JOIN
meta
ON posts.id = meta.post_id LEFT JOIN
images
ON posts.id = images.post_id LEFT JOIN
schools
ON posts.school_id = schools.id LEFT JOIN
campuses
ON posts.campus_id = campuses.id
ORDER BY posts.updated_date DESC LIMIT 10
One method is to use a subquery:
SELECT p.id , p.cat_id, p.school_id, p.campus_id , p.status,
p.priority, p.title, p.content, p.phone, p.email, p.tags, p.zip,
p.price_new, p.price_old, p.reviewed_by, p.reviewed_date,
p.updated_date, p.posted_date, p.expired_date, p.ip_address,
s.school_name, c.campus_name,
m.meta_key, m.meta_value,
i.img_name
FROM (SELECT p.*
FROM posts p
ORDER BY p.updated_date DESC
LIMIT 10
) p LEFT JOIN
meta m
ON p.id = m.post_id LEFT JOIN
images i
ON p.id = i.post_id LEFT JOIN
schools s
ON p.school_id = s.id LEFT JOIN
campuses c
ON p.campus_id = c.id;
Note that the use of table aliases makes the query easier to write, read, and understand.

mysql query not fetching data from where condition

I have written a MySQL query ?I want to fetch data t.taskid = b.id OR t.taskid = '0' AND t.subtaskid = j.id OR t.subtaskid = '0' from this but where condition is not working for this
SELECT t.id as id
, t.taskid
, t.subtaskid
, p.PNAME AS projectname
, t.date AS DATE
, b.Summary AS tasks
, j.SUMMARY AS subtasks
, t.mon AS time1
, t.tue AS time2
, t.wed AS time3
, t.thu AS time4
, t.fri AS time5
, t.sat AS time6
, t.sun AS time7
FROM bt_createissue b
, bt_createissue j
, timesheet t
LEFT
JOIN bt_project p
ON t.projectid = p.pkey
WHERE t.taskid = b.id
OR t.taskid = 0
AND t.subtaskid = j.id
OR t.subtaskid = 0
AND t.date >= '2015-03-09'
AND t.date <= '2015-03-30'
AND t.username = '$username'
If t.taskid = b.id
t.subtaskid = j.id are to be joins then check whether you can modify
WHERE t.taskid = b.id OR t.taskid = '0'
AND t.subtaskid = j.id OR t.subtaskid = '0'
the above lines with proper joins.
Because using join conditions in where clause can create cross join instead of intended one.
If it do not work
Try with using having clause instead of where clause and don't forget to use group by

how to inner join three tables and get count

I have three tables:
members (id, name, surname, usr_img)
user_uploads (imgID, user_id, filename, description, up_time)
img_likes (likeID, img_id, user_id)
I need to get all from user_uploads, and using the img_id, get uploader info from members and make 2 counts in the img_likes table (check if user_id (from session variable) and img_id exists and get the img total likes).
SELECT user_uploads.* AS uu, members.*, COUNT(img_id, user_id) AS usr_liked, COUNT(img_id) AS total_likes
FROM user_uploads
INNER JOIN members AS m ON m.id = uu.user_id -- owner info
INNER JOIN img_likes AS il ON il.img_id = uu.imgID AND il.user_id = ? -- check if logged in user already liked
INNER JOIN img_likes AS ilt ON ilt.img_id = uu.imgID -- total likes
GROUP BY img_id, user_id
ORDER BY up_time DESC
I don't need to get nothing from img_id, just count the number of rows. I don't know if an inner join is necessary, maybe to specify the user_id?
and to get the counts:
$usr_liked = row['usr_liked'];
$total_likes = rwo['total_likes'];
Will that work?
EDIT: add new query:
SELECT
user_uploads.*,
(
SELECT *
FROM members m
WHERE m.id = user_uploads.user_id
),
(
SELECT COUNT(*)
FROM img_likes t
WHERE t.img_id = user_uploads.imgID AND t.user_id = ?
) AS user_likes,
(
SELECT COUNT(*)
FROM img_likes t
WHERE t.img_id = user_uploads.imgID
) AS total_likes
FROM user_uploads
ORDER BY up_time DESC
You could use subquery:
SELECT
uu.*,
m.*,
(
SELECT COUNT(t.*)
FROM img_likes t
WHERE t.img_id = uu.imgID AND t.user_id = ?
) AS user_likes,
(
SELECT COUNT(t.*)
FROM img_likes t
WHERE t.img_id = uu.imgID
) AS total_likes
FROM
user_uploads AS uu
INNER JOIN members AS m ON
m.id = uu.user_id
ORDER BY
uu.up_time DESC

How To Left Join A Table Based On The Value Received From Inner Join Of The Same Query

I am trying to run the following query, and I keep getting a syntax error. The query works fine without the LEFT JOIN. How can I implement the LEFT JOIN without error?
SELECT
m.mid,
m.seq,
m.created_on,
m.created_by,
m.body,
r.status,
u.username_clean
FROM message_recipient r
INNER JOIN message m
ON m.mid = r.mid AND m.seq = r.seq
WHERE r.uid = ".$logged_in_id."
AND r.status in ('A', 'N')
AND r.seq = (
SELECT
MAX(rr.seq)
FROM message_recipient rr
WHERE rr.mid = m.mid
AND rr.status in ('A', 'N')
)
AND IF (m.seq=1 and m.created_by = ".$logged_in_id." , 1=0, 1=1)
ORDER BY created_on DESC
LEFT JOIN users u
ON u.user_id = m.created_by
The LEFT JOIN is in the wrong place. All of the JOINs need to be before the WHERE clause:
SELECT
m.mid,
m.seq,
m.created_on,
m.created_by,
m.body,
r.status,
u.username_clean
FROM message_recipient r
INNER JOIN message m
ON m.mid = r.mid AND m.seq = r.seq
LEFT JOIN users u
ON u.user_id = m.created_by
WHERE r.uid = ".$logged_in_id."
AND r.status in ('A', 'N')
AND r.seq = (
SELECT
MAX(rr.seq)
FROM message_recipient rr
WHERE rr.mid = m.mid
AND rr.status in ('A', 'N')
)
AND IF (m.seq=1 and m.created_by = ".$logged_in_id." , 1=0, 1=1)
ORDER BY created_on DESC
The SQL clauses go in the following order:
SELECT
FROM
JOIN
WHERE
GROUP BY
ORDER BY
Even if you have multiple joins they will all appear before the WHERE

Problem with nested SQL

I have a problem with nested select in MySQL.
This one works, but I need to get two of them.
Example:
SELECT `a`.`title` , `a`.`askprice` , `a`.`picture`
, `a`.`description` , `a`.`userid` , `a`.`id`
FROM (
`mm_ads_fields_values` AS afv
)
LEFT JOIN `mm_ads` AS a ON `a`.`id` = `afv`.`aid`
WHERE `afv`.`value` = '38'
AND `a`.`category` = '227'
AND `a`.`status` =1
AND a.id
IN (
SELECT a.id
FROM mm_ads AS a
LEFT JOIN mm_ads_fields_values AS afv ON afv.aid = a.id
WHERE afv.value = '2913'
)
ORDER BY `id` DESC
LIMIT 20
This one works. But I need SQL statement like this one:
SELECT `a`.`title` , `a`.`askprice` , `a`.`picture`
, `a`.`description` , `a`.`userid` , `a`.`id`
FROM (
`mm_ads_fields_values` AS afv
)
LEFT JOIN `mm_ads` AS a ON `a`.`id` = `afv`.`aid`
WHERE `afv`.`value` = '38'
AND `a`.`category` = '227'
AND `a`.`status` =1
AND a.id
IN (
SELECT a.id
FROM mm_ads AS a
LEFT JOIN mm_ads_fields_values AS afv ON afv.aid = a.id
WHERE afv.value = '2913'
)
AND a.id
IN (
SELECT a.id
FROM mm_ads AS a
LEFT JOIN mm_ads_fields_values AS afv ON afv.aid = a.id
WHERE afv.value = '51'
)
ORDER BY `id` DESC
LIMIT 20
And this one, last one, won't work. Its loading, loading and never nothing happen..
What am I doing wrong?
Regards, Mario
Sorry for my bad English..
Glib answer: shouldn't the second IN statement use OR instead of AND? (edit: and use correct operator precedence.)
...
AND
( a.id
IN (
SELECT a.id
FROM mm_ads AS a
LEFT JOIN mm_ads_fields_values AS afv ON afv.aid = a.id
WHERE afv.value = '2913'
)
OR a.id
IN (
SELECT a.id
FROM mm_ads AS a
LEFT JOIN mm_ads_fields_values AS afv ON afv.aid = a.id
WHERE afv.value = '51'
)
)
...

Categories