Date minus date query [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 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

Related

Is there a way to optimize this SQL query?

I have this query I have to automate with AWS Lambda but first I want to optimize it.
It seems legit to me but I have this feeling I can do something to improve it.
SELECT q_name, count(*)
FROM myTable
WHERE status = 2
AND DATEDIFF(mi, create_stamp, getdate()) > 1
GROUP BY q_name
The only improvement I can see is not to apply a function to your column, because that makes the query unsargable (unable to use indexes). Instead leave the column as it is and calculate the correct cutoff.
SELECT q_name, count(*)
FROM myTable
WHERE [status] = 2
--AND DATEDIFF(mi, create_stamp, getdate()) > 1
-- Adjust the logic to meet your requirements, because this is slightly different to what you had
AND create_stamp < DATEADD(minute, -1, getdate())
GROUP BY q_name;
Note, while dateadd does accept abbreviations for the unit to add, its much clearer to type it in full.

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

Get the rows with the latest date for an ID [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
My table has multiple rows for each id, with a calculated score and the date the calculation was done. Simplifying, it looks like this:
id
calc_score
date
1
82
today
1
53
yesterday
1
92
last week
2
23
today
2
60
yesterday
2
73
last week
I need a query that returns only today's scores for each ID. I tried various combinations of group by and distinct on but didn't get very far.
What's the best way for doing this?
PG has several ways. A simple approach is window functions, row_number, rank, etc.
The following will answer the question in your title, to return the latest (last) row per id (by date), which is different than the body of your question.
WITH cte AS (
SELECT t.*
, row_number() OVER (PARTITION BY id ORDER BY date DESC) AS rn
FROM scores
)
SELECT * FROM cte
WHERE rn = 1
;
This just picks the (latest dated) first row for each id based on the date column descending. This also assumes the date column really contains date values or something orderable like a date.
To answer your question in the question body:
I need a query that returns only today's scores for each ID
more strictly, we could also do this:
SELECT *
FROM scores
WHERE date = current_date
;
If you want only today's scores, then you could use a direct comparison if the date has no time component:
where date = current_date
Or for either dates or timestamps:
where date >= current_date and date < current_date + interval '1 day'
If you want the most recent row per id, you would use distinct on:
select distinct on (id) t.*
from t
order by id, date desc;

Write a query to display unique student ID who joined in the month of June. Sort the result in ascending order [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 2 years ago.
Improve this question
this is what I tried-
select distinct studid
from registration
where to_char(doj,'MM')='june'
order by studid;
but I did not get the desired results.
TO_CHAR() with MM parameter will give you 06, instead of JUNE. You may try below query instead -
select distinct studid
from registration
where to_char(doj,'MM')='06'
order by studid;
Rather than using TO_CHAR, You should use oracle specific function EXTRACT -
select distinct studid
from registration
where extract(month from doj) = 6
order by studid;
I assume that you are running Oracle, as the use of to_char() suggests.
If you want students that joined in june of a given year, say 2019, then I would recommend to check doj against a half-open interval (this is more efficient than applying a date function on the column):
select distinct studid
from registration
where doj >= date '2019-06-01' and doj < date '2019-07-01'
order by studid
On the other hand, if you want sudents that joined in any month of june:
select distinct studid
from registration
where extract(month from doj) = 6
order by studid

Selecting records based on other records using separate date/time fields [duplicate]

This question already has answers here:
TSQL to combine a date field and a time field
(4 answers)
Closed 9 years ago.
I have a database that stores date and time in separate fields. I need to select all records that occurred within + and - 90 minutes of the date and time each of these happened.
I am able to get everything in the format I need to pull it off
SELECT UFV1.USR_DATE
,UFV1.USR_TIME
,LEFT(CAST(DATEADD(minute, -90, UFV1.USR_TIME) AS TIME),8) AS MIN_TIME
,LEFT(CAST(DATEADD(minute, +90, UFV1.USR_TIME) AS TIME),8)AS MAX_TIME
FROM USR_Y_FACILITY_VISIT UFV1
WHERE UFV1.MASTER_CUSTOMER_ID = '2'
ORDER BY UFV1.USR_DATE, UFV1.USR_TIME
Where I am stuck is I need to build a query that takes this info (basically the min/max from each line) then selects all the info in the same table based off that. Thank you for your help I am totally stumped as to where to go next.
Add the key fields for the table to your query as given, along with a corresponding GROUP BY clause. Then query your data table joind to that query as a sun-query on this format:
SELECT *
FROM T
JOIN ( SELECT * ... ) U
ON U.key = T.key
AND T.dateTime BETWEENU.MinDateTime AND U.MaxDateTime
If I correctly understood a question then, this request is necessary for you
SELECT *
FROM USR_Y_FACILITY_VISIT UFV1
WHERE EXISTS (
SELECT 1
FROM USR_Y_FACILITY_VISIT UFV2
WHERE UFV2.MASTER_CUSTOMER_ID = '2'
AND UFV1.USR_DATE = UFV2.USR_DATE
AND UFV1.USR_TIME BETWEEN CAST(DATEADD(minute, -90, UFV2.USR_TIME) AS time)
AND CAST(DATEADD(minute, 90, UFV2.USR_TIME) AS time)
)