mysql select highest and lowest values with limit in one statement - mysql

I need to pull the 5 highest prices and 5 lowest prices from a table products on column prices. I thought I could do two select in one stmt like below, but I think you cannot because it is the same table? I have done similar stmts and it worked but with different tables.
SELECT products.* AS fullcount, (SELECT * FROM products ORDER BY price ASC LIMIT 5) AS highest, (SELECT * FROM products ORDER BY price DESC LIMIT 5) AS lowest FROM products
What am I doing wrong or should I be using a different approach?

Use UNION to combine the results of queries that get the highest and lowest rows.
SELECT *
FROM (
SELECT *
FROM products
ORDER BY price DESC
LIMIT 5) x
UNION (
SELECT *
FROM products
ORDER BY price ASC
LIMIT 5
) y

Related

Count total rows ignoring the select limit

I want to make a select in MySQL having limit of rows, but in the same select to count the total number of rows (not between limits).
How can I alter the code bellow to count all rows from that products table? If I add a count in this select it will count only 10.
SELECT id,
name,
categ
FROM products
LIMIT 0, 10
you can try this :
SELECT id,name,categ ,( SELECT count(*)
FROM products) as numberRows FROM products
LIMIT 10
there is an example :
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=ccc90496f13be1cc046b72cd9078c080

SQL order top rows differently than the rest

Is there any way how to order top rows in a query in a different way than the rest? For example, if I have a list of products with name and price, I would like to get the list ordered in a way that 10 most expensive products are on top ordered by price desc, and the rest below is ordered by product name.
What comes in my mind is something like this:
SELECT id,name, price FROM products ORDER BY price DESC LIMIT 10
UNION ALL
SELECT id,name,price FROM products
WHERE id NOT IN
(SELECT id FROM products ORDER BY price DESC LIMIT 10)
ORDER BY name
but this query does not execute, it prints Incorrect usage of UNION and ORDER BY, furthermore if I wrap the selects into another selects, it prints LIMIT & IN/ALL/ANY/SOME subquery. Any idea?
select * from
(
SELECT 1 a, id,name, price FROM products ORDER BY price DESC LIMIT 10
UNION ALL
SELECT 0, id,name,price FROM products
WHERE id NOT IN
(SELECT id FROM products ORDER BY price DESC LIMIT 10)
)
order by a*price desc, name

MySQL Query add limit in SubQuery

Here is my table test with values:
Price
----------
300
600
900
1000
1800
2000
I want to query such that when I search for 300 ,I should get 4 records 300,600,900,1000.
If I search for 900, I can get 600,900,1000,1800.
i.e. Two records <=900 and Two record >900
Here is the query I tried :
SELECT * FROM table h where CONDITIONS
and (price in (select price from table where price <=900) // I want to add LIMIT 2 in this subquery
or price in (select price from table where price >900)//LIMIT 2
)
order by FIELD(price ,900) DESC limit 5;
I searched a lot on stack overflow,but nothing worked. Please help .
You can try the following...
select * from ((select h.* from table_name h where amount <=300 order by amount desc limit 2)
union
(select h.* from table_name h where amount >300 order by amount limit 2))
derived_table order by FIELD(amount,300) desc;
MySQL doesn't support LIMIT in WHERE IN/EXSISTS/ANY/SOME subqueries, you can do this with UNION
(SELECT * /* this should be a columnlist */
FROM tablename
WHERE price < 900
ORDER BY price LIMIT 2)
UNION
(SELECT * /* this should be a columnlist */
FROM tablename
WHERE price >= 900
ORDER BY price LIMIT 2)
The parenthesis around each select are crucial.
See SQL Fiddle
Using union because this mysql version don't accept limit in subqueries
select * from table where price <=900 limit 2 union select * from table where price > 900 limit 2

How can I limit query's results without using LIMIT

I need to show ordered 20 records on my grid but I can't use LIMIT because of my generator(Scriptcase) using LIMIT to show lines per page. It's generator's bug but I need to solve it for my project. So is it possible to show 20 ordered record from my table with a query?
As from comments,if you can't use limit then you can rank your results on basis of some order and in parent select filter limit the results by rank number
select * from (
select *
,#r:=#r + 1 as row_num
from your_table_name
cross join (select #r:=0)t
order by some_column asc /* or desc*/
) t1
where row_num <= 20
Demo with rank no.
Another hackish way would be using group_concat() with order by to get the list of ids ordered on asc/desc and substring_index to pick the desired ids like you need 20 records then join with same table using find_in_set ,But this solution will be very expensive in terms of performance and group_concat limitations if you need more than 20 records
select t.*
from your_table_name t
join (
select
substring_index(group_concat(id order by some_column asc),',',20) ids_list
from your_table_name
) t1 on (find_in_set(t.id , t1.ids_list) > 0)
Demo without rank
What about SELECT in SELECT:
SELECT *
FROM (
-- there put your query
-- with LIMIT 20
) q
So outer SELECT is without LIMIT and your generator can add own.
In a Scriptcase Grid, you CAN use Limit. This is a valid SQL query that selects only the first 20 records from a table. The grid is set to show only 10 records per page, so it will show 20 results split in a total of 2 pages:
SELECT
ProductID,
ProductName
FROM
Products
LIMIT 20
Also the embraced query works out well:
SELECT
ProductID,
ProductName
FROM
(SELECT
ProductID,
ProductName
FROM Products LIMIT 20) tmp

MySQL select random rows with order by

I want to retrieve random rows from table but this rows must be order in category.
select category,
(select order_number
from orders
where order_number in (123,125,128,129,256,263,966,258,264,159,786)
order by rand())
from orders
order by category
This is the query I tried. But that retrieves whole data in table.
Worked query ;
SELECT category,order_number FROM (
SELECT category,order_number
from orders
where order_number in (`$order_numbers_variable`)
order by rand()
) order by category
I assume the requirement is:
Retrieve 'N' random rows from a table sorted by 'category'.
Lets assume N is 10. If you want to change the number of rows, then change it in the LIMIT clause.
SELECT * FROM (
SELECT category from orders ORDER BY rand() ASC LIMIT 10
) AS innerResult
ORDER BY innerResult.category