SQL Case statements deriving new attribute - sql

I have a table with indicators of directions and based on that I need to derive a new column which tells whether its IN or Out
ORG_IN ORG_OUT DEST_IN DEST_OUT Direction
0 0 0 0 NULL
0 0 0 1 Out
0 0 1 0 In
0 1 0 0 Out
0 1 0 1 Out
0 1 1 0 NULL
1 0 0 0 In
1 0 0 1 NULL
1 0 1 0 In
This is the query where ill derived the direction
http://sqlfiddle.com/#!4/a9f82/1
Do you think it will cover all cases in future for all the combinations. Right now I can see only above combinations. Any better way to write the sql.

select t.*, case ORG_IN + DEST_IN - ORG_OUT - DEST_OUT
when 2 then 'In'
when 1 then 'In'
when 0 then null
when -1 then 'Out'
when -2 then 'Out'
end as Direction
from tablename t
I can't figure out any more valid combinations. However, I'd recommend a check constraint that makes sure no invalid combinations are entered:
check (ORG_IN + ORG_OUT < 2 and DEST_IN + DEST_OUT < 2)

Related

A problem about the difference of SHA-1 logical functions between wikipedia and FIPS 180-4

wikipedia
standard manual
when calculating the SHA-1, we need a sequence of logical functions, f0, f1,…, f79,
I noticed that the function definitions in Wikipedia and the standard manual are different.
oddly, when I chose the ones in the standard manual, the SHA-1 result went wrong.
I used online sha-1 calculators and found that everyone uses the functions written in wikipedia.
Why?
Here are the truth tables for both versions of 'choose' (0..19) and 'majority' (40..59) (for 'parity' 20..39 and 60..79 both sources use xor). Please identify the rows for which the ior result is different from the xor result; those are the cases for which the two formulas produce different results.
x
y
z
x^y
¬x^z
ior
xor
0
0
0
0
0
0
0
0
0
1
0
1
1
1
0
1
0
0
0
0
0
0
1
1
0
1
1
1
1
0
0
0
0
0
0
1
0
1
0
0
0
0
1
1
0
1
0
1
1
1
1
1
1
0
1
1
x
y
z
x^y
x^z
y^z
ior
xor
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
1
0
0
0
0
0
0
0
1
1
0
0
1
1
1
1
0
0
0
0
0
0
0
1
0
1
0
1
0
1
1
1
1
0
1
0
0
1
1
1
1
1
1
1
1
1
1
Hint: there are no differences. The results are always the same, and it doesn't matter which formula you use, as long as you do it correctly you get the correct result.
In fact, on checking my copy of 180-4 this is even stated in section 4.1, immediately above the section you quoted:
... Each of the algorithms [for SHA-1, SHA-256 group, and SHA-512 group] include Ch(x, y, z)
and Maj(x, y, z) functions; the exclusive-OR operation (⊕ ) in these functions may be replaced
by a bitwise OR operation (∨) and produce identical results.
If something you did 'went wrong', it's because you did something wrong, but nobody here is psychic so we have absolutely no idea at all what you did wrong.

SQL: Is there a way I can find whether a value is within a specific index range of another value?

I have two columns filled with mostly 0's and a few 1's. I want to check whether IF a 1 occurs in the first column, a 1 in the second column occurs within a range of 5 rows of that index. So for example, lets say a 1 occurs in column 1 row 83, then I would like to return TRUE if one or more 1's occur in column 2 row 83-88, and FALSE if this is not the case. Examples of this are listed in the code block. I would want to count the number of TRUE and FALSE occurrences.
TRUE:
0 0
0 0
0 0
1 1
0 0
0 0
0 0
0 0
0 0
0 0
TRUE:
0 0
0 0
0 0
1 0
0 0
0 0
0 1
0 1
0 0
0 0
FALSE:
0 0
0 0
0 1
1 0
0 0
0 0
0 0
0 0
0 0
0 1
I have no idea where to begin, so I do not have any code to start with:(
Kind regards,
Kai
Assuming you have an ordering column, you can use window functions:
select (case when count(*) = 0 then 'false' else 'true' end)
from (select t.*,
max(col2) over (order by <ordering column>
rows between current row and 4 following
) as max_col2_5
from t
) t
where col1 = 1 and max_col2_5 = 1;

Add condition in SQL query based on table value

I am using oracle as my database. I want to add condition in sql query based on table data. In the table if CT_GENERAL is 1 then i want to add another condition in my sql query.( CST_GENERAL = USER ARGUMENT ).
select * from ch_caseinfo where
case when ct_general = 1
then cst_general = %3
end
%3 = Funding
//TABLE STRUCTURE
//CH_CASEINFO
VOLUMEID | CT_ADVERSE | CT_GENERAL | CT_HA | CT_MI | CST_GENERAL | CST_MI
149634 0 0 0 0
161077 0 0 0 0
161147 0 1 0 1 Funding Composition/ingredients
161268 0 1 0 0 Funding
161306 0 1 0 0 Manufacturing
240131 0 1 1 0 Funding
239364 0 0 0 0
239364 0 0 0 0
147434 0 0 0 0
147466 0 0 0 0
158990 0 1 0 1 Funding Administration
98863 1 1 1 1 Funding Disposal
159757 1 1 1 1 Funding Disposal
98863
191039 1 1 0 0 Other
97007 0 0 0 0
ORA-00905: missing keyword
00905. 00000 - "missing keyword"
You need to form your where clause to evaluate an expression that is true when you don't want to include the filter (CT_GENERAL is 0). Considering the example below, if ct_general = 0 then cst_general will always equal cst_general (unless null -- if that is a possibility, you need to accommodate nulls).
SELECT *
FROM ch_caseinfo
WHERE CASE WHEN ct_general = 0 THEN cst_general ELSE USERARGUMENT END = cst_general
AND OTHERCRITERIA = CRITERIA

How do I grab rows surrounding a flagged value?

I'm starting with a table like this:
code new_code_flag
abc123 0
xyz456 0
wer098 1
jio234 0
bcx190 0
eiw157 0
nzi123 0
epj676 0
ere654 0
yru493 1
ale674 0
I want to grab the 2 records before and 2 records after each value where "new_code_flag"=1. I want my output to look like this:
code new_code_flag
abc123 0
xyz456 0
wer098 1
jio234 0
bcx190 0
epj676 0
ere654 0
yru493 1
ale674 0
Any help on how to do this in SQL or SAS?
SQL tables represent unordered sets. Hence, in SQL you need to have a column that specifies the ordering. Assuming you do, you can do something like:
with t as (
select t.*, row_number() over (order by ?) as seqnum
from tbl t
)
select t.*
from t
where exists (select 1
from t t2
where t2.new_code_flag = 1 and
t.seqnum between t2.seqnum - 2 and t2.seqnum + 2
);
You could create two lag and two lead copies of the flag variable and then test if any of the 5 variables are 1 (true).
data have;
input code $ flag ;
cards;
abc123 0
xyz456 0
wer098 1
jio234 0
bcx190 0
eiw157 0
nzi123 0
epj676 0
ere654 0
yru493 1
ale674 0
;
data want ;
set have ;
set have(keep=flag rename=(flag=lead1_flag) firstobs=2) have(drop=_all_ obs=1);
set have(keep=flag rename=(flag=lead2_flag) firstobs=3) have(drop=_all_ obs=2);
lag1_flag=lag1(flag);
lag2_flag=lag2(flag);
if lag1_flag or lag2_flag or flag or lead1_flag or lead2_flag ;
run;
Results
lead1_ lead2_ lag1_ lag2_
Obs code flag flag flag flag flag
1 abc123 0 0 1 . .
2 xyz456 0 1 0 0 .
3 wer098 1 0 0 0 0
4 jio234 0 0 0 1 0
5 bcx190 0 0 0 0 1
6 epj676 0 0 1 0 0
7 ere654 0 1 0 0 0
8 yru493 1 0 . 0 0
9 ale674 0 . . 1 0
data want(drop=_: i);
merge have have(keep=flag firstobs=3 rename=(flag=_flag));
if flag or _flag then i=1;
if 0<i<=3 then do;
output;
i+1;
end;
else delete;
run;

sas variable difference with same id

I appreciate a lot you guys, especially when i got problems about modulating with SAS.
I have a data set like a follows.
ID key score
10002817 200207826243 0
10002817 200207826271 0
10002817 200208532180 0
10002976 200301583978 0
10003685 200302311690 0
10006588 200401613047 0
10006588 200502882618 0
10009377 201007510866 1
10009377 201111777969 0
10011044 200801328219 2
10011044 200803290654 3
10011044 200803290728 1
10011044 200803290905 1
10011044 200803291161 0
Sometimes the id is repeated in the data or not.
I want to see maximum difference in score according to ID.
That is, a form like followings.
ID key score diff_score
10002817 200207826243 0 0
10002817 200207826271 0 0
10002817 200208532180 0 0
10002976 200301583978 0 0
10003685 200302311690 0 0
10006588 200401613047 0 0
10006588 200502882618 0 0
10009377 201007510866 1 1
10009377 201111777969 0 1
10011044 200801328219 2 3
10011044 200803290654 3 3
10011044 200803290728 1 3
10011044 200803290905 1 3
10011044 200803291161 0 3
How can i make this with SAS?
It would be helpful if you help me.
Thank you all.
You can do this using proc sql:
proc sql;
create table want as
select ID, key, score, max(score)-min(score) as diff_score
from have
group by ID;
quit;
One of the advantages of using proc sql is your data doesn't need to be sorted for this to work.