I have one table named:
thread_comment
Now the table is getting filled as followed:
thread_comment_id thread_id user_id thread_comment thread_comment_time
1 2 1 This is a comment 2016-09-14 15:30:28
2 4 1 This is a comment 2016-09-14 15:32:28
3 2 1 This is a comment 2016-09-14 15:33:28
4 5 1 This is a comment 2016-09-14 15:34:28
5 7 1 This is a comment 2016-09-14 15:35:28
6 2 1 This is a comment 2016-09-14 15:37:28
7 2 1 This is a comment 2016-09-14 15:40:28
I want to show the newest threads to my page. for example:
as number one i want thread_comment_id 7
as number two i want thread_comment_id 5
I skipped 6 because i don't want any duplicates in the list.
In order to do so i did the folowing:
$sql = "SELECT DISTINCT thread_id FROM thread_comment ORDER BY thread_comment_time DESC"
This is kind of working (Not showing any duplicates). However the order does not make any sense...
For example:
It goes like 5 - 6 -4 - 7 etc...
The column used in the ORDER BY isn't specified in the DISTINCT. You need to use an aggregate function and GROUP BY to make the DISTINCT work.
SELECT DISTINCT thread_id, max(thread_comment_id) FROM thread_comment GROUP BY thread_id ORDER BY max(thread_comment_id) DESC, thread_id
EDIT: added aggregate func max()
Also thread_id is not mandatory in the ORDER BY
It I understand correctly, you want one row per thread. Here is a way to do this:
select tc.*
from thread_comment tc
where tc.thread_date = (select max(tc2.thread_date)
from thread_comment tc2
where tc2.thread_id = tc.thread_id
);
Related
Music table
id | title
1 Rap God
2 Blank Space
3 Bad Blood
4 Speedom
5 Hit 'em up
Like table
u_id | m_id
1 1
1 2
1 4
1 5
2 3
2 4
2 5
3 1
3 5
4 1
4 2
4 5
Now if someone visits music with m_id = 1
Then the output might be like
m_id
5
2
4
To explain this a bit...
As m_id = 1 is liked by users -> {1,3,4} which in turn likes ->{2,4,5} musics. Since m_id=5 is liked by max number of users its first followed by m_id = 2 and m_id = 4.
My Try
I queried the users who liked m_id = 1
SELECT u_id FROM likes WHERE m_id =1
Then i stored in in an array and selected each of their likes and
arranged them in desc order of count.
But it is a very slow and long process is there any way i can do this ?
p.s I have heard of Association Rules and Bayesian theorem can be user to achieve this. But can anyone help me out with an example ?
You can JOIN back on the Like table and do something like this.
SELECT also_like.m_id, COUNT(also_like.m_id)
FROM [like] AS did_like
JOIN [like] AS also_like ON
also_like.u_id = did_like.u_id
AND also_like.m_id != did_like.m_id
WHERE did_like.m_id = 1
GROUP BY also_like.m_id
ORDER BY COUNT(also_like.m_id)
Essentially you are getting a list of users who liked an item then getting a complete list of those user's likes excluding the item they just liked.
You can then add a HAVING clause or LIMIT to filter things down a bit more.
using a subquery ...
SELECT m_id, count(u_id) as Rank FROM `like`
WHERE u_id in
(
SELECT u_id
FROM `like`
WHERE m_id = 1
)
AND m_id <> 1
GROUP BY m_id
ORDER BY Rank DESC
and optionally
LIMIT 0, 10
or how many "alsolikes" you want to display
i am facing a very weird problem.
Basically i need to extract a set of rows from a table where every row is the "oldest" in its own group.
The table is structured as follow:
id, integer
domain_id, integer
value, integer
created_at, datetime
My query is
SELECT * FROM domains_urls GROUP BY domain_id HAVING created_at = MAX(created_at)
If i am not wrong, it should group the rows by domain_id and extract the one that it matches created_at = MAX(created_at).
The point is that it does not work as expected!
The table content is
id domain_id value created_at
1 2 1 2014-05-25 10:30:13
2 1 3 2014-05-25 19:30:13
3 2 2 2014-05-25 11:30:13
4 2 7 2014-05-25 15:30:13
5 2 4 2014-05-25 12:30:13
6 2 5 2014-05-25 13:30:13
I should get two rows:
id domain_id value created_at
2 1 3 2014-05-25 19:30:13
4 2 7 2014-05-25 15:30:13
Instead i get only
id domain_id value created_at
4 2 7 2014-05-25 15:30:13
I'm using MySQL 5.5 on Windows 7
I need to use an HAVING+GROUP BY or a DISTINCT+ORDER BY (not tested).
Thanks!
EDIT:
Because i am a dumb (i should avoid working on sunday), the value returned by MAX is related to the table and not to the group!
You can accomplish this by joining the table back to itself using the max(created_at):
select du.*
from domains_urls du
join (select domain_id, max(created_at) maxcreated_at
from domains_urls
group by domain_id
) du2 on du.domain_id = du2.domain_id
and du.created_at = du2.maxcreated_at
SQL Fiddle Demo
Try something like this
Select * from urls as u group by u.id having u.created >= any (select created from urls u2 where u.id == u2.id)
i have not tested this, just wrote that from the top of my head
I am using user Keevas' example, but asking a different question....
select Master_Code, SUM(Jan), SUM(Feb), SUM(Mar)
from dbo.foobar
WHERE Participating_City = 'foofoo'
GROUP BY Master_Code ORDER BY Master_Code ASC
something like this:
Master_Code sum(Jan) Sum(Feb) sum(Mar) Total
1 4 5 4 13
2 5 5 5 15
How do I get Total value column?
SELECT username,SUM(value) AS SumValue FROM
table GROUP BY username ORDER BY SumValue DESC
I have the following table:
step_id hospital_id step_number step_name
17 8 4 First Step
18 8 1 Second Step
19 8 2 Third Step
20 8 3 Finance Approval
What I am trying to do is get the step_id that corresponds to the smallest step number. So in the example above I am looking for step_id 18.
After looking over many posts I have been trying variations of the following to no avail:
SELECT `step_id`
FROM `progress_steps`
WHERE `hospital_id` = 8
GROUP BY `step_id`
HAVING MIN(`step_number`)
It seems to have worked for other but the above returns all rows from the example and other variations I have tried give me step_id 17 only.
You can do that by using ORDER BY and LIMIT
SELECT *
FROM tableName
WHERE hospital_id = 8
ORDER BY step_number ASC
LIMIT 1
SQLFiddle Demo
or if you want to get multiple rows having the same lowest step_number, use subquery:
SELECT *
FROM tableName
WHERE step_Number =
(
SELECT step_Number
FROM tableName
WHERE hospital_id = 8
ORDER BY step_number ASC
LIMIT 1
)
SQLFiddle Demo
SQLFiddle Demo (with duplicate record)
Try this one
SELECT `step_id`
FROM `progress_steps`
WHERE `hospital_id` = 8
Order BY `step_id`
LIMIT 1
Using the following query I am looking for a solution to get the latest record that having some conditions.
But it gives me the first record, not the latest. I think its only considering the group by
Please advise me
SELECT * FROM `contacts` WHERE `id_receiver`=1 GROUP BY `id_thread` ORDER BY created DESC
id id_sender id_thread sender_email id_receiver created(datetime)
1 2 2 51 1 2012-03-24 13:44:48
2 4 4 1 5 2012-04-26 13:46:05
3 2 2 51 1 2012-04-09 12:12:30
Required output
id id_sender id_thread sender_email id_receiver created(datetime)
3 2 2 51 1 2012-04-09 12:12:30
I had done a test just swap the order by and group by , giving me an erros.
Anybody can just look in to this?. Thanks.
EDIT Edited question, forget to write id_thread
How can you GROUP BY id_thread when there is no id_thread column in your table?
SELECT *
FROM contacts
WHERE id_receiver = 1
--- GROUP BY id_thread
--- removed
ORDER BY created DESC
LIMIT 1 --- only show one row
Based on your comments, what you want is the latest (ordered by created) row for every id_thread, which is a different and more complex query. There's even a tag for this kind of queries, named [greatest-n-per-group].
SELECT c.*
FROM contacts AS c
JOIN
( SELECT id_thread, MAX(created) AS created
FROM contacts
WHERE id_receiver = 1
GROUP BY id_thread
) AS g
ON (g.id_thread, g.created) = (c.id_thread, c.created)
WHERE c.id_receiver = 1
if records goes sequential than you might SORT by id too -- if and only if it's created in sequential order --