SQL: Count columns equal to a value - sql

I have a table and I would like to write query that shows lines which have all columns to '0' but one .
T_CELKO_TEN_IN_ON_TIO(TIO_ID,TIO_1,TIO_2,TIO_3,TIO_4,TIO_5,TIO_6,TIO_7,TIO_8,TIO_9,TIO_10);
I have numbers in it
for example if I have:
1(id) 0 1 1 0 0 0 0 0 0 0
2(id) 0 0 0 0 0 0 0 1 0 0
3(id) 0 1 -2 3 -4 5 -6 7 -8 5
So the query should prints:
2(id) 0 0 0 0 0 0 0 1 0 0
I have wrote this query:
Select * from T_CELKO_TEN_IN_ON_TIO where SUM (CASE WHEN TIO_1='0' THEN 1 ELSE 0 END OR
TIO_2='0' THEN 1 ELSE 0 END OR
TIO_3='0' THEN 1 ELSE 0 END OR
TIO_4='0' THEN 1 ELSE 0 END OR
TIO_5='0' THEN 1 ELSE 0 END OR
TIO_6='0' THEN 1 ELSE 0 END OR
TIO_7='0' THEN 1 ELSE 0 END OR
TIO_8='0' THEN 1 ELSE 0 END OR
TIO_9='0' THEN 1 ELSE 0 END OR
TIO_10='0' THEN 1 ELSE 0 END)=9;
I get an error: An expression of non-boolean type specified in a context where a condition is expected, near 'OR'
but I think even the my query does not work.

I hope I understand this correctly:
SUM is an aggregate function and cannot be used in this context. In my code I test each value (assuming they are numeric) if they are 1, zero or other. All other values are returned as 1000. So the pure summation of these values should only be "1" if there are many "0" and only one single "1" value...
Select * from T_CELKO_TEN_IN_ON_TIO
where ( CASE TIO_1 WHEN 1 THEN 1 WHEN 0 THEN 0 ELSE 1000 END
+ CASE TIO_2 WHEN 1 THEN 1 WHEN 0 THEN 0 ELSE 1000 END
+ CASE TIO_3 WHEN 1 THEN 1 WHEN 0 THEN 0 ELSE 1000 END
+ CASE TIO_4 WHEN 1 THEN 1 WHEN 0 THEN 0 ELSE 1000 END
+ CASE TIO_5 WHEN 1 THEN 1 WHEN 0 THEN 0 ELSE 1000 END
+ CASE TIO_6 WHEN 1 THEN 1 WHEN 0 THEN 0 ELSE 1000 END
+ CASE TIO_7 WHEN 1 THEN 1 WHEN 0 THEN 0 ELSE 1000 END
+ CASE TIO_8 WHEN 1 THEN 1 WHEN 0 THEN 0 ELSE 1000 END
+ CASE TIO_9 WHEN 1 THEN 1 WHEN 0 THEN 0 ELSE 1000 END
+ CASE TIO_10 WHEN 1 THEN 1 WHEN 0 THEN 0 ELSE 1000 END)=1;
UPDATE
I got this wrong, as I thought you want to handle the "1" separately. This should be what you really needed:
Select * from T_CELKO_TEN_IN_ON_TIO
where ( CASE TIO_1 WHEN 0 THEN 1 ELSE 0 END
+ CASE TIO_2 WHEN 0 THEN 1 ELSE 0 END
+ CASE TIO_3 WHEN 0 THEN 1 ELSE 0 END
+ CASE TIO_4 WHEN 0 THEN 1 ELSE 0 END
+ CASE TIO_5 WHEN 0 THEN 1 ELSE 0 END
+ CASE TIO_6 WHEN 0 THEN 1 ELSE 0 END
+ CASE TIO_7 WHEN 0 THEN 1 ELSE 0 END
+ CASE TIO_8 WHEN 0 THEN 1 ELSE 0 END
+ CASE TIO_9 WHEN 0 THEN 1 ELSE 0 END
+ CASE TIO_10 WHEN 0 THEN 1 ELSE 0 END)=9;

May be You want something like this.
Select * from T_CELKO_TEN_IN_ON_TIO
where SUM (CASE WHEN TIO_1='0' THEN 1
WHEN TIO_2='0' THEN 1
WHEN TIO_3='0' THEN 1
WHEN TIO_4='0' THEN 1
WHEN TIO_5='0' THEN 1
WHEN TIO_6='0' THEN 1
WHEN TIO_7='0' THEN 1
WHEN TIO_8='0' THEN 1
WHEN TIO_9='0' THEN 1
WHEN TIO_10='0' THEN 1 ELSE 0 END) = 9;

Related

SQL Server Query equivalent of excel formula

In my excel cellA to F are holding integer values.
IF(COUNTIFS(cellA:cellD,">0")=0,0,IF(COUNTIFS(cellA:cellD,">0")<=IF(AND(OR(cellE>=0),
cellE>0,cellF>0),1,0),"Y",0))
How can I convert the above excel formula into MSSQL query.
Note: In my SQL table named “MyData” the columns are as below and in brackets are corresponding cells in my excel.
You can check this below script works for you or not. If not, some adjustment should done the trick for you as all logic are there that you can be re-used
SELECT
CASE
WHEN
(
CASE WHEN 'CollE(CellA)' > 0 THEN 1 ELSE 0 END +
CASE WHEN 'CollE(CellB)' > 0 THEN 1 ELSE 0 END +
CASE WHEN 'CollE(CellC)' > 0 THEN 1 ELSE 0 END +
CASE WHEN 'CollE(CellD)' > 0 THEN 1 ELSE 0 END
) = 0
THEN "0"
WHEN
(
CASE WHEN 'CollE(CellA)' > 0 THEN 1 ELSE 0 END +
CASE WHEN 'CollE(CellB)' > 0 THEN 1 ELSE 0 END +
CASE WHEN 'CollE(CellC)' > 0 THEN 1 ELSE 0 END +
CASE WHEN 'CollE(CellD)' > 0 THEN 1 ELSE 0 END
) <= (CASE WHEN 'CollE(CellE)' > 0 AND 'CollF(CellF)' > 0 THEN 1 ELSE 0 END)
THEN "Y"
ELSE "0"
END
FROM your_table_name

Excel formulas to SQL

I have this 3 Excel formulas to convert to SQL.
"E1335" =IF(D135=0,0,IF(AND(AU135/D135>=0.8,AU135/D135<1),1,ROUNDDOWN(AU135/D135,0)))
here Comes the Problem in SQL since in this part it links back to (E135) the 1. if calculation and just fail.
"F135" =IF(C135=0,0,IF(E135=1,0,ROUNDDOWN((AU135-E135*D135)/C135,0)))
"G135" =IF(B135=0,0,IF(E135=1,0,ROUNDDOWN((AU135-E135*D135-F135*C135)/B135,0)))
CASE WHEN [D135] = 0 THEN 0
WHEN [AU135] / [D135] >= 0.8 AND [AU135] / [D135] < 1 THEN 1
ELSE Floor ([AU135] / [D135])
END AS E135,
CASE WHEN [C135] = 0 OR E135 1 THEN 0
ELSE Floor ([AU135] - [E135] * [D135] / [C135]) END AS [F135]
I think this is the equivalent in SQL:
The 1st:
CASE
WHEN [D135] = 0 THEN 0
ELSE CASE
WHEN [AU135] / [D135] >= 0.8 AND [AU135] / [D135] < 1 THEN 1
ELSE FLOOR([AU135] / [D135])
END
END
The 2nd:
CASE
WHEN [C135] = 0 THEN 0
ELSE CASE
WHEN [E135] = 1 THEN 0
ELSE FLOOR(([AU135] - [E135] * [D135]) / [C135])
END
END
The 3d:
CASE
WHEN [B135] = 0 THEN 0
ELSE CASE
WHEN [E135] = 1 THEN 0
ELSE FLOOR(([AU135] - [E135] * [D135] - [F135] * [C135]) / [B135])
END
END

Check how many 1 are in the column of a matrix #minizinc

Given a matrix Z[n,m]:
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
1 0 0 0 0
0 0 1 0 0
I'd like to check how many "1" there are in the different columns of the matrix. So given k=1 in this case, the problem should be unsatisfiable since in the column there are 2 "1", so "number of 1">k. I tried in this way but it doesn't work:
constraint forall(i in n, j in m) forall(k in n) k<=( Z[i,j]\/Z[k,j])
Where am I wrong?
In the case I have this variables how I can do?
int b;
int: k;
set of int: PEOPLE = 1..p;
set of int: STOPS = 1..s;
array [1..b, PEOPLE, STOPS] of var bool: Z;
Z[1]
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
1 0 0 0 0
0 0 1 0 0
Z[2]
0 1 0 0 0
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 0 0
p = 5;
s =5;
k=1;
b=2;
So in this case the result should be:
Z[1]: 1 0 1 0 0 , the number of "1" is 2, "2 > K"
Z[2]: 0 1 0 0 0, the number of "1" is 1, "1<=K"
UNSATISFIABLE
I just solved in this way:
array [1..b, STOPS] of var bool: M;
constraint forall (m in 1..b) ( forall (j in STOPS) ( M[m,j]= exists([Z[m,i,j] | i in PEOPLE ])));
constraint forall (m in 1..b) ( let {
var int: s = sum (j in STOPS)(M[m,j]>0);
} in
s <= t );
thank you all for the answers :)

Converting an IIF statement into case statement

Can someone convert this statement into CASE Statement in SQL Server?
IIf((LoanBalance)=0 And CurrentPrincipal<>0 And EndPaymentDate>MaxOfPayment_Date,iif(Pledged_Loan=True,1,2), IIf(LoanBalance=0 And currentprincipal<>0,3,IIf(OffCycle_Payment=True,4,5))) AS POFF
CASE statements cascade (meaning the first matching condition is chosen and no others). So, you don't have to nest the logic using case:
SELECT (CASE WHEN LoanBalance = 0 And CurrentPrincipal <> 0 And
EndPaymentDate > MaxOfPayment_Date and
Pledged_Loan = True
THEN 1
WHEN LoanBalance = 0 And CurrentPrincipal <> 0 And
EndPaymentDate > MaxOfPayment_Date
THEN 2
WHEN LoanBalance = 0 And CurrentPrincipal <> 0
THEN 3
WHEN OffCycle_Payment = True
THEN 4
ELSE 5
END) AS POFF
I think that would be something about like this:
CASE WHEN LoanBalance=0
And CurrentPrincipal<>0
And EndPaymentDate>MaxOfPayment_Date
THEN CASE WHEN Pledged_Loan=True THEN 1 ELSE 2 END
WHEN LoanBalance=0
And currentprincipal<>0
THEN 3
WHEN OffCycle_Payment=True
THEN 4 ELSE 5 END END AS POFF
Ah, and I believe boolean in SQL Server would be stored as a bit, so that would make it this:
CASE WHEN LoanBalance=0
And CurrentPrincipal<>0
And EndPaymentDate>MaxOfPayment_Date
THEN CASE WHEN Pledged_Loan=1 THEN 1 ELSE 2 END
WHEN LoanBalance=0
And currentprincipal<>0
THEN 3
WHEN OffCycle_Payment=1
THEN 4 ELSE 5 END END AS POFF
Try this
SELECT CASE WHEN LoanBalance = 0
AND CurrentPrincipal <> 0
AND EndPaymentDate > MaxOfPayment_Date
THEN CASE WHEN Pledged_Loan
THEN 1
ELSE 2
END
ELSE CASE WHEN LoanBalance = 0 AND currentprincipal <> 0
THEN 3
ELSE CASE WHEN OffCycle_Payment
THEN 4
ELSE 5
END
END
END AS POFF

set column value based on distinct values in another column

I am trying to do something very similar to this question: mysql - UPDATEing row based on other rows
I have a table, called modset, of the following form:
member year y1 y2 y3 y1y2 y2y3 y1y3 y1y2y3
a 1 0 0 0 0 0 0 0
a 2 0 0 0 0 0 0 0
a 3 0 0 0 0 0 0 0
b 1 0 0 0 0 0 0 0
b 2 0 0 0 0 0 0 0
c 1 0 0 0 0 0 0 0
c 3 0 0 0 0 0 0 0
d 2 0 0 0 0 0 0 0
Columns 3:9 are binary flags to indicate which combination of years the member has records in. So I wish the result of an SQL update to look as follows:
member year y1 y2 y3 y1y2 y2y3 y1y3 y1y2y3
a 1 0 0 0 0 0 0 1
a 2 0 0 0 0 0 0 1
a 3 0 0 0 0 0 0 1
b 1 0 0 0 1 0 0 0
b 2 0 0 0 1 0 0 0
c 1 0 0 0 0 0 1 0
c 3 0 0 0 0 0 1 0
d 2 0 1 0 0 0 0 0
The code in the question linked above does something very close but only when it is a count of the distinct years in which the member has records. I need to base the columns on the specific values of the years in which the member has records.
Thanks in advance!
SOLUTION
SELECT member,
case when min(distinct(year)) = 1 and max(distinct(year)) = 1 then 1 else 0 end y1,
case when min(distinct(year)) = 1 and max(distinct(year)) = 2 then 1 else 0 end y1y2,
case when min(distinct(year)) = 1 and max(distinct(year)) = 3 and count(distinct(year)) = 2 then 1 else 0 end y1y3,
case when min(distinct(year)) = 1 and max(distinct(year)) = 3 and count(distinct(year)) = 3 then 1 else 0 end y1y2y3,
case when min(distinct(year)) = 2 and max(distinct(year)) = 2 then 1 else 0 end y2,
case when min(distinct(year)) = 2 and max(distinct(year)) = 3 then 1 else 0 end y2y3,
case when min(distinct(year)) = 3 then 1 else 0 end y3
INTO temp5
FROM modset
GROUP BY member;
UPDATE modset M
SET y1 = T.y1, y2 = T.y1, y3 = T.y3, y1y2 = T.y1y2, y1y3 = T.y1y3, y2y3 = T.y2y3, y1y2y3 = T.y1y2y3
FROM temp5 T
WHERE T.member = M.member;
What is the query you are using to return the indicators of the years the member has records in?
It sounds like you would want take your query results and use it in your update:
http://dev.mysql.com/doc/refman/5.0/en/update.html
It may look something like this:
UPDATE targetTable t, sourceTable s
SET t.y1 = s.y1, t.y2 = s.y2 -- (and so on...)
WHERE t.member = s.member AND t.year = m.year;