How to do multiple actions in case when then in sql? - sql

I want to do something like this:
select sum(case ttt.ind = 1 then 1 else 0 end) from ttt
I want to add a column to this query, called myresult which indicates if the value of ttt.istry is equal to 1.
Maybe like:
select
sum(case ttt.ind = 1 then 1, ttt.istry as myresult else 0 end)
from ttt
of course I got an error...
How would I do that?
My data is:
ttt.ind | ttt.istry
--------+----------
1 | 0
0 | 1
1 | 1
and so on...
Expected result:
ttt.ind | ttt.istry | myresult | sum
--------+-----------+----------+------
1 | 0 | 0 | 2
0 | 1 | null | 2
1 | 1 | 1 | 2

You don't say which database so I'll assume it's a modern one. You can use a window function and a CASE clause to do this.
For example:
select
ind,
istry,
case when ind = 1 then istry end as myresult,
sum(ind) over() as sum
from ttt
See live example at SQL Fiddle.

Your logic is a bit hard to follow, but your result set suggests:
select ind, istry,
(case when istry = 1 then 1
when sum(istry) over (partition by ind) = 1 then 0
end),
sum(ttt.ind) over () as sum_ind
from ttt;

Related

How can I seperate one column into multiple columns depending on their value when selecting it?

I have a table called assignment_answers, which has the following attributes:
assignment_answers_id, question_id and order. The order is an attribute, which can take a value from 0 to 9.
I would like for every value that it can take to make it be displayed in a different column. For instance when the order has value 0, then I want it to be displayed in a column called number0. When it has value 1 I want it to be displayed in a column called number1.
Could someone help me with that? So far I have tried this but it does not work:
SELECT (CASE WHEN assessment_answers.order = 0
THEN(
select aq.order as number0
from assessment_answers)
END)
(CASE WHEN assessment_answers.order = 1
THEN(
select aq.order as number1
from assessment_answers)
END)
FROM assessment_answers
I get an error saying:
ERROR: syntax error at or near "("
LINE 6: (CASE WHEN assessment_questions."order" = 1
SAMPLE DATA
assignment_answers_id question_id order
1 1 0
2 1 0
3 2 1
desired output:
assignment_answers_id question_id order0 order1
1 1 0 null
2 1 0 null
3 2 null 1
You can try to use normal CASE WHEN
Query 1:
SELECT assignment_answers_id,
question_id,
(CASE WHEN order = 0 THEN order END) order0,
(CASE WHEN order = 1 THEN order END) order1
FROM assessment_answers
Results:
| assignment_answers_id | question_id | order0 | order1 |
|-----------------------|-------------|--------|--------|
| 1 | 1 | 0 | (null) |
| 2 | 1 | 0 | (null) |
| 3 | 2 | (null) | 1 |
Does this do what you want?
select (aa.order = 0)::int as order_0,
(aa.order = 1)::int as order_1,
(aa.order = 2)::int as order_2,
. . .
from assessment_answers aa;

BigQuery : case when expression to Count from Same column but different conditions

I have a table with 2 columns as below:
Col 1 | col_stats
Field 1 | open
Field 2 | close
Field 1 | close
Field 1 | open
I want the ouput to be as :
Col1 | cnt_open | Cnt_close
Field 1 | 2 | 1
Field 2 | 0 | 1
**I wrote a query **
select col 1, count(case when col_stats= 'open' then 1 else 0 END) cnt_open,
count (case when col_stats= 'close' then 1 else 0 END ) cnt_close
from `project.dataset.tablename`
group by col1
Resultant output from above query is incorrect:
Col1 | cnt_open | Cnt_close
Field 1 | 2 | 2
Field 2 | 1 | 1
Can somebody let me know why the output is giving incorrect result for count even after case condition is applied?
Use countif():
select col1, countif(col_stat = 'open') as num_opens, countif(col_stat = 'closed') as num_closes
from t
group by col1;
In SQL count() counts the number of non-NULL values. Your code would work with sum(). But countif() is simpler and clearer.
Use null instead of 0:
select col1, count(case when col_stats= 'open' then 1 else null END) cnt_open,
count (case when col_stats= 'close' then 1 else null END ) cnt_close
from `project.dataset.tablename`
group by col1

Counting occurrences of a value in multiple columns - postgres

I have a table called fixtures (I have simplified for this example) and would like to populate the last two columns (*_plus_mc_per) with the percentage of times occurred for each number with a query run against the mc_* columns. It would look like this as an example
#mc = Match Corner # mc_per = Match Corner Percentage
| mc_0 | mc_1 | mc_3 | mc_4 | match_count | one_plus_mc_per | two_plus_mc_per |
| 1 | 4 | 3 | null | 3 | 100 | 66 |
At the point where I run my query it looks like
#mc = Match Corner # mc_per = Match Corner Percentage
| mc_0 | mc_1 | mc_3 | mc_4 | match_count | one_plus_mc_per | two_plus_mc_per |
| 1 | 4 | 3 | null | 3 | null | null |
So starting with the query for one_plus_mc_per I can do this
SELECT COUNT(*) FROM fixtures WHERE coalesce(mc_0,0) >= 1 AND id = 182;
# Using coalesce for dealing with null, will return a 0 if value null
This returns
| count |
| 1 |
If I run this query on each column individually the results returned would be
| count | count | count | count |
| 1 | 1 | 1 | 0 |
Thus enabling me to add all the column values up and divide by my match count. This makes sense (and I thank dmfay for getting me to think about his suggestion in a previous question)
My problem is I can't run this query 4 times for example as that is very ineffective. My SQL fu is not strong and was looking for a way to do this in one call to the database, enabling me to then take that percentage value and update the percentage column
Thanks
Try this:
SELECT
SUM(CASE WHEN coalesce(mc_0,0) >= 1 THEN 1 ELSE 0 END) count_0,
SUM(CASE WHEN coalesce(mc_1,0) >= 1 THEN 1 ELSE 0 END) count_1,
SUM(CASE WHEN coalesce(mc_3,0) >= 1 THEN 1 ELSE 0 END) count_3,
SUM(CASE WHEN coalesce(mc_4,0) >= 1 THEN 1 ELSE 0 END) count_4,
FROM
fixtures
WHERE id = 182;
It will return count of all the columns in single query
I am not sure though, whats the use of id = id in your query as it will always be true.
If you want count of columns *_mc for every row with > 0 condition, try this:
SELECT
(CASE WHEN coalesce(mc_0,0) >= 1 THEN 1 ELSE 0 END +
CASE WHEN coalesce(mc_1,0) >= 1 THEN 1 ELSE 0 END +
CASE WHEN coalesce(mc_3,0) >= 1 THEN 1 ELSE 0 END +
CASE WHEN coalesce(mc_4,0) >= 1 THEN 1 ELSE 0 END) as count
FROM
fixtures
WHERE id = 182;
UPDATE:
Calculating one_plus_mc_per
SELECT
CAST((CASE WHEN coalesce(mc_0,0) >= 1 THEN 1 ELSE 0 END +
CASE WHEN coalesce(mc_1,0) >= 1 THEN 1 ELSE 0 END +
CASE WHEN coalesce(mc_3,0) >= 1 THEN 1 ELSE 0 END +
CASE WHEN coalesce(mc_4,0) >= 1 THEN 1 ELSE 0 END)AS DECIMAL)/match_count as one_plus_mc_per
FROM
fixtures
WHERE id = 182;
Postgres has very nice capabilities for answering this type of question:
SELECT COUNT(*) FILTER (WHERE mc_0 >= 1) as count_0,
COUNT(*) FILTER (WHERE mc_1 >= 1) as count_1,
COUNT(*) FILTER (WHERE mc_3 >= 1) as count_3,
COUNT(*) FILTER (WHERE mc_4 >= 1) as count_4,
AVG ( (mc_0 >= 1)::int + (mc_1 >= 1)::int + (mc_3 >= 1)::int + (mc_4 >= 1)::int
) as one_plus_mc_per
FROM fixtures
WHERE id = 182;
The FILTER is ANSI-standard syntax. The conversion of booleans to numbers is a very convenient construct.

how to group column as per its unique value and get count in to different column as per its value?

I am having a Category table as follows,
i want retrieve following results according to scStatusvalue and its count group by catID
catID | 0 | 2 | 3
----- |---|---|---
2 | 1 | 0 | 1
3 | 1 | 1 | 0
4 | 2 | 0 | 1
5 | 0 | 1 | 0
I tried this,select catID,count(scStatus) as [Count] from tableName group by catID,scStatus order by catID but i cant get into column that values.
`
Use a pivot query:
SELECT catID,
SUM(CASE WHEN scStatus = 0 THEN 1 ELSE 0 END) AS [0],
SUM(CASE WHEN scStatus = 2 THEN 1 ELSE 0 END) AS [2],
SUM(CASE WHEN scStatus = 3 THEN 1 ELSE 0 END) AS [3]
FROM Category
GROUP BY catID
pivot operator
select *
from (select catID,scStatusvalue from t) t
pivot (count(scStatusvalue) for scStatusvalue in ([0],[2],[3])) t

SQL - Sum two columns group by ID

I would like to sum two columns "Immo"+"Conso" group by "ID" in order to create a new variable "Mixte". My new variable "Mixte" is as follow:
if one ID has (at least) 1 in "Immo" AND 1 in "Conso" then "Mixte" is yes, otherwise "Mixte" is no.
For exemple:
Ident | Immo | Conso | Mixte
---------------------------------
1 | 0 | 1 | yes
1 | 1 | 0 | yes
2 | 1 | 0 | no
3 | 0 | 1 | no
3 | 0 | 1 | no
3 | 0 | 1 | no
4 | 0 | 1 | yes
4 | 0 | 1 | yes
4 | 1 | 0 | yes
Thank you for helping me. Do not hesitate to ask me questions if I wasn't clear.
Use a correlated sub-select:
select t1.Ident, t1.Immo, t1.Conso,
case when (select max(Immo) + max(Conso) from tablename t2
where t2.Ident = t1.Ident) = 2 then 'yes'
else 'no'
end as Mixte
from tablename t1
Ident is a reserved word in ANSI SQL, so you may need to delimit it as "Ident".
select ident,result=(case when sum(Immo)>0 and sum(Conso)>0 then 'yes'
else 'no' end)
from tabname (NOLOCK)
group by id
It may not be the smoothiest way but I'll do this as:
WITH X AS
(
SELECT T.Ident, MAX(T.Immo) Immo, MAX(T.Conso) Conso FROM Table AS T
GROUP BY T.Ident
)
SELECT X.*
,CASE WHEN X.Immo > 0 AND X.Conso > 0 THEN 'YES'
ELSE 'NO'
END Mixte
FROM X
In SQL-Server you could try to use window functions, something like:
select Ident, Immo, Conso,
case when rn1 > 0 and rn2 > 0 then 'Yes' else 'No' end as Mixte
from (
select
max(Immo) over (partition by Ident) rn1,
max(Conso) over (partition by Ident) rn2,
*
from table_name
)x