I have 2 datasets , one is base dateset and the other is subset of it , I want to create a dataset where the record is not present in the subset dataset but present in base dataset. So if combination of acct_num test_id trandate actual_amt is not present in the subset then it should come in the resultant dataset.
DATA base;
INPUT acct_num test_id tran_date:anydtdte. actual_amt final_amt final_amt_added ;
format tran_date date9.;
DATALINES;
55203610 2542 12-jan-20 30 45 45
16124130 8062 . 56 78 78
16124130 8062 14-dec-19 8 78 78
80479512 2062 19-mar-19 32 32 32
70321918 2062 20-dec-19 1 93 54
17312410 6712 . 45 90 90
17312410 6712 15-jun-18 0 90 90
74623123 2092 17-aug-18 34 87 87
24245321 2082 22-jan-17 22 56 67
;
run;
data subset;
input acct_num test_id tran_date:anydtdte. actual_amt final_amt final_amt_added ;
format tran_date date9.;
DATALINES;
55203610 2542 12-jan-20 30 45 45
16124130 8062 . 56 78 78
16124130 8062 14-dec-19 8 78 78
17312410 6712 . 45 90 90
74623123 2092 17-aug-18 34 87 87
24245321 2082 22-jan-17 22 56 67
;
run;
data that I want
80479512 2062 19-mar-19 32 32 32
70321918 2062 20-dec-19 1 93 54
17312410 6712 15-jun-18 0 90 90
I have tried using not in function in SQL but it does not match multiple variable in that statement.
Any help will be appreciated.
It is about how to solve minus set, see Except operator
proc sql noprint;
create table want as
select * from base
except
select * from subset
;
quit;
Make a list of all the observed values in subset, then simply merge the base file with the combinations found in subset and output the records that are in base only.
Note it is important to restrict subset_combinations to non-duplicates and only keep the sorting variables, else you may overwrite the values from subset.
proc sort data=base;
by acct_num test_id tran_date actual_amt;
proc sort data=subset out=subset_combinations (keep=acct_num test_id tran_date actual_amt) nodupkey;
by acct_num test_id tran_date actual_amt;
data want;
merge base (in=in1) subset_combinations (in=in2);
by acct_num test_id tran_date actual_amt;
if in1 & ^in2;
run;
I have a table named #hierachy, for which there are three columns:
childId, parentId, and linkType
The data is as follows:
childID parentID linktype
30 31 53
31 42 56
31 415349 18
31 437327 18
31 438333 18
35 32 56
32 35 18
32 38 52
32 39 52
32 439395 51
34 40 51
I'd like to spot any reverse repetitions and return a "true" or "1" if there is a reverse repetition between the first two columns childID and parentID
For example, the sixth and seventh lines are reversely similar: One is 35 then 32 and the other is the reverse: 32 and 35.
Thank you!
You can use exists:
select t.*,
(case when exists (select 1
from t t2
where t2.childID = t.parentID and t2.parentID = t.childID
)
then 1 else 0
end) as is_reversed
from t;
If the data is being returned from a stored procedure, you need to either put this logic in the stored procedure or put the data into a table and run the logic using that table.
id varname 1area 2area 3area 4area
------------------------------------
1 abc 345 3.7 34 87
1 pqr 46 67 78 55
1 lmn 67 99 33 44
2 xyz 78 78 33 32
I need to calculate SUM of column query.
Is it possible to get column count using while loop?
You probably want to do a SUM() of the Narea column group by your id column like
select id, sum(1area),
sum(2area), sum(3area), sum(4area)
from tbl1
group by id;
I have a query returned value in this form (query return more than 50 columns).
1-99transval 100-200transval 200-300transval ... 1-99nontransval 100...
50 90 80 67 58
For a row value. I want these details to be converted into columns and take the following shape:
Range Transval NonTransval
1-99 50 67
100-200 90 58
In pure SQL, it will need a lot of coding because you will have to manually put the range as there is no relation between the values and the range at all. Had there been a relationship, you could use CASE expression and build the range dynamically.
SQL> WITH DATA AS
2 (SELECT 50 "1-99transval",
3 90 "100-200transval",
4 80 "200-300transval",
5 67 "1-99nontransval",
6 58 "100-200nontransval",
7 88 "200-300nontransval"
8 FROM dual
9 )
10 SELECT '1-99' range,
11 "1-99transval" transval,
12 "1-99nontransval" nontransval
13 FROM DATA
14 UNION
15 SELECT '100-200' range,
16 "100-200transval",
17 "100-200nontransval" nontransval
18 FROM DATA
19 UNION
20 SELECT '200-300' range,
21 "200-300transval",
22 "200-300nontransval" nontransval
23 FROM DATA;
RANGE TRANSVAL NONTRANSVAL
------- ---------- -----------
1-99 50 67
100-200 90 58
200-300 80 88
From Oracle database 11g Release 1 and above, you could use UNPIVOT
SQL> WITH DATA AS
2 (SELECT 50 "1-99transval",
3 90 "100-200transval",
4 80 "200-300transval",
5 67 "1-99nontransval",
6 58 "100-200nontransval",
7 88 "200-300nontransval"
8 FROM dual
9 )
10 SELECT *
11 FROM DATA
12 UNPIVOT( (transval,nontransval)
13 FOR RANGE IN ( ("1-99transval","1-99nontransval") AS '1-99'
14 ,("100-200transval","100-200nontransval") AS '100-200'
15 ,("200-300transval","200-300nontransval") AS '200-300'));
RANGE TRANSVAL NONTRANSVAL
------- ---------- -----------
1-99 50 67
100-200 90 58
200-300 80 88
Above, in your case you need to replace the WITH clause with your existing query as a sub-query. You need to include other columns in the UNION.
In PL/SQL, you could (ab)use EXECUTE IMMEDIATE and get the "range" by extracting the column names in dynamic sql.
Although, it would be much better to modify/rewrite your existing query which you have not shown yet.
If you are using Oracle 11g version then you can use the UNPIVOT feature.
CREATE TABLE DATA AS
SELECT 50 "1-99transval",
90 "100-200transval",
80 "200-300transval",
67 "1-99nontransval",
58 "100-200nontransval",
88 "200-300nontransval"
FROM dual
SELECT *
FROM DATA
UNPIVOT( (Transval,NonTransval) FOR Range IN ( ("1-99transval","1-99nontransval") as '1-99'
,("100-200transval","100-200nontransval") as '100-200'
,("200-300transval","200-300nontransval") as '200-300'))
http://sqlfiddle.com/#!4/c9747/3/0
I have a database table like this:
C1 C2 C3
---------------------
81 1 10
81 2 20
81 3 30
82 1 40
82 2 50
82 3 60
Note that it has no primary key.
I want to run a query which prints C1 and the various occurrences of C3 values with it. It basically gives me the output in a serialised format. I mean something like this :
81 10 20 30
82 40 50 60
The one approach I can think of is using a rownum but am not sure if that;s the way to go about it. Is there a better way for doing this ?
The query will depend on DBMS you use.
In MySQL, you can use group_concat function:
select c1, group_concat(c3 separator ' ')
from t
group by c1;