subquery with an inner join - mysql

I'm stuck on a subquery issue, trying to get multiple columns while using a join.
I'm trying to grab different fields from other tables, based on what the "type" field is set as, for a notifications system that tracks different sections of a site.
I was hoping I could do something like this:
SELECT
n.`id`,
n.`last_date`,
IF(n.type = 'liked', (SELECT co.`article_id`, a.article_id FROM `articles_comments` co INNER JOIN `articles` a ON a.article_id = co.article_id WHERE co.`comment_id` = n.data_id), NULL),
n.`comment_id`,
n.`type`,
n.`data_id`,
FROM
`user_notifications` n
WHERE n.`owner_id` = 8505
The problem, is that phpmyadmin gives me an error of "#1241 - Operand should contain 1 column(s)"
I'm pretty confused, because if I do no INNER JOIN and only grab the "article_id" it works fine.

Sub-query must return only one column
you can see this link
this query
(SELECT a.article_id
FROM `article
s_comments` co
INNER JOIN `articles` a
ON a.article_id = co.article_id
WHERE co.`comment_id` = n.data_id)
must be something like this
(SELECT a.article_id
FROM `article
s_comments` co
INNER JOIN `articles` a
ON a.article_id = co.article_id
WHERE co.`comment_id` = n.data_id)
UNION ALL
(SELECT co.`article_id`
FROM `article
s_comments` co
INNER JOIN `articles` a
ON a.article_id = co.article_id
WHERE co.`comment_id` = n.data_id)

Related

Count matched words from IN operator

i have this little mysql query :
select t.title FROM title t
inner join movie_keyword mk on mk.movie_id = t.id
inner join keyword k on k.id = mk.keyword_id
where k.keyword IN (
select k.keyword
FROM title t
inner join movie_keyword mk on mk.movie_id = t.id
inner join keyword k on k.id = mk.keyword_id
where t.id = 166282
)
LIMIT 15
as you can see it will return all titles from title that have at least one the same keyword that have movie with id 166282.
Now i have problem, because i want also count how many keywords was matched in IN operator(let's say i want to see only titles that have 3 or more the same keywords), i tried something with aggregate functions, but everything failed, so i came here with my problem. Maybe somebody can give me some advice, or code example.
I'm not also sure, if this "subquery way" is good, so if there are some better options how i should solve my problem, I am open to any suggestions or tips.
Thank you!
#Edit
So after some problems, i have one more. This is my current query :
SELECT s.title,s.vote,s.rating,count(dk.key) as keywordCnt, count(dg.name) as genreCnt
FROM series s
INNER JOIN series_has_genre shg ON shg.series_id = s.id
INNER JOIN dict_genre dg ON dg.id = shg.dict_genre_id
INNER JOIN series_has_keyword shk ON shk.series_id = s.id
INNER JOIN dict_keyword dk ON dk.id = shk.dict_keyword_id
WHERE dk.key IN (
SELECT dki.key FROM series si
INNER JOIN series_has_keyword shki ON shki.series_id = si.id
INNER JOIN dict_keyword dki ON dki.id = shki.dict_keyword_id
WHERE si.title LIKE 'The Wire'
)
and dg.name IN (
SELECT dgo.name FROM series so
INNER JOIN series_has_genre shgo ON shgo.series_id = so.id
INNER JOIN dict_genre dgo ON dgo.id = shgo.dict_genre_id
WHERE so.title LIKE 'The Wire'
)
and s.production_year > 2000
GROUP BY s.title
ORDER BY s.vote DESC, keywordCnt DESC ,s.rating DESC, genreCnt DESC
LIMIT 5
Problem is, it is very, very, very slow. Any tips what i should change, to run it faster ?
Will this work for you:
select t.title, count(k.keyword) as keywordCount FROM title t
inner join movie_keyword mk on mk.movie_id = t.id
inner join keyword k on k.id = mk.keyword_id
where k.keyword IN (
select ki.keyword
FROM title ti
inner join movie_keyword mki on mki.movie_id = ti.id
inner join keyword ki on ki.id = mki.keyword_id
where ti.id = 166282
) group by t.title
LIMIT 15
Note that I have changed the table names inside the nested query to avoid confusion.

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

SQL - Ambiguous Column

I can't see what is wrong with this query. I get an error saying:
"column article_id in from clause is ambiguous"
I understand that it may have something to do with table name aliases but not sure of how to fix. If the query was smaller I may be able to work something out but it's pretty confusing to me and every time I change something to try and fix it, something else stops - so I thought I'd ask first.
SELECT bt.topic_title, f.article_id, p.photo_id, ba.title, ba.slug,
IFNULL(c.cnt,0) comments, IFNULL(ph.cnt,0) photos, IFNULL(v.cnt,0) videos
FROM blog_article_followers AS f
LEFT OUTER JOIN (
SELECT article_id, COUNT(comment_id) as cnt
FROM blog_comments
GROUP BY article_id) c
ON f.article_id = c.article_id
LEFT OUTER JOIN (" _
SELECT article_id, COUNT(photo_id) as cnt
FROM photos
GROUP BY article_id) ph
ON f.article_id = ph.article_id
LEFT OUTER JOIN (
SELECT article_id, COUNT(video_id) as cnt
FROM videos
GROUP BY article_id) v
ON f.article_id = v.article_id
LEFT JOIN blog_topics bt ON f.topic_id = bt.topic_id
LEFT JOIN blog_articles AS ba USING (article_id)
LEFT JOIN photos AS p USING (article_id)
WHERE f.member_id = 100 AND p.cover = 1
ORDER BY f.follow_date DESC;
Try replacing this:
LEFT JOIN blog_articles AS ba USING (article_id)
LEFT JOIN photos AS p USING (article_id)
With this
LEFT JOIN blog_articles AS ba ON f.article_id = ba.article_id
LEFT JOIN photos AS p ON f.article_id = photos.article_id
you have to rename the column
LEFT JOIN photos AS p USING (p.article_id)
or to whichever table article_id belongs to

Mysql joins problem

I use this query to select all articles :
SELECT articles.*,categories.category_name,users.username,tags.tag
FROM articles
LEFT JOIN `categories` ON articles.category_id = categories.category_id
LEFT JOIN `users` ON articles.author_id = users.user_id
LEFT JOIN `tags` ON articles.article_id = tags.article_id
ORDER BY articles.date_added DESC
I have an other table comments, and I want to count how many comments are there, where the article_id in that table = article_id in the articles table. I tried with COUNT, but then it returns only one result. How can I do that with one query?
You can use a subquery in the SELECT clause:
SELECT articles.*,categories.category_name,users.username,tags.tag, (SELECT count(*) FROM comments c WHERE c.article_id = articles.article_id) as comments_count
As arnaud576875 already stated, you can use a subquery to extract the summary data.
Two things I've noticed from your SQL that are not really a part of the question but still worth pointing out.
you can use a table alias to shorten your SQL and make it more readable.
So instead of
SELECT articles.*,categories.category_name,users.username,tags.tag
FROM articles
LEFT JOIN `categories` ON articles.category_id = categories.category_id
LEFT JOIN `users` ON articles.author_id = users.user_id
LEFT JOIN `tags` ON articles.article_id = tags.article_id
ORDER BY articles.date_added DESC
you'd code
SELECT a.*, c.category_name, u.username, t.tag
FROM articles a
LEFT JOIN `categories` c ON a.category_id = c.category_id
LEFT JOIN `users` u ON a.author_id = u.user_id
LEFT JOIN `tags` t ON a.article_id = t.article_id
ORDER BY a.date_added DESC
I would drop SELECT * and select only the fields that you actually are going to use. This also helps with readability of your code.

Mysql Error Code 1064

I'm having some issues with a mysql query.
I'm trying to join together multiple tables.
In one table, I have a list of successful online customers, and on another table I have a table which has the traffic source from which it came. I'm trying to track which customers came from a certain ad. So I want to query those new customers who came on a certain date and from a specific campaign.
SELECT keyword, COUNT(keyword) FROM in_clicks AS ic WHERE ic.create_date LIKE '%2011-08-19%' GROUP BY ic.keyword ORDER BY COUNT(ic.keyword) DESC
INNER JOIN leads AS l ON ls.lead_id = l.id
INNER JOIN lead_status AS ls ON ls.lead_id = ls.id
INNER JOIN ads AS a ON ic.ad_id = a.id
INNER JOIN ad_groups AS ag ON a.ad_group_id = ag.id
INNER JOIN campaigns AS c ON ag.campaign_id = c.id;
I ran the above code and got the following error.
Error Code: 1064
'INNER JOIN leads AS l ON ls.lead_id = l.id Innner Join lead_status AS ls' at line 2
This should run better :-).
SELECT keyword, COUNT(keyword)
FROM in_clicks AS ic
INNER JOIN leads AS l ON ls.lead_id = l.id
INNER JOIN lead_status AS ls ON ls.lead_id = ls.id
INNER JOIN ads AS a ON ic.ad_id = a.id
INNER JOIN ad_groups AS ag ON a.ad_group_id = ag.id
INNER JOIN campaigns AS c ON ag.campaign_id = c.id;
WHERE ic.create_date LIKE '%2011-08-19%'
GROUP BY ic.keyword
ORDER BY COUNT(ic.keyword) DESC
The order is: SELECT .. FROM ... JOIN ... WHERE ... GROUP BY .. HAVING .. ORDER BY .. LIMIT
All of the INNER JOIN clauses need to be between your FROM and WHERE clauses. It's syntactically invalid to use INNER JOIN following WHERE in the same query.
As pointed out by Bohemian, you also have a syntax error: Innner should be INNER (you have one to many n characters).