group by and count for month wise data - sql-server

I have t_street_name,t_vrm ,t_date_time_issued,ticket_no as columns in a table , i want to get how many tickets have been issued on all streets on all months I am eager to know if there are muilple tickets issued to same vrm on particular street on any given month. This was my query but group by command is not working.
SELECT t_vrm,t_streeet_name,JAN, FEB, MARCH,
APRIL, MAY, JUNE,JULY, AUG, SEPT, OCT, NOV, DECEMBER,
JAN+ FEB+ MARCH+
APRIL+ MAY+ JUNE+JULY+ AUG+ SEPT+ OCT+ NOV+ DECEMBER
AS row_total
FROM
( SELECT t_street_name,t_zone_name,t_vrm, SUM(t1) AS JAN, SUM(t2) AS FEB, SUM(t3) AS MARCH,
SUM(t4) AS APRIL, SUM(t5) AS MAY, SUM(t6) AS JUNE,
SUM(t7) AS JULY, SUM(t8) AS AUG, SUM(t9) AS SEPT,
SUM(t10) AS OCT, SUM(t11) AS NOV, SUM(t12) AS DECEMBER
FROM
(
SELECT b.*,
CASE WHEN DATEPART(mm,t_date_time_issued) BETWEEN '01' AND '01' THEN 1 ELSE 0 END AS t1,
CASE WHEN DATEPART(mm,t_date_time_issued) BETWEEN '02' AND '02' THEN 1 ELSE 0 END AS t2,
CASE WHEN DATEPART(mm,t_date_time_issued) BETWEEN '03' AND '03' THEN 1 ELSE 0 END AS t3,
CASE WHEN DATEPART(mm,t_date_time_issued) BETWEEN '04' AND '04' THEN 1 ELSE 0 END AS t4,
CASE WHEN DATEPART(mm,t_date_time_issued) BETWEEN '05' AND '05' THEN 1 ELSE 0 END AS t5,
CASE WHEN DATEPART(mm,t_date_time_issued) BETWEEN '06' AND '06' THEN 1 ELSE 0 END AS t6,
CASE WHEN DATEPART(mm,t_date_time_issued) BETWEEN '07' AND '07' THEN 1 ELSE 0 END AS t7,
CASE WHEN DATEPART(mm,t_date_time_issued) BETWEEN '08' AND '08' THEN 1 ELSE 0 END AS t8,
CASE WHEN DATEPART(mm,t_date_time_issued) BETWEEN '09' AND '09' THEN 1 ELSE 0 END AS t9,
CASE WHEN DATEPART(mm,t_date_time_issued) BETWEEN '10' AND '10' THEN 1 ELSE 0 END AS t10,
CASE WHEN DATEPART(mm,t_date_time_issued) BETWEEN '11' AND '11' THEN 1 ELSE 0 END AS t11,
CASE WHEN DATEPART(mm,t_date_time_issued) BETWEEN '12' AND '12' THEN 1 ELSE 0 END AS t12
FROM
(
SELECT t_street_name,t_zone_name,t_vrm,t_date_time_issued FROM tickets
)b
)d
group by t_vrm,t_street_name,t_zone_name )qry1

Related

How can separate morning and evening shifts patients with gender wise using SQL stored procedure

I want to separate the morning and evening patient checked-in count gender-wise and also if gender age less then show the Female child and M child on the basis of gender.
SELECT
COUNT(ch.EnteredOn) AS counter,
CONVERT(date, ch.EnteredOn) AS sessionDay,
SUM(CASE WHEN CAST(CONVERT(CHAR(2), ch.EnteredOn, 108) AS INT) < 12 THEN 1 ELSE 0 END) AS 'Morning',
SUM(CASE WHEN CAST(CONVERT(CHAR(2), ch.EnteredOn, 108) AS INT) >= 12 THEN 1 ELSE 0 END) AS 'Evening',
SUM(CASE WHEN p.Gender = 1 THEN 1 ELSE 0 END) AS Male,
SUM(CASE WHEN p.Gender = 2 THEN 1 ELSE 0 END) AS Fmale,
SUM(CASE WHEN DATEDIFF(hour, P.DOB, GETDATE()) / 8766 <= 18
AND P.Gender = 1 THEN 1 ELSE 0 END) AS MChild,
SUM(CASE WHEN DATEDIFF(hour, P.DOB, GETDATE()) / 8766 <= 18
AND P.Gender = 2 THEN 1 ELSE 0 END) AS FChild
FROM
Patient.CheckIn ch
INNER JOIN
Patient.Patients P ON ch.PatientId = p.PatientId
GROUP BY
Ch.EnteredOn
I have only three columns like Gender, Time and DOB. Gender id 1 shows the male and Gender id 2 is using for females.
enter image description here
SELECT convert(date, ch.EnteredOn) AS sessionDay, CAST( CONVERT(CHAR(2), ch.EnteredOn, 108) AS INT) <12 as morning, count(ch.EnteredOn) AS counter
,sum(case when p.Gender=1 Then 1 ELSE 0 end) as Male
,sum(case when p.Gender=2 Then 1 ELSE 0 end) as Fmale
,Sum( case when DATEDIFF(hour,P.DOB,GETDATE())/8766<=18 AND P.Gender=1 Then 1 ELSE 0 end ) as MChiled
,Sum( case when DATEDIFF(hour,P.DOB,GETDATE())/8766<=18 AND P.Gender=2 Then 1 ELSE 0 end ) as FChiled
FROM Patient.CheckIn ch
inner join Patient.Patients P on ch.PatientId=p.PatientId
Group by Ch.EnteredOn
Group BY can be
Group by convert(date, ch.EnteredOn) AS sessionDay, CAST( CONVERT(CHAR(2), ch.EnteredOn, 108) AS INT) <12

SQL Server 2014 pivot table row and column month grant total

How can I add row and column grand totals in the table below?
I want to get total and grand total by months.
However, I couldn't do that.
SELECT *
FROM(
SELECT
YEAR(DueDate) [Year],
CASE MONTH(DueDate)
WHEN 1 THEN 'January'
WHEN 2 THEN 'February'
WHEN 3 THEN 'March'
WHEN 4 THEN 'April'
WHEN 5 THEN 'May'
WHEN 6 THEN 'June'
WHEN 7 THEN 'July'
WHEN 8 THEN 'August'
WHEN 9 THEN 'September'
WHEN 10 THEN 'October'
WHEN 11 THEN 'November'
WHEN 12 THEN 'December'
END as [Month],
ProductID,
OrderQty
FROM Production.WorkOrder
) WorkOrders
PIVOT
(
SUM(OrderQty)
FOR [Month] IN (
[January],[February],[March],[April],
[May],[June],[July],[August],
[September],[October],[November],[December]
)
) AS PivotTable
ORDER BY [Year], ProductID
Stuff like this is far easier using a conditional aggregate over the restrictive PIVOT operator.
Without sample data, nor expected results, this isn't tested, but you should be able to achieve what you're after with something like this:
SELECT CASE WHEN GROUPING(DATEPART(YEAR,DueDate)) = 0 THEN
CAST(DATEPART(YEAR,DueDate) AS varchar(50))
ELSE 'GrandTotal' END AS [Year],
SUM(CASE DATEPART(MONTH,DueDate) WHEN 1 THEN OrderQty END) AS January, --Don't use single quotes for alaises,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 2 THEN OrderQty END) AS Feburary, --it can be very confusing to read.
SUM(CASE DATEPART(MONTH,DueDate) WHEN 3 THEN OrderQty END) AS March, --Single quotes are for literal strings.
SUM(CASE DATEPART(MONTH,DueDate) WHEN 4 THEN OrderQty END) AS April, --Using ' for alias only work in the SELECT too,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 5 THEN OrderQty END) AS May, --something like ORDER BY 'January' would not
SUM(CASE DATEPART(MONTH,DueDate) WHEN 6 THEN OrderQty END) AS June, --order by data by the column aliases as 'January'.
SUM(CASE DATEPART(MONTH,DueDate) WHEN 7 THEN OrderQty END) AS July,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 8 THEN OrderQty END) AS August,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 9 THEN OrderQty END) AS September,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 10 THEN OrderQty END) AS October,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 11 THEN OrderQty END) AS November,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 12 THEN OrderQty END) AS December,
SUM(OrderQty) AS GrandTotal,
ProductID
FROM Production.WorkOrder
GROUP BY GROUPING SETS(
(DATEPART(YEAR, DueDate), ProductID),
(DATEPART(YEAR, DueDate)),
()
);

SQL Tally up value based on the day of the week

Here is what my table looks like
ID | Date
------------
13 2013-03-21 00:00:00
13 2013-03-23 00:00:00
13 2013-03-24 00:00:00
25 2013-03-21 00:00:00
25 2013-03-22 00:00:00
25 2013-03-21 00:00:00
25 2013-03-23 00:00:00
25 2013-03-28 00:00:00
25 2013-03-21 00:00:00
82 2013-03-22 00:00:00
82 2013-03-22 00:00:00
I want it to output (combine sat & sun into 'weekend'). It'll combine all the Mondays, Tuesdays, Wednesdays, etc. and combine the values.
day | total
--------------
Friday 2
Thursday 3
Weekend 3
This is my query so far
SELECT
CASE
WHEN DATENAME(weekday, [date]) = 'Saturday' OR DATENAME(weekday, [date]) = 'Sunday' THEN 'Weekend'
ELSE DATENAME(weekday, [date])
END AS Day,
COUNT(DISTINCT [id]) AS score
FROM [table]
GROUP BY
CASE
WHEN DATENAME(weekday, [date]) = 'Saturday' OR DATENAME(weekday, [date]) = 'Sunday' THEN 'Weekend'
ELSE DATENAME(weekday, [date])
END
Currently I can get my query to output this, but it seems like it isn't adding both thursdays or sat + sun.
Day | total
--------------
Friday 2
Thursday 2
Weekend 2
Appears like what you are actually after is a distinct count of the ID and date combined. Seems like the easiest way, therefore, would be to concatenate the 2 values to make a new unique value and COUNT those DISTINCT values:
SELECT CASE WHEN DATENAME(WEEKDAY, V.[Date]) IN ('Saturday','Sunday') THEN 'Weekend' ELSE DATENAME(WEEKDAY, V.[Date]) END AS [Weekday],
COUNT(DISTINCT CONCAT(ID,[date]))
FROM (VALUES (13, CONVERT(datetime2(0),'2013-03-21T00:00:00')),
(13, CONVERT(datetime2(0),'2013-03-23T00:00:00')),
(13, CONVERT(datetime2(0),'2013-03-24T00:00:00')),
(25, CONVERT(datetime2(0),'2013-03-21T00:00:00')),
(25, CONVERT(datetime2(0),'2013-03-22T00:00:00')),
(25, CONVERT(datetime2(0),'2013-03-21T00:00:00')),
(25, CONVERT(datetime2(0),'2013-03-23T00:00:00')),
(25, CONVERT(datetime2(0),'2013-03-28T00:00:00')),
(25, CONVERT(datetime2(0),'2013-03-21T00:00:00')),
(82, CONVERT(datetime2(0),'2013-03-22T00:00:00')),
(82, CONVERT(datetime2(0),'2013-03-22T00:00:00'))) V (ID, [Date])
GROUP BY CASE WHEN DATENAME(WEEKDAY, V.[Date]) IN ('Saturday','Sunday') THEN 'Weekend' ELSE DATENAME(WEEKDAY, V.[Date]) END;
Try this!
select count(id)as Total,Day from
(
select id, case when Datename(weekday,dt1) IN('Saturday','Sunday') then 'Weekend' else Datename(weekday,dt1) end as 'Day' from tab
)x
group by Day
Demo here
select Day,Count(day) cnt from (
SELECT
CASE
WHEN DATENAME(weekday, [date]) = 'Saturday' OR DATENAME(weekday, [date]) = 'Sunday' THEN 'Weekend'
ELSE DATENAME(weekday, [date])
END AS Day
,[date]
FROM [Infinite_campus].[dbo].[AttendanceRecord]
) as t
group by Day

Count Number of Saturdays in a date range - SQL

I have a report which looks for orders during a given date range... It returns the DateName from the report to give me mondays, it then gives me times from the report, to give me 859 for 08:59 for example.. I then use a case on this report to do the following...
WHEN (DATENAME(DW,T1.DocDate)) = 'Monday' AND T1.DocTime >= '700' AND T1.DocTime <= '859' THEN '1 Monday 07:00-08:59'
What I want to achieve, is the count for "1 Monday 07:00-08:59" to be divided by 2 if there has been 2 mondays, divided by 3 if there has been 3 mondays etc... but I have to be able to have it divide by 3 mondays for example, but 2 wednesdays if the date is a tuesday...
The report currently gives a Total of all orders placed in a datetime grouped together but has no division to average for each day.
SELECT (DATENAME(DW, T1.DocDate)) AS Weekday,
T1.DocTime AS Time,
SUM(T1.DocTotal) AS Value,
CASE
WHEN (DATENAME(DW, T1.DocDate)) = 'Monday'
AND T1.DocTime >= '700'
AND T1.DocTime <= '859' THEN '1 Monday 07:00-08:59'
FROM ORDR T1
INNER JOIN OCRD T0 ON T0.CardCode = T1.CardCode
WHERE (T1.DocDate >= #Start
AND T1.DocDate <= #End)
AND T0.QryGroup20 = 'Y'
AND T1.Canceled = 'N'
GROUP BY T1.DocTime,
T1.DocDate;
I expect the report to count the mondays / tuesdays etc that occur between #START and #END to give me an average sale per day and time.Then be able to then somehow divide by the count of the defined days in the case statement. (I'll hopefully be doing this part in Crystal Reports) but if i can get the first part, I'll work on the second half.
Just cross join the DW_Count subquery, which returns the count of every weekday in your orders range. Then you can count your avg for each weekday
SELECT (DATENAME(DW, T1.DocDate)) AS Weekday,
T1.DocTime AS Time,
SUM(T1.DocTotal) AS Value,
SUM(T1.DocTotal)/(CASE WHEN DATENAME(DW, T1.DocDate) = 'Monday' then DW_Count.MonCount
WHEN DATENAME(DW, T1.DocDate) = 'Tuesday' then DW_Count.TueCount
WHEN DATENAME(DW, T1.DocDate) = 'Wednesday' then DW_Count.WedCount
WHEN DATENAME(DW, T1.DocDate) = 'Thursday' then DW_Count.ThuCount
WHEN DATENAME(DW, T1.DocDate) = 'Friday' then DW_Count.FriCount
WHEN DATENAME(DW, T1.DocDate) = 'Saturday' then DW_Count.SatCount
WHEN DATENAME(DW, T1.DocDate) = 'Sunday' then DW_Count.SunCount) AS AvgValue
CASE
WHEN (DATENAME(DW, T1.DocDate)) = 'Monday'
AND T1.DocTime >= '700'
AND T1.DocTime <= '859' THEN '1 Monday 07:00-08:59'
FROM ORDR T1
INNER JOIN OCRD T0 ON T0.CardCode = T1.CardCode
CROSS JOIN (select sum(case when DATENAME(DW, DW_Count.DateValue) = 'Monday' then 1 else 0 end) as MonCount,
sum(case when DATENAME(DW, DW_Count.DateValue) = 'Tuesday' then 1 else 0 end) as TueCount,
sum(case when DATENAME(DW, DW_Count.DateValue) = 'Wednesday' then 1 else 0 end) as WedCount,
sum(case when DATENAME(DW, DW_Count.DateValue) = 'Thursday' then 1 else 0 end) as ThuCount,
sum(case when DATENAME(DW, DW_Count.DateValue) = 'Friday' then 1 else 0 end) as FriCount,
sum(case when DATENAME(DW, DW_Count.DateValue) = 'Saturday' then 1 else 0 end) as SatCount,
sum(case when DATENAME(DW, DW_Count.DateValue) = 'Sunday' then 1 else 0 end) as SunCount
from (select distinct DocDate from ORDR where (T1.DocDate >= #Start AND T1.DocDate <= #End))) AS DW_Count
WHERE (T1.DocDate >= #Start
AND T1.DocDate <= #End)
AND T0.QryGroup20 = 'Y'
AND T1.Canceled = 'N'
GROUP BY T1.DocTime,
T1.DocDate;
You can use the below logic-
For MSSQL
DECLARE #DT1 DATE = '20190802'
DECLARE #DT2 DATE = '20190820'
DECLARE #SatCount INT = 0
WHILE #DT1<= #DT2
BEGIN
SET #SatCount = #SatCount + CASE WHEN DATEPART(WeekDay,#DT1) = 7 THEN 1 ELSE 0 END
SET #DT1 = DATEADD(DD,1,#DT1)
END
SELECT #SatCount
Just one more option-
DECLARE #DT1 DATE = '20190802',
#DT2 DATE = '20190920';
SELECT SUM(CASE WHEN DATEPART(WeekDay,Date) = 7 THEN 1 ELSE 0 END)
FROM
(
SELECT TOP (DATEDIFF(DAY, #DT1, #DT2) + 1)
Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, #DT1)
FROM sys.all_objects a
-- A System table just used for creating multiple rows.
CROSS JOIN sys.all_objects b
-- CROSS JOIN will create number of row = original number of row X original number of row.
)A

SQL Server Store Procedure producing data related to months between two dates

I'm stuck on the following problem.
I have a start range date and end range date calculated by a query and I have three columns also produced by another query, the outcome of the last query is:
PRJ_ID | START_DATE | END_DATE
I want to produce an output using a store procedure that considering all the months between start range date and end range date produces an output like this:
PRJ_ID | MONTHS1 | MONTHS2 | ... | MONTHSN
XXXX | YES | YES | ... | NO
The yes or no is obtained checking if the current month is in between the start_date and end_date of the project (table obtained above).
I'm able to produce all the months between two dates with this code:
DECLARE #StartDate DATETIME,
#EndDate DATETIME;
SELECT #StartDate = '20110501'
,#EndDate = '20110801';
SELECT DATENAME(MONTH, DATEADD(MONTH, x.number, #StartDate)) AS MonthName
FROM master.dbo.spt_values x
WHERE x.type = 'P'
AND x.number <= DATEDIFF(MONTH, #StartDate, #EndDate);
But I'm stuck on producing the last result.
Do you mean something like this?
DECLARE #t TABLE(PRJ_ID INT, START_DATE DATE, END_DATE date)
INSERT INTO #t VALUES
(1, '20110501', '20110801'),
(2, '20110101', '20110901'),
(3, '20110301', '20110401')
;WITH cte1 AS(SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) m(m)),
cte2 AS(SELECT * FROM cte1 c1 JOIN #t t ON c1.m BETWEEN MONTH(t.START_DATE) AND MONTH(t.END_DATE))
SELECT PRJ_ID,
START_DATE,
END_DATE,
CASE WHEN [1] IS NOT NULL THEN 'YES' ELSE 'NO' END AS January,
CASE WHEN [2] IS NOT NULL THEN 'YES' ELSE 'NO' END AS February,
CASE WHEN [3] IS NOT NULL THEN 'YES' ELSE 'NO' END AS March,
CASE WHEN [4] IS NOT NULL THEN 'YES' ELSE 'NO' END AS April,
CASE WHEN [5] IS NOT NULL THEN 'YES' ELSE 'NO' END AS May,
CASE WHEN [6] IS NOT NULL THEN 'YES' ELSE 'NO' END AS June,
CASE WHEN [7] IS NOT NULL THEN 'YES' ELSE 'NO' END AS July,
CASE WHEN [8] IS NOT NULL THEN 'YES' ELSE 'NO' END AS August,
CASE WHEN [9] IS NOT NULL THEN 'YES' ELSE 'NO' END AS September,
CASE WHEN [10] IS NOT NULL THEN 'YES' ELSE 'NO' END AS October,
CASE WHEN [11] IS NOT NULL THEN 'YES' ELSE 'NO' END AS November,
CASE WHEN [12] IS NOT NULL THEN 'YES' ELSE 'NO' END AS December
FROM cte2
PIVOT (MAX(m) FOR m IN([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])) p
Output:
PRJ_ID START_DATE END_DATE January February March April May June July August September October November December
1 2011-05-01 2011-08-01 NO NO NO NO YES YES YES YES NO NO NO NO
2 2011-01-01 2011-09-01 YES YES YES YES YES YES YES YES YES NO NO NO
3 2011-03-01 2011-04-01 NO NO YES YES NO NO NO NO NO NO NO NO

Resources