TSQL case with or in it - tsql

My problem:
In my WHERE statement "Shock.Comment" is null-able.
The result i want to achieve is if the parameter
#missingComments = 1
then i want to get all Shocks that has string empty or null.
What i have TRIED:
WHERE Shock.Comment = CASE WHEN #missingComments = 1 THEN '' OR IS NULL END
How can i get all posts with comment = null or empty when
#missingComments = 1

This is one way:
WHERE ( (#missingComments != 1)
OR (COALESCE(Shock.Comment, '') = '' )
Note that any answer to this using a single static SQL query will not be able to use any indexes on Shock.Comment to improve performance.

CASE is very picky, and can't evaluate to BIT, and you can't do v = A OR B, you have to do v = A OR v = B. This is the solution I came up with.
WHERE #missingComment = 0 OR (Shock.Comment = NULL OR Shock.Comment = '')

Related

Creating variable from other variables in MATLAB: code with reproduction

I have a question regarding this type of code:
First = ["A","B","C"];
Second = ["D","E","F"];
Group = ["First", "Second"];
for gr = Group
current = gr;
for number = 1:numel(current)
my_variable(number) = current(number);
end
end
That's the reproduction of my problem. In this case my_variable is equal to "First" for example. But I wanted it to be "A" then "B" then "C" from variable named "First".
For my understanding this code should do the following:
1st step: for gr = Group means gr = First to Second
2nd step: current = gr; means current = First
3rd step: for number = 1:numel(current) means number = 1:3 (number of elements in "First")
4th step: my_variable(number) = current(number); means my_variable = First(1) = "A"
Instead of that I get my variable equal to "First" or "Second".
I hope you understand what I mean.
P.S. the string arrays I'm using with double quotes (" ") like First = ["A","B","C"]; are only available in Matlab 2016b or later.
You should use cell arrays to do this:
first = {'A','B','C'};
second = {'D','E','F'};
group = {first, second};
for group_ind = 1:numel(group)
current = group{group_ind};
my_variable = cell(1,numel(current));
for number = 1:numel(current)
my_variable{number} = current{number};
disp(my_variable)
end
end
For first and second, you can also use the string arrays:
first = ["A","B","C"];
second = ["D","E","F"];
group = {first, second};
for group_ind = 1:numel(group)
current = group{group_ind};
my_variable = strings(1,numel(current));
for number = 1:numel(current)
my_variable(number) = current(number);
disp(my_variable)
end
end

Matlab Create an array with element of a for loop

Here's my code:
N = 1:999;
for i = N
if rem(i,3) == 0 || rem(i,5) == 0
v(i,1) = i
end
end
Te problem is that I get an Array with some zeros in, but I just want an an arraywith the values comforming to my conditions.
How can I fix it?
Thank you!
I think the OP is looking for a result like:
v= N( (rem(N,3)==0) | (rem(N,5)==0) );
though without looping... :-)
I'm assuming that you're using a loop for a reason, and am not removing it from my solution. However, loops should be avoided where possible.
If I understand your question, you're trying to store only those values of i which correspond to a true conditional evaluation. You're problem is that you're using i as your index value inside the assignment statement. Use the end index keyword. Like so:
N = 1:999;
v = [];
for i = N
if rem(i,3) == 0 || rem(i,5) == 0
v(end+1) = i
end
end

Iterate through a MATLAB structure numerically

Is it possible to iterate through a MATLAB structure numerically like a vector instead of using the field names?
Simply, I am trying to do the following inside an EML block for Simulink:
S.a.type = 1;
S.a.val = 100;
S.a.somevar = 123;
S.b.type = 2;
S.b.val = 200;
S.b.somevar2 = 234;
S.c.type = 3;
S.c.val = 300;
S.c.somevar3 = 345;
for i = 1:length(s)
itemType = S(i).type;
switch itemType
case 1
val = S(i).val * S(i).somevar1;
case 2
val = S(i).val * S(i).somevar2;
case 3
val = S(i).val * S(i).somevar3;
otherwise
val = 0
end
end
disp(var);
You should be able to generate the fieldnames dynamically using sprintf using something like the following:
for i = 1:length(s)
theFieldName = sprintf('somevar%d', S(i).type);
val = S(i).val * getfield(S(i), theFieldName);
end
You need to use the field names, but you can do so dynamically. If you have a structure defined as:
s.field1 = 'foo';
s.field2 = 'bar';
Then you can access the field field1 with either
s.field1
s.('field1')
The only thing you need is the function fieldnames to dynamically get the field names such that your code example will look somewhat like
elements = fieldnames(S);
for iElement = 1:numel(elements)
element = S.(elements{iElement});
itemType = element.type;
switch itemType
case 1
val = element.val * element.somevar1;
case 2
val = element.val * element.somevar2;
case 3
val = element.val * element.somevar3;
end
end
If those are the exact field names, you should do some other things. First of all you would need to rethink your names and secondly you could use part of Matt's solution to simplify your code.

Boolean expressions with strings and numbers

I have two variables in my pre block, and I need a third (a boolean) that identifies whether certain properties hold of those two:
str = "some string from a datasource";
qty = 15; //Also from a datasource
The third variable, valid, needs to be true when str is not empty and qty is greater than 0. How do I do that?
Oh! I just figured it out:
valid = not (str eq "") && (qty > 0);
I had some syntax errors in the rest of my ruleset; that's where the trouble was coming from.

SQL Sever: in...case...in WHERE clause

I need to code up a query for something like this:
Select [something]
Where
condition in
case
when (if another_condition = A and 3rd Condition = B) then (C,D)
when (if another_condition = N and 3rd Condition = E) then (F,G)
else (J,K)
end
essentially, what I want is if A and B are met, condition could be set to either C or D, if N or E are met, then condition could be set to F or G, else condition set to J or K.
However, when I run this, I kept getting
Incorrect syntax near the keyword 'Case'.
Please help! Thanks!
Maybe this:
Where (Another_Condition = 'A' And Third_Condition = 'B' And Condition in ('C','D'))
Or
(Another_Condition = 'N' and Third_Condition = 'E' And Condition in ('F','G'))
Or
Condition In ('J','K')
Be very careful about mixing and's and or's in a where clause. Parenthesis are important.
How about this - the UNION subquery will give you the full result set within the subquery. Then you can say 'WHERE condition IN ' (subquery). Like this:
SELECT [something]
WHERE
condition IN
(SELECT CASE WHEN (another_condition = A AND 3rd Condition = B) THEN C
WHEN (another_condition = N AND 3rd Condition = E) THEN F
ELSE J
END AS Value
UNION
SELECT CASE WHEN (another_condition = A AND 3rd Condition = B) THEN D
WHEN (another_condition = N AND 3rd Condition = E) THEN G
ELSE K
END AS Value
)
I'd probably go with G Mastro's approach of expanding the query as a Boolean expression. While the nested query approach will work, the intent of the code is less obvious IMO.
Having said that, if there are a lot of cases in your CASE statement, you may want to consider reshaping your data, because no matter how you write the query, it boils down to a big Boolean expression.