Average calculation using T-SQL - sql-server-2008

I have an EMP table in SQL Server that looks something like this
ID T_Date Jid Emp_Cost Con_Cost IsActive
--------------------------------------------------------
13178 null 214 0 0 0
12797 null 214 0 55 1
11906 null 214 0 55 1
12916 null 214 0 58 1
I am executing the below query
SELECT
AVG(CASE WHEN IsActive = 1 THEN Con_Cost ELSE Emp_Cost END) cost
FROM
EMP
WHERE
Jid = 214
AND (T_Date IS NULL OR T_Date >= sysdate);
My expected cost value must be 56.
Can anybody help me with this?
Arun

Since aggregate functions ignore null values, you can use nullif() to change 0 to null like so:
select avg(nullif(case
when IsActive = 1 then Con_Cost
else Emp_Cost
end
,0)) as cost
from EMP
where Jid = 214
and (T_Date is null or T_Date >= sysdatetime());
rextester demo: http://rextester.com/NPBOP19522
returns
+------+
| cost |
+------+
| 56 |
+------+
note: I changed sysdate to sysdatetime(), though I do not know if that is the intent of your query.

AVG actually works fine, since it does an average of the sum of 0+55+55+58 divided by the number of rows in the result set.
I believe what you are looking for is:
select distinct
sum(case when IsActive = 1 then con_cost else emp_cost end) over () /
count(case when IsActive = 1 then 1 else null end) over ()
from emp
where Jid = 214
and (T_Date is null or T_Date >= sysdatetime());
or maybe are you looking for:
select avg(con_cost)
from emp
where isActive = 1
and Jid = 214
and (T_Date is null or T_Date >= sysdatetime());

This can work too. http://rextester.com/QIXA57971
SELECT
AVG(CASE WHEN IsActive = 1 THEN Con_Cost ELSE Emp_Cost END) cost
FROM
EMP
WHERE
Jid = 214
AND (T_Date IS NULL OR T_Date >= GETDATE()) AND IsActive = 1;
Result
cost
-----
56

Related

How make request more readable and scalable?

i have request:
SELECT user_id FROM merchant_data
WHERE user_id IN (
SELECT user_id FROM merchant_data
WHERE merchant_id = 1134
AND created_date = '2022-12-02'
GROUP BY user_id
HAVING COUNT(*) > 2)
AND merchant_id = 1167
AND created_date = '2022-12-02'
GROUP BY user_id
HAVING COUNT(*) = 2;
That request return me data from something like log table. In this case i need to get all users that have 2 more rows with merchant_id == 1134 and 2 rows merchant_id == 1167. But how make it for 4 or 5 or 6 condition like merchant_id == ...?
SELECT user_id FROM merchant_data
WHERE created_date = '2022-12-02'
AND merchant_id IN (1134, 1167, 1186, ...)
GROUP BY user_id
HAVING SUM(merchant_id = 1134) >= 2
AND SUM(merchant_id = 1167) >= 2
AND SUM(merchant_id = 1186) >= 2
AND ...
That depends on an odd MySQL feature that booleans are literally the integer values 1 for true and 0 for false, so you can SUM() a boolean expression. You can't do that in standard SQL.
You could make it more standard SQL by using CASE expressions with no ELSE clause. CASE returns NULL if there is no match, and COUNT() will ignore NULLs.
SELECT user_id FROM merchant_data
WHERE created_date = '2022-12-02'
AND merchant_id IN (1134, 1167, 1186, ...)
GROUP BY user_id
HAVING COUNT(CASE merchant_id WHEN 1134 THEN 1 END) >= 2
AND COUNT(CASE merchant_id WHEN 1167 THEN 1 END) >= 2
AND COUNT(CASE merchant_id WHEN 1186 THEN 1 END) >= 2
AND ...

mysql 8 pivot query should return a non null value

I would like the following pivot query to show value 0 instead of null,
SELECT
pi.employeeId,
pi.Id,
MAX(CASE
WHEN pi.category = 'Repayment' THEN pi.value
WHEN isnull(pi.category) = 1 then 0
-- ELSE 0
END) as 'Repayment',
MAX(CASE
WHEN pi.category = 'Salary' THEN pi.value
ELSE 0
END) as 'Salary',
MAX(CASE
WHEN pi.category = 'Allowance' THEN pi.value
ELSE 0
END) as 'Allowance'
FROM
payData pi
GROUP BY pi.employeeId , pi.Id ;
Output for the above is,
employeeId Id Repayment Salary Allowance
121 2 2000 15000 1000
122 2 null 20000 2000
Employee id 122 does not have a Repayment value so the desired output is,
employeeId Id Repayment Salary Allowance
121 2 2000 15000 1000
122 2 0 20000 2000
dbfiddle
I don't see the need for the second branch of the repayment case. If you want 0 when the category is not available, just else 0:
SELECT
employeeId,
Id,
MAX(CASE WHEN category = 'Repayment' THEN value ELSE 0 END) as Repayment,
MAX(CASE WHEN category = 'Salary' THEN value ELSE 0 END) as Salary,
MAX(CASE WHEN category = 'Allowance' THEN value ELSE 0 END) as Allowance
FROM payData pi
GROUP BY employeeId, Id;
Notes:
Don't use single quotes for identifiers! They should be used for literal strings only, as specified in ANSI SQL and supported in all databases.
You have a mono-table query, so prefixing all column names is not mandatory

MySQL: How to achieve multiple conditions in CASE WHEN THEN

I have below query:
SELECT users_name, first_name, last_name,
(CASE
WHEN flag1==1 AND flag2==1 AND flag3==0 THEN 'Active'
WHEN flag1==0 AND flag2==1 AND flag3==0 THEN 'Deactive'
WHEN flag1==0 AND flag2==0 AND flag3==0 THEN 'Disabled'
ELSE ''
END) as Status FROM `users`
I have multiple flag conditions before defining it's status but on running the above query it gives me.
Syntax error near==1
What's the correct way to achieve it?
Intended Result:
username|firstname|lastname|status
Alex | Alex | mark | Active
April | April | mark | Deactive
In SQL the comparision operator is = so use = (and not == ):
SELECT users_name, first_name, last_name,
(CASE
WHEN flag1 = 1 AND flag2 = 1 AND flag3 = 0 THEN 'Active'
WHEN flag1 = 0 AND flag2 = 1 AND flag3 = 0 THEN 'Deactive'
WHEN flag1 = 0 AND flag2 = 0 AND flag3 = 0 THEN 'Disabled'
ELSE ''
END) as Status FROM `users`

Row counts Sql query

I want result in Sql query
id1 id2 id3 Count Id
A001 A001 A001 3
A001 NULL A001 2
A001 NULL NULL 1
In SQL Server, i would use VALUES construct :
SELECT t.*,
(SELECT COUNT(tt.ids) FROM ( VALUES (t.id1), (t.id2), (t.id3) ) tt(ids)
) as Count_Id
FROM table t;
In standard SQL you can use CASE Expression :
SELECT t.*,
( (CASE WHEN ID1 IS NOT NULL THEN 1 ELSE 0 END) +
(CASE WHEN ID2 IS NOT NULL THEN 1 ELSE 0 END) +
(CASE WHEN ID3 IS NOT NULL THEN 1 ELSE 0 END)
) AS Count_Id
FROM table t
are you find something like below
select id1,id2,id3,
case when id1 is not null then 1 else 0 end+
case when id2 is not null then 1 else 0 end+
case when id3 is not null then 1 else 0 end as val

how to marge the values of column in mysql

Lets consider this query
select class_id,case when event_id=2 then sum(time_spent) end as timespent ,case when event_id=3 then sum(timespent) end as visitedtimespent from class group by class_id,event_id;
output is looking like
class_id timespent visitedtimespent
1 2000 NULL
1 NULL 10
2 4000 NULL
2 NULL 5
when I use this query
select class_id,case when event_id=2 then sum(time_spent) end as timespent ,case when event_id=3 then sum(time_spent) end as timespent from class group by class_id;
output is looking like
class_id timespent visitedtimespent
1 2000 NULL
2 4000 NULL
but I expected this output
class_id timespent visitedtimespent
1 2000 10
2 4000 5
how can I achieve this?
select class_id,
sum(case when event_id=2 then time_spent else 0 end) as timespent,
sum(case when event_id=3 then time_spent else 0 end) as visitedtimespent
from class
group by class_id
sum the case.
select class_id,
sum(case when event_id=2 then time_spent end) as timespent ,
sum(case when event_id=3 then time_spent end) as visitedtimespent
from class group by class_id;
to explain the difference:
case when id... then sum(value) is equivalent to
select case when id then value from
(
select id, sum(value) as value from table
)subquery
which is an illegal grouping(ID is not aggregated or included in grouping, so the ID value will be chosen at random between all existing entries), and your ID information will be lost. IF you then apply a case to the ID info, you will not get relevant results.