Anyone please help me
How to use SQL to find yesterday max time and today min time. I need yesterday's max time Tine_in and today's min time yesterday Time_out.
Like this:
I have a table like this:
|--ID--|--Time-------|--Date------|
|--1---|08:03:00 PM|04/01/2014|
|--1---|08:07:00 AM|04/02/2014|
|--1---|08:11:00 PM|04/02/2014|
|--1---|08:02:00 AM|04/03/2014|
|--1---|08:10:00 PM|04/03/2014|
|--1---|08:05:00 AM|04/04/2014|
|--1---|08:10:00 PM|04/04/2014|
|--1---|08:06:00 AM|04/05/2014|
|--1---|08:15:00 PM|04/05/2014|
|--1---|08:01:00 AM|04/06/2014|
|--1---|08:08:00 PM|04/06/2014|
I need these results:
|--ID--|--Date------|--Time_in----|--Time_out--|
|--1---|04/01/2014|08:03:00 PM|08:07:00 AM|
|--1---|04/02/2014|08:11:00 PM|08:02:00 AM|
|--1---|04/03/2014|08:10:00 PM|08:05:00 AM|
|--1---|04/04/2014|08:10:00 PM|08:06:00 AM|
|--1---|04/05/2014|08:10:00 PM|08:01:00 AM|
|--1---|04/06/2014|08:08:00 PM|00:00:00 ----|
Like 04/02/2014 MAX time 04/02/2014 Time_in and 04/03/2014 MIN Time 04/02/2014 Time_Out.
Thanks..
Not sure how you are querying for this (stored proc, view, etc), but here is a generic advice:
For the purpose of your query, combine the Date and Time columns into one column (of type datetime or smalldatetime). Now find the min and max of that. You should be set!
I may have misunderstood the task, but you can do a self join as in:
with t(t) as (
values '2014-04-01-08.03.00'
,'2014-04-02-08.07.00'
,'2014-04-02-08.11.00'
,'2014-04-03-08.02.00'
)
select max(t1.t), min(t2.t)
from t t1
join t t2
on date(t1.t) = date(t2.t) - 1 day
group by date(t1.t)
FWIW you will get more answers if you provide sample data as either insert statements or cte (like above).
You can use group by with min and max
select
[Date],
Min([Time]) As Time_In,
Max([Time]) As Time_Out
from Table1
group by
[Date]
Also note that Time and Date are reserved words in SQL server. You should consider renaming those columns.
For each date the latest time and the next day's earliest time:
WITH cte AS
( SELECT
d,
MIN(t) AS mint,
MAX(t) AS maxt
FROM tab
GROUP BY d
)
SELECT
t1.d,
t1.maxt,
COALESCE(t2.mint, '00:00:00')
FROM cte AS t1
LEFT JOIN cte AS t2
ON t1.d = t2.d-1
Related
I am trying to create following logic in Alteryx and data is coming from Exasol database.
Column “Sum_Qty_28_days“ should sum up the values of “Qty ” column for same article which falls under last 28 days.
My sample data looks like:
and I want following output:
E.g. “Sum_Qty_28_days” value for “article” = ‘A’ and date = ‘’2019-10-8” is 8 because it is summing up the “Qty” values associated with dates (coming within previous 28 days) Which are:
2019-09-15
2019-10-05
2019-10-08
for “article” = ‘A’.
Is this possible using SQL window function?
I tried myself with following code:
SUM("Qty") OVER (PARTITION BY "article", date_trunc('month',"Date")
ORDER BY "Date")
But, it is far from what I need. It is summing up the Qty for dates falling in same month. However, I need to sum of Qty for last 28 days.
Thanks in advance.
Yes, this is possible using standard SQL and in many databases. However, this will not work in all databases:
select t.*,
sum(qty) over (partition by article
order by date
range between interval '27 day' preceding and current row
) as sum_qty_28_days
from t;
If your RDBMS does not support the range frame, an alternative solution is to use an inline subquery:
select
t.*,
(
select sum(t1.qty)
from mytable t1
where
t1.article = t.article
and t1.date between t.date - interval 28 days and t.date
) sum_qty_28_days
from mytable t
Below is my table.
I want to populate the break column by calculating the difference between two dates
I want to calculate time between column EndD,EndT and StartD,StartD but of different rows(2nd row).
for e.g-
EndD is '2016-06-01 18:17:48' and start date is '2016-06-01 18:46:05' and break time should be calculated between these two dates
Output should be like this:
Try this:
SELECT ID, AgentID, StartD, StartT, EndD, EndT,
DATEDIFF(minute,
CAST(t1.EndD + ' ' + t1.EndT AS DATETIME),
(SELECT CAST(t2.StartD + ' ' + t2.StartT AS DATETIME)
FROM yourTable t2
WHERE t2.ID = t1.ID + 1 AND t1.AgentID = t2.AgentID)) as [break]
FROM yourTable t1
The Datediff function takes the minutes between an embedded query (which takes the date and time from the next line with same agent) and the date and time of your current row. Also, be sure to use brackets around your column name "break", since it is a SQL-Server reserved word.
UPDATE:
User reported negative values from my answer. This should be resolved by switching the two date parameters in the DATEDIFF function. I have updated the code (above) to reflect this.
For tsql that would work
update a
set a.break=datediff(minute,a.endt,b.startt)
from tbl a
inner join tbl b
on a.startD=b.endD and a.ID=b.ID-1
SELECT
DATEDIFF(minute,'2016-06-01 20:17:48','2016-06-01 20:50:17')
Mention that you should change that in order you want and always increase the startT + 1
I have the following SQL query:
SELECT t.trans_id, t.business_process_id, tsp.status, tsp.timestamp
FROM tran_stat_p tsp, tran t
WHERE t.trans_id = tsp.trans_id
AND tsp.timestamp BETWEEN '1-jan-2008' AND SYSDATE
AND t.business_process_id = 'ABC01'
It outputs data like this:
trans_ID business_process_id status timestamp
14444400 ABC01 F 6/5/2008 12:37:36 PM
14444400 ABC01 W 6/6/2008 1:37:36 PM
14444400 ABC01 S 6/7/2008 2:37:36 PM
14444400 ABC01 P 6/8/2008 3:37:36 PM
14444401 ABC01 F 6/5/2008 12:37:36 PM
14444401 ABC01 W 6/6/2008 1:37:36 PM
14444401 ABC01 S 6/7/2008 2:37:36 PM
14444401 ABC01 P 6/8/2008 3:37:36 PM
In addition to the above, I'd like to add a column which calculates the time difference (in days) between statuses W&F, S&W, P&S for every unique trans_id.
The idea is to figure out how long transactions are sitting in the various statuses before they are finally processed to status "P". The life cycle of a transaction is in the following order -> F -> W -> S -> P. Where F is the first status, and P is the final status.
Can anyone help? Thanks in advance.
The actual query would use LAG, which will give you a value from a prior row.
Your status codes won't sort as F -> W -> S -> P, which is why the query below has the big CASE statement for the LAG function's ORDER BY - it translates the status codes into a value that follows your transaction life cycle.
SELECT
t.trans_id,
t.business_process_id,
tsp.status,
tsp.timestamp,
tsp.timestamp - LAG(timestamp) OVER (
PARTITION BY tsp.trans_id
ORDER BY
CASE tsp.Status
WHEN 'F' THEN 1
WHEN 'W' THEN 2
WHEN 'S' THEN 3
WHEN 'P' THEN 4
END) AS DaysBetween
FROM tran t
INNER JOIN tran_stat_p tsp ON t.trans_id = tsp.trans_id
WHERE tsp.timestamp BETWEEN DATE '2008-01-01' AND SYSDATE
AND t.business_process_id = 'ABC01';
A couple more notes:
The query is untested. If you have trouble please post some sample data and I'll test it.
I used DATE '2008-01-08' to define Jnauary 1, 2008 because that's how Oracle (and ANSI) likes a date constant to look. When you use 1-jan-2008 you're relying on Oracle's default date format, and that's a session value which can be changed. If it's changed your query will stop working.
You can use LEAD to retrieve the next timestamp value and calculated the time left in every status (F, W and S) and TRUNC to calculated days between as an integer :
SELECT t."trans_ID", t."business_process_id", tsp."status", tsp."timestamp",
LEAD("timestamp", 1) OVER (
PARTITION BY tsp."trans_ID"
ORDER BY "timestamp") AS "next_timestamp",
trunc(LEAD("timestamp", 1) OVER (
PARTITION BY tsp."trans_ID"
ORDER BY "timestamp")) - trunc(tsp."timestamp") as "Days"
FROM tran t
INNER JOIN tran_stat_p tsp ON t."trans_ID" = tsp."trans_ID"
AND tsp."timestamp" BETWEEN '01-jan-2008 12:00:00 AM' AND SYSDATE
WHERE t."business_process_id" = 'ABC01'
See SQLFIDDLE : http://www.sqlfiddle.com/#!4/04633/49/0
Look into oracle window analytics.
http://www.orafaq.com/node/55
You'll want to do a diff of your current row date and the lag of that date.
Hope that makes sense.
It's quite a hard one to explain but probably (hopefully) an easy one to solve so I'll just explain what it is I'm trying to achieve.
I have a table where multiple logs can be entered for a day each as a seperate row, I then have a decimal as another column, I'm trying to create a summary for each day which would be something like
01/01/1900 | | 5.5
When there's one entry for the 01/01/1900 with 2.5, one with 3 in the main table so adding the values together for the day?
My only issue is adding the dates together if the dates the same, I was thinking something like
Select distinct date and joining it with a table that gets the sum of the decimal column where date is... and that's where im not too sure?
Any help would be great! thanks
If your table is named logs with data like
log_date | value
1900-01-01 | 2.5
1900-01-01 | 3
then your query is
SELECT sum(value) FROM logs GROUP BY log_date
What you're looking for is probably a GROUP BY clause.
SELECT [ yourdatecol, ] sum(yourdecimalcol) FROM yourtable
[ WHERE yourdatecol = .. ]
GROUP BY [ get_ymd_from_date(yourdatecol) | yourdatecol ] ;
With such syntax you'll get sum of row sets, selected by the same datecol value. You may also want to approximate date ( e.g. taking only Y/M/D part from it ), if date contains H/M/ss and what you want is per-day sums. Optional parts I enclosed in square brackets.
SELECT log_date,sum(value) FROM logs GROUP BY log_date
CREATE VIEW Summary
AS
SELECT
DateValue,
SUM(DecimalValue) DayTotal
FROM
EventTable
GROUP BY
DateValue;
Then
SELECT
*
FROM
Summary
WHERE
DateValue = '1900-01-01'
Try this :
SELECT CONVERT(VARCHAR, DateColumn, 103) AS OutputDate, SUM(ValueColumn) AS TotalValue
FROM YourTable
GROUP BY CONVERT(VARCHAR, DateColumn, 103)
I'm presuming a DateTime is used, lets call it logdate. I'm also presuming the other one is a decimal, lets call it logdecimal.
Using SQL server 2008 you can do (the is a type called date which is without the time-part):
SELECT
CAST(logdate as date) as TheDay,
SUM(logdecimal) as TheSum
FROM logTable
GROUP BY CAST(logdatetime as date)
Using a SQL server without the type date, maybe something like:
SELECT
CONVERT(varchar(10), logdate, 101) as TheDay,
SUM(logdecimal) as TheSum
FROM logTable
GROUP BY CONVERT(varchar(10), logdate , 101)
Regards, Olle
Edit: This one will work if it is a DateTime (including time part) you want to group as a date (not including time part). Looks like this was not the case in this question.
i have table with 2 columns: date and points. I want to create a query that will return the sum of points for all days, including today. This is to generate a chart of points earned up and until today.
Edit: I think my question was clearer before ews edited it :)
With data like that
2012-01-01 1
2012-01-02 1
2012-01-02 2 same day as above (we can have many records for one day, you can think of it as a result of one game on that day)
2012-01-03 -1
I would like to see the result:
2012-01-01 1
2012-01-02 4 (1+1+2)
2012-01-03 3 (1+1+2-1)
I'm using SQL Server 2008. If you know how to do it in LINQ to Entities that would be great.
If you need cummulative, you should try this:
Edit:
SELECT
Date,
(SELECT SUM(Point) FROM A WHERE Date <= MainTable.Date) AS Points
FROM A MainTable
GROUP BY Date
Here is an SQL Fiddle to test it.
Some DBMSes have a better way to do this by using window functions, but here's a query that should work in most any SQL database:
SELECT t1.date,
SUM(t2.points) AS points_to_date
FROM table_name t1
JOIN table_name t2
ON t2.date <= t1.date
ORDER
BY t1.date
;
The only way I know to do this is with a new query for each day.
dateVariable = "2012-09-06"
SELECT Sum(points) From table_name WHERE Date<=dateVariable;
Obviously you would need to iterate over all the days to do this, changing dateVariable each time.
What I understand from the question you want a running sum of points, so that each date has the sum of points of all dates less than that date. If so, take a look at the running total section of this article.