How many Stored Procedures created everyday ( problem in converting Datetime )? - sql

I make a query that return to me the count of Stored Procedure that created everyday as follow
SELECT convert(varchar, crdate, 103) as Date,Count(*) as Counter
FROM sysobjects
WHERE (xtype = 'p') AND (name NOT LIKE 'dt%')
Group by convert(varchar, crdate, 103)
and its already work but dates appear in string format that i can't order it such as below
01/03/2010 3
01/04/2008 4
01/05/2010 5
01/11/2008 1
01/12/2008 4
02/03/2008 1
02/03/2010 2
02/04/2008 4
02/05/2010 2
02/11/2008 2
02/11/2009 2
02/12/2008 4
03/01/2010 1
03/02/2010 2
03/03/2010 2
03/04/2008 2
03/04/2010 2
03/05/2008 1
03/05/2010 2
I want to make that in which date is in datetime format that i can make order by successfully, i tried convert(datetime, crdate, 103) but it show Full date
any idea of how to do ?

To get a sortable date you need year, then month, then date. use format "112".
SELECT convert(varchar, crdate, 112) as Date,Count(*) as Counter
FROM sysobjects
WHERE (xtype = 'p') AND (name NOT LIKE 'dt%')
Group by convert(varchar, crdate, 112)
order by Date
which gives this:
Date Counter
20040711 124
20040713 1
20040725 1
20040726 2
20040803 6
If you want to get the right sort order but a differently formatted date, then you can use a subquery like this.
select CONVERT(varchar, GroupDate, 103) Date, Counter
FROM (
SELECT MIN(crdate) as GroupDate,Count(*) as Counter
FROM sysobjects
WHERE (xtype = 'p') AND (name NOT LIKE 'dt%')
Group by convert(varchar, crdate, 112)
) A
order by GroupDate
which yields
Date Counter
11/07/2004 124
13/07/2004 1
25/07/2004 1
26/07/2004 2
03/08/2004 6

How about this:
select dt, COUNT(*) from
(
SELECT convert(datetime, convert(varchar, crdate, 112)) as dt
FROM sysobjects
WHERE (xtype = 'p') AND (name NOT LIKE 'dt%')
) DayOnly
group by dt
order by dt asc

SELECT DATEADD(day, DATEDIFF(day, 0, o.crdate), 0) [Date],
COUNT(*) [Counter]
FROM sys.sysobjects o
WHERE o.xtype = 'p' AND o.name NOT LIKE 'dt%'
GROUP BY DATEADD(day, DATEDIFF(day, 0, o.crdate), 0)

Related

SQL - placing values in date bucket

Really struggling with this as a SQL newb, so i need to place values from the is_registered column into hourly buckets based on the time of day they were created. The below is a small sample
creation date
is_registered
2021-10-28 00:03:12.240
1
2021-10-28 00:09:16.221
1
2021-10-28 00:12:23.234
1
2021-10-29 00:03:19.240
1
2021-10-29 00:48:12:190
1
2021-10-29 01:09:36:129
1
2021-10-29 01:29:29:120
1
The result I would like to acheive (with the full dataset) is the following(buckets for each hour of the day
Date
Hour Bucket
Total in each bucket
2021-10-28
00:00-01:00
289
2021-10-28
01:00-02:00
876
--------
--------------
-------------
2021-10-29
00:00-01:00
190
2021-10-29
01:00-02:00
309
And so on.
Hope thats as enough information provided, any help would be greatly appreciated, thank you
Try following way
--Create table script
CREATE TABLE [dbo].[Table_4](
[creationdate] [datetime] NULL,
[isreg] [int] NULL
) ON [PRIMARY]
GO
--Sample data
insert into table_4 values (getdate(),1)
insert into table_4 values (getdate()-1,1)
go
-- query
WITH report(N) AS(
SELECT TOP(23) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM sys.columns
)
,hourly(creationdate) AS(
SELECT DATEADD(HOUR, t.N, d.creationdate)
FROM report t
CROSS JOIN(
SELECT DISTINCT DATEADD(DD, DATEDIFF(DD, 0, creationdate), 0) AS creationdate FROM table_4
) d
)
SELECT
convert(date, h.creationdate) as [Creation date],
convert(varchar(5), DATEPART(HOUR, h.creationdate)-1)+ ' - ' + convert(varchar(5),DATEPART(HOUR, h.creationdate)) as [Hour Bucket],
[Total in each bucket] = ISNULL(t.isreg, 0)
FROM hourly h
LEFT JOIN(
SELECT
creationdate = DATEADD(HOUR, DATEPART(HOUR, creationdate) ,DATEADD(DD, DATEDIFF(DD, 0, creationdate), 0)),
isreg = COUNT(*)
FROM table_4
GROUP BY DATEADD(DD, DATEDIFF(DD, 0, creationdate), 0), DATEPART(HOUR, creationdate)
)t
ON t.creationdate = h.creationdate
order by h.creationdate
Reference link
Using this tvf may be more maintainable:
DateRange TVF
WITH Ranges
AS
(
SELECT [Value] AS date_from
,LEAD([Value]) OVER (ORDER BY [Value]) AS date_to
,CAST([Value] AS date) AS [Date]
,CONVERT(char(5), [Value], 14) + '-'
+ CONVERT(char(5), LEAD([Value]) OVER (ORDER BY [Value]), 14) AS Hour_Bucket
FROM dbo.DateRange('2021-10-28', '2021-10-30', 'hh', 1)
)
SELECT R.[Date], R.Hour_Bucket
,COUNT(T.is_registered) AS Total_Registered
FROM Ranges R
LEFT JOIN YourTable T
ON T.creation_date >= R.date_from
AND T.creation_date < R.date_to
AND T.is_registered = 1
WHERE R.date_to IS NOT NULL
GROUP BY R.[Date], R.Hour_Bucket
ORDER BY [Date], Hour_Bucket;

Get sum of qty based on hour window

I'm working on a problem to figure out how much qty of product was created and dispatched between certain hours. For example, I need to see how much was created (by created I mean how many orders were created with X qty) between 6pm today and 3pm tomorrow. I'm trying to create a time bin for this but whatever I try isn't working out.
select CREATE_DATE
, CREATE_TIME
, RELEASED_DATE
, RELEASED_TIME
, sum(case
when CREATE_DATE = DATEADD(DAY, DATEDIFF(DAY, 0, CREATE_DATE), 0)
and CREATE_TIME >= '18:00:00' AND CREATE_DATE = DATEADD(DAY, DATEDIFF(DAY, 0, CREATE_DATE), 1)
then ORDER_QTY
when CREATE_DATE = DATEADD(DAY, DATEDIFF(DAY, 0, CREATE_DATE), 1)
and CREATE_TIME <= '14:59:59'
then ORDER_QTY
end) as small_window_qty
, sum(ORDER_QTY) as ord_qty
, sum(RELEASED_QTY) as rls_qty
from table
Any help with this would be appreciated. Just need a way to organize the days into the following buckets: Normal Hour Window = Created 6pm to 6pm; Smaller Hour Window = Created 6pm to 3pm; Agreed Upon = Dispatch by 3pm (12am to 3pm)
Edit: Some clarification. What im trying to accomplish is a root cause analysis. We have orders that create every day, and must ship within 2 days of being created. We're trying to figure out why our orders are not shipping on time. So as an RCA, Im trying to dig into the orders, when they were created, when they were dispatched(or released, same thing) and when they shipped. The Hour Window's mentioned above are cutoff times for orders to be created for a certain day. Example:
300 units were created today, and they must ship 2 days from now. I want to see, of that 300 created, how many were created before 3pm, and of that, how much dispatched by 3pm same day. Hope that clarifies things. Not everything that is created must be dispatched the same day, as we have 2 days to ship the orders.
you're leaving a lot of info out so i'm filling in the blanks and making assumptions here. doublecheck that my data types line up with your data types.
create table sales (create_date date, create_time time, released_date date, released_time time, qty int)
insert sales
select '1/14/13','18:45','1/15/13','10:45', 10
union all
select '1/14/13','19:45','1/15/13','12:45', 12
union all
select '1/15/13','19:15','1/16/13','16:45', 6
union all
select '1/15/13','18:00','1/16/13','14:45', 25
union all
select '1/15/13','18:45','1/16/13','15:00', 3
union all
select '1/16/13','19:45','1/17/13','16:30', 1
union all
select '1/16/13','20:45','1/17/13','17:45', 9
union all
select '1/17/13','18:30','1/18/13','18:00', 17
union all
select '1/18/13','18:30','1/19/13','17:15', 15
union all
select '1/18/13','18:45','1/19/13','19:15', 21
with base as
(
select *
, cast(create_date as datetime) + cast(create_time as datetime) as createtime
, cast(released_date as datetime) + cast(released_time as datetime) as releasetime
, datediff(hour,cast(create_date as datetime) + cast(create_time as datetime),cast(released_date as datetime) + cast(released_time as datetime)) as hrs
from sales
),
base2 as
(
select qty
, case
when create_time >= '18:00' and hrs <= 21 then 'small'
when create_time >= '18:00' and hrs <= 24 then 'normal'
else 'outside'
end as orderwindow
, case
when hrs between 6 and 21 then 'pass'
else 'fail'
end as agreedupon
from base
)
select sum(qty) as qty, orderwindow, agreedupon
from base2
group by orderwindow, agreedupon
drop table sales
this should give you the end result of being able to tell how much was created, what window of time it falls into, and if released by 3pm. adjust as needed.
i didn't want the code to get messy and convoluted so i used 2 CTEs.
I am not sure about your expected result and also your input data looks messay and not clear. So I used the data provided by the above answer. It looks you get running sum. If you can review the answer and get back to me if you need more modifications that is good. I suggest you to edit your Question and be more clear with your sample data and expected answer. Add more details to the question.
create table sales (create_date date, create_time time, released_date date, released_time time, qty int)
INSERT INTO sales
select '1/14/13','18:45','1/15/13','10:45', 10
union all
select '1/14/13','19:45','1/15/13','12:45', 12
union all
select '1/15/13','19:15','1/16/13','16:45', 6
union all
select '1/15/13','18:00','1/16/13','14:45', 25
union all
select '1/15/13','18:45','1/16/13','15:00', 3
union all
select '1/16/13','19:45','1/17/13','16:30', 1
union all
select '1/16/13','20:45','1/17/13','17:45', 9
union all
select '1/17/13','18:30','1/18/13','18:00', 17
union all
select '1/18/13','18:30','1/19/13','17:15', 15
union all
select '1/18/13','18:45','1/19/13','19:15', 21
SELECT
create_date
, create_time
, released_date
, released_time
,SUM(QTY) OVER ( PARTITION BY A.[Dispatched Window] ORDER BY released_date ) AS [Sum_qty]
,Qty
FROM
(
SELECT
create_date
, create_time
, released_date
, released_time
, CASE WHEN released_date BETWEEN CONVERT(DATETIME, CONVERT(CHAR(8), create_date, 112) + ' ' + CONVERT(CHAR(8), '18:00:00.0000000' , 108)) AND CONVERT(DATETIME, CONVERT(CHAR(8), DATEADD(DAY,1, create_date), 112) + ' ' + CONVERT(CHAR(8), '18:00:00.0000000' , 108)) THEN 'Normal Window'
WHEN released_date BETWEEN CONVERT(DATETIME, CONVERT(CHAR(8), create_date, 112) + ' ' + CONVERT(CHAR(8), '17:59:00.0000000' , 108)) AND CONVERT(DATETIME, CONVERT(CHAR(8), DATEADD(DAY,1, create_date), 112) + ' ' + CONVERT(CHAR(8), '15:00:00.0000000' , 108)) THEN 'Smaller Window'
WHEN released_date BETWEEN CONVERT(DATETIME, CONVERT(CHAR(8), create_date, 112) + ' ' + CONVERT(CHAR(8), '00:00:00.0000000' , 108)) AND CONVERT(DATETIME, CONVERT(CHAR(8), create_date, 112) + ' ' + CONVERT(CHAR(8), '15:00:00.0000000' , 108)) THEN 'Aggreed AUpon'
ELSE 'N/A'
END AS [Dispatched Window]
, Qty
FROM dbo.sales
) AS A

SQL Count with zero values

I want to create a graph for my dataset for the last 24 hours.
I found a solution that works but this is pretty bad since the table I am outer joining cotains every single row in the DB since I am using the (now deprecated) "all" parameter in the group by.
Here is the solution that currently kind of works.
First I declare the date intervals that is 24 hours back in time from now. I declare it twice so I can use it later in the procedure aswell.
Declare #StartDate datetime = dateadd(hour, -24, getdate())
Declare #StartDateProc datetime = dateadd(hour, -24, getdate())
Declare #EndDate datetime = getdate()
I populate the dates into a temp table including a special formated datetsring.
create table #tempTable
(
Date datetime,
DateString varchar(11)
)
while #StartDate <= #EndDate
begin
insert into #tempTable (Date, DateString)
values (#StartDate, convert(varchar(8), #StartDate, 5) + '-' + convert(varchar(2), #StartDate, 108));
SET #StartDate = dateadd(hour,1, #StartDate);
end
This gives me data that looks like this:
Date DateString
---------------------------------------------
2015-12-09 13:59:01.970 09-12-15-13
2015-12-09 14:59:01.970 09-12-15-14
2015-12-09 15:59:01.970 09-12-15-15
2015-12-09 16:59:01.970 09-12-15-16
So what I want is to join my dataset on the matching date string and show the date even if the matching rows is zero.
Here is the rest of the query
select
Date = c.Date,
Amount = sum(c.Amount)
from
DbTable a
outer apply
(select
Date = b.DateString,
Amount = count(*)
from
#tempTable b
where
convert(varchar(8), a.DateColumn, 5) + '-' + convert(varchar(2), a.DateColumn, 108) = b.DateString
group by all
b.DateString) c
where
a.SomeParameter = 'test' and
a.DateColumn >= #StartDateProc and
a.DateColumn <= #EndDate
group by
c.Date
drop table #tempTable
Test to show actual data:
Declare #StartDate datetime = dateadd(hour, -24, getdate())
Declare #EndDate datetime = getdate()
select
dateString = convert(varchar(8),a.DateColumn,5) + '-' + convert(varchar(2),a.DateColumn, 108),
Amount = COUNT(*)
from
DbTable a
where
a.someParameter = 'test' and
a.DateColumn>= dateadd(hour, -24, getdate()) and
a.DateColumn<= getdate()
group by
convert(varchar(8),a.DateColumn,5) + '-' + convert(varchar(2),a.DateColumn, 108)
First output rows:
dateString Amount
09-12-15-14 1
09-12-15-15 1
09-12-15-16 1
09-12-15-17 3
09-12-15-18 1
09-12-15-22 3
09-12-15-23 2
As you can see here there is no data for the times from 19.00 to 21.00. This is how I want the data to be displayed:
dateString Amount
09-12-15-14 1
09-12-15-15 1
09-12-15-16 1
09-12-15-17 3
09-12-15-18 1
09-12-15-19 0
09-12-15-20 0
09-12-15-21 0
09-12-15-22 3
09-12-15-23 2
Normally, this would be approached with left join rather than outer apply. The logic is simple: keep all rows in the first table along with any matching information from the second. This means put the dates table first:
select tt.DateString, count(t.DateColumn) as Amount
from #tempTable tt left join
DbTable t
on convert(varchar(8), t.DateColumn, 5) + '-' + convert(varchar(2), t.DateColumn, 108) = tt.DateString and
t.SomeParameter = 'test'
where tt.Date >= #StartDateProc and
tt.Date <= #EndDate
group by tt.DateString;
In addition, your comparison for the dates seems overly complex, but if it works for you, it works.
The best bet here would be to use DATETIME type itself and not to lose the opportunity to use indexes:
Declare #d datetime = GETDATE()
;WITH cte1 AS(SELECT TOP 25 -1 + ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) h
FROM master..spt_values),
cte2 AS(SELECT DATEADD(hh, -h, #d) AS startdate,
DATEADD(hh, -h + 1, #d) AS enddate
FROM cte1)
SELECT c.startdate, c.enddate, count(*) as amount
FROM cte2 c
LEFT JOIN DbTable a ON a.DateColumn >= c.startdate AND
a.DateColumn < c.enddate AND
a.SomeParameter = 'test'
GROUP BY c.startdate, c.enddate

Complicated query involving res

I have the table as below and I need to have the query how many tasks created for the day and how many are resolved and I need to capture the Tasks which are passed from previous day with active status. Ex: TaskId 101 is created on 11/10/2014 and it is resolved on 11/12/2014 so it should show in the count of 11/11/2014 and 11/12/2014 also.
TaskId CreateDate Status ResolvedDate
101 11/10/2014 Resolved 11/12/2014
102 11/10/2014 Resolved 11/10/2014
103 11/11/2014 Active NULL
104 11/11/2014 Resolved 11/13/2014
105 11/13/2014 Active 11/13/2014
Please help me as I am not able to think of any solution. Sorry I was trying to post the table schema in table format but not able to create table and I am new to this forum.
#radar, You just gave me the hope with the query and I have changed the query as below and it started showing result. But the TotalActive showing less value than TotalCreated.
declare #start_date datetime = getdate()-30
declare #end_date datetime = getdate()
;WITH CTE AS
(
SELECT #start_date AS date
UNION ALL
SELECT DATEADD(day, 1, date) as date
FROM CTE
WHERE DATEADD(day, 1, date) <= #end_date
)
select cte.date,
sum( case when CONVERT(varchar, CreateDate, 101) <= CONVERT(varchar, cte.date, 101) and CONVERT(varchar, cte.date, 101) <= CONVERT(varchar, ResolveDate, 101) then 1 else 0 end
) as TotalActive,
sum( case when CONVERT(varchar, cte.date, 101) = CONVERT(varchar, CreateDate, 101) then 1 else 0 end
) as TotalCreated,
sum( case when CONVERT(varchar, cte.date, 101) = CONVERT(varchar, ResolveDate, 101) then 1 else 0 end
) as TotalResolved
from cte
left join [WarehouseIncidents] T
ON CONVERT(varchar, CreateDate, 101) >= CONVERT(varchar, cte.date, 101)
GROUP BY CTE.DATE
you can get the result using case based aggregation
The CTE generates list of dates for a given range.
For each day, total active ( created that day and created previously but not resolved) and total resolved that day are calculated using case, max and group by
declare #start_date datetime = '2014-11-10'
declare #end_date datetime ='2014-11-13'
;WITH CTE AS
(
SELECT #start_date AS date
UNION ALL
SELECT DATEADD(day, 1, date) as date
FROM CTE
WHERE DATEADD(day, 1, date) <= #end_date
)
select cte.date,
sum( case when createDate <= cte.date and ( resolveddate is null or ResolvedDate >= cte.date) then 1 else 0 end
) as TotalActive,
sum( case when cte.date = ResolvedDate then 1 else 0 end
) as TotalResolved
from cte
left join Table1 T
ON T.createDate <= cte.date
GROUP BY CTE.DATE

How to build this sql query

i want to find the records in sql
from say 25-08-2012 to 01-09-2012
and i want to group by date
here is my query
SELECT CONVERT(VARCHAR(10), date, 105) AS dt,
COUNT(id) AS cnt
FROM tablename
WHERE date BETWEEN CONVERT(DATETIME, '21-08-2012 00:00:00:000',103)
AND CONVERT(DATETIME, '01-09-2012 23:59:00:000' ,103)
GROUP BY CONVERT(VARCHAR(10), date, 105)
i am getting result as
dt cnt
01-09-2012 48
27-08-2012 1
28-08-2012 3
29-08-2012 11
30-08-2012 3
but expect it as
dt cnt
25-08-2012 0
26-08-2012 0
01-09-2012 48
27-08-2012 1
28-08-2012 3
29-08-2012 11
30-08-2012 3
How i can modify above query
i also tried with CASE but no luck
Many Thanks..
The reason you are missing these dates in result is that there's no data for them in your table, however, the following would insure you are getting all of the dates in specified range:
CREATE TABLE #tmp_dates ([date] datetime)
DECLARE #dt_start datetime, #dt_end datetime, #dt_dif int
SET #dt_start = CONVERT(DATETIME, '21-08-2012 00:00:00:000',103)
SET #dt_end = CONVERT(DATETIME, '01-09-2012 23:59:00:000' ,103)
SET #dt_dif = datediff(day,#dt_start,#dt_end)
WHILE #dt_dif >= 0 BEGIN
INSERT INTO #tmp_dates
SELECT dateadd(day,#dt_dif,#dt_start)
SET #dt_dif = #dt_dif - 1
END
SELECT CONVERT(VARCHAR(10), t2.[date], 101) AS dt, COUNT(t1.id) AS cnt
INTO #tmp_result
FROM tablename t1
RIGHT OUTER JOIN #tmp_dates t2
ON CONVERT(VARCHAR(10), t1.[date], 101) = CONVERT(VARCHAR(10), t2.[date], 101)
GROUP BY CONVERT(VARCHAR(10), t2.[date], 101)
ORDER BY CONVERT(DATETIME,CONVERT(VARCHAR(10), t2.[date], 101)) ASC /* DESC */
SELECT convert(VARCHAR(10),CONVERT(DATETIME,dt),105) as dt,cnt FROM #tmp_result
DROP TABLE #tmp_dates
DROP TABLE #tmp_result
Your query cannot be directly modified to return the data you want. To count the dates in question, there must be records in the target table actually having those dates; in your case, however, the dates are merely parameters in the query. As a result, there is no way to incorporate them into your result set.
You must create a secondary table that includes all the dates for which you want data, and then recharacterize your query as a left outer join from that date table to your target table. This will, in turn, give you the zero counts for the dates present in the "date" table, but absent from the target table.
How about using IsNull()? Let me know if this works.
SELECT CONVERT(VARCHAR(10), date, 105) AS dt,
ISNULL(COUNT(id),0) AS cnt
FROM tablename
WHERE date BETWEEN CONVERT(DATETIME, '21-08-2012 00:00:00:000',103)
AND CONVERT(DATETIME, '01-09-2012 23:59:00:000' ,103)
GROUP BY CONVERT(VARCHAR(10), date, 105)