I have a SQL statement that has multiple case statements like the below:
SUM(CASE [Type]
WHEN 418
THEN CASE WHEN PMTS.DateCreated BETWEEN #sd AND #ed
AND( PMTS.Amount >0 OR PMTS.Mileage >0)
AND PMTS.PaymentEventID = 0 THEN Mileage END
ELSE 0 END) AS DriverMileage
But I need the result of the sum to set a variable and use that in the where in the WHERE clause.
Example below
DECLARE #contribution decimal
SElECT PMTS.VolunteerId ,
SET #contribution = SUM(CASE [Type]
WHEN 1003
THEN CASE WHEN PMTS.DateCreated BETWEEN #sd AND #ed
AND( PMTS.Amount >0 OR PMTS.Mileage >0)
AND PMTS.PaymentEventID = 0
THEN Amount END
ELSE 0 END) AS GPContributions
FROM PMTS WHERE #contribution >0
Many thanks
I don't think that you need a variable here, also please confirm the "case when" syntax used. Here is a sample query:
select * from
(SElECT PMTS.VolunteerId ,SUM(CASE [Type]
WHEN 1003
THEN CASE WHEN PMTS.DateCreated BETWEEN #sd AND #ed
AND( PMTS.Amount >0 OR PMTS.Mileage >0)
AND PMTS.PaymentEventID = 0
THEN Amount END
ELSE 0 END) AS GPContributions
FROM PMTS)as A WHERE GPContributions >0
Related
I have two calculated columns with case statements. Now, I need to take Sum of those columns and need the difference in it.
For Ex.
Select Case when account = '30' and status='active' then value as value1,
case when account = '31' and status='active' then value as value2,
Sum(value1) - Sum(Value2) as Total_SUM
from table
How can we achieve this.. This gives me a missing group by clause error. I tried many things but did not work out.
Use conditional aggregation and sum the CASE expressions:
SELECT
SUM(CASE WHEN account = '30' THEN value ELSE 0 END) AS value1,
SUM(CASE WHEN account = '31' THEN value ELSE 0 END) AS value2,
SUM(CASE WHEN account = '30' THEN value ELSE 0 END) -
SUM(CASE WHEN account = '31' THEN value ELSE 0 END) AS Total_SUM
FROM yourTable
WHERE status = 'active';
In a table I have 914 rows in that I have a Column which contains "yes or no" values(Yes=193 No = 721 total 914).
In this I want to create a function to use in select statement How many Yes and No
I wrote a query
create function TSS(
#string as nvarchar(20)
)
returns int
begin
declare #result int
if (#string='NO')
select #result=sum(case Re_engaged when 'NO' then 1 else null end) from TVS_PRE
else if (#string='YES')
select #result=sum(case Re_engaged when 'YES' then 1 else null end) from TVS_PRE
return #result
end
select [dbo].[TSS]('Yes') as columns_with_Yes,[dbo].[TSS]('No') as columns_with_No from TVS_PRE
And I got the result is
Columns_with_Yes
Columns_with_No
1
193
2
193
3
193
upto...
...
914
193
but I required this
Columns_with_Yes
Columns_with_No
1
193
You should combine this into one query
SELECT
sum(case Re_engaged when 'NO' then 1 end) Columns_with_No,
sum(case Re_engaged when 'YES' then 1 end) Columns_with_Yes
FROM TVS_PRE;
If you really want this as a function, you can turn it into an inline Table valued Function
CREATE FUNCTION TSS()
RETURNS TABLE
AS RETURN (
SELECT
sum(case Re_engaged when 'NO' then 1 end) Columns_with_No,
sum(case Re_engaged when 'YES' then 1 end) Columns_with_Yes
FROM TVS_PRE
);
GO
I don't understand your need... but if you want only one row... then dont use "from":
select [dbo].[TSS]('Yes') as columns_with_Yes,[dbo].[TSS]('No') as columns_with_No
Use this syntax
SELECT DISTINCT COUNT(CASE WHEN Re_engaged='No' then 1 else NULL end) OVER () AS No_col,
COUNT(CASE WHEN Re_engaged='Yes' then 1 else NULL end) OVER () AS Yes_col
FROM TVS_PRE
I'm trying to switch rows and columns with PIVOT (or another method). The documentation is pretty confusing to me. Thanks
DECLARE #CallCenterID Int;
DECLARE #BeginDateofReview SmallDateTime;
DECLARE #EndDateofReview SmallDateTime;
SELECT
COUNT(case when Score_Greeting = 'Yes' then Score_Greeting END) AS Score_Greeting_Passed,
SUM(CASE WHEN Score_Greeting IS NOT NULL THEN 1 ELSE 0 END) AS Score_Greeting_Reviewed,
ROUND(CONVERT(decimal(4,1), (COUNT(CASE WHEN Score_Greeting = 'Yes' THEN Score_Greeting END) * 100.0) / NULLIF(SUM(CASE WHEN Score_Greeting IS NOT NULL THEN 1 ELSE 0 END),0),0),0) AS Score_Greeting_PctngPassed,
COUNT(CASE WHEN Score_Authentication = 'Yes' THEN Score_Authentication END) AS Score_Authentication_Passed,
SUM(CASE WHEN Score_Authentication IS NOT NULL THEN 1 ELSE 0 END) AS Score_Authentication_Reviewed,
ROUND(CONVERT(decimal(4,1), (COUNT(CASE WHEN Score_Authentication = 'Yes' THEN Score_Authentication END) * 100.0) / NULLIF(SUM(CASE WHEN Score_Authentication IS NOT NULL THEN 1 ELSE 0 END), 0), 0), 0) AS Score_Authentication_PctngPassed,
FROM
Calls
WHERE
CallCenterID = #CallCenterID AND
(DateofReview >= #BeginDateofReview AND DateofReview <= #EndDateofReview)
Desired results:
Score_Greeting_Passed 5
Score_Greeting_Reviewed 9
Score_Greeting_PctngPassed 56
Score_Authentication_Passed 6
Score_Authentication_Reviewed 9
Score_Authentication_PctngPassed 67
You can use the UNPIVOT operator to transpose the rows and columns. If we assume your query above is stored in #YourData, it's going to be something like:
SELECT
UnpivotedData.ScoreType
, UnpivotedData.ScoreValue
FROM
#YourData
UNPIVOT (ScoreValue FOR ScoreType IN ( [Score_Greeting_Passed], [Score_Greeting_Reviewed], [Score_Greeting_PctngPassed],
[Score_Authentication_Passed], [Score_Authentication_Reviewed], [Score_Authentication_PctngPassed] )) AS UnpivotedData
I need some assistance with a query. I have a table with the following info:
enter image description here
I need to allocate a point system for every call, calls less than 1 min, calls between 1 and 5 min , calls between 5 and 10 min and lastly calls over 10 min
Currently my query looks like this:
Select distinct convert (date,AIV.PSEndTime,102) as TRXDATE
,AIV.Username
,AIV.FirstName+' '+AIV.LastName as Agent_Name
,AIV.ITypeDisplayValue
,convert (datetime,AIV.PSBeginTime,120) as PSBeginTime
,convert (datetime,AIV.PSEndTime,120) as PSEndTime
,convert(CHAR(8),DATEADD(second,AIV.Talking,0),108) as [Talking]
,CASE WHEN AIV.Talking <='60' THEN 1 ELSE 0 end as Less_than_1min
,CASE WHEN AIV.Talking between '61' and '300' THEN 1 ELSE 0 end as Between_1_and_5_min
,CASE WHEN AIV.Talking between '301' and '600' THEN 1 ELSE 0 end as Between_5_and_10_min
,CASE WHEN AIV.Talking >='601' THEN 1 ELSE 0 END as More_than_10min
From AgentInteractionsView as AIV WITH (NOLOCK)
WHere UserName in ('TomE','MicDe','JulCa')
and AIV.PSBeginTime > '2017-08-01'
and AIV.PSEndTime < '2017-09-01'
group by
convert (date,AIV.PSEndTime,102)
,AIV.Username
,AIV.FirstName+' '+AIV.LastName
,AIV.ITypeDisplayValue,AIV.DIDisplayValue
,convert (datetime,(DATEADD(hour,2,AIV.PSBeginTime)),120)
,convert (datetime,(DATEADD(hour,2,AIV.PSEndTime)),120)
,convert(CHAR(8),DATEADD(second,AIV.Talking,0),108)
,AIV.Talking
And this actually worked however I noticed that when the Column "talking" was Null it would not give me a result so I added a new query:
,CASE WHEN AIV.Talking <='60' THEN 1 ELSE 0 end as Less_than_1min
,CASE WHEN AIV.Talking = null THEN 1 ELSE 0 end as Less_than_1min
Hoping that these would result in a single column, but of course it gave me 2 columns with the same heading.
I want to join these two queries into 1 column, for example
,CASE WHEN AIV.Talking = null THEN 1
ELSE (CASE WHEN AIV.Talking <='60' THEN 1 ELSE 0) end
as Less_than_1min
am I missing something ( obviously) or am I expecting too much from SQL :)
As I mentioned in my comment, you can use ISNULL or COALESCE to handle a NULL value, example code:
DECLARE #time TIME;
SET #time = NULL;
SELECT CASE WHEN COALESCE(#time,'00:00:01') <= '00:01:00' THEN 1 ELSE 0 END AS Test_Time;
The above code returns a 1, as does:
DECLARE #time TIME;
SET #time = '00:00:01';
SELECT CASE WHEN COALESCE(#time,'00:00:01') <= '00:01:00' THEN 1 ELSE 0 END AS Test_Time;
And the below returns a 0:
DECLARE #time TIME;
SET #time = '00:02:01';
SELECT CASE WHEN COALESCE(#time,'00:00:01') <= '00:01:00' THEN 1 ELSE 0 END AS Test_Time;
As does:
DECLARE #time TIME;
SET #time = NULL;
SELECT CASE WHEN #time <= '00:01:00' THEN 1 ELSE 0 END AS Test_Time;
As the value is NULL, it cannot evaluate, so returns false.
So when using COALESCE, I just make sure that what I set the value to be if it is NULL fits in with the CASE expression logic, to return what I require.
Thanks for the assistance I was able to figure out what I was doing wrong.
As the Time is and Integer Showing the number of Seconds I came to this solution :)
Select CASE WHEN AIV.Talking <='60' THEN 1 ELSE 0 end as Less_than_1min
,CASE WHEN AIV.Talking between '61' and '300' THEN 1 ELSE 0 end as Between_1_and_5_min ,
CASE WHEN AIV.Talking between '301' and '600' THEN 1 ELSE 0 end as Between_5_and_10_min
,CASE WHEN AIV.Talking >='601' THEN 1 ELSE 0 END as More_than_10min
I really hope that this helps someone else in future :)
I'm using SQL Server 2005. I'm looking to add up the columns (AM, Midday, Evening) to see which ones contains the value "YES" and then take that total and multiply it by the rate for each row for a client.
Here is the query I have so far:
Select
Sum(Case When morning = 'yes' Then 1 Else 0 End) am_total,
Sum(Case When midday = 'yes' Then 1 Else 0 End) midday_total
From services
where client_id = 24
with the following output
am_total midday_total
45 49
When I introduce the rate variable, my query starts telling me I need the group_by clause and I don't think I'm ready for that since I still need to add the am_total and the midday_total together first and then multiply that by the rate.
Ultimately, all I'm looking for is the grand total.
If I understand your question, maybe this is what you need
declare #rate int
set #rate = 2 /*what ever rate is */
select am_total * #rate as am, midday_total * #rate as midday
from (
Select
Sum(Case When morning = 'yes' Then 1 Else 0 End) am_total,
Sum(Case When midday = 'yes' Then 1 Else 0 End) midday_total
From services
where client_id = 24
)
You can also join another table and use its columns in calculation
Select
Sum(Case When morning = 'yes' Then 1 * u.rate Else 0 End) am_total,
Sum(Case When midday = 'yes' Then 1 * u.rate Else 0 End) midday_total
From services srv inner join users u on services.id = u.service_id -- assuming this is relation
pay attention on u.rate above