I want to get the latest 5 messages in the inbox.
To get the 5 latest IDs i need to use this:
SELECT
MAX(id)
FROM
samtaler
WHERE
brukerid_mottaker = 1
GROUP BY brukerid_avsender
ORDER BY id DESC
LIMIT 5
This return the correct ID's I need. But in the same query i want to select data from the same table, the row that got the id that returned from this query above.
I have tried out some things, variables and self-join but no luck:
select
p2.title,
p2.message,
#a:=max(p1.id)
from
samtaler p1
join samtaler p2
on (#a = p2.id)
where
p2.brukerid_mottaker = 1
group by p2.brukerid_avsender
order by p2.id DESC
limit 5
Why isnt this working?
This is the current data in the database:
I want to return in this case, row 13 and 4. Sorry for bad english.
Join against a subquery, instead of a plain self join. An IN() clause won't work since LIMIT cannot be used inside an IN(). It should work in the joined subquery though:
SELECT
p1.title,
p1.message,
p2.id
FROM
samtaler p1
JOIN (
SELECT MAX(id) AS id
FROM
samtaler
WHERE
brukerid_mottaker = 1
GROUP BY brukerid_avsender
ORDER BY id DESC
LIMIT 5
) p2 ON p1.id = p2.id
By this method, there is no need for variables.
Related
Yesterday I tried to retrieve data from my db table using 'user_id' as a criterion to limit the amount of data per user.
I tried to get data from table https://prnt.sc/p53zhp in format like this https://prnt.sc/p541wk and limit the number of output records for user_id where limit will be 2 (count(user_id) <= 2), but i don't understand how to do that. What kind of sql request can i use to get this data?
Assuming that your RDBMS, here is a solution yo select only the top 2 records per user. You can use ROW_NUMBER() in a subquery to rank records by id within groups of records having the same user_id, and the filter out unerelevant records in the outer query, like:
SELECT *
FROM (
SELECT
t.*,
ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY id)
FROM mytable
) x WHERE rn <= 2
On earlier versions of MySQL, you could use self-LEFT JOIN the table and use GROUP BY and HAVING COUNT(...) < 2 to limit the results to first two records per group:
SELECT
t.id,
t.user_id,
t.vip,
t.title,
t.description,
t.data
FROM mytable t
LEFT JOIN mytable t1 ON t1.user_id = t.user_id AND t1.id > t.id
GROUP BY
t.id,
t.user_id,
t.vip,
t.title,
t.description,
t.data
HAVING COUNT(t1.id) < 2
I don't understand if your problem is a Transact-SQL or your code.
In SQL you can limit record with "LIMIT": https://www.w3schools.com/sql/sql_top.asp
In code, you can use a condition IF.
I'm trying to get the latest certificate a user has from the database. I only want to see the latest one and not all the others so I'm using group by and then ordering by the unique id from the main table.
Without group by this works perfectly. I see the last certificate uploaded and then all the others below.
As soon as I add the group by I see the first certificate ever uploaded which is pointless as it could be from years ago.
My query is quite large as I'm drawing in a lot of other information from other tables.
Here is my query.
SELECT
usercert.*,
cert.*,
certCat.certCatName,
certTask.certTaskName ,
certStatus.certStatusName
FROM
`usercert`
INNER JOIN
cert
ON
cert.idcert = usercert.idcert
INNER JOIN
certCat
ON
certCat.idcertCat = cert.idcertCat
INNER JOIN
certTask
ON
certTask.idcertTask = usercert.idcertTask
INNER JOIN
certStatus
ON
certStatus.idcertStatus = usercert.idcertStatus
WHERE
usercert.iduser=%s
GROUP BY
usercert.idcert
ORDER BY
usercert.usercertEnd DESC
SELECT
usercert.*,
cert.*,
certCat.certCatName,
certTask.certTaskName ,
certStatus.certStatusName
FROM
`usercert`
INNER JOIN
cert
ON
cert.idcert = usercert.idcert
INNER JOIN
certCat
ON
certCat.idcertCat = cert.idcertCat
INNER JOIN
certTask
ON
certTask.idcertTask = usercert.idcertTask
INNER JOIN
certStatus
ON
certStatus.idcertStatus = usercert.idcertSttus
WHERE
usercert.iduser=%s
ORDER BY
usercert.usercertEnd
DESC limit 0,1
in this query it will take all the record in descending order it means the last inserted row will come first and the limit 0,1 means it will start from 0 and fetch 1 record that's it ...
You can either use MAX():
SELECT ... FROM ... WHERE ... ORDER BY MAX(usercert.usercertEnd)
Or LIMIT:
SELECT ... FROM ... WHERE ... ORDER BY usercert.usercertEnd DESC LIMIT 1
I have a table as follow. I want to run a query to select the data from the table using php in which if date column is repeated then I want to take only last row of that date
id Date start end publish
1 04-Nov-2015 1000 1300 0
4 04-Nov-2015 2100 3500 0
5 05-Nov-2015 1500 3000 0
like for the below table, When I run the query then the result should come:
4 04-Nov-2015 2100 3500 0
5 05-Nov-2015 1500 3000 0
When I run the query
$select = mysql_query("select * from `entry` Group by `date`") or die(mysql_error());
Then It shows the first row of repeating table, What should I modify in the query that the result should show the last row of repeating colum
Select * from (Select * from entry order by date,id desc) x group by x.date
You can do this with this approach:
$select = mysql_query("select * from `entry` Group by `date`" ORDER BY id DESC LIMIT 1) or die(mysql_error());
Try inner query, I'm not sure following will work exactly as I cant test that now, but for getting result you have to use inner query. Inner query help me to get expected result in my case.
SELECT *
FROM entry p
WHERE id =
(SELECT max(id) FROM entry p2
WHERE p2.id = p.id)
GROUP BY p.date
ORDER BY p.id DESC;
This query will work for you:
create TABLE test (id INT PRIMARY KEY, tdate DATE, start INT);
SELECT t1.* FROM test as t1
LEFT JOIN test as t2
ON (t1.tdate = t2.tdate AND t1.id < t2.id)
WHERE t2.id IS NULL;
Try this query :-
select * from( select * from entry order by id DESC ) new Group by date
I'm having difficulty understanding how to Order a query by data from another table.
The existing query is: SELECT ID FROM UserTour WHERE Live = 1 ORDER BY LastUpdated DESC
This obviously Orders by the column 'LastUpdated' in the table 'UserTour'
However, I need it to be ordered by the column 'LastUpdated' which is in another table 'ImageLinks', Where 'TypeID' = 16 (again in 'ImageLinks').
I hope that makes sense.
So it would be something like: $ids = #mysql_values('SELECT ID FROM UserTour WHERE Live = 1 ORDER BY ('Select ID FROM 'ImageLinks' Where TypeID = 16 Order by LastUpdated DESC')');
Any help would be appreciated on how to do this. Cheers
If there is no relationship between the two tables your query in your question will look like this
select id from
(
SELECT
ID
, (Select ID FROM ImageLinks Where TypeID = 16
Order by LastUpdated DESC limit 1) as order_val
FROM UserTour
WHERE Live = 1
) x
ORDER BY x.order_val
which will work but will not do not any ordering as the order_val column will have a fixed value.
If the IDs are linked 1:1 (no indication that they are, but just supposin') we could do this:
select u.id
from UserTour u inner join ImageLinks i on u.ID = i.ID
where u.Live = 1 and i.TypeID = 16
order by i.LastUpdated desc
If the above is incorrect then you will have to decide how the two tables are related and join them correspondingly.
In other words, If the tables are in no way connected, then you cannot provide an ordering of one table's data based on a column in the other.
UPDATE
select
i.LinkID
, i.LastUpdated
from UserTour u inner join ImageLinks i
on u.ID = i.LinkID
where u.Live = 1 and i.TypeID = 16
group by i.LinkID, i.LastUpdated
order by i.LastUpdated desc LIMIT 30
My tables are like this:
Table 1 (students)
Table 2 (results)
I want to select all students from Table 1 students who have 4 results in the results table. I tried this query, but with no success:
SELECT *
FROM students
WHERE gender = 'm'
AND (SELECT COUNT( result ) AS count
FROM results
INNER JOIN students ON results.stuID = students.stuID
WHERE result !=0
) =4
ORDER BY rank ASC
You can rewrite your query by using join and HAVING clause to check the count for each student group ,This can be done without using the subquery which sometimes affects on performance
SELECT s.*,COUNT(*) AS count
FROM students s
INNER JOIN results r ON r.stuID = s.stuID
WHERE r.result !=0
GROUP BY s.stuID
HAVING count =4
ORDER BY s.rank ASC
um, that's a little convoluted.
the where clause should come after the subquery, and the subquery still needs to be JOINed back to the main query.
something like
SELECT * FROM students
INNER JOIN (SELECT COUNT(result),results.stuID as count FROM results WHERE result != 0) as result_count
ON result_count.stuID = students.stuID
WHERE result_count.count =4 AND students.gender = 'm'
ORDER BY rank ASC
You have to use alias for table also -
SELECT *
FROM students as a
WHERE gender = 'm'
AND (SELECT COUNT(result) AS count
FROM results as b
WHERE b.stuID = a.stuID AND
(result!=0 OR result IS NOT NULL OR result!='')
) = 4
ORDER BY rank ASC