Mysql select records with offset - mysql

I'm looking for a mysql select that will allow me to select (LIMIT 8) records after some changing number of first few matches;
select id
from customers
where name LIKE "John%"
Limit 8
So if i have a table with 1000 of johns with various last names
I want to be able to select records 500-508

You can send the offset to the limit statement, like this:
SELECT id
FROM customers
WHERE name LIKE "John%"
LIMIT 8 OFFSET 500
Notice the OFFSET 500 on the limit. That sets the 'start point' past the first 500 entries (at entry #501).
Therefor, entries #501, #502, #503, #504, #505, #506, #507 and #508 will be selected.
This can also be written:
LIMIT 500, 8
Personally, I don't like that as much and don't understand the order.
Pedantic point: 500-508 is 9 entries, so I had to adjust.

As a solution please try executing the following sql query
select id from customers where name LIKE "John%" Limit 500,8

Related

SQL Query - selecting higher priority rows more often

I am trying to do SQL code in mysqli query to select rows with higher priority more often. I have a DB where all posts are sorted by priority, but I want it select like this (10 - the highest priority):
**Priority**
10
3
10
9
7
10
9
1
10
How can I do this? I have tried that to solve by more ways but no result. Thank you.
If you want to sample your data with preference to higher priorities, you could do something like this:
SELECT *
FROM (
SELECT OrderDetailID
,mod(OrderDetailID, 10) + 1 AS priority
,rand() * 10 AS rand_priority
FROM OrderDetails
) A
WHERE rand_priority < priority
ORDER BY OrderDetailID
This query runs in MySQL Tryit from W3Schools.
mod(OrderDetailID, 10) + 1 simulates a 1-10 priority - your table just has this value in it already
rand() * 10 gives you a random number between 0 and 10
Then by filtering to only ones where the random number is less than the priority, you get a result set where the higher priorities are more likely.
You may use rank function if your MySQL version supports it. It will order your data by priority in descending order and ranks each row. If the two rows have same priority then both rows will have same ranking. Then you can filter out the first rank data which will give you highest priority rows always.
Select * FROM
(
SELECT
col1,
col2,
priority,
RANK() OVER w AS 'rank'
FROM MyTable
WINDOW w AS (ORDER BY priority)
) MyQuery
Where rank = 1
Note : Syntax might be incorrect, please feel to edit the query.
This post might help you for ranking if your MySql version doesn't support Rank.

How can I finish my MySQL fetch after searching a specific amount of rows even if the row is not found?

I have a MySQL Database with over 100k rows, so I need to make a search to fetch only the last 1000 rows , so if it is not found in the last 1000 rows the fetch ends (even if it is not found)
Example: if my table is like that
id name
1 AL
2 BL
...
1000 P12
1001 P15
And I do a fetch like this: SELECT * FROM myTable WHERE name = 'AL' ONLY LAST 1000 ROWS ORDER BY id DESC (Since I don't know what to use I invented the ONLY LAST 1000 ROWS)
This should return empty because I wanted my query to get the information only if it was on the last 1000 rows, not on the 1001th as specified.
Using LIMIT field doesn't work as it would LIMIT the FOUND ROWS not when they are not found.
Is there a way to implement this in MySQL ?
Thank you!
As touched on in the comments, you can use OFFSET to get the id of the 1000th last record, then SELECT records with an id larger than that record's id.
Something like this:
SELECT name
FROM myTable
WHERE id > (SELECT id FROM myTable ORDER BY id DESC LIMIT 1 OFFSET 1000)
AND name = 'AL'

I need to query MYSQL records based on the first characters of values

I have 1 MYSQL table with 8000 records. I would like to query First name, Middle name, and Last name by the first characters of their full name. For instance, i have 40 rows of records (First name, Middle name, and Last name) which their first character of their name is SSS. My question is, how do i query "SSS" to only return 6 results and when i query "SSS" again i need another 6 results and so on until all the 40 records query ends.
I used the following query but only return the first 6 results and when i query "SSS" the next time, it returns the same results over and over. Please i need your help.
SELECT *
FROM Table
WHERE (UPPER(FName) LIKE UPPER('S%')
AND UPPER(MName) LIKE UPPER('S%')
AND UPPER(LName) LIKE UPPER('S%')
ORDER BY ID
LIMIT 6 OFFSET 0
Thanks in advance.
You're ordering by ID - good. Remember max ID of the last returned data set and when you query next time add condition ID > your_last_max_id
Second time, change offset:
LIMIT 6 OFFSET 6
and then
LIMIT 6 OFFSET 12
etc.

specific ordering in mysql

I have a sql statement that brings back ids. Currently I am ordering the id's with the usual "ORDER BY id". What I need to be able to do is have the query order the first 3 rows by specific id's that I set. The order the remaining as it is currently. For example, I want to say the first 3 rows will be id's 7,10,3 in that order, then the rest of the rows will be ordered by the id as usual.
right now i just have a basic sql statement...
SELECT * from cards ORDER BY card_id
SELECT *
FROM cards
ORDER BY
CASE card_id WHEN 7 THEN 1 WHEN 10 THEN 2 WHEN 3 THEN 3 ELSE 4 END,
card_id
A bit shorter than Quassnoi's query, with FIELD :
-- ...
ORDER BY FIELD(card_id, 3, 10, 7) DESC
You have to invert the order because of the DESC, I didn't find a way to do it more naturally.

Weighted conditions in the WHERE clause of a SQL statement

I want to search for records where a particular field either STARTS WITH some string (let's say "ar") OR that field CONTAINS the string, "ar".
However, I consider the two conditions different, because I'm limiting the number of results returned to 10 and I want the STARTS WITH condition to be weighted more heavily than the CONTAINS condition.
Example:
SELECT *
FROM Employees
WHERE Name LIKE 'ar%' OR Name LIKE '%ar%'
LIMIT 10
The catch is that is that if there are names that START with "ar" they should be favored. The only way I should get back a name that merely CONTAINS "ar" is if there are LESS than 10 names that START with "ar"
How can I do this against a MySQL database?
You need to select them in 2 parts, and add a Preference tag to the results. 10 from each segment, then merge them and take again the best 10. If segment 1 produces 8 entries, then segment 2 of UNION ALL will product the remaining 2
SELECT *
FROM
(
SELECT *, 1 as Preferred
FROM Employees
WHERE Name LIKE 'ar%'
LIMIT 10
UNION ALL
SELECT *
FROM
(
SELECT *, 2
FROM Employees
WHERE Name NOT LIKE 'ar%' AND Name LIKE '%ar%'
LIMIT 10
) X
) Y
ORDER BY Preferred
LIMIT 10
Assign a code value to results, and sort by the code value:
select
*,
(case when name like 'ar%' then 1 else 2 end) as priority
from
employees
where
name like 'ar%' or name like '%ar%'
order by
priority
limit 10
Edit:
See Richard aka cyberkiwi's answer for a more efficient solution if there are potentially lots of matches.
My solution is:
SELECT *
FROM Employees
WHERE Name LIKE '%ar%'
ORDER BY instr(name, 'ar'), name
LIMIT 10
The instr() looks for the first occurrence of the pattern in question. AR% will come before xxAR.
This prevents:
Should only do table scan 1 time. Unions and derived tables do 3. The first two on the columns to filter out the patterns and then the 3rd on the subset to find where they equal - since union filters out dupes.
Gives a true sort based on the location of the pattern. Wx > xW > xxW > etc...
Try this (don't have a MySQL instance immediately available to test with):
SELECT * FROM
(SELECT * FROM Employees WHERE Name LIKE 'ar%'
UNION
SELECT * FROM Employees WHERE Name LIKE '%ar%'
)
LIMIT 10
There are probably better ways to do it, but that immediately sprang to mind.
SELECT *
FROM Employees
WHERE Name LIKE 'ar%' OR Name LIKE '%ar%'
ORDER BY LIKE 'ar%' DESC
LIMIT 10
Should work orders by the binary true / false for like and if index'ed should benefit from the index