COALESCE function in MYSQL with select gives error - mysql

I am wondering what is the problem of my query which is simple for me, please also have a look and please let me know if I missed something
SELECT users.*, p.*,
COALESCE(SELECT picture_location FROM pictures
WHERE user_id = 'patient' AND default_pic = 1,
SELECT picture_location FROM pictures
WHERE user_id = 'patient' ORDER BY id ASC LIMIT 1) AS default_pic,
pic.picture_location, MONTHNAME(users.registered_on) AS month_reg,
YEAR(users.registered_on) AS year_reg FROM users
LEFT JOIN profile p ON p.profile_id = users.profile_id
LEFT JOIN pictures pic ON pic.user_id = p.profile_id
WHERE users.pseudo = 'patient' GROUP BY users.pseudo
ORDER BY pic.default_pic DESC LIMIT 1
Do you see something ? It returns me this :
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT picture_location FROM pictures WHERE user_id = 'patient' AND default_pic ' at line 1

A nested select needs an additional layer of parentheses:
SELECT users.*, p.*,
COALESCE((SELECT picture_location FROM pictures WHERE user_id = 'patient' AND default_pic = 1),
(SELECT picture_location FROM pictures WHERE user_id = 'patient' ORDER BY id ASC LIMIT 1)) AS default_pic,
pic.picture_location,
MONTHNAME(users.registered_on) AS month_reg, YEAR(users.registered_on) AS year_reg
FROM users LEFT JOIN
profile p
ON p.profile_id = users.profile_id LEFT JOIN
pictures pic
ON pic.user_id = p.profile_id
WHERE users.pseudo = 'patient'
GROUP BY users.pseudo
ORDER BY pic.default_pic DESC
LIMIT 1;

Related

MySQL Multiple INNER JOIN + GROUP BY not working as expected

I am generating a Member Leaderboard based on some field values.. Using Below SQL i am getting those values...
SELECT ue1.user_id,
ue1.meta_value coins ,
ue3.meta_value user_rank ,
ue2.meta_value gems,
COUNT(ue4.user_id) quiz_count,
COUNT(ue5.user_id) video_watch_count,
ue1.meta_value + ue3.meta_value + ue2.meta_value total_points
FROM `wp_usermeta` as ue1
INNER JOIN `wp_usermeta` as ue2 ON ue2.user_id = ue1.user_id
AND ue1.meta_key = '_coin_points'
AND ue2.meta_key = '_gem_points'
INNER JOIN `wp_usermeta` as ue3 ON ue3.user_id = ue1.user_id
AND ue3.meta_key = '_user_rank'
INNER JOIN `wp_gamipress_user_earnings` as ue4 ON ue4.user_id = ue1.user_id
AND ue4.post_type = 'quiz-game-master'
INNER JOIN `wp_gamipress_user_earnings` as ue5 ON ue5.user_id = ue1.user_id
AND ue5.post_type = 'video-game-master'
WHERE ue1.meta_value > 0
AND ue2.meta_value > 0
GROUP BY ue1.user_id, ue1.meta_value, ue2.meta_value, ue3.meta_value, ue4.user_id, ue5.user_id
ORDER BY total_points DESC LIMIT 0, 50
What i am getting is... Not Expected Query Result
See? video_watch_count is copying quiz_count value.. I don't know why? Would appreciate if you could help me out here.
Check you join statement. For both quiz_count, video_watch_count, you select data from table wp_gamipress_user_earnings. For each entry if join condition satisfied it will return user_id from corresponding table.
Finally you group it using user_id which is common to both join results.That's why you get same count.

Results returning twice from MySQL query

I'm struggling to figure out why my results are returning twice for the group messages. It's returning the correct values for the single conversations.
It should be returning all the data from Data in table screenshot. However it's returning the data with is_group = 1 twice.
Data in Table:
MySQL Query:
(SELECT dm.* FROM `direct_message`AS dm
INNER JOIN direct_message_thread AS dmt
ON dmt.chat_id = dm.id
WHERE
( dm.recipient_id = '10896' OR dm.creator_id = '10896' )
AND dm.school_id = '1'
GROUP BY dm.id
ORDER BY dmt.inserted DESC
) UNION ALL (
SELECT dm.* FROM `direct_message` AS dm
INNER JOIN direct_message_thread AS dmt ON dmt.chat_id = dm.id
LEFT JOIN direct_message_group AS dmg ON dmg.chat_id = dm.id
WHERE dmg.staff_id = '10896' AND dm.school_id = '1'
GROUP BY dm.id
ORDER BY dmt.inserted DESC
) LIMIT 0, 25
Results:
I think it could be because of the first SELECT getting the results and then the UNION ALL get the same results but not grouping together with the first SELECT
When I try and do the following:
(SELECT dm.* FROM `direct_message`AS dm
INNER JOIN direct_message_thread AS dmt
ON dmt.chat_id = dm.id
WHERE ( dm.recipient_id = '10896' OR dm.creator_id = '10896' )
AND dm.school_id = '1'
) UNION ALL (
SELECT dm.* FROM `direct_message` AS dm
INNER JOIN direct_message_thread AS dmt ON dmt.chat_id = dm.id
LEFT JOIN direct_message_group AS dmg ON dmg.chat_id = dm.id
WHERE dmg.staff_id = '10896' AND dm.school_id = '1'
)
GROUP BY dm.id
ORDER BY dmt.inserted DESC
LIMIT 0, 25
It shows this error message:
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use
near 'GROUP BY dm.id ORDER BY dmt.inserted DESC LIMIT 0, 25' at line
14
You are using union for two queries.
Records 595-597 and 599-601 are met both of them.
My be better to select to whole query with
select id,...
from (...)
group by id

SELECT query check for something outside of database

I have the following query below and it works for the most part, until I just noticed it is causing a slight issue. Basically what the existing query does it select all the information from my 'home_comments' table and then matches the max id from the profile_img table and takes that image.
The issue I am running into is that not all of my users have profile images within this database. For default images, I use a static image. So, is there anyway I can check if the user has a profile_img and if not use this?
$default_profile_img = '<img class="home-profile-pic" src="profile_images/default.jpg">';
Query:
$select_comments_sql = "
SELECT c. *, p.user_id, p.img
FROM home_comments AS c
INNER JOIN (SELECT max(id) as id, user_id
FROM profile_img
GROUP BY user_id) PI
on PI.user_id = c.user_id
INNER JOIN profile_img p
on PI.user_id = p.user_id
and PI.id = p.id
ORDER BY c.id DESC
EDIT: updated SQL
$select_comments_sql = "
//SELECT c. *, p.user_id, p.img
SELECT c. *, PI.user_id, case when PI.img <> '' and PI.img is not null then PI.img else 'profile_images/default.jpg' end img
FROM home_comments AS c
LEFT JOIN (SELECT max(id) as id, user_id
FROM profile_img
GROUP BY user_id) PI
on PI.user_id = c.user_id
LEFT JOIN profile_img p
on PI.user_id = p.user_id
and PI.id = p.id
ORDER BY c.id DESC
";
Errors:
[27-Oct-2016 13:29:56 America/Chicago] PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '//SELECT c. *, p.user_id, p.img
SELECT c. *, PI.user_id, case when PI.img <> ' at line 1' in /home4//public_html/.com/account/ajax-php/comment-retrieve.php:36`
You can use a case statement:
$select_comments_sql = "
SELECT c. *, p.user_id, case when p.img <> '' and p.img is not null then p.img else 'my-default.png' end img
FROM home_comments AS c
INNER JOIN (SELECT max(id) as id, user_id
FROM profile_img
GROUP BY user_id) PI
on PI.user_id = c.user_id
INNER JOIN profile_img p
on PI.user_id = p.user_id
and PI.id = p.id
ORDER BY c.id DESC
Try this way, I assume you use mysqli and $row returns associative array.
$row = mysqli_fetch_assoc($select_comments_sql);
if(!empty($row['profile_image_field_name'])){
$default_profile_img = '<img class="home-profile-pic" src="profile_images/'.$row['profile_image_feild_name'].'">';
}else{
$default_profile_img = '<img class="home-profile-pic" src="profile_images/default.jpg">';
}

MySQL case when using JOIN/GROUP BY

I have a posts table. I am joining it with votes table via:
SELECT posts.*,
(CASE
WHEN vs.user_id = 1 THEN 0
ELSE 1
END) AS voted_by_me
FROM `posts`
LEFT OUTER JOIN votes AS vs ON vs.post_id = posts.id
GROUP BY posts.id
Basically I want know if the joined value vs.user_id = 1. This obviously doesn't work because it will just use a random returned value in CASE WHEN condition . I am wondering if there's a way to find out if the join values group by contains a specific value.
To clarify:
I want to get all posts, and also for each post have a column called voted_by_me where if posts was voted by user with id 1, then make it value 0, otherwise 1.
Is that what you want?
SELECT posts.id,
sum(vs.user_id = 1 AND vs.option = 0) > 0 AS downvoted_by_me,
sum(vs.user_id = 1 AND vs.option = 1) > 0 AS upvoted_by_me
FROM `posts`
LEFT OUTER JOIN votes AS vs ON vs.post_id = posts.id
GROUP BY posts.id
SELECT posts.id,
ifnull(vs.isvoted, 0) AS voted_by_me
FROM `posts`
LEFT OUTER JOIN (select distinct postid , 1 as isvoted from votes where user_id=1) AS vs
ON vs.post_id = posts.id

MySql error in your SQL syntax for date

I have just migrated my database from MS SQL to MySQL.
When running reports I now get the following error:
Application Execution Exception
Error Type: database : 0
Error Messages: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '2 YEAR(res_created) AS responseYear FROM Responses INNER JOIN ' at line 1
SQL Sent:
SELECT DISTINCT TOP #arguments.yearsToReturn# YEAR(res_created) AS responseYear
FROM
Responses
INNER JOIN
Questions ON Responses.question_id = Questions.question_id
INNER JOIN
Lookup_Survey_Questions ON Questions.question_id = Lookup_Survey_Questions.question_id
INNER JOIN
Survey ON Lookup_Survey_Questions.survey_id = Survey.survey_id
INNER JOIN
School ON Survey.sch_id = School.sch_id
INNER JOIN
Authority ON School.auth_id = Authority.auth_id
WHERE
Authority.auth_id = #arguments.authorityID#
AND
Questions.question_id = #arguments.questionID#
AND
Responses.survey_id IN (SELECT Survey.survey_id FROM Survey where Survey.sch_id in (SELECT School.sch_id FROM School where auth_id=#arguments.authorityID#))
ORDER BY
responseYear ASC
How can I resolve?
Thanks
I think that this can be simplified as follows...
SELECT DISTINCT YEAR(res_created) responseYear
FROM Responses r
JOIN Questions q
ON q.question_id = r.question_id
JOIN Lookup_Survey_Questions lsq
ON lsq.question_id = q.question_id
JOIN Survey u
ON u.survey_id = lsq.survey_id
JOIN School c
ON c.sch_id = u.sch_id
JOIN Authority a
ON a.auth_id = c.auth_id
WHERE a.auth_id = #arguments.authorityID#
AND q.question_id = #arguments.questionID#
AND c.auth_id=#arguments.authorityID#
ORDER
BY responseYear ASC
LIMIT 2;
"Top 2" isn't MySQL syntax. To select the first two results add limit 2 to the end of the query:
...
ORDER BY
responseYear ASC LIMIT 2
You are using the two clause at a place. You are using the DISTINCT and TOP that's why there is error.
Use this query:
SELECT DISTINCT YEAR(res_created) AS responseYear
FROM Responses
INNER JOIN Questions ON Responses.question_id = Questions.question_id
INNER JOIN Lookup_Survey_Questions ON Questions.question_id = Lookup_Survey_Questions.question_id
INNER JOIN Survey ON Lookup_Survey_Questions.survey_id = Survey.survey_id
INNER JOIN School ON Survey.sch_id = School.sch_id INNER JOIN Authority ON School.auth_id = Authority.auth_id
WHERE Authority.auth_id = 5 AND Questions.question_id = 20 AND Responses.survey_id IN (
SELECT Survey.survey_id FROM Survey where Survey.sch_id in (SELECT School.sch_id FROM School where auth_id=5))
ORDER BY responseYear ASC
LIMIT 0,2; //use the limit