Extract the percent days from a specific month - sql-server

I have a table like this one - changes table:
Table 1:
id start_date end_date s_g r_c s_c
111 1/1/15 25/5/2015 A1 1 0
111 26/05/2015 31/12/9999 Z1 1 2
222 1/1/14 10/2/2015 Q1 1 0
222 11/2/2015 31/12/9999 R1 1 0
And I need to build an montly output for 2015 like this:
id month s_g r_c _s_c percent
111 1 A1 1 0 100%
111 2 A1 1 0 100%
111 3 A1 1 0 100%
111 4 A1 1 0 100%
111 5 A1 1 0 83.33%
111 5 Z1 1 2 16.67%
111 6 Z1 1 2 100%
111 7 Z1 1 2 100%
111 8 Z1 1 2 100%
222 1 Q1 1 0 100%
222 2 Q1 1 0 35.71%
222 2 R1 1 0 64.29%
222 3 R1 1 0 100%
222 4 R1 1 0 100%
222 5 R1 1 0 100%
222 6 R1 1 0 100%
222 7 R1 1 0 100%
222 8 R1 1 0 100%
I need this month only for year 2015.
Any idea how can I build this thing? just assum that those are the only case.

You could try this.
DECLARE #Month_2015 TABLE
(
Date1 Date,
Date2 Date
)
INSERT INTO #Month_2015
select '2015-01-01','2015-01-31'
union all
select '2015-02-01','2015-02-28'
union all
select '2015-03-01','2015-03-31'
union all
select '2015-04-01','2015-04-30'
union all
select '2015-05-01','2015-05-31'
union all
select '2015-06-01','2015-06-30'
...
With CTE as
(
Select ID, date1, s_g, r_c, s_c,
le = case when start_date < Date2 AND End_date > DATE1 THEN Datediff(d,
(case when start_date < date1 THEN date1 else start_date end),
(case when end_date < date2 THEN end_date else date2 end)
Else 0
end,
m = DATEDIFF (d, date1, date2)
from
Table1, #Month_2015
)
Select ID, Month(date1), s_g, r_c, s_c, (le*100.0 / m)
from CTE
Where le > 0
order by ID, Month(date1), s_g, r_c, s_c

Try this. It worked for me based on your table ##
DECLARE #TableRezult TABLE (id INT,month INT,s_g varchar(2),r_c INT,s_c INT, MonthPercentage varchar(25))
DECLARE #month INT=1
WHILE #month<=12
BEGIN
INSERT INTO #TableRezult
SELECT id,#month,s_g,r_c,s_c,
CASE WHEN (end_date >= dateadd(m,1,convert(varchar,#month)+'/1/2015') OR end_date='12/31/2015')
AND ([START_DATE]<=convert(varchar,#month)+'/1/2015') THEN '100%' ELSE
CASE WHEN end_date >= convert(varchar,#month)+'/1/2015' AND end_date < dateadd(m,1,convert(varchar,#month)+'/1/2015') THEN convert(VARCHAR ,Day(end_date)*100.0/DAY(EOMONTH(start_date)))+'%'
WHEN start_date >= convert(varchar,#month)+'/1/2015' AND start_date < dateadd(m,1,convert(varchar,#month)+'/1/2015') THEN convert(varchar,(DAY(EOMONTH(start_date))-Day(start_date))*100.0/DAY(EOMONTH(start_date)))+'%'
ELSE '0%' END
END FROM Table1 WHERE MONTH([START_DATE])<=#month AND MONTH(end_date)>=#month
SET #month=#month+1
END
SELECT * FROM #TableRezult ORDER BY id,[MONTH]

since it is not fully explain,i am posting half solution,after clearing doubts calculation can be corrected.
declare #Table1 table (id int,start_date datetime,end_date datetime
, s_g varchar(20), r_c int, s_c int )
insert into #Table1 values
(111 ,'2015-01-01','2015-5-25','A1', 1, 0 )
,(111 ,'2015-05-26','9999-12-31','Z1', 1, 2 )
,(222 ,'2014-01-01','2015-02-10','Q1', 1, 0 )
,(222 ,'2015-02-11','9999-12-31','R1', 1, 0 )
DECLARE #year INT = 2015
;WITH CTE
AS (
SELECT id
,s_g
,r_c
,s_c
,CASE
WHEN datepart(year, start_date) = #year
THEN start_date
WHEN datepart(year, start_date) < #year
THEN CAST(#year AS CHAR(4)) + '-' + '01' + '-' + '01'
WHEN datepart(year, start_date) > #year
THEN CAST(#year AS CHAR(4)) + '-' + '12' + '-' + '31'
END startdate
,CASE
WHEN datepart(year, end_date) = #year
THEN end_date
WHEN datepart(year, end_date) < #year
THEN CAST(#year AS CHAR(4)) + '-' + '01' + '-' + '01'
WHEN datepart(year, end_date) > #year
THEN CAST(#year AS CHAR(4)) + '-' + '12' + '-' + '31'
END enddate
FROM #table1
)
,CTE1
AS (
SELECT A.id
,A.s_g
,A.r_c
,A.s_c
,A.startdate
,A.enddate
,DATEPART(month, A.startdate) MonthList
FROM CTE A
UNION ALL
SELECT A.id
,A.s_g
,A.r_c
,A.s_c
,dateadd(month, 1, A.startdate)
,A.enddate
,a.MonthList + 1
FROM CTE1 A
WHERE A.MonthList < DATEPART(month, a.enddate)
)
--select * from cte1
SELECT *
,CASE
WHEN datediff(month, startdate, enddate) >= 1
THEN 100
ELSE (datepart(day, enddate) / cast(datepart(day, dateadd(day, - 1, dateadd(month, (datediff(month, 0, enddate) + 1), 0))) AS DECIMAL(4, 2))) * 100
END
FROM cte1
ORDER BY id
,s_g
,monthlist

Related

How to derive new columns in YYYYMM format between two dates

I have following table
ID
Name
StartDate
EndDate
1
Aa
2021-10-14
2021-12-22
2
Ab
2021-12-02
2022-10-05
The requirement is to add new columns in YYYYMM format consisting of all the months between min(StartDate) and max(EndDate), and assign values to the corresponding cells. The cell value should be 1 if the date lies between StartDate and EndDate in that row, and should be 0 if it does not fall within that date range.The final output should be like in the below table
ID
Name
StartDate
EndDate
202110
202111
202112
202201
202202
202203
202204
202205
202206
202207
1
Aa
2021-10-14
2021-12-22
1
1
1
0
0
0
0
0
0
0
2
Ab
2021-12-02
2022-07-05
0
0
1
1
1
1
1
1
1
1
For the 1st row, since the startdate=2021-10-14 & EndDate=2021-12-22, corresponding new columns should be 202110,202111 & 202112; and corresponding cell values are 1 for these columns while the other cells are 0. Same logic should be applied to other rows as well.
I could not figure out the logic to derive new tables with new columns and corresponding cell values.
How about this approach using dynamic SQL:
CREATE TABLE Data ( ID INT, Name VARCHAR(100), StartDate DATE, EndDate DATE )
INSERT Data
VALUES
('1', 'Aa', '2021-10-14', '2021-12-22'),
('2', 'Ab', '2021-12-02', '2022-10-05')
-- Extract overall date range
DECLARE #MinStartDate DATE, #MaxEndDate AS DATE
SELECT #MinStartDate = MIN(StartDate), #MaxEndDate = MAX(EndDate)
FROM Data
-- Convert to months (DATETRUNC() may be used instead with SQL Server 2022 and later)
DECLARE #StartMonth DATE = DATEADD(day, 1 - DAY(#MinStartDate), #MinStartDate)
DECLARE #EndMonth DATE = DATEADD(day, 1 - DAY(#MaxEndDate), #MaxEndDate)
-- Generate calendar of months within range
DECLARE #Months TABLE ( Month DATE)
;WITH Months AS (
SELECT #StartMonth AS Month
UNION ALL
SELECT DATEADD(month, 1, M.Month)
FROM Months M
WHERE M.Month < #EndMonth
)
INSERT #Months
SELECT M.Month
FROM Months M
-- Define SQL Templates
DECLARE #SqlTemplate VARCHAR(MAX) = '
SELECT ID, Name, StartDate, EndDate
<ColumnSql>
FROM Data D
ORDER BY D.Name
'
DECLARE #ColumnTemplate VARCHAR(MAX) = '
, CASE WHEN D.StartDate <= <MonthEnd> AND <MonthStart> <= D.EndDate THEN 1 ELSE 0 END AS <ColumnName>'
-- Build month-specific column select items from template
DECLARE #ColumnSql VARCHAR(MAX) = (
SELECT STRING_AGG(C.ColumnSql, '') WITHIN GROUP(ORDER BY M.Month)
FROM #Months M
CROSS APPLY (
SELECT
CONVERT(CHAR(6), M.Month, 112) AS ColumnName,
M.Month AS MonthStart,
EOMONTH(M.Month) AS MonthEnd
) MD
CROSS APPLY (
SELECT REPLACE(REPLACE(REPLACE(
#ColumnTemplate
, '<ColumnName>', QUOTENAME(MD.ColumnName))
, '<MonthStart>', QUOTENAME(CONVERT(CHAR(8), MD.MonthStart, 112), ''''))
, '<MonthEnd>', QUOTENAME(CONVERT(CHAR(8), MD.MonthEnd, 112), ''''))
AS ColumnSql
) C
)
--SELECT #ColumnSql
-- Build final SQL
DECLARE #Sql VARCHAR(MAX) = REPLACE(#SqlTemplate, '<ColumnSql>', #ColumnSql)
SELECT #Sql
-- Deliver
EXEC (#Sql)
Generated SQL:
SELECT ID, Name, StartDate, EndDate
    , CASE WHEN D.StartDate <= '20211031' AND D.EndDate >= '20211001' THEN 1 ELSE 0 END AS [202110]
    , CASE WHEN D.StartDate <= '20211130' AND D.EndDate >= '20211101' THEN 1 ELSE 0 END AS [202111]
    , CASE WHEN D.StartDate <= '20211231' AND D.EndDate >= '20211201' THEN 1 ELSE 0 END AS [202112]
    , CASE WHEN D.StartDate <= '20220131' AND D.EndDate >= '20220101' THEN 1 ELSE 0 END AS [202201]
    , CASE WHEN D.StartDate <= '20220228' AND D.EndDate >= '20220201' THEN 1 ELSE 0 END AS [202202]
    , CASE WHEN D.StartDate <= '20220331' AND D.EndDate >= '20220301' THEN 1 ELSE 0 END AS [202203]
    , CASE WHEN D.StartDate <= '20220430' AND D.EndDate >= '20220401' THEN 1 ELSE 0 END AS [202204]
    , CASE WHEN D.StartDate <= '20220531' AND D.EndDate >= '20220501' THEN 1 ELSE 0 END AS [202205]
    , CASE WHEN D.StartDate <= '20220630' AND D.EndDate >= '20220601' THEN 1 ELSE 0 END AS [202206]
    , CASE WHEN D.StartDate <= '20220731' AND D.EndDate >= '20220701' THEN 1 ELSE 0 END AS [202207]
    , CASE WHEN D.StartDate <= '20220831' AND D.EndDate >= '20220801' THEN 1 ELSE 0 END AS [202208]
    , CASE WHEN D.StartDate <= '20220930' AND D.EndDate >= '20220901' THEN 1 ELSE 0 END AS [202209]
    , CASE WHEN D.StartDate <= '20221031' AND D.EndDate >= '20221001' THEN 1 ELSE 0 END AS [202210]
FROM Data D
ORDER BY D.Name
Results:
ID
Name
StartDate
EndDate
202110
202111
202112
202201
202202
202203
202204
202205
202206
202207
202208
202209
202210
1
Aa
2021-10-14
2021-12-22
1
1
1
0
0
0
0
0
0
0
0
0
0
2
Ab
2021-12-02
2022-10-05
0
0
1
1
1
1
1
1
1
1
1
1
1
See this db<>fiddle.
The above uses a standard test for date range overlap of "start1 <= end2 AND start2 <= end1", which assumes all dates are inclusive.

Return a row for each time increment if it does not exist

I have a query that returns the amount of jobs received per 15 minutes increments of everyday for a year. The problem is that it only returns data for each of the 15 minute increments if a job was received in that timeframe. The succinct version of the query is:
SELECT
DATEPART(MONTH, Datim) AS Month#,
DATEPART(DAY, Datim) AS Day#,
(DATEPART(HOUR, Datim) + 1) AS Hour#,
((DATEPART(MINUTE, Datim) / 15) + 1) AS Interval#,
COUNT(JobNumber) AS TotalJobs
FROM Table
WHERE (Datim >= '2020-01-01' AND Datim <= '2021-01-01')
GROUP BY
DATEPART(MONTH, Datim),
DATEPART(DAY, Datim),
(DATEPART(HOUR, Datim) + 1),
((DATEPART(MINUTE, Datim) / 15) + 1)
ORDER BY
DATEPART(MONTH, Datim),
(DATEPART(DAY, Datim) + 0),
(DATEPART(HOUR, Datim) + 1),
((DATEPART(MINUTE, Datim) / 15) + 1)
This is currently the output that is getting returned:
Month#
Day#
Hour#
Interval#
TotalJobs
1
1
1
3
123
1
1
2
4
456
1
1
4
1
789
I would like the data output to fill in a 0 for the TotalJobs field for each of the 15 minute increments as well as hours if they do not exist. The final output would look like this:
Month#
Day#
Hour#
Interval#
TotalJobs
1
1
1
1
0
1
1
1
2
0
1
1
1
3
123
1
1
1
4
0
1
1
2
1
0
1
1
2
2
0
1
1
2
3
0
1
1
2
4
456
1
1
3
1
0
1
1
3
2
0
1
1
3
3
0
1
1
3
4
0
1
1
4
1
789
1
1
4
2
0
1
1
4
3
0
1
1
4
4
0
Any ideas on what might be the best way to achieve this?
Possible solution with a tally table.
Sample data
Move your current query to a subquery or common table expression (CTE) so you can do a left join with it. Here, I just recreated the result rows from your current query.
create table AvailableData
(
Month int,
Day int,
Hour int,
Interval int,
TotalJobs int
);
insert into AvailableData (Month, Day, Hour, Interval, TotalJobs) values
(1, 1, 1, 3, 123),
(1, 1, 2, 4, 456),
(1, 1, 4, 1, 789);
Solution
Gives you the first two months of 2021. Update the CTE's Tally and Intervals to get more incremental numbers and more months.
with Tally (n) as
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n) -- 10^1 = 10
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n) -- 10^2 = 100
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n) -- 10^3 = 1000
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) d(n) -- 10^4 = 10000
),
Intervals as
(
select top (2*31*24*4) -- increase as required, max determined by Tally, example for 2 months
--t.n,
--dateadd(day, (t.n-1)/(24*4), '2021-01-01') as [Date],
datepart(month, dateadd(day, (t.n-1)/(24*4), '2021-01-01')) as [Month],
datepart(day, dateadd(day, (t.n-1)/(24*4), '2021-01-01')) as [Day],
(((t.n-1) % (24*4)))/4 +1 as [Hour],
( (t.n-1) % 4 ) +1 as [Interval]
from Tally t
)
select i.Month,
i.Day,
i.Hour,
i.Interval,
coalesce(ad.TotalJobs, 0) as TotalJobs
from Intervals i
left join AvailableData ad
on ad.Month = i.Month
and ad.Day = i.Day
and ad.Hour = i.Hour
and ad.Interval = i.Interval;
Fiddle with some intermediate results.
Full solution
Quick merge and edit for the full year of 2021. Not validated.
with Tally (n) as
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM ( VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n) -- 10^1 = 10
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n) -- 10^2 = 100
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n) -- 10^3 = 1000
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) d(n) -- 10^4 = 10000
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) e(n) -- 10^5 = 100000
),
Intervals as
(
select top (365*24*4) -- full year of 2021
datepart(month, dateadd(day, (t.n-1)/(24*4), '2021-01-01')) as [Month],
datepart(day, dateadd(day, (t.n-1)/(24*4), '2021-01-01')) as [Day],
(((t.n-1) % (24*4)))/4 +1 as [Hour],
( (t.n-1) % 4 ) +1 as [Interval]
from Tally t
),
AvailableData as
(
SELECT
DATEPART(MONTH, Datim) AS [Month],
DATEPART(DAY, Datim) AS [Day],
(DATEPART(HOUR, Datim) + 1) AS [Hour],
((DATEPART(MINUTE, Datim) / 15) + 1) AS [Interval],
COUNT(JobNumber) AS TotalJobs
FROM Table
WHERE (Datim >= '2020-01-01' AND Datim <= '2021-01-01')
GROUP BY
DATEPART(MONTH, Datim),
DATEPART(DAY, Datim),
(DATEPART(HOUR, Datim) + 1),
((DATEPART(MINUTE, Datim) / 15) + 1)
)
select i.Month,
i.Day,
i.Hour,
i.Interval,
coalesce(ad.TotalJobs, 0) as TotalJobs
from Intervals i
left join AvailableData ad
on ad.Month = i.Month
and ad.Day = i.Day
and ad.Hour = i.Hour
and ad.Interval = i.Interval
order by i.Month,
i.Day,
i.Hour,
i.Interval;

SQLSERVER 2008: Breaking a output for the entire day into 2 records for 12 hours

I am looking for the count of records as below.
PLANNED_SHIP_From_Date PLANNED_SHIP_To Date Total_Lines_Count ....
1) 09-04-2016 07:00:01 09-04-2016 18:59:59 165 .....
2) 09-04-2016 19:00:00 10-04-2016 07:00:00 121 .....
3) 10-04-2016 07:00:01 10-04-2016 18:59:59 165 .....
4) 10-04-2016 19:00:00 11-04-2016 07:00:00 123 .....
5) 11-04-2016 07:00:01 11-04-2016 18:59:59 234 .....
.
Currently my query is counting the records as per date.
SELECT
cast(shdr.PLANNED_SHIP_DATE as date),
SUM(sdtl_1_1.TOTAL_LINES_COUNT) AS TOTAL_LINES_COUNT
FROM
dbo.SHIPMENT_HEADER AS shdr WITH (NOLOCK)
INNER JOIN
(
SELECT
SHIPMENT_ID,
COUNT(*) AS TOTAL_LINES_COUNT
FROM
dbo.SHIPMENT_DETAIL AS SHIPMENT_DETAIL_1 WITH (NOLOCK)
WHERE
(
STATUS1 >= 401
)
AND (
DATEDIFF(day, PLANNED_SHIP_DATE, CONVERT(date, SYSDATETIME())) < 4
)
GROUP BY
SHIPMENT_ID
) AS sdtl_1_1
ON sdtl_1_1.SHIPMENT_ID = shdr.SHIPMENT_ID
WHERE
(
shdr.TRAILING_STS >= 401
)
AND (
DATEDIFF(day, shdr.PLANNED_SHIP_DATE, CONVERT(date, SYSDATETIME())) < 4
)
GROUP BY
cast(shdr.PLANNED_SHIP_DATE as date)
Try this -
DECLARE #ReportDays int = 30,
#StartHr int = 7,
#Today DATETIME2 = CAST(SYSDATETIME() AS DATE);
--http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/you-require-a-numbers-table.aspx
WITH
a AS (SELECT 1 AS i UNION ALL SELECT 1),
b AS (SELECT 1 AS i FROM a AS x, a AS y),
c AS (SELECT 1 AS i FROM b AS x, b AS y),
d AS (SELECT 1 AS i FROM c AS x, c AS y),
e AS (SELECT 1 AS i FROM d AS x, d AS y),
numbers as (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1 AS number FROM e),
StartDates AS (
SELECT
DATEADD(
HH,
#StartHr + (n2.number * 12),
DATEADD(D, 0-n1.number, #Today)
) AS StartDT
FROM
(SELECT * FROM numbers WHERE Number BETWEEN 0 AND #ReportDays) n1
CROSS JOIN (SELECT * FROM numbers WHERE Number IN (0,1)) n2
),
DateRanges AS
(SELECT StartDT, DATEADD(hh, 12, StartDT) AS EndDT FROM StartDates),
Shipments AS
(SELECT
StartDT AS PLANNED_SHIP_From_Date,
EndDT AS PLANNED_SHIP_To_Date,
1 AS Shipment
FROM
DateRanges dr
LEFT JOIN dbo.SHIPMENT_DETAIL sd
ON sd.Status1 >=401
AND sd.PLANNED_SHIP_DATE BETWEEN dr.StartDT AND dr.EndDT)
SELECT
PLANNED_SHIP_From_Date,
PLANNED_SHIP_To_Date,
SUM(Shipment) AS TOTAL_LINES_COUNT
FROM
Shipments
ORDER BY
PLANNED_SHIP_From_Date;
What we're doing is -
Building a numbers table
Using that to pull a list of days, with two records per day
Working out the start & finish times for each time window
Joining the time windows to the records and summing
Hope that helps :-)
Add another column to your select....
CASE
WHENE DATEPART(HOUR, Planned_SHIP_DATE) < 12 THEN 'AM' ELSE 'PM'
END AS ShipPeriod
You could then add that column into a GROUPING to seperate the 'AM's from 'PM's
Of course I have assuumed you wanted AM/PM. But you can modify the CASE statement to break the hours up as you see fit.
Hope this helps
Thank you all for helping me out.
I have created a SQL query which worked for me. This query gives the count of records from morning 7 AM to 7 PM as MORNING_SHIFT count and 7PM to next day 7AM morning as EVENING_SHIFT for dates greater than 14 days in the past.
SELECT
CASE
WHEN convert(VARCHAR(50), sh.PLANNED_SHIP_DATE, 120) BETWEEN
(convert(VARCHAR(10), sh.PLANNED_SHIP_DATE, 120) + ' 07:00:00') AND
(convert(VARCHAR(10), sh.PLANNED_SHIP_DATE, 120) + ' 18:59:59')
THEN (CONCAT(cast(sh.PLANNED_SHIP_DATE as date),' ','morning_shift'))
WHEN convert(VARCHAR(50), sh.PLANNED_SHIP_DATE, 120) BETWEEN
(convert(VARCHAR(10), sh.PLANNED_SHIP_DATE, 120) + ' 00:00:00') AND
(convert(VARCHAR(10), sh.PLANNED_SHIP_DATE, 120) + ' 06:59:59')
then (CONCAT(cast(DATEADD(DAY, -1, sh.PLANNED_SHIP_DATE) as date),' ','EVENING_shift'))
when
convert(VARCHAR(50), DATEADD(DAY, -1, sh.PLANNED_SHIP_DATE) , 120) BETWEEN (convert(VARCHAR(10), cast(DATEADD(DAY, -1, sh.PLANNED_SHIP_DATE) as date), 120) + ' 19:00:00') AND
(convert(VARCHAR(10), cast(DATEADD(DAY, -1, sh.PLANNED_SHIP_DATE) as date), 120) + ' 23:59:59')
THEN (CONCAT(cast(DATEADD(DAY, -1, sh.PLANNED_SHIP_DATE) as date),' ','EVENING_shift'))
END AS 'actual_date_time', sh.PLANNED_SHIP_DATE
FROM dbo.SHIPMENT_HEADER AS sh WITH (nolock)
WHERE (shdr.TRAILING_STS >= 401) AND (DATEDIFF(day, shdr.ACTUAL_SHIP_DATE_TIME, CONVERT(date, SYSDATETIME())) < 14)
group by sh.ACTUAL_SHIP_DATE_TIME;

How to display all the days of a month in SQL Server 2008?

I have written a query like
SELECT
Sum(a.in_total) as Totall,
DATEPART(dd, a.in_date_issued) as dateissued
FROM
dbo.IN_Invoices as a
WHERE
DATEPART(mm, a.in_date_issued) = 5
AND DATEPART(yyyy, a.in_date_issued)= 2015
AND a.sy_id='DPI'
AND EXISTS(SELECT DISTINCT cl_id as clid
FROM dbo.cloi_clientorderitems as c
WHERE c.masterorderid=a.masterorderid)
--AND c.cl_id NOT IN ('100001_DPO'))
GROUP BY
DATEPART(dd, a.in_date_issued)
ORDER BY dateissued ASC
This query will written the out put like
Total| day
100 | 1
0 | 3
150 | 10
-
-
200 | 31
Expected output
Total| day
100 | 1
150 | 2
0 | 3
600 | 4
-
-
200 | 31
Please help me in that query.
You can try something like this:
DECLARE #y INT;
DECLARE #m INT;
SET #y = 2015;
SET #m = 5;
WITH
m AS(SELECT 1 AS d UNION ALL SELECT d+1 FROM m WHERE d < datediff(d, DATEADD(mm, #m - 1, CAST(#y AS VARCHAR(8)) + '0101'), dateadd(m, 1, DATEADD(mm, #m - 1, CAST(#y AS VARCHAR(8)) + '0101'))))
SELECT isnull(Totall, 0) AS Totall, m.d AS dateissued
FROM m
LEFT JOIN(
SELECT SUM(a.in_total) AS Totall ,
DATEPART(dd, a.in_date_issued) AS dateissued
FROM dbo.IN_Invoices AS a
WHERE DATEPART(mm, a.in_date_issued) = #m
AND DATEPART(yyyy, a.in_date_issued) = #y
AND a.sy_id = 'DPI'
AND EXISTS ( SELECT DISTINCT
cl_id AS clid
FROM dbo.cloi_clientorderitems AS c
WHERE c.masterorderid = a.masterorderid )
--and c.cl_id not in ('100001_DPO'))
GROUP BY DATEPART(dd, a.in_date_issued)
)t ON m.d = t.dateissued
ORDER BY m.d ASC

How to make Query for that

I have a table structure from there i have to make a query in some different way
Table Structure
id unique identifier
code varchar(5) Not Null
Recording_date Datetime Not Null
Max_Temp numeric(5,2) Not Null
Min_Temp numeric(5,2) Not Null
We have some data as well in this table.We have data only for 2013 year and for first 3 months.
But the main thing is that i have to return's data in such a format like
Please help me to create a query for such a logic.
Thanks in advance.
Presuming you have one recording per day then
SELECT
DATEPART(m, Month_Start) + ' ' + DATEPART(yyyy, Month_Start)
, Max_Temp_Days
, CASE
WHEN Denominator = 0 THEN 0
ELSE (Max_Temp_Days / Denominator) * 100
END AS Percent_Max_Temp_Days
, Min_Temp_Days
, CASE
WHEN Denominator = 0 THEN 0
ELSE (Min_Temp_Days / Denominator) * 100
END AS Percent_Max_Temp_Days
FROM (
SELECT
DATEADD(MONTH, DATEDIFF(MONTH, 0, Recording_Date), 0) Month_Start
, Sum(CASE WHEN Max_Temp <= 0 THEN 1 END) Max_Temp_Days
, Sum(CASE WHEN Min_Temp <= 0 THEN 1 END) Min_Temp_Days
, COUNT(*) Denominator
FROM TemperatureRecordings
WHERE Recording_Date BETWEEN '2013-01-01' AND '2013-03-31'
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Recording_Date), 0)
) t
ORDER BY Month_Start
This works for all month data
DECLARE #maxTempratureTable table(monthName varchar(20), [No. of days Max<=0] int,[Percentage Max <=0] float)
INSERT INTO maxTempratureTable
SELECT RIGHT(CONVERT(VARCHAR, Recording_date, 106), 8) ,
COUNT(*) ,
COUNT(*) / DAY(DATEADD(mm,DATEDIFF(mm,-1,Recording_date),-1)) * 100
FROM tablename
WHERE Max_Temp <=0
GROUP BY RIGHT(CONVERT(VARCHAR, Recording_date, 106), 8)
DECLARE #minTempratureTable table(monthName varchar(20), [No. of days Min<=0] int,[Percentage Min<=0] float)
INSERT INTO #minTempratureTable
SELECT RIGHT(CONVERT(VARCHAR, Recording_date, 106), 8) ,
COUNT(*) ,
COUNT(*) / DAY(DATEADD(mm,DATEDIFF(mm,-1,Recording_date),-1)) * 100
FROM tablename
WHERE Min_Temp <=0
GROUP BY RIGHT(CONVERT(VARCHAR, Recording_date, 106), 8)
SELECT * FROM #minTempratureTable min
INNER JOIN #maxTempratureTable max
ON min.monthName = max.monthName
SELECT
MONTH(Recording_date),
SUM(CASE WHEN Max_Temp <= 0 THEN 1 ELSE 0 END),
SUM(CASE WHEN Max_Temp <= 0 THEN 1 ELSE 0 END) / COUNT(*),
SUM( CASE WHEN Min_Temp <= 0 THEN 1 ELSE 0 END ),
SUM( CASE WHEN Min_Temp <= 0 THEN 1 ELSE 0 END ) / COUNT(*)
FROM temperatures
GROUP BY MONTH(Recording_date)

Resources