Correct syntax for COUNT(DISTINCT...) - mysql

I've got the following SQL query and I'm trying to implement pagination, so I first want to get the COUNT of the result:
The normal query (works fine)
SELECT DISTINCT c.*, p1.*, username FROM candidate c
LEFT JOIN note p1 ON (c.candID = p1.candidateID)
LEFT JOIN user ON p1.userID = user.id
LEFT OUTER JOIN note p2 ON
(c.candID = p2.candidateID AND (p1.noteID < p2.noteID))
WHERE p2.candidateID IS NULL ORDER BY c.firstname ASC
I've tried the following, but it throws an error and I'm not sure what correct syntax to use:
Attempting to count the results (doesn't work)
SELECT COUNT(DISTINCT c.*, p1.*, username) FROM candidate c
LEFT JOIN note p1 ON (c.candID = p1.candidateID)
LEFT JOIN user ON p1.userID = user.id
LEFT OUTER JOIN note p2 ON
(c.candID = p2.candidateID AND (p1.noteID < p2.noteID))
WHERE p2.candidateID IS NULL ORDER BY c.firstname ASC
The error:
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 ', p1., username) FROM candidate c LEFT ' at line 1

One option is to use a subquery:
SELECT COUNT(*)
FROM (
SELECT DISTINCT c.*, p1.*, username FROM candidate c
LEFT JOIN note p1 ON (c.candID = p1.candidateID)
LEFT JOIN user ON p1.userID = user.id
LEFT OUTER JOIN note p2 ON
(c.candID = p2.candidateID AND (p1.noteID < p2.noteID))
WHERE p2.candidateID IS NULL
) t
Depending on your data, you may be able to do this without the subquery, but you cannot use multiple columns with the count aggregate -- that's what is causing your error.

Related

Error in JOIN while using Common Table Expresion

I am using the expression below to find out which 'resource' type customers have 'work_resource' that are active.
WITH cte_ss AS (SELECT wr.user_id
FROM work w
JOIN work_resource wr ON wr.work_id = w.id
WHERE wr.work_resource_status_type_code = 'active'
),
SELECT u.uuid
FROM user u
JOIN company c ON c.id = u.company_id
LEFT JOIN cte_ss on cte_ss.user_id = u.id
AND c.customer_type = 'resource'
White trying to run this, I get the following error
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 u.uuid
FROM user u
JOIN company c ON c.id = u.company_id
LEFT JOIN cte_ss' at line 6
Both the individual queries (without the LEFT JOIN) are working, so not sure what I am doing wrong here
A cte would look like this
But as i don't know nothing about your tables, you have to figure it out yourself
WITH cte_ss AS (
SELECT
user_id
FROM work w
JOIN work_resource wr ON wr.work_id = w.id
WHERE wr.work_resource_status_type_code = 'active'
)
SELECT u.uuid
FROM user u
JOIN company c ON c.id = u.company_id
LEFT JOIN cte_ss on cte_ss.user_id = u.id
AND c.customer_type = 'resource'

left join, inner join, one before the other, other issue?

I have a form and MySQL that works with this:
$sql = "
SELECT p.*
, t.*, f.name AS fname
FROM table_posts p
JOIN table_topics t
USING(tid)
JOIN table_forums f
ON f.fid = t.fid
WHERE f.fid IN($forums)";
I wish to add an option on the form so that any tid's in the subscriptions table for the user are excluded from the results from the sql above:
$sql .= " LEFT JOIN (SELECT x.tid FROM table_subscriptions AS x WHERE x.username = '$user' AND x.type = 'x' GROUP BY x.tid) AS query2 USING (tid) AND query2.tid IS NULL";
however, am encountering
MySQL encountered the following error: 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 'LEFT JOIN (
Is the issue because the left join should be done first, or is there some other issue? Any clues for corrections appreciated.
You can bring in the subscriptions table with a LEFT JOIN, and then filter on unmatched records in the WHERE clause
SELECT
p.*,
t.*,
f.name AS fname
FROM table_posts AS p
INNER JOIN table_topics AS t USING (tid)
INNER JOIN table_forums AS f ON f.fid = t.fid
LEFT JOIN table_subscriptions AS s ON s.username = ? AND s.type = 'x' AND s.tid = p.tid
WHERE
f.fid IN (?, ?, ?)
AND s.tid IS NULL
Note: I updated your query so it uses query parameters instead of concatenating variables in the SQL string: this is both more efficient and secure.
You can also use NOT EXISTS:
SELECT
p.*,
t.*,
f.name AS fname "
FROM table_posts AS p
INNER JOIN table_topics AS t USING (tid)
INNER JOIN table_forums AS f ON f.fid = t.fid
WHERE NOT EXISTS (
SELECT 1
FROM table_subscriptions AS s
WHERE s.username = ? AND s.type = 'x' AND s.tid = p.tid
)
WHERE f.fid IN (?, ?, ?)

SELECT query IF CONDITION

I have one problem with my SELECT query in my blog page.
I want comment count of each blog when comment status=1.
I am apply following query..
SELECT CONCAT(u.first_name," ",u.last_name) name, r.*,
IF(c.status=1,COUNT(c.id)) as comment
FROM users u
RIGHT JOIN resources r ON u.id = r.created_by
LEFT JOIN comments c ON r.id = c.resource_id
WHERE r.type = 1
AND r.status=1
GROUP BY r.id
ORDER BY r.created_date DESC
LIMIT 0,5
but it giving SYNTAX ERROR..
Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your
SQL syntax; check the manual that corresponds to your MariaDB server version for the right
syntax to use near ') as comment FROM users u RIGHT JOIN resources r ON u.id = r.created_by
LEFT JOI' at line 1
Please tell me where I am wrong.
Thanks
If statement contains three expressions. First, the expression, second the value returned if condition is true and third if condition is false so you are missing the third expression.
Try the below code
SELECT CONCAT(u.first_name," ",u.last_name) name,r.*,IF(c.status=1,COUNT(c.id), 0) as comment
FROM users u RIGHT JOIN resources r ON u.id = r.created_by
LEFT JOIN comments c ON r.id = c.resource_id
WHERE r.type = 1
AND r.status=1
GROUP BY r.id
ORDER BY r.created_date DESC
LIMIT 0,5
Select concat(u.first_name," ",u.last_name) name,r.*,
case when c.status=1 then COUNT(c.id) end as comment
FROM users u RIGHT JOIN resources r ON u.id = r.created_by
LEFT JOIN comments c ON r.id = c.resource_id
WHERE r.type = 1
AND r.status=1
GROUP BY r.id
ORDER BY r.created_date DESC
LIMIT 0,5
https://www.w3schools.com/sql/func_mysql_case.asp
if function requires 3 parameters to be passed to it. IF(expression ,expr_true, expr_false) is how it should be used.
Have a look at https://www.w3resource.com/mysql/control-flow-functions/if-function.php

No results showing up AND error as well with where clause

So i am trying to get values that ONLY have name in role as admin
When i put the WHERE command right after the FROM command i get an error that says
#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 'INNER JOIN `users` AS `u` ON u.uid = ur.uid INNER JOIN `role` AS `r` ON r.rid = ' at line 9
But when i put it in the end of the entire thing likt it is below i get no error BUT i dont get any results EITHER!
SELECT f.field_first_name_value,
l.field_last_name_value,
r.name,
u.name,
u.mail,
u.created
FROM `users_roles` AS `ur`
INNER JOIN `users` AS `u` ON u.uid = ur.uid
INNER JOIN `role` AS `r` ON r.rid = ur.rid
INNER JOIN `field_data_field_first_name` AS `f` ON f.entity_id = ur.uid
INNER JOIN `field_data_field_last_name` AS `l` ON l.entity_id = ur.uid
WHERE 'role.name' = 'admin'
What can i do to get what i want.
Change it to:
WHERE r.name = 'admin'
The way you wrote it, you were comparing two literal strings, not comparing a column to a string.
Also, you have to use r.name rather than role.name -- once you assign an alias to a table, you can't refer to the original table name.

Joining two select queries and ordering results

Basically I'm just unsure as to why this query is failing to execute:
(SELECT replies.reply_post, replies.reply_content, replies.reply_date AS d, members.username
FROM (replies) AS a
INNER JOIN members ON replies.reply_by = members.id)
UNION
(SELECT posts.post_id, posts.post_title, posts.post_date AS d, members.username
FROM (posts) as b
WHERE posts.post_set = 0
INNER JOIN members ON posts.post_by = members.id)
ORDER BY d DESC LIMIT 5
I'm getting this error:
#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 'a INNER JOIN members ON replies.re' at line 2
All I'm trying to do is select the 5 most recent rows (dates) from these two tables. I've tried Join, union etc and I've seen numerous queries where people have put another query after the FROM statement and that just makes no logical sense to me as to how that works?
Am I safe to say that you can join the same table from two different but joined queries? Or am I taking completely the wrong approach, because frankly I can't seem see how this query is failing despite reading the error message.
(The two queries on there own work fine)
I think there is syntax error in your query at below part :
FROM (posts) as b
WHERE posts.post_set = 0
INNER JOIN members ON posts.post_by = members.id)
Inner join should come first before where condition. Also your join conditions are wrong. You need to apply conditions like
INNER JOIN members ON a.reply_by = members.id)
INNER JOIN members ON b.post_by = members.id)
So your query should be like this
(SELECT a.reply_post, a.reply_content, a.reply_date AS d, members.username
FROM (replies) AS a
INNER JOIN members ON a.reply_by = members.id)
UNION
(SELECT b.post_id, b.post_title, b.post_date AS d, members.username
FROM (posts) as b
INNER JOIN members ON b.post_by = members.id
WHERE b.post_set = 0)
ORDER BY d DESC LIMIT 5
Try this:
(SELECT a.reply_post, a.reply_content, a.reply_date AS d, members.username
FROM replies AS a
INNER JOIN members ON a.reply_by = members.id)
UNION
(SELECT b.post_id, b.post_title, b.post_date AS d, members.username
FROM posts as b
INNER JOIN members ON b.post_by = members.id
WHERE b.post_set = 0) /* Use where condition after matching Id's using ON */
ORDER BY d DESC LIMIT 5