How to select only last rows that satisfies conditions? - mysql

I'm trying to select rows where x=5, but x changes constantly. So I have such a table:
id x
---- ---
1 5
2 6
3 4
4 5
5 5
So I want to perform a query like "SELECT * FROM table WHERE x=5 AND _???_;" so that it returns rows 4 & 5 but not row 1.
In other words, I want to get the rows where x had this value most recently. I hope I made myself clear. Thanks!
edit:
Number of entries after x got the last value my change. I mean the table could also be like this:
id x
---- ---
1 5
2 6
3 4
4 5
5 1
6 5
7 5
... 5
100 5
101 5
in this case it should return rows [6-101].

Following wil get recent row
SELECT * FROM table WHERE x=5 ORDER BY id DESC LIMIT 0,1

SQLFiddle demo
select * from t t1
where
x=(select x from t order by id desc limit 1)
and
not exists
(select x from t where id>t1.id and x<>t1.x)
or
SQLFiddle demo
select * from t t1
where
x=(select x from t order by id desc limit 1)
and
id>=
(select max(id) from t
where x<>
(select x from t order by id desc limit 1)
)
Select what is faster on your base.

Related

Get most recent ROW with a GROUP BY on multiple columns

I'm trying to get the most resent result for every amount linked to a duration.
This is my table :
SELECT * FROM financement;
id amount duration total
8 200 5 result8
7 200 4 result7
6 100 5 result6
5 100 4 result5
4 200 5 result4
3 200 4 result3
2 100 5 result2
1 100 4 result1
There is is a total for every amount linked to a duration.
My problematic is that, they can be multiple row for the same amout x duration and I only want the most recent.
For exemple in my case :
id amount duration total
5 100 4 result5
1 100 4 result1
I tried to use a GROUP BY like this:
SELECT * FROM `financement` GROUP BY amout, duration ORDER BY `id` DESC
But with this method, even with the ORDER BY id DESC, I still get the most ancien ROW.
I also tried to SELECT max() in a sub query like this, but the query is extremely long and it times out.
SELECT * financement where id in (select max(id) from financement group by amount, duration);
How can I get this output ?
id amount duration total
8 200 5 result8
7 200 4 result7
6 100 5 result6
5 100 4 result5
This should work:
SELECT * FROM `financement`
WHERE id IN (
SELECT max(id) as id FROM `financement` GROUP BY duration, amount
)
ORDER BY `id` DESC
I think you want filtering. You can use a scalar subquery:
select f.*
from financement f
where f.id = (select max(f2.id)
from financement f2
where f2.amount = f.amount and f2.duration = f.duration
);
Try this query:
SELECT * FROM financement ORDER BY id DESC
output of this query

SQL query get random number of records from two categories

I have a table:
Numbers
id type_id
1 1
2 1
3 2
4 1
5 2
6 2
7 1
8 1
9 2
etc...
I need to get 3 random records of type 1 and the same number of random records of type 2. How can I get it with one query?
(select * from your_table where type_id = 1 order by rand() limit 3)
union all
(select * from your_table where type_id = 2 order by rand() limit 3)
Using MySQL
SELECT <<columns>> FROM <<table_name>>
ORDER BY RAND()
LIMIT <<count>>
Using Oracle
SELECT * FROM (SELECT * FROM <<table_name>> ORDER BY
SYS.DBMS_RANDOM.VALUE) WHERE ROWNUM <<Count>>

id order is mixed while using order by

I am using MySQL as a database.
Now I got everything working correctly but as my client wants to have filter on the website I am in the some sort of problem of what exactly I need to do and what would be the best way of doing it.
So this is my data ( I will simplify it as much as possible )
id name price nr.bed nr.bath
---------------------------------
1 a 33 2 4
2 b 100 5 1
3 c 102 2 2
4 d 85 1 1
5 e 37 6 4
6 f 19 2 1
So first time page loads I am using this query to get first 5 from the database:
SELECT * FROM hotel LIMIT 5
And I get this:
id name price nr.bed nr.bath
---------------------------------
1 a 33 2 4
2 b 100 5 1
3 c 102 2 2
4 d 85 1 1
5 e 37 6 4
After that each time I am calling this:
SELECT * FROM hotel WHERE id>'last_id(in this case 5)' LIMIT 5
And I am getting:
id name price nr.bed nr.bath
---------------------------------
6 f 19 2 1
And so on...
But now I need to use filter for example I will have filter for price
So I need to have something like:
SELECT * FROM hotel where id>5 order by price desc LIMIT 5
But then I am loosing my id order and I can't get next five from the database because I can't compare to and id of hotel because everything is orderd by price.
How can I achieve this?
Do I need to add another column or something which will keep my order as it is? Everything is presented on the website using and id from the table.
EDIT:
I am not sure if that is even possible because I need to have id ordered in asc and price in desc but I am not sure if we can combine those two together without adding another column or something.
EDIT2:
I would like to get something like this
id id_copy name price nr.bed nr.bath
-----------------------------------------
1 3 c 102 2 2
2 2 b 100 5 1
3 4 d 85 1 1
4 5 e 37 6 4
5 1 a 33 2 4
6 6 f 19 2 1
First, you should never use limit without order by when the ordering is important. Your queries should be like:
SELECT *
FROM hotel
WHERE id>'last_id(in this case 5)'
ORDER BY id
LIMIT 5
For your question, you want a subquery:
select *
from (SELECT * FROM hotel where id>5 order by price desc LIMIT 5
) t
order by id
The inner query selects the 5 by price. The outer one orders by id.
If you want to use this for "pagination", then you should become familiar with the offset argument to limit. This is described in the MySQL documentation here.
Order two columns then:
SELECT * FROM hotel where id>5 order by price desc , id asc LIMIT 5
i think this what you are looking for
SELECT * FROM hotel order by price desc limit 0 ,5
then if you want next 5
SELECT * FROM hotel order by price desc limit 5 ,5
then
SELECT * FROM hotel order by price desc limit 10 ,5
and so on...
you can make this in php like that
$sql="SELECT * FROM hotel order by price desc "
if (sombutton is clicked) {
$sql .= " limit 0,5" ;}
if (sombutton is clicked){
$sql .= " limit 5,5" ; }
or you can do it by a loop with variable $i everytime you add 5.

Select DISTINCT values from Two Columns using an inner join on the same table in MySQL

I have a query that selects 20 rows from a table, loops, and pulls a single row from the same table that falls in the desired score range. The found row is then deleted so that it will not be selected again.
user_id is unique and some rows have col1=0 and others have col1=1, therefore the second query will never select a row from the first query.
The temp table looks like this:
user_id col1
-------------------
1 0
2 0
3 1
4 1
The user table looks like this:
user_id score
-----------------
1 1000
2 2000
3 3000
4 4000
$res = do_query("SELECT temp.user_id,user.score
FROM temp,user
WHERE temp.col1=0 AND temp.user_id=user.user_id LIMIT 20");
while (($row = mysql_fetch_row($res))) {
$score = $row[1];
$alt_res = do_query("SELECT temp.user_id, user.score
FROM temp,user
WHERE temp.col1=1 AND temp.user_id=user.user_id
AND user.score<$score AND user.score>$score*0.66 LIMIT 1");
$alt_row = mysql_fetch_row($alt_res)
$user_id = $alt_row[0];
do_query("DELETE FROM temp WHERE user_id=$user_id");
}
This works just fine, however I was trying to turn this into a single query, but I keep getting duplicate values, and I can't seem to weed them out.
SELECT temp.user_id,t1.user_id,t1.score FROM (
SELECT temp.user_id,user.score
FROM temp,user
WHERE temp.col1=0 AND temp.user_id=user.user_id LIMIT 20) AS t1,temp,user
WHERE temp.col1=1 AND temp.user_id=user.user_id
AND t1.score<user.score AND t1.score>user.score*0.66 GROUP BY temp.user_id
I get 20 rows with temp.user_id being unique, but duplicates with t1.user_id.
For example:
temp.user_id t1.user_id
----------------------------
1 6
2 7
3 7
4 7
5 8
and I want:
temp.user_id t1.user_id
-----------------------------
1 6
2 7
3 8
4 9
5 10
Any idea how to make it so that no user_id is repeated in either column?
Maybe you can change LIMIT 20 to LIMIT 1 on the sub-query?

mysql random with condition

I have a table in mysql, say table1.
I am running this on it:
SELECT FLOOR( MAX(id) * RAND()) FROM `table1`
This works well, but I am now trying to add a condition of "AND tom".
Where tom is a integer field.
For example:
id tom
1 0
2 3
3 2
4 0
5 0
6 3
7 1
8 1
9 3
etc.
So, my question is,
How can I pick a random value from id, which also satisfies tom='0' say?
SELECT id FROM `table1` WHERE tom = 0 ORDER BY RAND() LIMIT 1
This will first get all rows in which tom = 0,then order those results randomly. MySQL will then limit those results to just one, returning the single value you want to retrieve.
I hope I understood correctly:
SELECT id FROM `table1` WHERE tom = 0 order by rand() limit 1
select * from (
select * from table where tom = 0 ) as t order by rand() limit 1