my dates
Dates
2011-03-01 00:00:00.000
2011-03-03 00:00:00.000
2011-03-07 00:00:00.000
2011-03-08 00:00:00.000
2011-03-13 00:00:00.000
2011-03-14 00:00:00.000
2011-03-15 00:00:00.000
How to convert this dates in to one date range like below
i need output like this'
Date_from Date_to
2011-03-01 00:00:00.000 2011-03-01 00:00:00.000
2011-03-03 00:00:00.000 2011-03-03 00:00:00.000
2011-03-07 00:00:00.000 2011-03-08 00:00:00.000
2011-03-13 00:00:00.000 2011-03-15 00:00:00.000
SQL Server 2005+
;WITH cte
AS (SELECT *,
DATEDIFF(DAY, 0, Dt) -
DENSE_RANK() OVER (ORDER BY DATEDIFF(DAY,0,Dt) ) AS Grp
FROM Dates)
SELECT MIN(Dt) AS Date_from,
MAX(Dt) AS Date_to
FROM cte
GROUP BY Grp
Related
I'm finding a way to group SQL query by trimester. I have found a way to do it using MySQL on this link.
This is what I'm expecting:
Range Start Range End Count
----------- ---------- -----
2013-09-01 2013-11-26 87
2013-06-01 2013-08-31 92
2013-03-01 2013-05-31 92
2012-12-01 2013-02-28 90
2012-09-01 2012-11-30 91
This is what I have tried:
SELECT MIN(start_date) AS Range_Start, MAX(start_date) AS Range_End, COUNT(ID) AS Total
FROM [dbo].[table]
GROUP BY FLOOR(DATEDIFF(MONTH, DATEADD(DAY, -DAY(start_date)+1, start_date), DATEADD(DAY, -DAY(start_date)+1,getdate())) /3)
ORDER BY 1 ASC
This is what I get:
Range Start Range End Count
----------- ---------- -----
1900-01-01 00:00:00.000 1900-01-01 00:00:00.000 8
1952-01-01 00:00:00.000 1952-01-01 00:00:00.000 2
1954-01-01 00:00:00.000 1954-01-01 00:00:00.000 11
1955-01-01 00:00:00.000 1955-01-01 00:00:00.000 3
1956-01-01 00:00:00.000 1956-01-01 00:00:00.000 2
1957-01-01 00:00:00.000 1957-01-01 00:00:00.000 8
1958-01-01 00:00:00.000 1958-01-01 00:00:00.000 2
1959-01-01 00:00:00.000 1959-01-01 00:00:00.000 5
1960-01-01 00:00:00.000 1960-01-01 00:00:00.000 17
1960-03-17 00:00:00.000 1960-03-17 00:00:00.000 1
I have tried this -
declare #maxD datetime
select #maxD= max(loggingdate) FROM CommunicationLogs
SELECT Count(loggingdate),#maxD FROM CommunicationLogs
WHERE loggingdate BETWEEN (#maxD - 6) AND #maxD and clientid ='20154'
4 2017-08-21 11:18:24.930
The above output means communication logged before 2017-08-21 11:18:24.930 and before its 7 days are 4. But the problem is its specific to max date. I want to get same result for all the logged date.
I tried but giving wrong data-
SELECT COUNT(id),loggingdate FROM CommunicationLogs
WHERE loggingdate BETWEEN (loggingdate - 6) AND loggingdate and clientid ='20154'
group by loggingdate
ORDER BY loggingdate desc
The sql data is -
31935 2017-08-21 11:18:24.930
31936 2017-08-21 00:00:00.000
31933 2017-08-18 14:53:03.707
31934 2017-08-18 00:00:00.000
31924 2017-08-10 12:06:00.397
31918 2017-07-26 00:00:00.000
31919 2017-07-26 00:00:00.000
31920 2017-07-26 00:00:00.000
31921 2017-07-26 00:00:00.000
31922 2017-07-26 00:00:00.000
31923 2017-07-26 00:00:00.000
31898 2017-07-25 00:00:00.000
31899 2017-07-25 00:00:00.000
31900 2017-07-25 00:00:00.000
31901 2017-07-25 00:00:00.000
31902 2017-07-25 00:00:00.000
31903 2017-07-25 00:00:00.000
31904 2017-07-25 00:00:00.000
31905 2017-07-25 00:00:00.000
31906 2017-07-25 00:00:00.000
31907 2017-07-25 00:00:00.000
31908 2017-07-25 00:00:00.000
31909 2017-07-25 00:00:00.000
31910 2017-07-25 00:00:00.000
31911 2017-07-25 00:00:00.000
31912 2017-07-25 00:00:00.000
31913 2017-07-25 00:00:00.000
31914 2017-07-25 00:00:00.000
31915 2017-07-25 00:00:00.000
31916 2017-07-25 00:00:00.000
31917 2017-07-25 00:00:00.000
31889 2017-07-24 00:00:00.000
31890 2017-07-24 00:00:00.000
Try this , hope it helps , or give you and idea.
SQL Server 2005
--to get the logging data weekly depends on Maximum Date
select Count(loggingDate),max(loggingDate) from (select CommunicationLogs.id,CommunicationLogs.loggingDate,cast(DATEDIFF(day,loggingDate,maxLoggingDate)/7 as int)WeekGroup from CommunicationLogs
cross apply (select max(loggingDate) maxLoggingDate from CommunicationLogs)maxData)weekGroupData
group by WeekGroup
--to get the logging data weekly depends on Maximum Date for each id
select id,Count(*),max(loggingDate) from
(select CommunicationLogs.id,CommunicationLogs.loggingDate,cast(DATEDIFF(day,loggingDate,maxLoggingDate)/7 as int)WeekGroup from CommunicationLogs
left join (select id,max(loggingDate) maxLoggingDate from CommunicationLogs group by id) maxData
on maxData.id=CommunicationLogs.id
)weekGroupData
group by id,WeekGroup
SQL server 2008+ you can use CTE clause to make it more readable
--to get the logging data weekly depends on Maximum Date
with maxData as
(
select max(loggingDate) maxLoggingDate from CommunicationLogs
),
weekGroupData as(
select CommunicationLogs.id,CommunicationLogs.loggingDate,cast(DATEDIFF(day,loggingDate,maxLoggingDate)/7 as int)WeekGroup from CommunicationLogs
cross apply maxData
)
select Count(loggingDate),max(loggingDate) from weekGroupData
group by WeekGroup
--to get the logging data weekly depends on Maximum Date for each id
with maxData as
(
select id, max(loggingDate) maxLoggingDate from CommunicationLogs
group by id
),
weekGroupData as(
select CommunicationLogs.id,CommunicationLogs.loggingDate,cast(DATEDIFF(day,loggingDate,maxLoggingDate)/7 as int)WeekGroup from CommunicationLogs
left join maxData on maxData.id=CommunicationLogs.id
)
select id,Count(*),max(loggingDate) from weekGroupData
group by id,WeekGroup
Example data:
FK_EmployeeId FromDate ToDate DateDiff
20325 2016-06-24 00:00:00.000 2016-06-25 00:00:00.000 2
20325 2016-06-25 00:00:00.000 2016-06-26 00:00:00.000 2
20325 2016-06-26 00:00:00.000 2016-06-28 00:00:00.000 3
20325 2016-06-28 00:00:00.000 2016-06-29 00:00:00.000 2
20325 2016-06-29 00:00:00.000 2016-06-30 00:00:00.000 2
20325 2016-06-30 00:00:00.000 2016-07-01 00:00:00.000 2
20325 2016-07-01 00:00:00.000 2016-07-02 00:00:00.000 2
20325 2016-07-02 00:00:00.000 2016-07-03 00:00:00.000 2
20325 2016-07-03 00:00:00.000 2016-07-04 00:00:00.000 2
20325 2016-07-04 00:00:00.000 2016-07-05 00:00:00.000 2
And I would like to get the following output:
FK_EmployeeId FromDate ToDate DateDiff
20325 2016-06-24 00:00:00.000 2016-06-26 00:00:00.000 3
20325 2016-06-28 00:00:00.000 2016-07-05 00:00:00.000 8
I think you are trying to do something like the below using a windowing function to join the records to themselves to perform the date comparisons across 2 rows.
However as people have already suggested in the comments your sample data above contains all sequential dates so its not really clear how your expecting this to work. I've therefore excluded a middle value in the sample data to demonstrate the approach.
--TABLE JUST FOR EXAMPLE QUERY
DECLARE #SomeTable TABLE ([FK_EmployeeId] INT,[FromDate] DATETIME,[ToDate] DATETIME,[DateDiff] INT)
--YOUR SAMPLE DATA
INSERT INTO #SomeTable
([FK_EmployeeId],[FromDate],[ToDate],[DateDiff])
SELECT 20325,'2016-06-24 00:00:00.000','2016-06-25 00:00:00.000',2
UNION SELECT 20325,'2016-06-25 00:00:00.000','2016-06-26 00:00:00.000',2
UNION SELECT 20325,'2016-06-26 00:00:00.000','2016-06-28 00:00:00.000',3
UNION SELECT 20325,'2016-06-28 00:00:00.000','2016-06-29 00:00:00.000',2
UNION SELECT 20325,'2016-06-29 00:00:00.000','2016-06-30 00:00:00.000',2
--UNION SELECT 20325,'2016-06-30 00:00:00.000','2016-07-01 00:00:00.000',2 --<<
UNION SELECT 20325,'2016-07-01 00:00:00.000','2016-07-02 00:00:00.000',2
UNION SELECT 20325,'2016-07-02 00:00:00.000','2016-07-03 00:00:00.000',2
UNION SELECT 20325,'2016-07-03 00:00:00.000','2016-07-04 00:00:00.000',2
UNION SELECT 20325,'2016-07-04 00:00:00.000','2016-07-05 00:00:00.000',2
--THE POINT:
;WITH cte AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY [FK_EmployeeId] ORDER BY [ToDate]) AS 'RowNo'
FROM
#SomeTable
)
SELECT
a.*,
DATEDIFF(DAY,a.[FromDate],b.[ToDate]) AS 'NewDiff'
FROM
cte a
JOIN cte b
ON a.[RowNo] + 1 = b.[RowNo]
WHERE
a.[ToDate] <> b.[FromDate]
A little more detail in the question next time please.
I have a query that I don't think should be that hard to make, however, I've spent a lot of time on it now and still can't get it the way I want, so I hope someone here can help me.
Basically, I need to create a report that will give a value for each month, for each area. However, not all areas deliver data each month; in that case the view should return NULL for that month and area. So, the view need to look something like this:
Month Area Value
2012-08-01 Area1 2
2012-08-01 Area2 3
2012-09-01 Area1 3
2012-09-01 Area2 NULL
My data table looks something like this
Date Area Value
2012-08-01 Area1 2
2012-08-01 Area2 3
2012-09-01 Area1 3 -- Notice that Area2 is not present for September here
I have a table with all the available areas
Furthermore, I have created a table-valued function that returns all dates from a given date until now.
For example this statement
SELECT * FROM Periods_Months('2012-01-01')
would return 8 records like:
DateValue Year Month YearMonth
2012-01-01 00:00:00.000 2012 1 20121
2012-02-01 00:00:00.000 2012 2 20122
2012-03-01 00:00:00.000 2012 3 20123
2012-04-01 00:00:00.000 2012 4 20124
2012-05-01 00:00:00.000 2012 5 20125
2012-06-01 00:00:00.000 2012 6 20126
2012-07-01 00:00:00.000 2012 7 20127
2012-08-01 00:00:00.000 2012 8 20128
Based on the suggestions, my query now looks like this:
WITH months AS (
SELECT DateValue, YearMonth FROM Periods_Months('2011-01-01')
)
select m.DateValue
,CAST(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,m.DateValue)+1,0)) AS Date) AS DateReported -- Get last day in month
,ResponseTime AS Value
,g.ExternalId
from GISDB.dbo.GisObjects g
CROSS JOIN months m
LEFT OUTER JOIN
( -- SELECT data from data table, grouped by area and month
SELECT dbo.YearMonth(CloseDate) AS YearMonth
,MAX(CloseDate) AS LastDate
,GisObjectId
,SUM(DATEDIFF(HH,RegDate,CloseDate)) AS ResponseTime -- calculate response time between start and end data (the value we need)
FROM DataTable
WHERE CloseDate IS NOT NULL
AND GisObjectId IS NOT NULL
GROUP BY GisObjectId, dbo.YearMonth(CloseDate) -- group by area and month
) c
ON g.ObjectId = c.GisObjectId AND c.YearMonth = m.YearMonth
WHERE g.CompanyId = 3 AND g.ObjectTypeId = 1 -- reduce the GIS objects that we compare to
ORDER BY m.DateValue, g.ObjectId
But the result is this (Value is always NULL):
DateValue DateReported Value ExternalId
2011-01-01 00:00:00.000 31-01-2011 NULL 9994
2011-01-01 00:00:00.000 31-01-2011 NULL 9993
2011-01-01 00:00:00.000 31-01-2011 NULL 9992
2011-01-01 00:00:00.000 31-01-2011 NULL 9991
2011-01-01 00:00:00.000 31-01-2011 NULL 2339
2011-01-01 00:00:00.000 31-01-2011 NULL 2338
2011-01-01 00:00:00.000 31-01-2011 NULL 2337
2011-01-01 00:00:00.000 31-01-2011 NULL 2336
2011-01-01 00:00:00.000 31-01-2011 NULL 2335
2011-01-01 00:00:00.000 31-01-2011 NULL 2334
2011-01-01 00:00:00.000 31-01-2011 NULL 2327
2011-01-01 00:00:00.000 31-01-2011 NULL 2326
2011-01-01 00:00:00.000 31-01-2011 NULL 2325
2011-01-01 00:00:00.000 31-01-2011 NULL 2324
2011-01-01 00:00:00.000 31-01-2011 NULL 2323
2011-01-01 00:00:00.000 31-01-2011 NULL 2322
etc.
I suppose you have a table with all your areas, which I call area_table.
WITH month_table AS (
SELECT dateValue FROM Periods_Months('2012-01-01')
)
select * from area_table
CROSS JOIN month_table
LEFT OUTER JOIN myValueTable
ON area_table.name = myValueTable.area
AND myValueTable.date = left(convert(varchar(30),month_table.dateValue,120),10)
ORDER BY myValueTable.Month, myValueTable.area
Suppose Areas is your table for all available areas, t - is your data table:
SELECT pm.dateValue,Ar.Area, t.value
FROM Periods_Months('2012-01-01') pm, Areas ar
left join t on (pm.dateValue=t.Date) and (ar.Area=t.Area)
order by pm.DateValue,ar.Area
I have daily values in one table and monthly values in another table. I need to use the values of the monthly table and calculate them on a daily basis.
basically, monthly factor * daily factor -- for each day
thanks!
I have a table like this:
2010-12-31 00:00:00.000 28.3
2010-09-30 00:00:00.000 64.1
2010-06-30 00:00:00.000 66.15
2010-03-31 00:00:00.000 12.54
and a table like this :
2010-12-31 00:00:00.000 98.1
2010-12-30 00:00:00.000 97.61
2010-12-29 00:00:00.000 99.03
2010-12-28 00:00:00.000 97.7
2010-12-27 00:00:00.000 96.87
2010-12-23 00:00:00.000 97.44
2010-12-22 00:00:00.000 97.76
2010-12-21 00:00:00.000 96.63
2010-12-20 00:00:00.000 95.47
2010-12-17 00:00:00.000 95.2
2010-12-16 00:00:00.000 94.84
2010-12-15 00:00:00.000 94.8
2010-12-14 00:00:00.000 94.1
2010-12-13 00:00:00.000 93.88
2010-12-10 00:00:00.000 93.04
2010-12-09 00:00:00.000 91.07
2010-12-08 00:00:00.000 90.89
2010-12-07 00:00:00.000 92.72
2010-12-06 00:00:00.000 93.05
2010-12-03 00:00:00.000 91.74
2010-12-02 00:00:00.000 90.74
2010-12-01 00:00:00.000 90.25
I need to take the value for the quarter and multiply it buy all the days in the quarter by the daily value
You could try:
SELECT dt.day, dt.factor*mt.factor AS daily_factor
FROM daily_table dt INNER JOIN month_table mt
ON YEAR(dt.day) = YEAR(mt.day)
AND FLOOR((MONTH(dt.day)-1)/3) = FLOOR((MONTH(mt.day)-1)/3)
ORDER BY dt.day
or (as suggested by #Andriy)
SELECT dt.day, dt.factor*mt.factor AS daily_factor
FROM daily_table dt INNER JOIN month_table mt
ON YEAR(dt.day) = YEAR(mt.day)
AND DATEPART(QUARTER, dt.day) = DATEPART(QUARTER, mt.day)
ORDER BY dt.day