SQL: can't understand CASE syntax [closed] - mysql

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I'm trying to solve a Hackerrank problem of detecting the triangle type for which I have the following code:
SELECT A,B,C FROM TRIANGLES
CASE
WHEN (A >= B + C) OR (B >= A + C) OR (C >= A + B) THEN "Not A Triangle"
WHEN A = B AND B = C THEN "Equilateral"
WHEN (A = B AND B = C) OR (B = C AND C = A) OR (C = A AND A = B) THEN "Isosceles"
ELSE "Scalene"
END;
But it does not work:
ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASE
WHEN (A >= B + C) OR (B >= A + C) OR (C >= A + B) THEN "Not A Trian' at line 2

I suppose you want your output like this:
A B C TYPE
6 2 3 Not a Triangle
3 3 3 Equilater
and so on...
Try this:
SELECT A,B,C,
CASE
WHEN (A >= B + C) OR (B >= A + C) OR (C >= A + B) THEN "Not A Triangle"
WHEN A = B AND B = C THEN "Equilateral"
WHEN (A = B AND B = C) OR (B = C AND C = A) OR (C = A AND A = B) THEN "Isosceles"
ELSE "Scalene"
END AS type
FROM TRIANGLES

Not sure what you intended to do, but this should work :
SELECT A,B,C ,
CASE
WHEN (A >= B + C) OR (B >= A + C) OR (C >= A + B) THEN 'Not A Triangle'
WHEN A = B AND B = C THEN 'Equilateral'
WHEN (A = B AND B = C) OR (B = C AND C = A) OR (C = A AND A = B) THEN 'Isosceles'
ELSE 'Scalene'
END
FROM TRIANGLES
You had two mistakes, first, strings need to be wrapped with single quotes, double quotes are for column names. Second, Syntax is:
SELECT <columns>
FROM <Table>
WHERE <Filters>

Related

My code in octave seemed has a problem with the code error

I was trying to run the program but the window says
error: 'a' undefined near line 2, column 10
error: called from
false_position at line 2 column 6
here's my code
function y = false_position(f, a, b, error)
if ~(f(a) < 0)
disp("f(a) must be less than 0")
elseif ~(f(b) > 0)
disp("f(b) must be greater than zero")
else
c = 100000;
while abs(f(c)) > error
%Formula for the x-intercept
c = -f(b) * (b - a) / (f(b) - f(a)) + b;
if f(c) < 0
a = c;
else
b = c;
endif
disp(f(c))
endwhile
x = ["The root is approximately located at ", num2str(c)];
disp(x)
y = c;
endif
endfunction
every time i ran the code, it says like that and i am not really a pro with using the octave. I was kinda hoping someone will help me with this error.
Any answers will do

How to display zero values in mysql query?

This code make an operation on a and b and check if result is equal to c.
If yes, just print this row. My question is how to change this code to display
rows when result (a / b) = 0.
SELECT id, a, b, operation, c
FROM expressions
where
case
when operation LIKE '+' AND (a + b = c) then c
when operation LIKE '-' AND (a - b = c) then c
when operation like '/' AND (a / b = c) then c
when operation like '*' AND (a * b = c) then c
ELSE FALSE END;
Output:
id a b operation c
1 2 3 + 5
4 4 7 * 28
11 0 1 / 0
14 239 0 * 0
15 18 18 - 0
1, 2 rows are ok and printed. 3, 4, 5 rows should be printed but they are not!
When a / b = 0 then second condition in sql query is false - row is not printed, e.g. 0 / 1 = 0. It is 0 and should be printed. In contrart to 1 / 0 which shouldn`t be printed.
My solution is to cast (a / b = c) to unsigned but it is not working?
You shouldn't mix types like boolean and int because implicit conversion occurs.
Use explicit value instead of TRUE/FALSE (0 is treated as FALSE).
SELECT id, a, b, operation, c
FROM expressions
where
case
when operation LIKE '+' AND (a + b = c) then 1
when operation LIKE '-' AND (a - b = c) then 1
when operation like '/' AND (a / b = c) then 1
when operation like '*' AND (a * b = c) then 1
ELSE 0 END = 1;
alternatively:
SELECT id, a, b, operation, c
FROM expressions
where
case
when operation LIKE '+' AND (a + b = c) then TRUE
when operation LIKE '-' AND (a - b = c) then TRUE
when operation like '/' AND (a / b = c) then TRUE
when operation like '*' AND (a * b = c) then TRUE
ELSE FALSE END;
As already pointed out, the issue is that 0 is treated as false.
I would simplify the logic to:
SELECT id, a, b, operation, c
FROM expressions
WHERE (operation LIKE '+' AND (a + b = c) ) OR
(operation LIKE '-' AND (a - b = c) ) OR
(operation LIKE '/' AND (a / b = c) ) OR
(operation LIKE '*' AND (a * b = c) );
I don't think the CASE makes the code more understandable.
If you are concerned about divide-by-zero, then use nullif():
(operation LIKE '/' AND (a / nullif(b, 0) = c) ) OR

How to writer the condition A or B is zero , but not both is zero in MYSQL?

What is the correct syntax for the following SQL statement ?
SELECT * FROM TABLE WHERE (A = 0 AND B != 0) OR (A!=0 AND B=0)
Thanks
Updated: How about negative case? I would like to check if A or B is non-zero , but not both is non-zero, Thanks
SELECT OperateProductId FROM DPS_UserLoginStatus Where OperateProductId <> 0 XOR OperateIssueId <> 0
You're looking for the XOR logical operator:
SELECT * FROM TABLE WHERE A = 0 XOR B = 0
In terms of other operators, a XOR b (commonly a ^ b when used bitwise rather than logical), is equivalent to (a and !b) or (b and !a). It's also equivalent to: (a or b) and (!a or !b). In English, it's exactly what you're looking for: a xor b is true if and only if either a or b is true but both are not true.

Reducing a boolean expression

I am having an expression, suppose,
a = 1 && (b = 1 || b != 0 ) && (c >= 35 || d != 5) && (c >= 38 || d = 6)
I expect it to be reduced to,
a = 1 && b != 0 && (c >= 38 || d = 6)
Does anyone have any suggestions? Pointers to any algorithm?
Nota Bene: Karnaugh Map or Quine-McCluskey are not an option here, I believe. As these methods don't handle grey cases. I mean, expression can only be reduced as far as things are like, A or A' or nothing, or say black or white or absense-of-colour. But here I'm having grey shades, as you folks can see.
Solution: I have written the program for this in Clojure. I used map of a map containing a function as value. That came pretty handy, just a few rules for a few combinations and you are good. Thanks for your helpful answers.
I think you should be able to achieve what you want by using Constraint Handling Rules. You would need to write rules that simplify the OR- and AND-expressions.
The main difficulty would be the constraint entailment check that tells you which parts you can drop. E.g., (c >= 35 || d != 5) && (c >= 38 || d = 6) simplifies to (c >= 38 || d = 6) because the former is entailed by the latter, i.e., the latter is more specific. For the OR-expressions, you would need to choose the more general part, though.
Google found a paper on an extension of CHR with entailment check for user-defined constraints. I don't know enough CHR to be able to tell you whether you would need such an extension.
I believe these kinds of things are done regularly in constraint logic programming. Unfortunatly I'm not experienced enough in it to give more accurate details, but that should be a good starting point.
The general principle is simple: an unbound variable can have any value; as you test it against inequalities, it's set of possible values are restricted by one or more intervals. When/if those intervals converge to a single point, that variable is bound to that value. If, OTOH, any of those inequalities are deemed unsolvable for every value in the intervals, a [programming] logic failure occurs.
See also this, for an example of how this is done in practice using swi-prolog. Hopefully you will find links or references to the underlying algorithms, so you can reproduce them in your platform of choice (maybe even finding ready-made libraries).
Update: I tried to reproduce your example using swi-prolog and clpfd, but didn't get the results I expected, only close ones. Here's my code:
?- [library(clpfd)].
simplify(A,B,C,D) :-
A #= 1 ,
(B #= 1 ; B #\= 0 ) ,
(C #>= 35 ; D #\= 5) ,
(C #>= 38 ; D #= 6).
And my results, on backtracking (line breaks inserted for readability):
10 ?- simplify(A,B,C,D).
A = 1,
B = 1,
C in 38..sup ;
A = 1,
B = 1,
D = 6,
C in 35..sup ;
A = 1,
B = 1,
C in 38..sup,
D in inf..4\/6..sup ;
A = 1,
B = 1,
D = 6 ;
A = 1,
B in inf.. -1\/1..sup,
C in 38..sup ;
A = 1,
D = 6,
B in inf.. -1\/1..sup,
C in 35..sup ;
A = 1,
B in inf.. -1\/1..sup,
C in 38..sup,
D in inf..4\/6..sup ;
A = 1,
D = 6,
B in inf.. -1\/1..sup.
11 ?-
So, the program yielded 8 results, among those the 2 you were interested on (5th and 8th):
A = 1,
B in inf.. -1\/1..sup,
C in 38..sup ;
A = 1,
D = 6,
B in inf.. -1\/1..sup.
The other were redundant, and maybe could be eliminated using simple, automatable logic rules:
1st or 5th ==> 5th [B == 1 or B != 0 --> B != 0]
2nd or 4th ==> 4th [C >= 35 or True --> True ]
3rd or 1st ==> 1st ==> 5th [D != 5 or True --> True ]
4th or 8th ==> 8th [B == 1 or B != 0 --> B != 0]
6th or 8th ==> 8th [C >= 35 or True --> True ]
7th or 3rd ==> 3rd ==> 5th [B == 1 or B != 0 --> B != 0]
I know it's a long way behind being a general solution, but as I said, hopefully it's a start...
P.S. I used "regular" AND and OR (, and ;) because clpfd's ones (#/\ and #\/) gave a very weird result that I couldn't understand myself... maybe someone more experienced can cast some light on it...

Mysql Precedence Logic

Any explanation to the following queries :
Select x FROM y WHERE a = 1 OR a = 2 AND (b = 1 OR b = 2)
why it doesn't return the correct info while this return the correct info :
Select x FROM y WHERE (a = 1 OR a = 2) AND (b = 1 OR b = 2)
Am i missing something here ?
X Y (X OR Y) X OR Y
1 0 1 1
0 1 1 1
1 1 1 1
0 0 0 0
I know in term of precedence the () have priority , but why should i add them the the first part of the query ?
Correct me if I'm wrong
Thank you
AND has a higher precedence than OR so your first query is equivalent to this:
Select x FROM y WHERE a = 1 OR a = 3 OR (a = 2 AND (b = 1 OR b = 2))
Which is not equivalent to
Select x FROM y WHERE (a = 1 OR a = 2 OR a = 3) AND (b = 1 OR b = 2)
I guess you forgot the a = 3 part in your first query.
Operator precedence in MySQL
Because ambiguity is an undesirable trait?
Also, the optimizer will re-order your WHERE Conditions if it thinks it will perform better. Your ambiguity will, therefore, cause different results depending on how/what it evaluates first.
Always be explicit with your intentions.
Using parentheses in your WHERE clause does not just affect precedence but also groups predicates together. In your example the difference in results is more a matter of grouping rather than precedence.
You could think of this: (pN = predicate expression)
WHERE a = 1 OR a = 2 AND (b = 1 OR b = 2)
as:
WHERE p1 OR p2 AND p3
And this:
WHERE (a = 1 OR a = 2 OR a = 3) AND (b = 1 OR b = 2)
as:
WHERE p1 AND p2
and so it becomes clear that the results could be quite different.