Show most popular items of today? - mysql

I want to output all entries of today, sorted by the most popular entries (most likes = most popular).
I'm using this query which just selects the most popular entries in the past 24 hours, but if it's 0:00 o'clock for example the count should reset to zero. I also want to order alphabetically if entries have the same count-amount.
How could I achieve that? I tried to ORDER BY count DESC, p.id DESC but I think this didn't seem to work using GROUP BY I assume.
__
This is my code:
SELECT
p.id, COUNT(l.id) AS count, p.title_de, p.de
FROM
pages p
JOIN pages_likes l on l.page_id = p.id
WHERE
l.date >= DATE_SUB(NOW(),INTERVAL 1 DAY)
AND
l.`status` = 1 GROUP BY p.id
ORDER BY count DESC LIMIT 6
This outputs for example:

I guess you want count only the records from current day?
instead of
>= DATE_SUB(NOW(),INTERVAL 1 DAY)
Remove the time part with DATE()
SELECT DATE(NOW());
Now the order part: dont use reserved word for alias
SELECT
p.id,
COUNT(l.id) AS cnt, p.title_de, p.de
....
ORDER BY cnt DESC, p.title_de

Related

How can I get a users that exceed $ 1000 in the last 30 days? for each user last 30 days. SQL Having Limit

i have table products in DB.
Products: id, user_id, product_price.
How can I get a users that exceed $ 1000 in the last 30 days? (for each user last 30 days)
My script not help me:
SELECT t.user_id,
,SUM(t.product_price)
FROM ( SELECT p.user_id
, p.product_price
FROM products p
ORDER BY p.id DESC LIMIT 30
) t
GROUP BY t.user_id
HAVING SUM(t.product_price) >= 1000
You don't need a subquery, you need a WHERE. "Last 30 days" implies a time period up to today. For that, use curdate() (or a similar construct):
SELECT p.user_id, SUM(p.product_price)
FROM products p
WHERE p.<date column> >= curdate() - interval 30 day
GROUP BY p.user_id
HAVING SUM(p.product_price) >= 1000;
Presumably, you don't have future dates in the data, so you don't need to check that the date is in the past.
The names of tables in your database are quite suspicious. I don't see why a user_id would be in a table called products.

mysql : Get latest value and sum of values from previous hour

I would like to return a product together with its latest value and values from last hour.
I have a product-table :
id, name, type (and so on)...
I have a values-table :
id_prod, timestamp, value
Something like :
12:00:00 = 10
12:15:00 = 10
12:30:00 = 10
12:45:00 = 10
13:00:00 = 10
13:15:00 = 10
13:30:00 = 10
I would like a query that returns the latest value (13:30:00) together with the sum of values one hour back. This should return:
time = 13:30:00
latestread = 10
lasthour = 40
What I almost got working was:
SELECT *,
(SELECT value FROM values S WHERE id_prod=P.id
ORDER BY timestamp DESC LIMIT 1) as latestread,
(SELECT sum(value) FROM values WHERE id_prod=D.id and
date_created>SUBTIME(S.date_created,'01:00:00')) as trendread
FROM prod P ORDER BY name
But this fails with "Unknown column 'S.date_created' in 'where clause'"
Any suggestions?
If I understand correctly what you're trying to do, then You would have something like:
SELECT p.id, max(date_created), sum(value), mv.max_value
FROM product p
JOIN values v on p.id = v.product_id
JOIN (SELECT product_id, value as max_value
FROM values v2
WHERE date_created = (SELECT max(date_created) FROM values WHERE product_id=v2.product_id)) mv on product_id=p.id
WHERE date_created between DATE_SUB(now(), INTERVAL 1 HOUR)) and now()
GROUP BY p.id
ORDER BY p.id
Aleks G and mhasan gave solutions, but not the reason why this fails. The reason this fails is because the alias S is not known inside the subquery. Subqueries have no knowledge about the tables outside their scope.
You have missed providing alias for table Values in subquery below
SELECT *,
(SELECT value FROM values S WHERE id_prod=P.id
ORDER BY timestamp DESC LIMIT 1) as latestread,
(SELECT sum(value) FROM values S WHERE id_prod=P.id and
date_created>SUBTIME(S.date_created,'01:00:00')) as trendread
FROM prod P ORDER BY name
I think this is the query that you are trying to write:
SELECT p.*,
(SELECT v.value
FROM values v
WHERE v.id_prod = p.id
ORDER BY v.timestamp DESC
LIMIT 1
) as latestread,
(SELECT sum(v.value)
FROM values v
WHERE v.id_prod = p.id and
v.timestamp > SUBTIME(now(), '01:00:00')
) as trendread
FROM prod p
ORDER BY p.name;
This changes all the aliases to be abbreviations for the table name. It also fixes the expression for the last hour by using now() and gets rid of date_created which doesn't seem to be in either table based on the question. The query conveniently assumes that timestamp is a datetime. If it is a unix timestamp, then somewhat different time logic is necessary.
This should be reasonably efficient with an index on values(id_prod, timestamp, value).

MYSQL how to add more rows if results are less than a number

I am creating a view so show the most popular questions in the last 2 days.
However because we don't have a lot of activity, it only shows 68 items.
I want to add a way for this statement to say, if results have less than 1000 items, then add the remaining ones without worrying about ranking.
1000 results = 68 popular, 932 regulars
SELECT *, ((likesCount*.8)+(commentsCount*.6)+(sharesCount*1)/2.4) as wavg
FROM production.question
JOIN production.feed
ON production.question.id = production.feed.q_id
WHERE (production.feed.timestamp >= (now() - interval 2 day))
GROUP BY production.question.name
ORDER BY wavg DESC
LIMIT 0,1000;
(only returns 68 results, need to add the other 932 by just saying SELECT * FROM production.question, or whatever...)
You can do what you want by moving the where condition into the order by clause. So, order by the data you want first, and then put the rest.
The following query also replaces the join with a left join, and includes a match for the second table in the order by:
SELECT *, ((likesCount*.8)+(commentsCount*.6)+(sharesCount*1)/2.4) as wavg
FROM production.question q LEFT JOIN
production.feed f
ON q.id = f.q_id
GROUP BY q.name
ORDER BY (f.timestamp >= (now() - interval 2 day)) desc,
(f.q_id is not null) desc,
wavg DESC
LIMIT 0,1000;
It also uses table aliases to make a query a bit more readable.
EDIT:
To randomize the questions at the end:
ORDER BY (f.timestamp >= (now() - interval 2 day)) desc,
wavg DESC,
rand()
LIMIT 0,1000;
This won't affect anything where wavg is defined, only the "rest" of the records.

Multiple column counts by week

I have the following two tables:
Posts
post_id
post_title
post_timestamp
Comments
comment_id
posts_post_id
comment_content
comment_timestamp
I want to create a report that shows the weekly post count and comment count. Something like this:
Week StartDate Posts Comments
1 1/1/2012 100 305
2 1/8/2012 115 412
I have this query but it only pulls form the Posts table.
select makedate( left(yearweek(p.post_timestamp),1),week(p.post_timestamp, 2 ) * 7 ) as Week, COUNT(p.post_id) as Posts
FROM cl_posts p
GROUP BY Week
ORDER BY WEEK(p.post_timestamp)
How do I add the Comment count too?
I think you need something like this:
select
week(post_timestamp) as Week,
adddate(date(post_timestamp), INTERVAL 1-DAYOFWEEK(post_timestamp) DAY) as StartDate,
count(distinct post_id),
count(comment_id)
from
posts left join comments
on comments.posts_post_id = posts.post_id
group by Week, StartDate
Here is one way, using join:
select coalesce(p.week, c.week) as week, p.Posts, c.Comments
from (select makedate( left(yearweek(p.post_timestamp),1),week(p.post_timestamp, 2 ) * 7 ) as Week,
COUNT(*) as Posts
FROM cl_posts p
GROUP BY Week
) p full outer join
(select makedate( left(yearweek(c.comment_timestamp),1),week(c.comment_timestamp, 2 ) * 7 ) as Week,
COUNT(*) as Comments
FROM cl_comments c
GROUP BY Week
) c
on p.week = c.week
order by 1
The reason that I'm using a full outer join instead of another join type is to keep weeks even when one or the other counts are 0. The reason I'm not joining the tables together is because, presumably, you want the report by the comment date, not the post date of the post associated with the comment.

mysql order by timestamp latest and group the rows of that category with limit

Order by timestamp DESC and group by a category with a limit in Mysql
cat timestamp
----------------
11 1308748405
11 1308747228
13 1308749273
57 1308748289
11 1308746228
...to get a table of the format, where it is sorted by timestamp and also relevant rows of that category grouped together with a limit. (ie group by category of all rows and arrange amoung the groups by the descending order of timestamps but keep the group together)
cat timestamp
----------------
13 1308749273
11 1308748405
11 1308747228
57 1308748389
I am guessing what you are looking for is: Get the minimum timestamp per category, and sort the results by timestamp?
SELECT t.cat, t.timestamp
FROM table t
JOIN (SELECT MIN(timestamp) as min_time, cat
FROM table
GROUP BY cat) as tmp
ON (t.cat = tmp.cat AND t.timestamp = tmp.min_time)
ORDER BY 2 DESC
SELECT cat, timestamp
FROM yourtable
ORDER BY timestamp DESC
GROUP BY cat
LIMIT 4
without more details, this is the best you're going to get.
If you want to get 4 groups based on sorted by it's latest timestamp. This may works:
SELECT tblTes.cat, tblTes.timestamp
FROM tblTes INNER JOIN (SELECT cat, MAX(TIMESTAMP) AS latest FROM tblTes GROUP BY cat) AS subQuery
ON tblTes.cat = subQuery.cat AND tblTes.timestamp = subQuery.latest
ORDER BY tblTes.timestamp DESC LIMIT 4;