LIMIT(SELECT...) IN SQL? - mysql

Is this syntax allowed in sql (any DMS):
SELECT rows from table limit (select count(*) from table where value = 7)
In other words, is having a select statement within a limit allowed? Why or why not?

The syntax is not allowed in MySQL, not without using dynamic SQL to build the LIMIT clause. On MySQL 8+, we can try the following using ROW_NUMBER:
SELECT *
FROM
(
SELECT *, ROW_NUMBER() OVER (ORDER BY some_col) rn
FROM yourTable
) t
WHERE rn < (SELECT COUNT(*) FROM yourTable WHERE value = 7);

Postgres supports this syntax. For example:
create table n as
values (1), (2) ;
select *
from (values ('a'), ('b')) v(x)
limit (select count(*) from n)
Here is a db<>fiddle.
However, most databases require that the value for limit (or the equivalent construct) be defined at compile time.

Your syntax is not allowed in any database engine. limit requires fix values not varying one (applicable in sqlite and postgresql)
SELECT rows from table limit (select 10)
see dbfiddle

Related

MySQL Query from version 5.1 is not working in 5.7

select * from batches join (
select * from (
select *, row_number() over (
partition by batch_id
order by date ASC
) as row_num
from batch_schedule where display = 'Yes'
) as d_schedule
where d_schedule.row_num = 1
)
as f_schedule
on batches.id = f_schedule.batch_id
WHERE (f_schedule.date BETWEEN '2021/03/01' AND '2021/04/30')
This query is working fine in version 5.1 but not working in 5.7
What I am trying to achieve is,
filtering batches based on batch_schedule start dates.
I need to select the 1st row from the right table with condition display = 'Yes' and order by date asc and based on that row value i need to display batches.
I am getting the below error message
select is not valid at this position for this server version expecting '(' with
select * from batches join ( SELECT * from batch_schedule
where display = 'Yes' group by batch_id order by date asc )
as f_schedule on batches.id = f_schedule.batch_id
where(f_schedule.date BETWEEN '2021/03/01' AND '2021/04/30');
I tried this and it works.
I am posting here in case if someone looking for the same thing it will help.

How Can I set result set row count using sql query

I wanted to set the number rows returned per query say 5. How can I set this in the sql query.
Can any one please help me
Highly dependent on what RDBMS you are using.
For Oracle
SELECT * FROM the_table WHERE ROWNUM < 6
(since 12c there is another option, too).
For Postgresql
SELECT * FROM the_table LIMIT 5
According to the MySQL manual you can do this by adding LIMIT statement to your query:
SELECT * FROM tbl_name
LIMIT offset, row_numbers
or
SELECT * FROM tbl_name
LIMIT row_numbers OFFSET offset
offset option is very useful in case of pagination.
SELECT TOP 5 *
FROM dbo.MyTable
As someone suggest zou can use:
select top X from table_name
where X is the numer of rows that you want
or you can use row_number
With cte AS
( SELECT *,
ROW_NUMBER() OVER (order by table_column) as RowNumber
FROM table_name)
select *
from cte
Where RowNumber <= 5
or even:
With cte AS
( SELECT *,
ROW_NUMBER() OVER (order by table_column) as RowNumber
FROM table_name)
select *
from cte
Where RowNumber between 5 and 10

Equivalent of MSSQL with statement in MYSQL

is there any equivalent to the following statement in mysql ?
With Tmp1 as (
Select Distinct EmpID, TypeID
From tb_deductionBalance
), Tmp2 as (
Select *,
row_number() OVER ( order by empID /* no employeeID in Tmp1 */) as RowNum
From Tmp1
)
Select * From Tmp2
Where RowNum Between #Start and #End
I have to migrate an mssql database to mysql and there are plenty of such statements which would take much more time to recreate in mysql if it cannot be translated.
Thanks
SELECT DISTINCT EmpID, TypeID
FROM tb_deductionBalance
ORDER BY empID
LIMIT YourStartNumber - 1, YourEndNumber - YourStartNumber
Unfortunately, you can't use variables in LIMIT, so you'll need to use actual integers there. For instance, if you want results from the rows 3 to 10, you'll need to use:
SELECT DISTINCT EmpID, TypeID
FROM tb_deductionBalance
ORDER BY empID
LIMIT 2, 7

how to select rows of a table in 3th multiply order in sql like 3,6,9 etc

My table consists of 1024 rows and two columns.
I want to select and display rows like 3,4,6,etc..
Is it possible in sql query.
If possible what is the code for that..
In a relational database there is no concept of the "3rd" or "6th" row unless you can define a sort order.
Assuming you do have a column by which you can order the result in order to define a row as "3rd", or "4th", the following will work with Postgres:
select *
from (
select col1, col2, col3,
row_number() over (order by your_sort_column) as rn
from your_table
) t
where rn in (3,4,6);
Where your_sort_column is the one that defines the order or rows. This could be an incremental id or a timestamp column that stores the time of insert or update of the row.
In MySQL it can be accomplished as follows:
SELECT * from
(SELECT (#row := #row + 1) num, tab.* FROM your_table, (SELECT #row := 0) r
ORDER by your_sort_column) t
WHERE (num % 3) = 0
We have used a MODULO operator to get row which is at multiple of 3.
See it working at SQL Fiddle: http://www.sqlfiddle.com/#!2/192b0/4
In PostgreSQL it can be accomplished as follows:
select *
from (
select *, row_number() over (order by your_sort_column) as rn
from your_table
) t
where (rn % 3)=0 ;
http://www.sqlfiddle.com/#!15/cc649/5

Mysql get top half of table then bottom half of table

I need to get the top half of my table in my first query and in the next query I need the bottom half.
I tried doing this for the top but it wont work
SELECT * FROM t_domains WHERE type_domain='radio' ORDER BY
date_created DESC LIMIT 0, (COUNT(*) / 2)
I need it as two queries for my function to work.
Anybody have any pointers or tips?
I would suggest doing 2 query's:
select count(*) from t_domains
to get the total count, and then get the data you want by using limit and offset:
select * from t_domains limit count/2
for the top and
select * from t_domains offset count/2
for the lower half......
This approach gives you also a way to limit the query's in another situation: what if the table contains 1 million records?
for first half
mysql-> SET #n := 0
mysql-> SELECT *,nnn FROM (
SELECT *, #n := #n + 1 AS nnn FROM t_domains ORDER BY date_created
) AS t
WHERE nnn <= ( SELECT COUNT(date_created) / 2 FROM t_domains ) AND type_domain = 'radio'
for second half, change here WHERE nnn <= this "<" on this ">"
As explained in MySQL's official documentation, LIMIT's two arguments must both be CONSTANTS except for prepared statements and stored programs. It does not seem very easy to simply store the count and later use it in a LIMIT clause.
As of version 8.0, MySQL has provided a ROW_NUMBER() function, which provides a much simpler solution than other answers have pointed out.
set #count=(select count(*)/2 from t_domains);
select * from (
select *, ROW_NUMBER() over (order by date_created desc) as row_num
from t_domains
) as t
where row_num <= #count
;
You may also check RANK(), which considers rows with equal values to have the same "ranking".
This always works.
Store the count
SELECT COUNT(*) FROM t_domains WHERE type_domain='radio'
Then use the stored count.
SELECT * FROM t_domains WHERE type_domain='radio' ORDER BY
date_created DESC LIMIT 0, {$stored_count/2}