Get last rows before certain value [closed] - sql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
In my table, I have a field RAZ (bit) whose value is 0 except at 5am, 1pm and 9pm when it's equal to 1. I would like to get the last rows in my table before RAZ is equal to 1.
Here is a sample data :
For exemple, the final request would display the row with idEvenement = 8454.
I will use this request in a stored procedure to compute indicators.
The RAZ field changes to 1 automatically, it means that the data has been reset.
I don't know if it's possible and how to do it.

You can use SQL Server windowing function LEAD to see if the next record's RAZ turns to 1 while it was 0 before. LEAD gets the next record based on RAZTime order. This returns ID = 8454 as the result
; WITH cte (ID, RAZTime, RAZ) AS (
SELECT 8456, convert(datetime, '13:01 pm'), 1
union SELECT 8455, convert(datetime, '13:00 pm'), 1
union SELECT 8454, convert(datetime, '12:59 pm'), 0
union SELECT 8453, convert(datetime, '12:58 pm'), 0
)
, q AS (
SELECT
*
, NextRAZ = LEAD (RAZ, 1, NULL) OVER (ORDER BY RAZTime)
FROM cte
)
SELECT *
FROM q
WHERE
RAZ = 0
AND NextRAZ = 1

Related

SQL - Lead function to get dates from next row [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
I have a table with a date and value for example:
AccID Date Value
1 01/01/2007 10
1 01/02/2008 20
1 01/03/2009 40
I want to create a new table that starts from the date in row 1 and ends with the date in row 2 and so on.....for example
AccID Date DateEnd Value
1 01/01/2007 01/02/2008 10
1 01/02/2008 01/03/2009 20
1 01/03/2009 01/04/2050 40
Select
date,
isnull(lead(date) over (partition by accID order by date), '01/04/2050') as DateEnd,
value
from column A
I have tried this code but I can't seem to get the correct output. This is the output I am currently getting
AccID Date DateEnd Value
1 01/02/2008 01/02/2009 20
1 01/02/2009 01/03/2007 40
1 01/01/2007 01/04/2050 10
You are not getting any output, you are getting an error
Incorrect syntax near 'partition'.
You get the correct results when you correct the error
Select
date,
isnull(lead(date) over (partition by accID order by date), '01/04/2050') as DateEnd,
value
from column A
Edit: Do yourself some favours and apply the following:
Avoid the use of reserved words or if you "must" use them, surround the column or table name with [ ] e.g. [date], [value],[column]
Research the function you're going to use to make the most of what it has to offer, to simplify your queries e.g. See the documentaion for Lead
Use date formats that are unambiguous e.g. '2050-04-01' in preference to '01/04/2050'. The latter could be either 1st April or 4th January depending on where in the world you happen to be

How to calculate Time between Start and Submit in SQL? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
How do I calculate time these two blocks Start and Submit?
The Activity column has Start and Submit. I need to calculate the time difference between Submit and the Start before the Submit Activity. How do we calculate that?
Thanks!
Here is the sample Table:
Sample Table
I took the liberty of converting your image to a usable table:
DECLARE #Activity TABLE (Activity VARCHAR(MAX), Timestamp DATETIME)
INSERT #Activity
VALUES
('Start', '5/12/21 3:30 PM'),
('Start', '5/13/21 3:31 PM'),
('Start', '5/14/21 3:33 PM'),
('Submit', '5/15/21 3:36 PM'),
('Start', '5/14/21 3:37 PM')
Without any other identifier to associate the start and submit times, I will assume that the most recent Start applies to a Submit and that other Start entries are ignored. For any given Submit, one way to select a candidate Start is with a CROSS APPLY and appropriate selection, ordering, and TOP 1 criteria. Something like:
SELECT
StartTime = ST.TimeStamp,
SubmitTime = SU.TimeStamp,
Elapsed = SU.TimeStamp - ST.TimeStamp,
ElapsedMinutes = DATEDIFF(minute, ST.TimeStamp, SU.TimeStamp)
FROM #Activity SU
CROSS APPLY (
SELECT TOP 1 *
FROM #Activity ST
WHERE ST.Activity = 'Start'
AND ST.TimeStamp <= SU.TimeStamp
ORDER BY ST.TimeStamp DESC
) ST
WHERE SU.Activity = 'Submit'
Note the last record of your data is the actual closest match using the above criteria, yielding 1439 minutes of elapsed time. If your table contains keys that better associate your start and submit times, you should adjust the above logic accordingly.
I would also recommend an index on TimeStamp for efficient lookup.

SQL query to get time spent on specific statuses based on single datetime column [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I need to build a SQL query in which I can get time spent on multiple statuses (onHold,Waiting for customer,Resolved,Closed), so basically I do not want to include time spent on this statues and table looks like as below
So I need a query in which I can get actual time spent on ticket or time spent on status which I have mentioned so far I have tried below solutions and tried Cross APPLY but seems all did not help me as expected.
Tried below query so far and that gives me correct time spent on first status on-hold not after that:
SELECT t1.TICKETNUMBER,SUM(DATEDIFF(MINUTE,TICKETTIME,CloseTime)) as TotalMinutes
FROM [Admin].[TbtrnTicketHistory] t1
CROSS APPLY(SELECT TOP 1 TICKETTIME as CloseTime FROM [Admin].[TbtrnTicketHistory] t2 WHERE t1.TICKETNUMBER = t2.TICKETNUMBER and t2.TICKETHISTORYID > t1.TICKETHISTORYID ORDER BY t2.TICKETTIME) as t2
WHERE t1.CURRENTSTATUS_ANALYST not in('On-Hold','Waiting For Customer','Resolved','Closed') and t1.ticketnumber = '211135'
GROUP BY t1.TICKETNUMBER;
calculate difference between two times in two rows in sql
Calculate Time Difference Between Two Consecutive Rows
with SQL Server you can use those very usefull windowed functions LEAD and FIRST_VALUE :
select *
,[duration(sec)] = DATEDIFF(SECOND
,ticketTime
,LEAD(ticketTime,1,ticketTime)over(partition by ticketNumber order by ticketTime)
)
,[cumulative duration(sec)] = DATEDIFF( SECOND
, FIRST_VALUE(ticketTime)over(partition by ticketNumber order by ticketTime)
, ticketTime)
from (values
(1,cast('20211101 10:00:01' as datetime))
,(1,'20211101 10:00:33')
,(1,'20211101 10:01:59')
)T(ticketNumber,ticketTime)
ticketNumber
ticketTime
duration(sec)
cumulative duration(sec)
1
2021-11-01 10:00:01.000
32
0
1
2021-11-01 10:00:33.000
86
32
1
2021-11-01 10:01:59.000
0
118

SQL oracle sort by date [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I would like to show data created after 01.01.2014 - data created before should not be shown in the output.
I got this so far:
AND TO_CHAR(table1.datum,'IW') = 17 (number of the week - just a start from me)
AND TO_CHAR(table1.datum,'YYYY') = 2014 (shows only data from 2014)
Can you help me?
I would like to show data created after 01.01.2014 - data created before should not be shown in the output.
Then just put the date condition in the filter predicate.
WHERE table1.datum > TO_DATE('01-01-2014','DD-MM-YYYY')
Note that this will not include the rows which were created on '01-01-2014', to include them as well you need greater than or equal to:
WHERE table1.datum >= TO_DATE('01-01-2014','DD-MM-YYYY')
For example,
SQL> WITH table1 AS(
2 SELECT to_date('20-12-2013','DD-MM-YYYY') datum FROM dual UNION ALL
3 SELECT to_date('01-04-2014','DD-MM-YYYY') datum FROM dual UNION ALL
4 SELECT to_date('20-10-2015','DD-MM-YYYY') datum FROM dual
5 )
6 SELECT * FROM table1
7 WHERE table1.datum >= TO_DATE('01-01-2014','DD-MM-YYYY')
8 /
DATUM
---------
01-APR-14
20-OCT-15
SQL>
So, '20-12-2013' is filtered out and you have rows created only created after '01.01.2014'.
Select * from table
Where the_date_field < to_date('01-01-2014','dd-mm-yyyy')
Order by ..... /* If needed */

Date minus date query [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a query like below and I want to make calculation for end_scan-packing_date column, how can I achieve this?
SELECT a.invoice_no,
CONVERT(VARCHAR, b.packing_date,3) as packing_date ,
CONVERT(VARCHAR, b.exw_date,3) as exw,
CONVERT(VARCHAR, b.bcd_end_date, 3) as end_date,
(SELECT TOP 1 insert_date FROM wms.bcd_shipment d,wms.shinvoicedetails WHERE d.invoice_no = a.invoice_no ORDER BY insert_date ASC) as start_date ,
(SELECT TOP 1 insert_date FROM wms.bcd_shipment d,wms.shinvoicedetails WHERE d.invoice_no = a.invoice_no ORDER BY insert_date DESC) as end_scan,
CONVERT(VARCHAR, send_date, 3) as swnd_date,customer_short_name,
Sum(picking_qty) as qty,total_carton
FROM wms.shinvoicedetails a,
wms.shinvoiceheder b,
wms.shinvoice_ctrl c
WHERE send_date BETWEEN '2014/8/26 00:00:01' AND '2014/9/25 23:59:59'
AND a.invoice_no = b.invoice_no
AND a.invoice_no = c.invoice_no
GROUP BY a.invoice_no,
b.packing_date,
b.exw_date,
b.bcd_end_date,
send_date,
customer_short_name,
total_carton
ORDER BY 1;
May I refer you to the documentation for the DATEDIFF function (I'm assuming your're using SQL Server as RDBMS).
It has 3 parameters, I am assuming you want the difference in days. So what you want would read something like:
DATEDIFF(DAY,
(SELECT TOP 1 insert_date
FROM wms.bcd_shipment d,
wms.shinvoicedetails
WHERE d.invoice_no = a.invoice_no
ORDER BY insert_date DESC),
b.packing_date
) AS diff_days
Your query is wrong on many levels though. You are grouping on nearly all columns to get a SUM while you should write that as a derived table (a sub-query) grouping only on the necessary fields. Also you are converting to VARCHAR which probably translates to VARCHAR(1). You should probably write it as CONVERT(VARCHAR(10), <your date field>, 3).
A day does not start at 00:00:01 and does not finish as 23:59:59. Do yourself a favour an don't try to bend your needs to the syntax of between. There is an easier and more reliable method
WHERE send_date >= '20140826' AND send_date < '20140926'
LESS THAN the 26th; it's more accurate & no silly one second deductions.
the best practice with date and time ranges is to avoid BETWEEN and to
always use the form:
WHERE col >= '20120101' AND col < '20120201'
This form works with all
types and all precisions, regardless of whether the time part is
applicable.
Itzik Ben-Gan
http://sqlmag.com/t-sql/t-sql-best-practices-part-2