How can I control several columns at the same time? - sql-server

I have the following table and I want to control the selection with the DATE_FORM variable.
Why does my T-SQL code not work? Does someone have an idea?
Table1
-- #DATE_FORM = 1 select a particular INFO-DATE INTERVALL
-- #DATE_FORM = 2 select a particular ORDER-DATE INTERVALL
-- #DATE_FORM = 3 select a particular SHIPPING INTERVALL
DECLARE #DATE_FORM int = 3,
#FROM smalldatetime = '2022-10-05 00:00:00',
#UNTIL smalldatetime = '2022-10-06 00:00:00';
SELECT *
FROM [AdventureWorksDW2019].[dbo].[Table_2]
WHERE 1 = 1
AND (CASE WHEN #DATE_FORM = 1 THEN INFO_DATE
WHEN #DATE_FORM = 2 THEN ORDER_DATE END) BETWEEN #FROM AND #UNTIL
AND ((CASE WHEN #DATE_FORM = 3 THEN SHIPPING_DATE_START END) BETWEEN #FROM AND #UNTIL
AND (CASE WHEN #DATE_FORM = 3 THEN SHIPPING_DATE_END END) BETWEEN #FROM AND #UNTIL)

It doesn't work because your cases doesn't allow your conditions to ever be met.
For instance, let's say #Date_Form = 3, what will happen to this condition?:
(CASE WHEN #DATE_FORM = 1 THEN INFO_DATE
WHEN #DATE_FORM = 2 THEN ORDER_DATE
END) between #FROM and #UNTIL
Since #DATE_FORM = 3 is not handled in the Case it would bascially result in:
null between #From AND #UNTIL
which will result in false..
I would (for simplicity) remove the cases completely:
SELECT *
FROM [AdventureWorksDW2019].[dbo].[Table_2]
WHERE (#DATE_FORM = 1
AND INFO_DATE BETWEEN #FROM AND #UNTIL)
OR (#DATE_FORM = 2
AND ORDER_DATE BETWEEN #FROM AND #UNTIL)
OR (#DATE_FORM = 3
AND SHIPPING_DATE_START BETWEEN #FROM AND #UNTIL
AND SHIPPING_DATE_END BETWEEN #FROM AND #UNTIL)

The first condition:
AND (CASE WHEN #DATE_FORM = 1 THEN INFO_DATE WHEN #DATE_FORM = 2 THEN ORDER_DATE END) between #FROM and #UNTIL`
When #DATE_FORM is 3 that will just be AND NULL between #FROM and #UNTIL which will always be FALSE.
Since that is always FALSE when #Date_Form = 3 then you likely want to switch your AND to an OR:
SELECT *
FROM [AdventureWorksDW2019].[dbo].[Table_2]
WHERE
(CASE WHEN #DATE_FORM = 1 THEN INFO_DATE
WHEN #DATE_FORM = 2 THEN ORDER_DATE END) between #FROM and #UNTIL
OR (
(CASE WHEN #DATE_FORM = 3 THEN SHIPPING_DATE_START END) between #FROM and #UNTIL
AND (CASE WHEN #DATE_FORM = 3 THEN SHIPPING_DATE_END END) between #FROM and #UNTIL
)

Related

Need Help on SQL Query - incorporating AVG

[Edit from #marcus-vinicius-pompeu: I rewrote the query for better identation. To bypass 'mostly code' constraint, I changed the original group by logic]
I am totally stuck while writing a query. Required output is attached. Query I have written is as below. it is working fine till column SL_30_Sec. How to add two columns ASA & AHT based on average values of each date
SELECT
Date(t.call_date) as created_date,
--
Sum(CASE WHEN t.table_name = 'one' THEN 1 ELSE 0 END) AS Offered_Calls,
Sum(CASE WHEN t.table_name = 'two' THEN 1 ELSE 0 END) AS Answered_Calls,
--
Concat(
Round(
(
Sum(CASE WHEN t.table_name = 'two' THEN 1 ELSE 0 END) /
Sum(CASE WHEN t.table_name = 'one' THEN 1 ELSE 0 END) * 100
), 2
), '%'
) AS Success_Rate,
--
Sum(CASE WHEN t.table_name = 'three' THEN 1 ELSE 0 END) AS OB_Calls,
Sum(CASE WHEN t.table_name = 'four' THEN 1 ELSE 0 END) AS OB_Calls_Received,
Sum(CASE WHEN t.table_name = 'five' THEN 1 ELSE 0 END) AS Calls_ANS_in_30_Sec,
--
Concat(
Round(
(
Sum(CASE WHEN t.table_name = 'five' THEN 1 ELSE 0 END) /
Sum(CASE WHEN t.table_name = 'one' THEN 1 ELSE 0 END) * 100
), 2
), '%'
) AS SL_30_Sec
FROM
(
SELECT call_date, 'one' AS table_name FROM table_1
WHERE call_date BETWEEN '2020-01-01' AND '2020-01-31 23:59' AND campaign_id = 'abc_inbound'
-- -----
UNION ALL
-- -----
SELECT call_date, 'two' AS table_name FROM table_1
WHERE call_date BETWEEN '2020-01-01' AND '2020-01-31 23:59' AND campaign_id = 'abc_inbound' AND term_reason IN('agent', 'caller')
-- -----
UNION ALL
-- -----
SELECT call_date, 'three' AS table_name FROM table_2
WHERE call_date BETWEEN '2020-01-01' AND '2020-01-31 23:59' AND campaign_id = 'xyz'
-- -----
UNION ALL
-- -----
SELECT call_date, 'four' AS table_name FROM table_2
WHERE call_date BETWEEN '2020-01-01' AND '2020-01-31 23:59' AND campaign_id = 'xyz' AND term_reason IN('agent', 'caller')
-- -----
UNION ALL
-- -----
SELECT call_date, 'five' AS table_name FROM table_1
WHERE call_date BETWEEN '2020-01-01' AND '2020-01-31 23:59' AND campaign_id = 'abc_inbound' AND term_reason IN('agent', 'caller', 'ABANDON') AND queue_seconds <= 30
) t
GROUP BY Date(t.call_date)
Required Output
You cannot, given the dataset...
Table_1 = date of offered calls
Table_2 = date of answered calls
Table_3 = date of outbound calls
Table_4 = date of offered outbound calls
Table_5 = date of answered outbound calls in less than 30 seconds
To compute:
ASA - you have to have the time of answer time (you should have, since the data allows for filtering those answered in 30 seconds or below)
AHT - you have to have answer time and talk & wrap time
For not outbound calls it seems we already have answer time from table_1.queue_seconds...
Links for definitions:
https://www.genroe.com/resources/glossary/call-centre-definitions-and-glossary
https://www.callcentrehelper.com/how-to-measure-average-handling-time-52403.htm
You can try this.
SELECT ((SUM(ASA) +SUM(AHT))/count(*))
FROM tableName
GROUP BY date

When I SUM values of each month between 2 dates, I get the wrong value

I am really struggling with a query. I want the sum of each month between Aug 2014 and July 2015. If I specify the between dates in the where clause it sums all the months.
Here is my query:
DECLARE #CurrentYear int = DATEpart(year,getdate())
DECLARE #PreviousYear int = DATEpart(year,getdate()) -1
SELECT
SUM(CASE WHEN a.fin_period = concat(#PreviousYear,'08') THEN a.balance ELSE 0 END) AS BalanceAug ,
SUM(CASE WHEN a.fin_period = concat(#PreviousYear,'09') THEN a.balance ELSE 0 END) AS BalanceSep ,
SUM(CASE WHEN a.fin_period = concat(#PreviousYear,'10') THEN a.balance ELSE 0 END) AS BalanceOct ,
SUM(CASE WHEN a.fin_period = concat(#PreviousYear,'11') THEN a.balance ELSE 0 END) AS BalanceNov ,
SUM(CASE WHEN a.fin_period = concat(#PreviousYear,'12') THEN a.balance ELSE 0 END) AS BalanceDec ,
...etc.
FROM subaccount_history a with (nolock)
WHERE fin_period between concat(#PreviousYear,'08') and concat(#CurrentYear,'12')
The issue is with the between clause, i tried group by but that also doesn't work. It sums everything between the 2 dates specified.

Syntax error in EXEC(#sql) in stored procedure

I'm coding a sp to use in an asp.net page which displays a gridview (with multiple pages) and checkboxes for the select query. However it gives me syntax error on the EXEC(#sql), can't I call it within the if after using the WITH...AS ?
SET #sql=#sql +' ' +' FROM DATASET WHERE (RowId BETWEEN (#page - 1) * #pageSize AND (#page) * #pageSize)
OR (#page IS NULL)'
if #filter='pt'
BEGIN
WITH DataSet AS
(
SELECT TOP 100 PERCENT
row_number() over(order by date desc) as 'RowId'
, convert(varchar(10), date 105) AS 'date'
, product1
, product2
, product3
, product4
, Y
, N
FROM (select date
, count(case when product='product1' then 1 else null end) as 'product1'
, count(case when product='product2' then 1 else null end) as 'product1'
, count(case when product='product3' then 1 else null end) as 'product1'
, count(case when onsale='Y' then 1 else null end) as 'Y'
, count(case when onsale='N' then 1 else null end) as 'N'
from dbo.vwSales
group by date) as o
WHERE
(date BETWEEN #from AND #to)
)
EXEC (#sql)
END
You have to have the whole SQL in the variable for the Exec -command, starting with the "with ...".
Unless there is something we're not seeing here, there is no reason to execute dynamic SQL here. Writing dynamic SQL and executing it with EXEC is generally an anti-pattern, as it opens you up to the possibility of writing some inefficient code with security problems.
Can you just run...
WITH DataSet AS
(
SELECT TOP 100 PERCENT
row_number() over(order by date desc) as 'RowId'
, convert(varchar(10), date 105) AS 'date'
, product1
, product2
, product3
, product4
, Y
, N
FROM (select date
, count(case when product='product1' then 1 else null end) as 'product1'
, count(case when product='product2' then 1 else null end) as 'product1'
, count(case when product='product3' then 1 else null end) as 'product1'
, count(case when onsale='Y' then 1 else null end) as 'Y'
, count(case when onsale='N' then 1 else null end) as 'N'
from dbo.vwSales
group by date) as o
WHERE
(date BETWEEN #from AND #to)
)
FROM DATASET WHERE (RowId BETWEEN (#page - 1) * #pageSize AND (#page) * #pageSize)
OR (#page IS NULL)
Also note that the "TOP 100 PERCENT" is unnecessary.

Adding another Table

Okay so I have made a report calculating how many contracts are funded in each month within the year 2014.
So Now I have to calculate the total for all the contracts that are in SERVICE ONLY.
What I mean by this is I have a table called tlkOrigDept. Within that table I have this
Table tlkOrigDept
orig_dept_id Orig_Dept_Name
1 Sales
2 Service
3 F&I
4 Other
5 Direct Marketing
So I have to get all the funded contracts ONLY that from SERVICE which is 'orig_dept_id' = 2 So this is my Query but the problem I see is in my where clause. Because when I change the orig_dept_Id to 3 it works but not for 2. It just shows blank and not an error message.
The user inputs a #Begin_date and #End_Date the User than picks a company which is #Program. The user should see ALL the FUNDED Contracts for each month that are from SERVICE ONLY.
I either see a problem in the SELECT Statement or my WHERE Clause
Here is my Query
[code="sql"]
Alter Proc spGetAdminServiceYTD
(#Begin_Date DATETIME,
#End_Date DATETIME,
#program int=null) As
Declare #year int
Set #year = 2014
Declare #orig_dept_ID Int
Set #orig_dept_ID = 2
Begin
SELECT d.name, a.dealer_code, b.last_name, b.city, b.state, b.phone,e.orig_dept_name
, COUNT(CASE WHEN MONTH(c.orig_dept_id) = 1 THEN 1 ELSE NULL END) January
, COUNT(CASE WHEN MONTH(c.orig_dept_id) = 2 THEN 1 ELSE NULL END) Feburary
, COUNT(CASE WHEN MONTH(c.Funded_date) = 3 THEN 1 ELSE NULL END) March
, COUNT(CASE WHEN MONTH(c.Funded_date) = 4 THEN 1 ELSE NULL END) April
, COUNT(CASE WHEN MONTH(c.Funded_date) = 5 THEN 1 ELSE NULL END) May
, COUNT(CASE WHEN MONTH(c.Funded_date) = 6 THEN 1 ELSE NULL END) June
, COUNT(CASE WHEN MONTH(c.Funded_date) = 7 THEN 1 ELSE NULL END) July
, COUNT(CASE WHEN MONTH(c.Funded_date) = 8 THEN 1 ELSE NULL END) August
, COUNT(CASE WHEN MONTH(c.Funded_date) = 9 THEN 1 ELSE NULL END) September
, COUNT(CASE WHEN MONTH(c.Funded_date) = 10 THEN 1 ELSE NULL END) October
, COUNT(CASE WHEN MONTH(c.Funded_date) = 11 THEN 1 ELSE NULL END) November
, COUNT(CASE WHEN MONTH(c.Funded_date) = 12 THEN 1 ELSE NULL END) December
, count(1) As YTD
FROM tdealer a
JOIN tContact b ON a.contact_id = b.contact_id
JOIN tContract c ON a.dealer_id = c.dealer_id
JOIN tCompany d ON c.company_id = d.company
JOIN tlkOrigDept E ON c.orig_dept_id = e.orig_dept_id
WHERE c.orig_dept_id = 2
And d.company_id = #program
AND c.Funded_date >= DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-5, 0)
And YEAR(c.Funded_date) = #Year
And c.Funded_date < DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, 0)
And (c.funded_date) between #Begin_Date And #End_Date
GROUP BY
d.name,
a.dealer_code,
b.last_name,
b.city,
b.state,
b.phone,
MONTH(c.funded_date),
Month(e.orig_dept_name),
e.orig_dept_name
end
exec spGetAdminServiceYTD '01/01/2014', '05/30/2014', '47'

How to add Totals in SQL

I am trying to get the totals of each month as of YTD (Years to date) Can someone please help me figure out how to integrate this in my query? thank you This is what I have so far.
DECLARE #Year int
set #Year = 2013
select a.first_name, a.last_name
, COUNT(CASE WHEN MONTH(b.Funded_date) = 1 THEN 1 ELSE NULL END) January
, COUNT(CASE WHEN MONTH(b.Funded_date) = 2 THEN 1 ELSE NULL END) February
, COUNT(CASE WHEN MONTH(b.Funded_date) = 3 THEN 1 ELSE NULL END) March
, COUNT(CASE WHEN MONTH(b.Funded_date) = 4 THEN 1 ELSE NULL END) April
From tContact a Join tContract b ON a.contact_id = b.contract_id
Group by a.first_name, a.last_name
This is just an example of how you could count up rows that fall under a certain month.
SELECT MONTH(b.Funded_date) AS 'MonthNum',
COUNT(*) AS 'Total'
FROM Table AS b
WHERE YEAR(b.Funded_date) = 2014
GROUP BY MONTH(b.Funded_date)
Hopefully this will help you with your query.
Thanks
What I tried to do here is create an upper bound record for each month in tContract then join that back into the query you already had. It is joined on dates that are between the beginning of the year and the current month.
DECLARE #Year int
set #Year = 2013
select Ms.thismonth, count(B.thing_You_are_Totalling) from (
select thisMonth = dateadd(month,datediff(month,0,Funded_date),0)
from tContract
where moid = 2005405
and year(Funded_date) = #Year
group by dateadd(month,datediff(month,0,Funded_date),0)
) Ms
inner join (select * from tContact a inner join tContract ON a.contact_id = tContract.contract_id) B
on B.Funded_date >=dateadd(year,datediff(year,0,B.Funded_date),0) -- beginning of year
and B.Funded_date <= Ms.thisMonth -- this month
where year(B.Funded_date) = #Year -- restrict to only this year
group by thisMonth, first_name, last_name
I don't have your full table definition so there might be some issues (maybe a SqlFiddle is in order)
Not sure if this is what you are asking for.
select a.first_name, a.last_name
, COUNT(CASE WHEN MONTH(b.Funded_date) = 1 THEN 1 ELSE NULL END) January
, COUNT(CASE WHEN MONTH(b.Funded_date) = 2 THEN 1 ELSE NULL END) February
, COUNT(CASE WHEN MONTH(b.Funded_date) = 3 THEN 1 ELSE NULL END) March
, COUNT(CASE WHEN MONTH(b.Funded_date) = 4 THEN 1 ELSE NULL END) April
, COUNT(*) TotalCount
, SUM(CASE WHEN MONTH(b.Funded_date) = 1 THEN Amount ELSE NULL END) JanuaryAmount
, SUM(CASE WHEN MONTH(b.Funded_date) = 2 THEN Amount ELSE NULL END) FebruaryAmount
, SUM(CASE WHEN MONTH(b.Funded_date) = 3 THEN Amount ELSE NULL END) MarchAmount
, SUM(CASE WHEN MONTH(b.Funded_date) = 4 THEN Amount ELSE NULL END) AprilAmount
From tContact a Join tContract b ON a.contact_id = b.contact_id
WHERE YEAR(b.Funded_date) = #Year
Group by a.first_name, a.last_name
How about this:
declare #year int = 2013
select a.first_name
, a.last_name
, month(b.Funded_date) [Month]
, datename(month, dateadd(month, month(date_of_birth_dt), - 1)) [MonthName]
, count(month(b.Funded_date)) [Total]
from tContact a
where a.[Year] = #year
group by a.first_name, a.last_name, month(b.Funded_date)
It returns the total of each Month for the year 2013. a.[Year] might not the the name of the field that you have so adjust accordingly. Also, [Month] returns numeric value for month.
Use the Count(*) As Total function. I'm sure this will help you
SELECT MONTH(b.Funded_date) AS 'MonthNum',
COUNT(*) AS 'Total'
FROM Table AS b
WHERE YEAR(b.Funded_date) = 2014
GROUP BY MONTH(b.Funded_date)

Resources