MySql Select Id <= Maximum value in the table - mysql

When using the <= in a MySql statement, is it possible to make MySql select the maximum value in a table without supplying a value to <= in the sql statement?
Eg:
id
----
1
2
3
4
5
6
Eg:
// start from the last record when no value is supplied
select id from table where id <= * ORDER BY id DESC LIMIT 5
Result
6
5
4
3
2
// start from the 5th record when a value is supplied
select id from table where id <= 5 ORDER BY id DESC LIMIT 5
Result
5
4
3
2
1
My problem is, this statement is in a php function, so I cannot change it dynamically. Is it somehow possible to do what I'm trying, or perhaps another way to get around this?

You can use NULL instead of using *
SET #var_search_value = NULL -- OR 5
SELECT id
FROM table
WHERE id <= #var_search_value OR #var_search_value IS NULL
ORDER BY id DESC LIMIT 5

If you want to get every record which is less than or equal to the maximum value in a particular column, then logically you want to get every record:
select id from table ORDER BY id DESC LIMIT 5
No WHERE clause is required.

Related

How to treat missing id 's value as 0 and order by it?

When I use in keyword in sql, there may be some id is missing , but I want treat them like they exist and other columns are null or 0.
For example, suppose I have a table with two columns and some rows:
[id,value1]
1      1
2      4
3      3
5      5
I may write sql like this:
select * from table where id in (1,4,5) order by value1 limit 0,2 ;
When this sql is executed, the return result is [(1,1),(5,5)].
But what I want is [(4,0),(1,1)], because I want to treat the missing id 4 like it exists in the table.
So the question is : Is there some elegant way to achieve it using sql instead of select all rows and sort them in memory.
Use a left join:
select *
from (select 1 as id union all
select 4 union all
select 5
) i left join
table t
using (id)
order by t.value1
limit 0, 2 ;
Note that you are ordering by a value in the existing table, so this depends on the fact that NULL is ordered before other values.

Return rows matching one condition and if there aren't any then another in MYSQL

I have the following table as an example:
numbers type
--------------
1 1
5 2
6 1
8 2
9 3
14 2
3 1
From this table I would like to select the closest number that is less or equal to 5 AND of type 1 and if there is no such row matching, then (and only then) I would like to return the first closest number larger than 5 of type 2
I can solve this by running two queries:
SELECT number FROM numbers WHERE number <= 5 AND type = 1 ORDER BY number LIMIT 1
and if above query returns 0 results, I simply run the second query:
SELECT number FROM numbers WHERE number > 5 AND type = 2 ORDER BY number LIMIT 1
But is it possible, to achieve the same result by only using one query?
I was thinking something like
SELECT number FROM numbers WHERE (number <= 5 AND type = 1) OR (number > 5 AND type = 2) ORDER BY number LIMIT 1
But that would only work, if mysql first checks the first conditional in the parentheses against all rows and if it finds a match, it returns it, and if not, then it checks all rows against the second parenthesed conditional. It will not work, if it checks each row against both parentheses and only then moves to the next row, which is how I suspect it works.
This query will do what you want. It selects all numbers that match your two query constraints, and orders the results first by type (so that if there is a result for type 1 it will appear first) and then by either -number or number dependent on type (so that numbers <= 5 sort in descending order but numbers > 5 sort in ascending order):
SELECT number
FROM numbers
WHERE ( number <= 5 AND type = 1 )
OR ( number > 5 AND type = 2 )
ORDER BY type, CASE WHEN type = 1 THEN -number ELSE number END
LIMIT 1
Output:
3
Demo on dbfiddle
Combine the two, and you always prefer type 1 over type 2, hence the ORDER BY and LIMIT. The ABS means whichever is first by type, is the closes to the number 5.
SELECT number, type
FROM numbers
WHERE (number <=5 AND type=1) OR
(number > 5 AND type=2)
ORDER BY type ASC, ABS(number-5) ASC
LIMIT 1

Mysql search text in one column

For Example our table;
İd--------Price---------Level
1 ------100-300 ------ 1,2
2 ---------200----------1
3 ------100-280--------1,3
We want search a price value is 110. 110 is between 100-300 and 100-280 so id 1 and id 2 must listed. Can we write this query with my-sql?.
Additional , we want search price and level value. Price 110 and level 2 searching. Can we write this query with my-sql?.
Thank You
Remember that database tables should be created with the idea that it will satisfy your query needs. It doesn't make sense to have a table with a price "100-300" which represents a String (or in mysql a VARCHAR) and you want to treat this as a number. So what to do?
1) The first thing i would do is re write my table schema having a minPrice and maxPrice fields, so this way you could have this:
İd----minPrice---maxPrice------level
1 ------100---------300 ------ 1,2
2 ------200---------200----------1
3 ------100---------280--------1,3
2) Then your query would be like:
SELECT id FROM Mytable x WHERE myValue >= x.minPrice AND myValue <= x.maxPrice
3) In case you also want to look for a level value. you would do:
SELECT id FROM Mytable x WHERE myValue >= x.minPrice AND myValue <= x.maxPrice AND myLevelValue IN (x.level)
Use two columns for the price ...
ID FROM TO LEVEL
1 100 300 1,2
2 200 200 1
3 100 280 1,3
Then SQL:
SELECT `level` FROM `table`
WHERE X >= `from` AND X <= `to`

How can I return the next row of WHERE clause?

I am using mysql DB server ..
I have the following table that consists of only one column with the following data (where 0's separate sorted integers)
Number
-------
0
1
2
3
0
4
5
0
6
7
8
0
9
10
0
11
I want to get the first value that comes after each 0 , so e.g. output would be
Output
------
1
4
6
9
11
MySQL doesn't guarantee a return order unless you specify a ORDER BY clause. If you get the values back in the order you insert them then that's just coincidence. As it stands there's no way to do what you want to do reliably. You need to add something to order the data by. An ID field set to autoincrement will probably do.
SELECT id1 FROM table WHERE id IN
(SELECT t1.id+1 FROM table t1
LEFT JOIN table t2 ON t1.id1=t2.id
WHERE t2.id1 IS NULL);
SQL Fiddle
Assuming no gaps in the increment field,but since it will be created..
First of all you should add Auto_increment key to your table to guarantee order of records.
Alter table T ADD id INT PRIMARY KEY AUTO_INCREMENT;
And here is the query:
select * from T as T1
Where (SELECT Number From T where Id<T1.Id ORDER BY ID DESC LIMIT 1) = 0
order by ID
SQL Fiddle demo

Random row from big query result

I need to get 1-2 rows from query result retrived with SQL select on indexed columns without getting the whole record set.
For example I will retrieve 10 000 records using query
SELECT * FROM table WHERE field 1>1 AND field1 < 10
but I need only 1 random row from this query regarding to highload of my database.
I can use
SELECT * FROM table WHERE field 1>1 AND field1 < 10 LIMIT 100, 1
But I don't know records numebr to use correct offset range
How can I achieve this goal?
You could use ORDER BY RAND()
SELECT * FROM table WHERE field1 > 1 AND field1 < 10 ORDER BY RAND() LIMIT 1
This will return 1 random row with field1 in between 1 and 10
How about restricting the records you select in the first place?
SELECT * FROM table WHERE field1 IN (CONVERT(RAND()*10,SIGNED),CONVERT(RAND()*10,SIGNED)) LIMIT 2