order by date and select until specific id is reached - mysql

I have a simple table with ID, STATUS, DATE columns, the rows in the table are ordered by DATE, I want to get all the rows until a specific ID is reached, and then stop, something like:
SELECT FROM myTable WHERE `DATE` <= '2017-10-09' ORDER BY `DATE` ASC UNTIL? `ID` = 119;
I like to know if that is possible somehow, to stop on a specific ID, whatever the ID was..
Thanks.
EDIT EXPLAINING
I want to select rows that are ordered under any column, but stop when a specific provided ID is reached. in the above image the result should be all the rows except the ones below the row 119.
I hope it's clear now.

Something like this might work:
SET #marker = NULL;
SELECT *
FROM myTable
WHERE `DATE` <= '2017-10-09'
AND ISNULL(#marker := IF(id = 119, 1, #marker))
ORDER BY `DATE` ASC;

You should phrase the query to select records whose date is less than the date of the record for which ID = 119:
SELECT *
FROM myTable
WHERE DATE <= (SELECT DATE FROM myTable WHERE ID = 119);

Tim Biegeleisen's answer is correct, but if you have no time in your date field then the order by is going to use the date and then any ordered indexes you have specified. So you will get all of the records back that equal the date of the id specified in the subquery's WHERE clause.
So for example, you are going to also return the rows for ids 200-202, no way around that unless you provide more precision on your date OR add the id field to your order by clause, in which case you'll need to be comfortable excluding all IDs above the specified ids integer value for the same date.

Related

MySQL ORDER BY + LIMIT + OFFSET statements: how to OFFSET firts and only then sort with ORDER BY

I have a table which consists of ID, NAME, PRICE and DATE columns.
I'm trying to write a pager-style navigation because there are plenty of entries in the table, so looking at the whole SELECT's output had become uncomfortable.
I've written the following request:
SELECT id
, name
, price
, date
FROM mytable
ORDER
BY name asc
LIMIT 30 OFFSET _here's_my_offset_depending_on_the_current_position_
This works fine only as in the example. When I try to sort it, say, by price, it seems that MYSQL first sorts the whole table with ORDER BY and only after it makes an offset.
How do I change this behavior, in other words how do I make an offset and only than sort the resulting rows by whaterver I like?
It's can be easy if you use subquery:
SELECT * FROM (
SELECT id, name, price, date FROM mytable LIMIT 30 OFFSET _offset_
) AS page ORDER BY page.name asc

Excluding first and last result from sql query

I'm fairly new to SQL so this may be fairly simple but I'm trying to write a script in SQL that will allow me to get a set of data but I don't want the first or last result in the query. I can find lots on how to remove the first result and how to remove the last result but not both.
This is my query so far:
SELECT * FROM itinerary Where ID = 'A1234' ORDER BY DateTime ASC
I want to remove the first and the last record of that select based on the DateTime.
This may not be the most performant way to do this, but you didn't give any schema info, and it looks like your ID column is not unique. It would be easier if you had a primary key to work with.
SELECT * FROM itinerary
WHERE ID = 'A1234'
AND DateTime <
(SELECT MAX(DateTime) FROM itinerary WHERE ID = 'A1234')
AND DateTime >
(SELECT MIN(DateTime) FROM itinerary WHERE ID = 'A1234')
ORDER BY DateTime ASC
This will basically select every record where the ID is A1234 and the DateTime doesn't equal the max or min datetime. Please note, if you have multiple records with the same value for DateTime and that also happens to be the min or max value, you might exclude more than just the first or last.
This might be good enough though. If not, you might need to write a stored procedure and not just straight ANSI SQL.
Try this ..
select * from
(select a.*,row_number() over (partition by DateTime order by DateTime desc) as rnm
from itinerary Where ID = 'A1234')x
where rm <> 1 and rm not in (
select max(rm) from
(
select row_number() over (partition by DateTime order by DateTime desc) as rnm
from itinerary Where ID = 'A1234'))
Select in reverse order & skip first and then select in the required order from the result, skipping first.
SELECT * FROM (SELECT *
FROM itinerary
Where ID = 'A1234'
ORDER BY DateTime DESC
LIMIT 1, 18446744073709551615) x ORDER BY DateTime ASC
LIMIT 1, 18446744073709551615
18446744073709551615 is max integer just in case you wanted to know why I picked that value

Find the last inserted row that matches a query

I want to find the last inserted row that matches a query (ie, find the row that has the largest id among the matching rows.)
for instance, suppose the following query matches 3 rows. with ids, 1,2,and 3. I want to get only the row with id 3.
SELECT * FROM `table` WHERE `mail` = 'someone#example.com'
How do I do this?
You need to write your query like this
SELECT *
FROM table_name
WHERE `mail` = 'someone#example.com'
ORDER BY id DESC
LIMIT 1
Simply use Order By. You sort your result with Id values in decreasing order (that way, you would have maximum ID at the top, in this case 3) and then just limit your result with value 1. That would give you only one row, with max ID. So,
here goes the query:
SELECT * FROM *YourTableName* where mail = '*YourMail*'ORDER BY id DESC LIMIT 1;
Query
SELECT * FROM tbl
WHERE `mail` = 'someone#example.com'
AND id=
(
SELECT MAX(id) FROM tbl
WHERE `mail` = 'someone#example.com'
);
Fiddle demo

How to delete records from database table excluding records from another SQL

I've a search log table, I keep search logs. Table structure is like searchstring, date, number of results of each search string as results and some other info. I have the following SQL that I get records I need. A keyword could be searched several times so latest date is important. I use following SQL to get records I need. It's working fine.
SELECT id, searchstring, max(logdate) as logdate
FROM log_search
WHERE locale = 'en' AND results > 0
GROUP BY searchstring
ORDER BY logdate DESC
My problem is there are millions of records and I need to clean it up. I just want to keep records that matches sql above.
I tried to use NOT IN over id field but since sorting by logdate is important didn't let me.
DELETE FROM log_search WHERE id NOT IN (...MYQUERY...) but it gives Operand should contain 1 column(s) error
Another important field is locale . While deleting records for en I need to keep other locales even though they don't match my SQL above.
Is there a way to delete records and keep the ones I need.
EDIT
Table structure
Id - Auto increment
searchstring
results - containt number of results for that searchstring
logdate - date and time that search is made
results and logdate both are important to get latest query that return result.
SOLUTION / WORKAROUND
#Sunny's answer technically works, but for big tables like some millions of records, it's performance is awful. Insted, I did a workaround by creating another table and inserting records I need into there. Here is my SQL
INSERT INTO log_search_simple
SELECT id, searchstring, max(logdate) as logdate, locale
FROM log_search
WHERE locale = 'en' AND results > 0
GROUP BY searchstring
ORDER BY logdate DESC
Your try is right you just need to select one column of id instead of multiple columns.
Try that.
 DELETE FROM log_search FROM log_search WHERE id Not in (SELECT id FROM log_search WHERE locale = 'en' AND results > 0 GROUP BY searchstring )
You may try this...
Delete from log_search where NOT EXISTS (SELECT id, searchstring, max(logdate) as logdate
FROM log_search
WHERE locale = 'en' AND results > 0
GROUP BY searchstring
ORDER BY logdate DESC)
try this:
DELETE FROM log_search where id NOT IN(
SELECT id FROM (
SELECT id, searchstring, max(logdate) as logdate
FROM log_search
WHERE locale = 'en' AND results > 0
GROUP BY searchstring
ORDER BY logdate DESC
) AS a);
Operand should contain 1 column(s)
It looks for 1 column to match data for a column and for here it is getting three columns in result set by SELECT statement. So the quick solution is to slice a column from the result set and match the column. it will do the trick :)

mysql max(date) not working

So i have this query that is supposed to return some information like price, open, close, etc.. for the LATEST entry.
SELECT * FROM History WHERE symbol = $symbol Having max(`date`);
But for whatever reason its not returning the correct information. It for some reason believes that the max date is 2013-02-14, but if i look at all the data the most recent is actually 2013-02-27.
in this particular case
$symbol = "AGNC"
Does the max function not work on date?
I think you want to have something like this. I'm not fan of doing this using ORDER BY clause because there are some possibilities (although much little) that records may have the same latest date entry.
SELECT *
FROM History
WHERE symbol = $symbol AND
date = (SELECT MAX(date) FROM History)
SQLFiddle Demo
My suggestion would be not using MAX at all; if what you want to do is only fetching the latest entry in the table, you could try:
SELECT * FROM History WHERE symbol = $symbol ORDER BY date DESC LIMIT 1;
This works perfectly as long as your date field is actually declared as a date-related MySQL field type, like date, datetime, etc.
As JW pointed out in his answer, you may want to add more fields in your ORDER BY statement to disambiguate records that have the exact same date.
Also, you may want to put $symbol in quotes if that's a string field (char, varchar, etc):
SELECT * FROM History WHERE symbol = '$symbol' ORDER BY date DESC LIMIT 1;
Cheers!
The following should do what you want:
SELECT *
FROM History h
WHERE symbol = $symbol and
`date` = (select max(`date`) from History where symbol = $symbol)
You may use alias table name:
SELECT *
FROM History
WHERE symbol = $symbol AND
date = (SELECT MAX(date) FROM History);