SQL command: get min date and hour from table - sql

SQL command: get min date and hour from table
TblAzmon:
Acode(pk) | Aname | Adate | Ahour | ADcode_fk
----------------------------------------------------------------------------
1 system 1358/05/05 08:00 2
2 graphic 1389/05/05 08:00 1
3 simulation 1392/05/06 07:30 1
4 math 1389/05/05 09:00 1
I want the output date and time for the manager (ADcode) to get the smallest.
Desired output: [Where ADcode_fk='1']
Acode | Adate | Ahour
----------------------------------
2 1389/05/05 08:00
SQL command:
select Acode,Adate,Ahour from TblAzmon<br>
where Adate in (select min(Adate) from TblAzmon where ADcode_fk='1')
And Ahour in (select min(Ahour) from TblAzmon where ADcode_fk='1')
Output:---------->0 rows - NULL
Tip: All columns are of type text. Apart from the column Acode.
Please write the SQL code.

You could made it like that, using order by and top:
select top 1 *
from tblAzmon a
order by Adate, Ahour

Assuming you mean the earliest combination of date and hour, You can do this with order by and top:
select top 1 *
from tblAzmon a
order by Adate, Ahour

Your SQL doesnt work, because u select the minHour and minDate at once, and since the min(Date) doesnt have the min(Hour) you get 0 rows back.
U need to brake them apart and select them one by one like this. With that u should be able to do it on your own =)
SELECT Acode,Adate,min(Ahour)
FROM (Select Acode,min(Adate),Ahour FROM TblAzmon WHERE ADcode_fk='1') t
WHERE ADcode_fk='1'

Related

SQL Calculating time from last transaction for each ID

Hello I'm stuck trying to calculate the difference in time between each transaction for each ID.
The data looks like
Customer_ID | Transaction_Time
1 00:30
1 00:35
1 00:37
1 00:38
2 00:20
2 00:21
2 00:23
I'm trying to get the result to look something like
Customer_ID | Time_diff
1 5
1 2
1 1
2 1
2 2
I would really appreciate any help.
Thanks
Most databases support the LAG() function. However, the date/time functions can depend on the database. Here is an example for SQL Server:
select t.*
from (select t.*,
datediff(second,
lag(transaction_time) over (partition by customer_id order by transaction_time),
transaction_time
) as diff
from t
) t
where diff is not null;
The logic would be similar in most databases, although the function for calculating the time difference varies.

Counting number of Days in the where clause

I have a SQL Server table that looks like this:
ID | Club Name | Booking Date | Submission Date
---+-------------+-------------------------+-------------------------
1 | Basketball | 2015-10-21 00:00:00.000 | 9/18/2015 3:23:42 PM
2 | Tennis | 2015-10-14 00:00:00.000 | 9/28/2015 1:50:25 PM
3 | Basketball | 2015-10-06 00:00:00.000 | 9/29/2015 11:08:20 AM
1 | Other | 2015-10-21 00:00:00.000 | 9/29/2015 11:08:39 AM
I want to know how many times each club did a submission less than 15 days from the booking date..
The solution I came up with was adding a new column and running a the datefiff function and storing the value in the new column.. Then just grouping by club name and adding a parameter for > 15 on the new column..
The question I have is: can this be done on the fly with out having to create the new column? how much would that affect performance if its done on the fly?
Yes, this can be done inline, in a query. In a database, you almost never want to store a calculated column, which is what that datediff column would be. Instead, you can do the math in the WHERE clause.
SELECT
*
FROM
myTable
WHERE
DATEDIFF(day, -15, BookingDate) >= SubmissionDate
I wrote that pretty quickly, so the date math might be going in the wrong direction (checking in the future instead of in the past) but playing with the above query should set you on the right path. Just keep in mind that, if this table gets very big, you're going to be doing a TON of DATEDIFFs and that can have a performance impact.
Something like this?
Declare #Table table (Id int,Club_Name varchar(50),Booking_Date datetime,Sumbission_Date datetime)
Insert #Table values
(1,'Basketball','2015-10-21 00:00:00.000','9/18/2015 3:23:42 PM'),
(2,'Tennis ','2015-10-14 00:00:00.000','9/28/2015 1:50:25 PM'),
(3,'Basketball','2015-10-06 00:00:00.000','9/29/2015 11:08:20 AM'),
(1,'Other ','2015-10-21 00:00:00.000','9/29/2015 11:08:39 AM')
Select Club_Name
,Submissions= count(*)
,Early = sum(case when datediff(DD,Sumbission_Date,Booking_Date)<15 then 1 else 0 end)
From #Table
Group By Club_Name
Returns
Club_Name Submissions Early
Basketball 2 1
Other 1 0
Tennis 1 0
Try this.
SELECT ID,
ClubName,
Sum(Value) As Ttle
FROM
(
SELECT ID,
ClubName,
COUNT(*) AS Value
FROM TableName
GROUP BY ID,
ClubName,
RecordDate
HAVING DATEDIFF(D, BookingDate, SubmissionDate) > 15
) Data
GROUP BY ID,
ClubName,
ORDER BY ttle DESC

Open Ticket Count Per Day

I have a table that looks like this
id | Submit_Date | Close_Date
------------------------------
1 | 2015-02-01 | 2015-02-05
2 | 2015-02-02 | 2015-02-04
3 | 2015-02-03 | 2015-02-05
4 | 2015-02-04 | 2015-02-06
5 | 2015-02-05 | 2015-02-07
6 | 2015-02-06 | 2015-02-07
7 | 2015-02-07 | 2015-02-08
I can get a count of how many ticket were open on a particular day with this:
Select count(*) from tickets where '2015-02-05' BETWEEN Submit_Date and Close_Date
This gives me 4, but I need this count for each day of a month. I don't want to have to write 30 queries to handle this. Is there a way to capture broken down by multiple days?
I created a solution a way back using a mix of #Heinzi s solution with the trick from Generate a resultset of incrementing dates in TSQL
declare #dt datetime, #dtEnd datetime
set #dt = getdate()
set #dtEnd = dateadd(day, 100, #dt)
SELECT dates.myDate,
(SELECT COUNT(*)
FROM tickets
WHERE myDate BETWEEN Submit_Date and Close_Date
)
FROM
(select Dates_To_Checkselect dateadd(day, number, #dt) mydate
from
(select distinct number from master.dbo.spt_values
where name is null
) n
where dateadd(day, number, #dt) < #dtEnd) dates
Code is combined from memory, I don't have it in front of me so there can be some typo's
First, you'll need a table that contains each date you want to check. You can use a temporary table for that. Let's assume that this table is called Dates_To_Check and has a field myDate:
SELECT myDate,
(SELECT COUNT(*)
FROM tickets
WHERE myDate BETWEEN Submit_Date and Close_Date)
FROM Dates_To_Check
Alternatively, you can create a huge table containing every possible date and use a WHERE clause to restrict the dates to those you are interested in.
If you're in SQL Server 2012 or newer you can do this using window functions with a small trick where you add 1 to the open days -1 to the closing days and then do a running total of this amount:
select distinct date, sum(opencnt) over (order by date) from (
select
Submit_Date as date,
1 as opencnt
from
ticket
union all
select
dateadd(day, 1, Close_Date),
-1
from
ticket
) TMP
There's a dateadd + 1 day to include the close date amount to that day
You could generate the list of dates and then retrieve the count for each date in your dateset.
The cte part generates the date list since the beginning of the year (an ssumption) and the next part calculates the count from your data set.
with cte as
(select cast('2015-01-01' as date) dt // you should change this part to the correct start date
union all
select dateadd(DD,1,dt) dt from cte
where dt<getdate()
)
select count(*)
from tickets
inner join cte
on cte.dt between Submit_Date and Close_Date
group by cte.dt

how to count days between two dates with where conditions

i have table and it has following data:
USERID NAME DATEFROM DATETO
1 xxx 2014-05-10 2014-05-15
1 xxx 2014-05-20 2014-05-25
4 yyy 2014-04-20 2014-04-21
now i have sql query like :
select * from leave where datefrom>='2014-05-01' and dateto<='2014-05-31'
so now i want output :
userid name total_leave_days
1 xxx 12
4 yyy 2
(2014-05-10 - 2014-05-15 )=6 days
(2014-05-20 - 2014-05-25 )=6 days
total = 12 days for useid 1
(2014-04-20 - 2014-04-21)= 2 days for userid 4
how can i calculate this total days .?
Please try:
select
USERID,
NAME,
SUM(DATEDIFF(day, DATEFROM, DATETO)+1) total_leave_days
From leave
group by USERID, NAME
SQL Fiddle Demo
It's important to note that you need "+1" to emulate the expected calculations because there is an inherent assumption of ""start of day" for the Start date and "end of day" for end date - but dbms's don't think that way. a date is always stored as "start of day".
select
USERID
, name
, sum( datediff(day,DATEFROM,DATETO) + 1 ) as leave_days
from leavetable
group by
USERID
, name
produces this:
| USERID | NAME | LEAVE_DAYS |
|--------|------|------------|
| 1 | xxx | 12 |
| 4 | yyy | 2 |
see: http://sqlfiddle.com/#!3/ebe5d/1
You can use DateDiff.
SELECT UserID, Name, SUM(DATEDIFF(DAY, DateFrom, DateTo) + 1) AS total_leave_days
FROM leave
WHERE datefrom >= '2014-05-01' AND dateto <= '2014-05-31'
GROUP BY UserID, Name
The + 1 ,of course, is because DATEDIFF will return the exclusive count, where it sounds like you want the inclusive number of days.
Try this:
select userid, name, sum (1 + datediff(day,datefrom,dateto)) as total_leave_days
from leaves
where datefrom>='2014-05-01' and dateto<='2014-05-31'
group by userid, name
This will sum the total leaves per userid. Note that datediff will give you 5 days difference for the range 2014-05-10 to 2014-05-15, so we need to add 1 to the result to get 6 days i.e. range inclusive of both ends.
Demo

MAX on group returns multiple values with same date but different times

I have followed many of the excellent pieces of advise on this site about selecting the MAX from a group of rows.
I have a history file and I only want the top date and comments for each project number. I am creating a derived table in a Boxi universe from this information. It all goes pretty well but if there are two entries for the same day but with different times they are both returned. This duplicates that entry on the subsequent report. Is there some way to make the MAX command go down to the time level of the date field?
Database is SQL Server 2005
-------------Sql used for derived table
Select
Projectno, Comment, CreatedOn
from
ReportHistory
Where
ReportHistory.ItemName=('ProjectCode1')
and
CreatedOn in(Select max(CreatedOn) FROM ReportHistory group by Projectno)
-------------------Example database
Projectno Comment Created on
1 Started 2013-01-04 11:04:00
2 Late 2013-01-06 11:22:00
3 Late 2013-01-07 11:06:00
1 On Time 2013-01-08 11:01:00 *these two both get selected*
1 Late 2013-01-08 12:05:00 *these two both get selected*
3 Back on schedule 2013-01-08 14:20:00
2 Still overdue 2013-01-09 09:01:00
MAX on a DATETIME data type do obviously take the time into account, that is not what's wrong with your query. The problem is that you are not ensuring that the max value for CreatedOn is for the correct ProjectNo. You could use analytical functions for this:
;WITH CTE AS
(
SELECT Projectno,
Comment,
CreatedOn,
ROW_NUMBER() OVER(PARTITION BY ProjectNo ORDER BY CreatedOn DESC) RN
FROM ReportHistory
WHERE ReportHistory.ItemName = 'ProjectCode1'
)
SELECT Projectno, Comment, CreatedOn
FROM CTE
WHERE RN = 1
Query if there are no same projectno with the same date:
SQLFIDDLEExample
SELECT h.Projectno,
h.Comment,
h.[Created on]
FROM ReportHistory h
WHERE h.[Created on] =(Select max(h2.[Created on])
FROM ReportHistory h2
WHERE h2.Projectno = h.Projectno )
ORDER BY h.Projectno
Result:
| PROJECTNO | COMMENT | CREATED ON |
-----------------------------------------------------------------
| 1 | Late | January, 08 2013 12:05:00+0000 |
| 2 | Still overdue | January, 09 2013 09:01:00+0000 |
| 3 | Back on schedule | January, 08 2013 14:20:00+0000 |
Query if there are same projectno with the same date:
SELECT h.Projectno,
MAX(h.Comment) AS Comment,
h.[Created on]
FROM ReportHistory h
WHERE h.[Created on] =(Select max(h2.[Created on])
FROM ReportHistory h2
WHERE h2.Projectno = h.Projectno )
GROUP BY h.Projectno,
h.[Created on]
ORDER BY h.Projectno
I think you receive copies when dates at different projects are identical.
For eg. add in your data (4, 'On Time', '2013-01-08 11:01:00')
Then result will be SQLFiddle
But you need this result SQLFiddle
SELECT *
FROM ReportHistory t
WHERE t.ItemName=('ProjectCode1')
AND EXISTS (
SELECT 1
FROM ReportHistory
WHERE projectNo = t.projectNo
GROUP BY projectNo
HAVING MAX(CreatedOn) = t.CreatedOn
)