Transform multiple queries into single row - sql

I have a report that I would like to base on a single SQL statement. The problem is the data is based on several SQL statements. For example.
SELECT COUNT(*) as 'Cases Opened'
FROM tblCases
WHERE DateAssigned BETWEEN #StartDate AND #EndDate
SELECT COUNT(*) as 'Cases Closed'
FROM tblCases
WHERE ClosedDate BETWEEN #StartDate AND #EndDate
SELECT COUNT(*) as 'Tickets Issued'
FROM tblTicket
WHERE DateIssued BETWEEN #StartDate AND #EndDate
SELECT COUNT(*) as 'Warnings Issued'
FROM tblWarning
WHERE DateIssued BETWEEN #StartDate AND #EndDate
Is there a way to turn these four seperate SQL statements into a single SQL statement such that each result is listed as a column? For example ..
Cases Opened Cases Closed Tickets Issued Warnings Issued
******************************************************************************
256 | 165 | 56 | 165
EDIT I am using SQL Server and no there is no relationship between the tables.

select
(
SELECT COUNT(*)
FROM tblCases
WHERE DateAssigned BETWEEN #StartDate AND #EndDate
) as 'Cases Opened' ,
(SELECT COUNT(*)
FROM tblCases
WHERE ClosedDate BETWEEN #StartDate AND #EndDate
) as 'Cases Closed' ,
(SELECT COUNT(*)
FROM tblTicket
WHERE DateIssued BETWEEN #StartDate AND #EndDate
) as 'Tickets Issued' ,
(SELECT COUNT(*)
FROM tblWarning
WHERE DateIssued BETWEEN #StartDate AND #EndDate
) as 'Warnings Issued'
from dual
from dual would be necessary in oracle, mysql supports it but is not necessary and I'm not sure about sqlserver since I don't have one in front of me.

You could union and pivot the data, like so:
SELECT SUM(CASE WHEN FieldName='Cases Opened' THEN Value ELSE 0 END) AS Cases_Opened,
SUM(CASE WHEN FieldName='Cases Closed' THEN Value ELSE 0 END AS Cases_Closed,
SUM(CASE WHEN FieldName='Warning Issued' THEN Value ELSE 0 END) AS Warnings_Issued,
SUM(CASE WHEN FieldName='Tickets Issued' THEN Value ELSE 0 END) AS Tickets_Issued
FROM
(
SELECT COUNT(*) as Value, 'Cases Opened' as FieldName
FROM tblCases
WHERE DateAssigned BETWEEN #StartDate AND #EndDate
UNION
SELECT COUNT(*) as Value, 'Cases Closed' as FieldName
FROM tblCases
WHERE ClosedDate BETWEEN #StartDate AND #EndDate
UNION
SELECT COUNT(*) as Value, 'Tickets Issued' as FieldName
FROM tblTicket
WHERE DateIssued BETWEEN #StartDate AND #EndDate
UNION
SELECT COUNT(*) as Value, 'Warnings Issued' as FieldName
FROM tblWarning
WHERE DateIssued BETWEEN #StartDate AND #EndDate
)

Check out the pivot statement if you are running in SQLServer

Related

Add a date range to SQL query

I have simple SQL Server view that I need to make amends to:
CREATE VIEW [dbo].[ApplicantStat]
AS SELECT ISNULL(CONVERT(VARCHAR(50), NEWID()), '') AS Pkid,
AVG(ApplicationTime) AS 'AvgApplicationTime',
AVG(ResponseTime) AS 'AvgResponseTime',
CAST(ROUND(100.0 * count(case when [IsAccepted] = 1 then 1 end) / count(case when [IsValid] = 1 then 1 end), 0) AS int) AS 'AcceptRate'
FROM [Application]
It works as planned, but I need to add a date range to it. It's not quite as simple as Where > this date and < that date, instead I need to create a range.
Suppose I have a 'CreatedOn' date in my Application table. I want to be able to include all rows from the last full day (yesterday) and work back 30 days (inclusive).
I'm using SQL Server 2014.
Use :
where CreatedOn between cast(getdate()-30 as date) and cast(getdate()-1 as date)
Please notice CAST is used, it is because to get the full day ignoring the time part.
Something like this:
where MyColumn between dateadd(dd, -1, convert(date, getdate())) and dateadd(dd, -30, convert(date, getdate()))
It's a bit beyond the scope of this question, but maybe useful to some. I like this way of creating a table with date range, to use in queries:
USE MyDataBase
DECLARE #StartDate DATE
DECLARE #EndDate DATE
SET #StartDate = '2014-01-01' -- << user input >> --
SET #EndDate = '2036-12-31' -- << user input >> --
IF OBJECT_ID ('TEMPDB..#Date') IS NOT NULL DROP TABLE #Date
IF OBJECT_ID ('TEMPDB..#Date') IS NULL CREATE TABLE #Date (DateOne DATE)
INSERT INTO #Date VALUES (#StartDate)
WHILE #StartDate < #EndDate
BEGIN
INSERT INTO #Date
SELECT DATEADD (DD, 1, #StartDate) AS Date
SET #StartDate = DATEADD (DD, 1, #StartDate)
END
SELECT * FROM #Date
You should be able to just stick a WHERE with a BETWEEN clause on the end.
CREATE VIEW [dbo].[ApplicantStat]
AS SELECT ISNULL(CONVERT(VARCHAR(50), NEWID()), '') AS Pkid,
AVG(ApplicationTime) AS 'AvgApplicationTime',
AVG(ResponseTime) AS 'AvgResponseTime',
CAST(ROUND(100.0 * count(case when [IsAccepted] = 1 then 1 end) / count(case when [IsValid] = 1 then 1 end), 0) AS int) AS 'AcceptRate'
FROM [Application]
WHERE CreatedOn BETWEEN GETDATE()-1 AND GETDATE()-30

SQL Show all items that are on hire before and up until a certain date

I have a table with a number of tools an on-hire date and an off-hire date.
I want to show all tools that are on hire in a given month.
eg.
tool on_hire off_hire
tool 1 02/01/2016 15/01/2016
tool 2 16/12/2015 16/01/2016
tool 3 05/01/2016 20/02/2016
I have a variable set #startdate = 20160101 and #enddate = 20160131
It is possible to get everything that started in JAN with a WHERE but I need to capture tool 2 also which started in DEC but ended in JAN
Any ideas?
Help is much appreciated, cheers
Takes me back, but this is what you want to show EVERYTHING on hire in the period, including non-returned items
select *
from MyTable
where on_hire < #EndDate
and (off_hire >= #StartDate or off_hire is null)
For the follow up, total number of days for each tool
with CTE as
(
select *
from MyTable
where on_hire < #EndDate
and (off_hire >= #StartDate or off_hire is null)
)
select Tool,
sum(datediff(dd,
case
when off_hire > #EndDate then #EndDate
when off_hire is null then #EndDate
else off_hire
end,
case
when on_hire < #StartDate then #StartDate
else on_hire
end)) as DaysOnHire
from CTE
froup by Tool
Try like this
SELECT * FROM TABLE1
WHERE on_hire BETWEEN #startdate AND #enddate
OR off_hire BETWEEN #startdate AND #enddate
Try this query
create table #yourtable (tools varchar(50),on_hire datetime,off_hire datetime)
insert into #yourtable
select 'tool1' ,'2016-01-02' ,'2016-01-15'
union all
select 'tool2' , '2015-12-16' ,'2016-01-16'
union all
select 'tool3' , '2016-01-05', '2016-02-20'
select * from #yourtable
where datepart(mm,on_hire)='01' and tools<>'tool2'
union all
select * from #yourtable
where datepart(mm,on_hire)='12' and datepart(mm,off_hire)='01' and tools='tool2'
Two lines x1-x2 and y1-y2(date ranges etc) intersect when:
x1 <= y2 and y1 <= x2
So:
select * from table
where on_hire <= #enddate and #startdate <= off_hire
It should be three options:
1. |______| --hire time
s|—————|e
2. |______| --hire time
s|—————|e
3. |______|--hire time
s|—————————————|e
4. |______|--hire time
s|———|e --included in 2 and 3
DECLARE #startdate date = '01/01/2016', #enddate DATE = '01/31/2016'
;WITH tb(tool,on_hire,off_hire)AS(
SELECT 'tool 1','01/02/2016','01/15/2016' UNION
SELECT 'tool 2','12/16/2015','01/16/2016' UNION
SELECT 'tool 3','01/05/2016','02/20/2016'
)
SELECT * FROM tb
WHERE
DATEDIFF(d,tb.on_hire,#startdate)>0 AND DATEDIFF(d,#startdate,tb.off_hire)>0
OR DATEDIFF(d,tb.on_hire,#enddate)>0 AND DATEDIFF(d,#enddate,tb.off_hire)>0
OR DATEDIFF(d,tb.on_hire,#startdate)>0 AND DATEDIFF(d,tb.off_hire,#enddate)>0

RUN Query based on a given condition

Hi Guys i want to run this query based on condition following condition. if parameter date is less than 01/01/16 it should run the first CTE else the 2nd CTE thanks
DECLARE #Date AS DATET
SET #Date = '2015-10-31'
;WITH OLDVTE AS (SELECT
SalesID,
City,
Amount,
SalesDate
FROM INFO.SALESOLD
),
NEWVTE AS (
SalesID,
City,
Amount,
SalesDate
FROM INFO.SALESNEW
)
SELECT
CASE WHEN GETDATE() <= #Date THEN
(SELECT * FROM OLDVTE)
ELSE
(SELECT * FROM NEWVTE)
END AS DD
You might try something like this:
DECLARE #Date AS DATE = {d'2015-10-31'}
DECLARE #CurrentDateTime DATETIME = GETDATE();
SELECT
SalesID,
City,
Amount,
SalesDate
FROM INFO.SALESOLD
WHERE #CurrentDateTime <= #Date
UNION ALL
SELECT
SalesID,
City,
Amount,
SalesDate
FROM INFO.SALESNEW
WHERE #CurrentDateTime > #Date
The UNION ALL will return both results in one. But there will be only one of the selects returning rows actually...
Hint
I actually doubt, that your filter against GETDATE() would work as you expect it...
You could try with IF ELSE like below..
DECLARE #Date AS DATETIME
SET #Date = '2015-10-31'
If GETDATE() <= #Date--will this clause work..
select * FROM INFO.SALESOLD
Else
select * FROM INFO.SALEnew
You could also join the two tables if they contain any common field and pass date

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

SQL query to find available future dates except weekends

I have table called "detail" where i am storing start date and end date of jobs.I have one more table called "leaves" which is also have leave startdate and leave enddate fields.I need to find the nearest available dates of a user without weekends and leave dates.
DECLARE #PackagerLastAssignedDate DATETIME
SELECT #PackagerLastAssignedDate = MAX(EndDate) FROM detail WHERE userId = 1
SELECT lveStartDate,lveEndDate FROM Leaves WHERE UserId = 1 and lveStartDate > #PackagerLastAssignedDate
Thanks In advance
Berlin.M
Try this one -
DECLARE
#DateFrom DATETIME
, #DateTo DATETIME
SELECT
#DateFrom = '20130101'
, #DateTo = '20130202'
SELECT [Date]
FROM (
SELECT [Date] = DATEADD(DAY, sv.number, t.DateFrom)
FROM (
SELECT
DateFrom = #DateFrom
, diff = DATEDIFF(DAY, #DateFrom, #DateTo)
) t
JOIN [master].dbo.spt_values sv ON sv.number <= diff
WHERE sv.[type] = 'p'
) t2
WHERE DATENAME(WEEKDAY, [Date]) NOT IN ('Saturday', 'Sunday')
AND NOT EXISTS (
SELECT 1
FROM dbo.Leaves l
WHERE l.UserId = 1
AND t2.[Date] BETWEEN l.lveStartDate AND l.lveEndDate
)