MYSQL Union from left and right and group - mysql

I have a forum with two tables forum_posts and forum_replies. I need to get the most active users. Here is what I recently tried
SELECT forum_reply.added_by, forum_posts.added_by FROM forum_reply LEFT JOIN forum_posts ON forum_posts.added_by = forum_reply.added_by
UNION
SELECT forum_posts.added_by, forum_reply.added_by FROM forum_posts RIGHT JOIN forum_reply ON forum_reply.added_by = forum_posts.added_by
WHERE forum_reply.date_added < '".$now."' AND forum_reply.date_added > '".$past24h."' AND forum_posts.date_added < '".$now."' AND forum_posts.date_added > '".$past24h."'
GROUP BY forum_reply.added_by, forum_posts.added_by ORDER BY COUNT(*) DESC LIMIT 5");
The problem is this query gives me only one result instead of 5. And the result is definitely not real because the user this query gives me haven't posted anything for the last 24 hours.

Related

Searching and Sorting Using MySQL Inner Join

I guess I can't explain my problem properly. I want to explain this to you with a picture.
Picture 1
In the first picture you can see the hashtags in the trend section. These hashtags are searched for the highest total and it is checked whether the date has passed. If valid data is available, the first 5 hashtags are taken.
Picture 2
In the second picture, it is checked whether the posts in the hashtag are in the post, if any, the oldest date value is taken, LIMIT is set to 1 and the id value from the oyuncular table is matched with sid. Thus, the name of the person sharing can be accessed.
Picture 3
My English is a little bad, I hope I could explain it properly.
SELECT
social_trend.hashtag,
social_trend.total,
social_trend.tarih,
social_post.sid,
social_post.tarih,
social_post.post,
oyuncular.id,
oyuncular.isim
FROM
social_trend
INNER JOIN
social_post
ON
social_post.post LIKE '%social_trend.hashtag%' ORDER BY social_post.tarih LIMIT 1
INNER JOIN
oyuncular
ON
oyuncular.id = social_post.sid
WHERE
social_trend.tarih > UNIX_TIMESTAMP() ORDER BY social_trend.total DESC LIMIT 5
YOu should use a sibquery
and add a proper join between subqiery and social_trend
(i assumed sing both sid)
SELECT
social_trend.hashtag,
social_trend.total,
social_trend.tarih,
t.sid,
t.tarih,
t.post,
oyuncular.id,
oyuncular.isim
FROM (
select social_post.*
from social_post
INNER JOIN social_trend ON social_post.post LIKE concat('%',social_trend.hashtag,'%' )
ORDER BY social_post.tarih LIMIT 1
) t
INNER JOIN social_trend ON social_trend.hashtag= t.post
INNER JOIN oyuncular ON oyuncular.id = t.sid
WHERE
social_trend.tarih > UNIX_TIMESTAMP() ORDER BY social_trend.total DESC LIMIT 5
but looking to your new explanation and img seems you need
SELECT
t.hashtag,
t.total,
t.tarih_trend,
t.sid,
t.tarih,
t.post,
oyuncular.id,
oyuncular.isim
FROM (
select social_post.sid
, social_post.tarih
, social_post.post
, st.hashtag
, st.total
, st.tarih tarih_trend
from social_post
INNER JOIN (
select * from social_trend
WHERE social_trend.tarih > UNIX_TIMESTAMP()
order by total DESC LIMIT 5
) st ON social_post.post LIKE concat('%',st.hashtag,'%' )
ORDER BY social_post.tarih LIMIT 5
) t
INNER JOIN oyuncular ON oyuncular.id = t.sid

MySQL Subquery returned more than 1 row

I cannot figure out why this is not working. Basically, I am running a subquery to count all rows of p.songid WHERE trackDeleted=0. The subquery works fine when I execute it by itself, but when I implement I get "subquery returned more than 1 row".
SELECT u.username, u.id, u.score, s.genre, s.songid, s.songTitle, s.timeSubmitted, s.userid, s.insWanted, s.bounty,
(SELECT COUNT(p.songid)
FROM songs s
LEFT JOIN users u
ON u.id = s.userid
LEFT JOIN posttracks p
ON s.songid = p.songid
WHERE p.trackDeleted=0
GROUP BY s.timeSubmitted ASC
LIMIT 25)
AS trackCount
FROM songs s
LEFT JOIN users u
ON u.id = s.userid
LEFT JOIN posttracks p
ON s.songid = p.songid
WHERE paid=1 AND s.timeSubmitted >= ( CURDATE() - INTERVAL 60 DAY )
GROUP BY s.timeSubmitted ASC
LIMIT 25
Obviously, a sub-query can't return more than one row, as this makes no sense. You only expect one value to be returned - COUNT(p.songid) - yet you GROUP BY s.timeSubmitted, which will make it return multiple rows, and multiple counts of p.songid.
Think about it this way, a subquery in the SELECT statement like you have needs to return a single value since it is going to act like just another column in your select list. Since you have a LIMIT 25 on yours, you're obviously expecting more than one value back, which is inocrrect for this usage.
OK, your query is a mess. Not only is the subquery broken, but I'm pretty sure the GROUP BY s.timeSubmitted ASC isn't doing what you think think it does. (Did you mean ORDER BY instead?) It might help if you explained in words what you're trying to accomplish.
Anyway, I'm going to take a wild guess and suggest that this might be what you want:
SELECT
u.username, u.id, u.score, s.genre, s.songid, s.songTitle,
s.timeSubmitted, s.userid, s.insWanted, s.bounty,
COUNT(p.songid) AS trackCount
FROM songs s
LEFT JOIN users u ON u.id = s.userid
LEFT JOIN posttracks p ON p.songid = s.songid AND p.trackDeleted = 0
WHERE paid = 1 AND s.timeSubmitted >= ( CURDATE() - INTERVAL 60 DAY )
GROUP BY s.songid
ORDER BY s.timeSubmitted ASC
LIMIT 25
Edit: Fixed the COUNT() so that it will correctly return 0 if there are no matching tracks.

Using MySQL to SELECT the MAX of a SUM of the last 5 entries?

Hey, I'm not the biggest expert with MySQL but here is what I have so far to get the MAX entery
SELECT DISTINCT
websites.id,
websites.title,
websites.url,
websites.screenshot,
impressions.number,
blocks.price
FROM websites
LEFT JOIN blocks ON websites.id = blocks.website
LEFT JOIN impressions ON blocks.id = impressions.block
WHERE status = 1
AND blocks.active = '1'
AND impressions.number = (SELECT MAX(number)
FROM impressions)
What I want to do is SELECT the max(number) but of the sum of the last 5 entries. I've tried messing around but just can't get it.
The last five impressions.number this should do it don't know what you want to sum on though
SELECT DISTINCT websites.id,
websites.title,
websites.url,
websites.screenshot,
impressions.number,
blocks.price
FROM websites
LEFT JOIN blocks
ON websites.id = blocks.website
LEFT JOIN impressions
ON blocks.id = impressions.block
WHERE status = 1
AND blocks.active = '1'
ORDER BY impressions.number
LIMIT 5
If you wanted to sum of blocks.price you could just do
SELECT SUM(lastblocks.price)
FROM (
SELECT
price
FROM websites
LEFT JOIN blocks
ON websites.id = blocks.website
LEFT JOIN impressions
ON blocks.id = impressions.block
WHERE status = 1
AND blocks.active = '1'
ORDER BY impressions.number
LIMIT 5 ) lastblocks
To get the last five records, it depends on the column by which you are sorting. Let's assume this is a date column, so then an example would be:
SELECT MAX(n) FROM tbl ORDER BY datecol DESC limit 5;

Using INNER JOIN to receive crossed data by date range

I have a theme gallery. In the dashboard i have to display the most viewed themes BY date (today, last 7 days, last 30 days, all time).
These are the 2 involved tables:
theme
id_theme
title
views
id_view
id_theme
date
The $timestamp values are calculated with mktime() (no prob in there).
This is my current SQL query:
SELECT t.id_theme,t.title,
(SELECT COUNT(*)
FROM views
WHERE views.id_theme=t.id_theme
AND views.date BETWEEN '.$timestamp1.' AND '.$timestamp2.')
AS q
FROM theme AS t
INNER JOIN views ON t.id_theme = views.id_theme
GROUP BY views.id_theme
ORDER BY q
DESC LIMIT 10
The problem is that The catch, is that sometimes it receives themes with 0 views, and that should not happen. I tried changing the INNER JOIN with RIGHT JOIN with no results. Any ideas?
Hmm. not sure why you're using subqueries for this, seems like this would work better:
SELECT theme.id_theme, theme.title, COUNT(views.id_view) as view_count
FROM theme
LEFT JOIN views ON (theme.id_theme = views.id_theme)
GROUP BY theme.id_theme
WHERE views.date > DATE_SUB(now() INTERVAL 30 day)
ORDER BY view_count DESC
HAVING view_count > 0
SELECT t.id_theme, t.title, COUNT(*) AS q
FROM theme AS t
INNER JOIN views ON t.id_theme = views.id_theme
AND views.date BETWEEN '.$timestamp1.' AND '.$timestamp2.'
GROUP BY t.id_theme, t.title
ORDER BY q
DESC LIMIT 10

Getting the last 5 records of a joined query

I have a query that does what i want joining table but i need it to change sligtly so i can use it for something else.
I need to get the last 5 records so i should be using the max function and limit it to 5 but it's not working properly
This is my current query, just need to get the last 5 records (probably by the festivalid)
SELECT f.*,
v.total,
v.votes,
v.festivalid,
ifnull(r.reviewcount,0) as count
FROM festivals f
INNER
JOIN vote v
ON f.festivalid = v.festivalid
LEFT OUTER
JOIN (SELECT festivalid,
count(*) as reviewcount
FROM reviews
GROUP BY festivalid) as r
ON r.festivalid = v.festivalid
WHERE f.datefrom > CURRENT_TIMESTAMP
ORDER BY f.datefrom, f.eventname
ORDER BY f.datefrom DESC, f.eventname DESC
Limit 5