Case statement logic gone wrong - mysql

I have a question , as I am new to programming , I Can't figure out this simple logic. I am creating buckets under this code and for some reason the last buckets that I have created i.e 5 and 6 are not working. Everything is falling under classification 1. Need some help to categorising the data in different buckets. Can someone please tell me what can be done so that the data that is meeting condition 5 & 6 falls under it.
case when Sum(SubscriptLineAmount) > 0 and sum([Previous Amount]) = 0 then 1
when Sum(SubscriptLineAmount) > 0 and Sum(differenceAmount) > 0 then 2
when Sum(SubscriptLineAmount) > 0 and Sum(differenceAmount) < 0 then 3
when Sum(SubscriptLineAmount) = 0 and Sum(differenceAmount) <> 0 then 4
when Sum(SubscriptLineAmount) > 0 and sum([Previous Amount]) = 0 and [SUBSCRIPTION ORDER TYPE LIST] = 'Acquisition' then 5
when Sum(SubscriptLineAmount) > 0 and sum([Previous Amount]) = 0 and [SUBSCRIPTION ORDER TYPE LIST] = 'Other' then 6
else 7
end classification

Related

How to find 7 consecutive non zero values in SQL?

If we have a table of 15 columns, the first one is id, and the other columns have numeric
data type,
in MySQL or a similar languages, how can I find if the record have 7 consecutive non zero values, meaning that 7 of the contiguous columns have a value not equals to zero?
We can write a query has a lot of OR operations to check that each 7 columns don't have 0 value, but I want to know if there is shorter way
Try the following using CONCAT and INSTR functions, explanation is within query comments:
/*
check if the col value is not equal to 0,
this will return 1 if true and 0 if false,
and concatenate all of the returned values.
*/
with concat_cols as
(
select *,
concat(
col1<>0, col2<>0, col3<>0, col4<>0, col5<>0,
col6<>0, col7<>0, col8<>0, col9<>0, col10<>0,
col11<>0, col12<>0, col13<>0, col14<>0, col15<>0
) as con_col
from table_name
)
/*
using the instr function, check if the concatenated
result contains 7 consecutive 1s (7 not 0 values).
*/
select * from concat_cols
where instr(con_col, repeat('1', 7))
See demo
One way:
field(0,col1,col2,col3,col4,col5,col6,col7) = 0 or
field(0,col2,col3,col4,col5,col6,col7,col8) = 0 or
field(0,col3,col4,col5,col6,col7,col8,col9) = 0 or
field(0,col4,col5,col6,col7,col8,col9,col10) = 0 or
field(0,col5,col6,col7,col8,col9,col10,col11) = 0 or
field(0,col6,col7,col8,col9,col10,col11,col12) = 0 or
field(0,col7,col8,col9,col10,col11,col12,col13) = 0 or
field(0,col8,col9,col10,col11,col12,col13,col14) = 0 or
field(0,col9,col10,col11,col12,col13,col14,col15) = 0
SELECT id
FROM your_table
WHERE SUM(CASE WHEN column_2 > 0 THEN 1 ELSE 0 END +
CASE WHEN column_3 > 0 THEN 1 ELSE 0 END +
CASE WHEN column_4 > 0 THEN 1 ELSE 0 END +
CASE WHEN column_5 > 0 THEN 1 ELSE 0 END +
CASE WHEN column_6 > 0 THEN 1 ELSE 0 END +
CASE WHEN column_7 > 0 THEN 1 ELSE 0 END +
CASE WHEN column_8 > 0 THEN 1 ELSE 0 END) >= 7

SQL - How To List True Case Statements In 1 Field [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 months ago.
Improve this question
My current SQL statement groups certain colors and certain fruits as 2 new columns (Colors, Fruit) and adds + 1 whenever either respective column is greater than 0.
I want whenever Colors, or Fruits, is > 0, to have the name listed in the column "NewColumn".
Here is an example, with the last column being the expected output.
You can see Tom Brady does not have "Fruit" in the NewColumn, as the value is 0 for "Fruit".
Here Is My Current Code
SELECT
*,
( (CASE WHEN apple > 0 THEN 1 ELSE 0 END)
+ (CASE WHEN WHEN grapes > 0 THEN 1 ELSE 0 END)) as fruit,
( (CASE WHEN red > 0 THEN 1 ELSE 0 END)
+ (CASE WHEN blue > 0 THEN 1 ELSE 0 END)) as colors
from table
You can just add up color and fruit counts to get their totals and see whether you get a count greater than zero. Use CASE expressions for the texts 'Colors' and 'Fruits'. Use CONCAT_WS for the concatenation.
select
blue, red, apple, grapes,
concat_ws(',',
case when blue + red > 0 then 'Colors' end,
case when apple + grapes > 0 then 'Fruits' end
) as new_column
from mytable;
You can use a subquery to get the value of your NewColumn. Additional select case for this newly added column.
select t.*, case when t.Colors > 0 and t.Fruit > 0 then 'Colors;Fruit'
when t.Colors > 0 and t.Fruit = 0 then 'Colors'
when t.Colors = 0 and t.Fruit > 0 then 'Fruit'
else '' end as NewColumn
from (
select case when Red+Blue > 0 then Red+Blue else 0 end as Colors
, case when Apple+Grapes > 0 then Apple+Grapes else 0 end as Fruit
, Blue, Red, Apple, Grapes
from table) as t
This code is work for you.
Select *,
case When Fruit>0 and Colors > 0 then 'Colors;Fruit'
when Fruit > 0 and Colors = 0 then 'Fruit'
when Fruit = 0 and Colors > 0 then 'Colors' end as NewColumn
From Example

Apply function to entire dataframe

I am trying to recode all values in a dataframe using an if statement.
I have:
a b c
0 .05 0
-.02 0 -.06
-.01 0 -.08
0 0 .09
I want:
a b c
0 1 0
0 0 -1
0 0 -1
0 0 1
I have tried several things like:
def unit_weighted (x):
if x >= 0.05:
return 1
elif x <= -0.05:
return -1
else:
return 0
new = df.apply(unit_weighted, axis=0)
I get this error:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
I don't want to have to list all the columns like this:
new = df['a'].apply(unit_weighted, axis=0)
new = df['b'].apply(unit_weighted, axis=0)
Any help please?
Just remove the axis=0, and it will apply element-wise.

SQL - Multiple case when functions

I have an issue relating to an earlier post I made (for ref: SQL - How to find optimal performance numbers for query)
Essentially, I am now trying to use the CASE WHEN function to make a variety of different groups. For example, and following the example from the previous post, I have the following:
SELECT
Vehicle_type,
case when Number_of_passengers::numeric = 0 then 'cat=0'
when Number_of_passengers::numeric < 2 then 'cat1<2'
when Number_of_passengers::numeric < 3 then 'cat1<3'
when Number_of_passengers::numeric < 4 then 'cat1<4'
when Number_of_passengers::numeric < 5 then 'cat1<5'
when Number_of_passengers::numeric < 6 then 'cat1<6'
when Number_of_passengers::numeric < 7 then 'cat1<7'
when Number_of_passengers::numeric > 2 then 'cat1>2'
when Number_of_passengers::numeric > 3 then 'cat1>3'
when Number_of_passengers::numeric > 4 then 'cat1>4'
when Number_of_passengers::numeric > 5 then 'cat1>5'
when Number_of_passengers::numeric > 6 then 'cat1>6'
when Number_of_passengers::numeric > 7 then 'cat1>7'end as category1,
case when Number_of_doors::numeric = 0 then 'cat2=0'
when Number_of_doors::numeric > 2 then 'cat2>2'
when Number_of_doors::numeric > 3 then 'cat2>3'
when Number_of_doors::numeric > 4 then 'cat2>4'
when Number_of_doors::numeric > 5 then 'cat2>5'
when Number_of_doors::numeric > 6 then 'cat2>6'
when Number_of_doors::numeric > 7 then 'cat2>7'
when Number_of_doors::numeric < 2 then 'cat2<2'
when Number_of_doors::numeric < 3 then 'cat2<3'
when Number_of_doors::numeric < 4 then 'cat2<4'
when Number_of_doors::numeric < 5 then 'cat2<5'
when Number_of_doors::numeric < 6 then 'cat2<6'
when Number_of_doors::numeric < 7 then 'cat2<7' end as category2,
round(sum(case when in_accident='t' then 1.0 end)/ count(*),3) as accident_rate,
FROM Accidents
GROUP by 1,2,3
This is actually giving me the correct output in terms of format, however, the numbers I receive in the 'accident_rate'column vary.
If i ran this whole query, I get a different accident_rate for the groups than if i looked at groups individually.
To explain, if i ran the above query and looked at : Car, Number_of_passengers > 2 and Number_of_doors > 2, my accident rate could be 60%.
Yet, if i ran the query as:
SELECT
Vehical_type,
case when Number_of_passengers::numeric > 2 then 'cat1>2' end as category1,
case when Number_of_doors::numeric > 2 then 'cat2>2' end as category2,
round(sum(case when in_accident='t' then 1.0 end)/ count(*),3) as accident_rate,
FROM Accidents
GROUP by 1,2,3
my accident rate might only be 20%.
Any suggestion guys?
Thanks

How to convert a 3 input AND gate into a NOR gate?

I know that I can say convert a 2-input AND gate into a NOR gate by simply inverting the two inputs because of DeMorgan's Theorem.
But how would you do the equivalent on a 3-input AND gate?
Say...
____
A___| \
B___| )___
C___|____ /
I'm trying to understand this because my homework asks me to take a circuit and convert it using NOR synthesis to only use nor gates, and I know how to do it with 2 input gates, but the gate with 3 inputs is throwing me for a spin.
DeMorgan's theorem for 2-input AND would produce:
AB
(AB)''
(A' + B')'
So, yes, the inputs are inverted and fed into a NOR gate.
DeMorgan's theorem for 3-input AND would similarly produce:
ABC
(ABC)''
(A' + B' + C')'
Which is, again, inputs inverted and fed into a (3-input) NOR gate:
___
A--O\ \
B--O ) )O---
C--O/___ /
#SailorChibi has truth tables that show equivalence.
If i haven't made any mistakes it is pretty much the same, invert all 3 of the inputs and you get a NOR
Table:
AND with inverted in is exact the same as
1 1 1 = 1
1 1 1 = 0
1 0 1 = 0
0 1 0 = 0
0 1 1 = 0
0 1 0 = 0
0 0 1 = 0
0 0 0 = 0
NOR with original input
0 0 0 = 1
0 0 1 = 0
0 1 0 = 0
1 0 1 = 0
1 0 0 = 0
1 0 1 = 0
1 1 0 = 0
1 1 1 = 0