Excluding first and last result from sql query - mysql

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

Related

How to get previous or next row in a given row in mysql using lead or lag?

I've been reading on lead and lag functions but I still don't get it. My sql syntax is as follows:
SELECT description, lag(description) over (ORDER BY transid ASC)
FROM transaction
WHERE transid = 20;
It's not returning the desired data. I have a table where transid is the primary key in int, and a column called description. I think the syntax is wrong because I want to return the whole row (all the column data) and I think this just returns one column of the previous row. How do I do that? Anybody?
Return an entire previous/next row.
For previous row you can simply do this:
SELECT *
FROM transaction
WHERE transid < 20
ORDER BY transid DESC
LIMIT 1
For next row you reverse the conditions:
SELECT *
FROM transaction
WHERE transid > 20
ORDER BY transid ASC
LIMIT 1
One option would be to use a subquery with LEAD to restrict to the desired previous record:
WITH cte AS (
SELECT *, LEAD(transid) OVER (ORDER BY transid) transid_lead
FROM transaction
)
SELECT *
FROM cte
WHERE transid_lead = 20;

order by date and select until specific id is reached

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.

mysql group by year() of timestamp and foreign_id order by timestamp

i have a table like
create table `my_table`
(
`id` int auto_increment primary key,
`foreign_id` int not null,
`some_data` text,
`some_timestamp` timestamp default CURRENT_TIMESTAMP not null
);
I need to get unique rows both per year(got from timestap) and foreing_id , and get it from table ordered by timestamp
i've tried query :
SELECT *
FROM (
SELECT *
FROM `my_table`
ORDER BY `some_timestamp` DESC) as lr
GROUP BY YEAR(lr.`some_timestamp`),lr.`foreign_id`;
but this one not ordering by timestamp, idk why.
Other query worked ok untill i've loaded it to other server:
SELECT * FROM `my_table`
WHERE `id`,`some_timestamp` IN
(
SELECT `id`,max(`some_timestamp`)
FROM `my_table` lr2
GROUP BY YEAR(lr2.`some_timestamp`),`lr2`.foreign_id
);
on my pc this query executes around 3 seconds, on other server it get's error 504 gateway timeout.
Please help me to find best solution for this task.
You're making things too complicated. It didn't order correctly because GROUP BY does an implicit sorting, when no ORDER BY is specified.
Simply do it like this:
SELECT some_timestamp, foreign_id, MAX(some_timestamp) AS most_recent_timestamp_per_year
FROM `my_table`
GROUP BY YEAR(some_timestamp), foreign_id
ORDER BY `some_timestamp` DESC
I'm not sure, what your final query is supposed to do.
Also note, that you don't use group by correctly.
Every column in the select clause must either be specified in the group by clause or have an aggregate function applied to it. Otherwise you get random rows per group.
To order this query by date you need to rewrite it like this:
SELECT *
FROM (
SELECT *
FROM `my_table`) as lr
GROUP BY YEAR(lr.`some_timestamp`),lr.`foreign_id`
ORDER BY YEAR(lr.`some_timestamp`) DESC;
About execution time for second query.
If you don't want to dig in, try to add index on server DB to columns some_timestamp and foreign_id. It probably speed up the execution time.
Try something like this in mysql shell:
`CREATE INDEX my_request ON my_table (foreign_id, some_timestamp);
More about indexes you can find here

MySQL sort by not sorting?

I am fetching rows from my DB using this request:
SELECT * FROM {$db_sales} WHERE date = '{$date}' ORDER BY 'amount' DESC
So, obviously, i expected the returned values to be sorted in descending order by the amount column in my DB, but it doesn't? it still fetches them, but just doesn't sort them?
Any ideas here? is my SQL statement wrong?
remove single quote around amount like this and try:
SELECT * FROM {$db_sales} WHERE date = '{$date}' ORDER BY amount DESC
Use below query
SELECT * FROM {$db_sales} WHERE date = '{$date}' ORDER BY amount DESC
ORDER BY clause uses column name.
Column name should not give in quotes.
there fore the query becomes as follows
SELECT * FROM {$db_sales} WHERE date = '{$date}' ORDER BY amount DESC

Returning the closest to a date in a table using PDO Mysql/MSSQL

I have 2 PDO database connections. I am doing a search within a MS SQL table for a row that closest matches a date (mysql datetime) row.
I have mysql.table1.date passed to mssql.table and I am looking for the closest date accordingt to the mssql.table.date. It is also defined as a datetime field. I only need 1 row returned, the closest to the time, so in essence:
SELECT * FROM table ORDER BY CLOSEST(mysqldate = mssql.table.date) LIMIT 1;
I know the syntax above is incorrect but that basically outputs what I need, but I really do not know how to do this with mssql.
Any help?
Basically u can find the difference of the mysql date with all the dates in mssql.Table.Date column .Then u need to select the least difference value from the above query .Hopefully the below query might help u
;with CTE as
(
Select mssql.table.date,row_number()
over (order by abs(datediff(day,mysqlDate,mssql.table.date))) rowNumber
from mssql.Table)
select mssql.table.date from CTE where rowNumber=1
A simple solution which worked for me was to do the following:
SELECT * FROM `table` WHERE `date` < `startDate` ORDER BY `date` LIMIT 1;
This returns 1 row matching the closest time to the time I am passing :)