I am trying to do a Order by after a Limit Query - mysql

So this is my First Question here, so please forgive me if something is wrong.
I am trying to do Order by a limit query.
So there is a Customers table of 90 records.
I want Limit 3 records query to be done first and then sort this query records by a column called ContactName.
I think it would be a nested. The nested works fine in SQL server, but don't know how to do in MySQL.
Limit Query:
Select * from customers limit 3;
Order by after limit Query ( My guess, but this doesn't works):
Select * from (Select * from customers limit 3) Order by ContactName;
Please Help. Thanks

you just need this
Select * from customers Order by ContactName limit 3;

When you use a subquery in a FROM or JOIN clause, you're required to give it an alias.
Select *
from (Select * from customers limit 3) AS x
Order by ContactName;
Note that using LIMIT 3 without ORDER BY in the subquery doesn't really make much sense -- you don't know how it's going to choose the 3 customers to return. It would make more sense if you were choosing the 3 newest customers and then ordering them by name:
Select *
from (
Select *
from customers
order by registration_date DESC
limit 3) AS x
Order by ContactName;

Related

How can i apply group by after applying limit in mysql?

I am trying to run the below query but it is wrong as per MySQL syntax.
I want to select the first 100 rows then want to apply group by to it.
select customerid from customer
limit 100
group by customerid
How can I achieve it?
How about this? You need to add an aggregation column for it to work.
SELECT customerid
FROM (SELECT *
FROM customer
LIMIT 100) sub1
GROUP BY sub1.customerid;

How to Group By after Order By without any aggregate function

I'm trying to get the unique records after sorting the data in specific order.
The data table looks like this
SELECT * FROM category_products;
Now, requirement is to Order By the records on category_id and then select unique rows of product_id. I wrote the below query to sort the records
SELECT * FROM category_products ORDER BY category_id=2 desc;
When I try to Group By this sorted results with product_id, then the results aren't in right order. Even tried Group By clause in both child query and same query.
SELECT * FROM
(SELECT
*
FROM
category_products
ORDER BY category_id = 2 DESC) AS cat_products
GROUP BY cat_products.product_id;
Current Output:
Expected Output:
The result isn't the right one for which I'm looking for. Kindly help me guys, this doesn't seems to that tricky thing but I'm kind of stuck with it.
requirement is to Order By the records on category_id and then select
unique rows of product_id. I wrote the below query to sort the records
This should be what you are looking for:
SELECT DISTINCT product_id
,(SELECT category_id
FROM category_products
WHERE product_id = CP.product_id
ORDER BY category_id
LIMIT 1) AS cat_id
FROM category_products CP;
you need a SUBQUERY with an ORDER BY and LIMIT 1
It's a little unclear on how you aim to achieve this but from my understanding you can maybe create a custom sorting column to fulfill your requirement. See example below:
SELECT *,
CASE WHEN category_id=2 THEN 1
WHEN category_id=4 THEN 2
ELSE 99 END AS rownum
FROM category_products
ORDER BY rownum, product_id;
I'm using CASE to define a custom rownum and use it in the ORDER BY clause.
Demo fiddle here: https://www.db-fiddle.com/f/kAcGYtng2RWCf2Yhn5N1C9/0

SELECT all but the last 5 items in MySQL

I'm trying to run a query that will SELECT all but the 5 items in my table.
I'm currently using the following query to get the last 5 items.
SELECT * FROM articles ORDER BY id DESC LIMIT 5
And I would like another query to get all the other items, so excluding the last 5.
You select the last 5 items by conveniently sorting them in the reverse order.
SELECT * FROM articles ORDER BY id DESC LIMIT 5
LIMIT 5 is, in fact, a short form of LIMIT 0, 5.
You can use the same trick to skip the first 5 items and select the rest of them:
SELECT * FROM articles ORDER BY id DESC LIMIT 5, 1000000
Unfortunately MySQL doesn't provide a way to get all the rows after it skips the first 5 rows. You have to always tell it how many rows to return. I put a big number (1 million) in the query instead.
For both queries, the returned articles will be sorted in the descending order. If you need them in the ascending order you can save the smallest value of id returned by the first query and use it in the second query:
SELECT * FROM articles WHERE id < [put the saved id here] ORDER BY id ASC
There is no need for limit on the second query and you can even sort the records by other columns if you need.
You can do it like this:
SELECT * FROM articles
ORDER BY id ASC
LIMIT (SELECT count(*)-5 FROM articles)
You can also use NOT EXISTS() or NOT IN() but I'll have to see the columns names to adjust the sql for you, something like this:
SELECT * FROM articles a
WHERE a.id NOT IN(SELECT id FROM articles ORDER BY id DESC LIMIT 5)
Can also be done with a left join:
SELECT t.* FROM articles t
LEFT JOIN (SELECT id FROM articles ORDER BY id DESC LIMIT 5) s
ON(t.id = s.id)
WHERE s.id is null
Note that if the table has more then one key(the ID column) you have to add it to the relations of the ON clause.
Try
SELECT * FROM articles a NOT EXIST (SELECT * FROM articles b WHERE a.id=b.id ORDER BY id DESC LIMIT 5);

MySQL: First select 10 newest rows in descending PK order, then the rest of records alphabetically

I have a simple table USERS:
id | name
----+------
Can you help me with the query that would fetch all rows from the table and:
a) Place 10 rows with highest PK values on top, in id DESC order;
b) Place all remaining rows ordered by name ASC order.
Thank you!
This is a bit of a tricky question. The approach I would take is a join approach. Identify the primary keys for the first group using a join (this is happily fast because you are working with primary keys). Then use the match to that table for the order by:
select t.*
from table t left outer join
(select id
from table t
order by id desc
limit 10
) t10
on t.id = t10.id
order by t10.id desc,
t.name asc;
First question would be: do you really need this in one single query? I'm really not seeing the use case for such a query to be honest.
It'd be easier to just fetch the 10 biggest ids (storing somewhere the 10th biggest), and then fetch the rest in ascending name order (with a restriction on ids being smaller than the 10th biggest).
Otherwise in a single query, something like this would work, but it doesn't seem very efficient to me (maybe someone will have a better idea).
(
SELECT
id, name
from
USERS
ORDER BY id DESC LIMIT 0,10
)
UNION
(
SELECT
id, name
from
USERS
WHERE
id NOT IN (
SELECT id, name from USERS ORDER BY id DESC LIMIT 0,10
)
ORDER BY name ASC
)
(or maybe with a NOT EXISTS - the inner query will be different - instead of the NOT IN)

Is this an inefficient query?

Assuming table1 and table2 both have a large number of rows (ie several hundred thousand), is the following an inefficient query?
Edit: Order by field added.
SELECT * FROM (
SELECT title, updated FROM table1
UNION
SELECT title, updated FROM table2
) AS query
ORDER BY updated DESC
LIMIT 25
If you absolutely need distinct results, another possibility is to use union all and a group by clause instead:
SELECT title FROM (
SELECT title FROM table1 group by title
UNION ALL
SELECT title FROM table2 group by title
) AS query
group by title
LIMIT 25;
Testing this without the limit clause on an indexed ID column from two tables with ~920K rows each in a test database (at $work) resulted in a bit over a second with the query above and about 17 seconds via a union.
this should be even faster - but then I see no ORDER BY so what 25 records do you actually want?
SELECT * FROM (
SELECT title FROM table1 LIMIT 25
UNION
SELECT title FROM table2 LIMIT 25
) AS query
LIMIT 25
UNION must make an extra pass to fetch the distinct records, so you should use UNION ALL.
Yes, use order by and limits in the inner queries.
SELECT * FROM (
(SELECT title FROM table1 ORDER BY title ASC LIMIT C)
UNION
(SELECT title FROM table2 ORDER BY title ASC LIMIT C)
) AS query
LIMIT 25
This will only go through C rows instead of N (hundreds of thousands). The ORDER BY is necessary and should be on an indexed column.
C is a heuristic constant that should be tuned according to the domain. If you only expect a few duplicates, C=50-100 is probably ok.
You can also find out this for yourself by using EXPLAIN.