This is table 1:
col_1 col_2 date_1
----- ----- ------
1 3 2016
2 4 2015
And this is table 2:
col_3 col_4 date_2
----- ----- ------
5 8 2014
6 9 2012
I want a result like this:
col_1 col_2 col_3 col_4 date_1 date_2
----- ----- ----- ----- ------ ------
1 3 NULL NULL 2016 NULL
2 4 NULL NULL 2015 NULL
NULL NULL 5 8 NULL 2014
NULL NULL 6 9 NULL 2012
Any solutions?
Using Union All and Null as a different column:
SELECT col_1, col_2, NULL as col_3, NULL as col_4,
date_1, NULL as date_2
FROM table_1
Union All
SELECT NULL, NULL, col_3, col_4, NULL, date_2
FROM table_2
Use union all:
select col_1, col_2, NULL as col_3, NULL as col_4, date_1, NULL as date_2
from table1
union all
select NULL, NULL, col_3, col_4, NULL, date_2
from table2;
Using Join:
select t1.col_1,t1.col_2,t2.col_3,t2.col_4,t1.date_1,t2.date_2
from t1
full join t2
on t1.col_1=t2.col_3
order by t1.col_1;
Related
I have a table from which I want to generate 18 digit code.
Below is the 18 digit code sample which I want.
R-AP-AP01-SMT-4567
Also for generating the above sample code, here is the data and its logic:
R - Fix value
AP – (2 digit state code from STATE column)
EAST- (From ZONE_NAME column from query below
SMT – (From FORMAT_CODE column from below query)
4567 – (From Store Code column from below query)
SELECT STATE, STORE_CODE, ZONE_NAME FROM TBL_RRSOC_STORE_INFO;
AND
select FORMAT_CODE from TBL_SITE_STORE_FORMAT;
How can it be achieved?
Update
Below is the table description
Table name:- TBL_RRSOC_STORE_INFO
Name Null Type
--------------------------- -------- --------------
RRSOC_ID NOT NULL NUMBER
STORE_CODE NOT NULL NVARCHAR2(55)
STATE NVARCHAR2(55)
SLP_STATE NVARCHAR2(100)
FORMAT_GROUP NVARCHAR2(100)
Table name:- TBL_SITE_STORE_FORMAT
Name Null Type
------------ ---- -------------
ID VARCHAR2(20)
STORE_FORMAT VARCHAR2(100)
ISACTIVE VARCHAR2(3)
FORMAT_GROUP VARCHAR2(100)
FORMAT_CODE VARCHAR2(50)
The way you put it, you'd join those tables somehow (cross join is as good as any other, as you didn't explain it better) and concatenate column values.
Something like this:
SQL> with
2 tbl_rrsoc_store_info (state, store_code, zone_name) as
3 (select 'AP', 'EAST', 'SMT' from dual union all
4 select 'NY', 'WEST', 'XYZ' from dual
5 ),
6 tbl_site_store_format (format_code) as
7 (select 4567 from dual)
8 --
9 select 'R' ||'-'|| r.state ||'-'|| r.store_code ||'-'|| r.zone_name ||'-'|| s.format_code result
10 from tbl_rrsoc_store_info r cross join tbl_site_store_format s;
RESULT
--------------------
R-AP-EAST-SMT-4567
R-NY-WEST-XYZ-4567
SQL>
Function returns a value; you didn't explain how it should look like (which parameters it accepts) so I chose to pass state, presuming it is unique within the table.
Sample data:
SQL> select * From tbl_rrsoc_store_info;
ST STOR ZON
-- ---- ---
AP EAST SMT
NY WEST XYZ
SQL> select * from tbl_site_store_format;
FORMAT_CODE
-----------
4567
Function:
SQL> create or replace function f_test (par_state in varchar2)
2 return varchar2
3 is
4 retval varchar2(18);
5 begin
6 select 'R' ||'-'|| r.state ||'-'|| r.store_code ||'-'|| r.zone_name ||'-'|| s.format_code
7 into retval
8 from tbl_rrsoc_store_info r cross join tbl_site_store_format s
9 where r.state = par_state;
10
11 return retval;
12 end;
13 /
Function created.
Testing:
SQL> select r.state, f_test(r.state) result
2 from tbl_rrsoc_store_info r;
ST RESULT
-- --------------------
AP R-AP-EAST-SMT-4567
NY R-NY-WEST-XYZ-4567
SQL>
For every row of my data set, there exist data for the only one of the two options for calculation and the other columns are Null.
My goal is to find simplest way to select not null result of calculation for each row. Expected result:
ROW_NUM result
-------- -------
1 4.5
2 4.56
My code:
With DATASET AS (
-- column 1 is just for row number,
-- column 2 and 3 for caculation option1,
--- columns 4~6 for caculation option2
SELECT 1 ROW_NUM, NULL time1, NULL qty1, 2 time2_1, 2.5 time2_2, 1 qty2
FROM DUAL
UNION
SELECT 2 ROW_NUM, 4.56 time1, 1 qty1, NULL time2_1, NULL time2_2, NULL qty2
FROM DUAL
)
SELECT ROW_NUM, time1/qty1 OPTION1, (time2_1+time2_2)/qty2 OPTION2
FROM DATASET;
Result:
ROW_NUM OPTION1 OPTION2
-------- ------- ---------
1 4.5
2 4.56
You can decode and use different representation when null:
SELECT ROW_NUM, decode(time1/qty1,null,(time2_1+time2_2)/qty2,time1/qty1) result FROM DATASET;
Or nvl
SELECT ROW_NUM, nvl(time1/qty1,(time2_1+time2_2)/qty2,time1/qty1) result FROM DATASET;
NVL lets you replace null (returned as a blank) with a string in the results of a query.
use COALESCE function as following:
With DATASET AS (
--each row contain information for either option1 or 2
SELECT *
FROM
(
--column 1 is just for row number, column 2 and 3 for caculation option1, columns 4~6 for caculation option2
SELECT 1 ROW_NUM, NULL time1, NULL qty1 , 2 time2_1 , 2.5 time2_2, 1 qty2 FROM DUAL
UNION
SELECT 2 ROW_NUM, 4.56 time1 , 1 qty1 , NULL time2_1 , NULL time2_2 , NULL qty2 FROM DUAL
)
)SELECT ROW_NUM, coalesce(time1/qty1,(time2_1+time2_2)/qty2) as result FROM DATASET;
db<>fiddle demo
Cheers!!
I had a situation like to read max(end_time_) when delete_reason_ != 'deleted', but when end_time_ has null, the query should return 2nd row only.
SELECT MAX(END_TIME_) FROM TASK_HISTORY WHERE DELETE_REASON_ != 'deleted'
is returning me 1st Row. But, my desired result should return 2nd row. As per Oracle documentation, Aggregate functions like max, sum, min shouldn't consider null values unlike Count.
Is there a way to get the Null value as max if null present, otherwise, max(end_time_) should be my desired output.
Any help will be appreciated.
thank you.
If I understood you correctly, here's one option:
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
SQL> with test (end_time_, delete_reason_) as
2 (select date '2017-12-13', 'completed' from dual union
3 select null, null from dual union
4 select date '2017-12-12', 'deleted' from dual union
5 select date '2018-01-05', 'unknown' from dual
6 ),
7 inter as
8 (select row_number() over (order by end_time_ desc) rn,
9 end_time_, delete_reason_
10 from test
11 where nvl(delete_reason_, 'x') <> 'deleted'
12 )
13 select end_time_ From inter
14 where rn = 1;
END_TIME_
----------
NULL
SQL>
SQL> with test (end_time_, delete_reason_) as
2 (select date '2017-12-13', 'completed' from dual union
3 -- select null, null from dual union
4 select date '2017-12-12', 'deleted' from dual union
5 select date '2018-01-05', 'unknown' from dual
6 ),
7 inter as
8 (select row_number() over (order by end_time_ desc) rn,
9 end_time_, delete_reason_
10 from test
11 where nvl(delete_reason_, 'x') <> 'deleted'
12 )
13 select end_time_ From inter
14 where rn = 1;
END_TIME_
----------
05.01.2018
SQL>
Finally I got a query something like this to achieve null value as result instead of date when I use max() function.
SELECT task_def_key_
, CASE WHEN MAX(CASE WHEN end_time_ IS NULL THEN 1 ELSE 0 END) = 0 THEN MAX(end_time_) END
FROM TASK_HISTORY WHERE DELETE_REASON_ != 'deleted'
GROUP BY task_def_key_
select * from (select * from TASK_HISTORY where DELETE_REASON_ != 'deleted' order by end_time desc) where rownum=1
This will work for your problem
table1 dwh.fct_nc_crm_dims#etl4
Name Null Type
--------------------------- -------- -------------
BAN_KEY NOT NULL NUMBER(9)
CLIENT_NAME VARCHAR2(300)
CLIENT_INN VARCHAR2(40)
EFFECTIVE_DATE NOT NULL DATE
EXPIRATION_DATE DATE
table2 etl.stg_acrm_ban_attr#etl2
Name Null Type
---------------- ---- -------------
SEGMENT_CRM VARCHAR2(150)
BAN_KEY VARCHAR2(32)
table3 evkuzmin_b2b_churn_ban_segment
Name Null Type
----------- ---- -------------
BAN_KEY NUMBER(9)
CLIENT_NAME VARCHAR2(300)
CLIENT_INN VARCHAR2(40)
SEGMENT_CRM VARCHAR2(150)
My query. Here I join first 2 tables on ban_key and insert the result into the third table. The types match, but I still get the error. Why?
INSERT INTO evkuzmin_b2b_churn_ban_segment
SELECT a.ban_key, a.client_name, a.client_inn, b.segment_crm FROM(
SELECT ban_key, client_name, client_inn
FROM(
SELECT ban_key,client_name, client_inn,
ROW_NUMBER() OVER (PARTITION BY ban_key, client_inn ORDER BY effective_date DESC) AS rn
FROM dwh.fct_nc_crm_dims#etl4
WHERE expiration_date >= TO_DATE('01.04.2016','DD.MM.YYYY') OR expiration_date IS NULL --1ST DAY OF REPORTING PERIOD
)
WHERE rn = 1
) a, etl.stg_acrm_ban_attr#etl2 b
WHERE a.ban_key = b.ban_key;
Your ban_key in evkuzmin_b2b_churn_ban_segment(table 3) is a Number as compare to the other two tables(varchar).
your a.ban_key is number and b.ban_key is varchar
I have a table TABLE101 with the following fields:
COL1 COLB COLC COLD
ACT1 UYT 876 KJH
ACT2 CFG 976 TRY
I have another table TABLE102 as under:
COL1 COL2 COL3 COL4 COL5 COL6
ACt1 A1_B1 98 UI 2
ACT2 C1 00 N
ACT2 D1_D4 1 PP Y RT
ACT2 A1_F1 9T UI 2
Now i want to insert data into a 3rd table which has all the fields from table101 and table 102 like:
COL1 COLB COLC COLD COL2 COL3 COL4 COL5 COL6 LVL
ACT1 UYT 876 KJH 1
ACt1 A1_B1 98 UI 2 2
ACT2 CFG 976 TRY 1
ACT2 C1 00 N
ACT2 D1_D4 1 PP Y RT 2
ACT2 A1_F1 9T UI 2 2
So 1st i need to insert 1st row from table101 and for corresponding COL1 value i need to insert row from TABLE102.
In table101, COL1 is unique but in table 101 col1 can have multiple rows.
If i insert row from table101, i have to set lvl col to 1 and if i insert form table102 i set lvl col to 2
How can i do so?
You can use UNION ALL for combining your tables. Then use INSERT ... SELECT syntax for inserting into 3rd table.
SELECT COL1 , COLB, COLC , COLD, NULL AS COL2, NULL AS COL3, NULL AS COL4, NULL AS COL5, NULL AS COL6, 1 AS LVL FROM TABLE101
UNION ALL
SELECT COL1, NULL AS COLB, NULL AS COLC, NULL AS COLD, COL2, COL3, COL4 , COL5 , COL6 , 2 AS LVL FROM TABLE102
Setup:
create table table101 as
select 'ACT1' col1, 'UYT' colb, 876 colc, 'KJH' cold from dual union all
select 'ACT2' , 'CFG' , 976 , 'TRY' from dual
;
commit;
select * from table101;
COL1 COLB COLC COLD
---- ---- ---- ----
ACT1 UYT 876 KJH
ACT2 CFG 976 TRY
2 rows selected.
create table table102 as
select 'ACT1' col1, 'A1_B1' col2, '98' col3, 'UI' col4, null col5, '2' col6 from dual union all
select 'ACT2' , 'C1' , null , '00' , 'N' , null from dual union all
select 'ACT2' , 'D1_D4' , '1' , 'PP' , 'Y' , 'RT' from dual union all
select 'ACT2' , 'A1_F1' , '9T' , 'UI' , null , '2' from dual
;
commit;
select * from table102;
COL1 COL2 COL3 COL4 COL5 COL6
---- ----- ---- ---- ---- ----
ACT1 A1_B1 98 UI 2
ACT2 C1 00 N
ACT2 D1_D4 1 PP Y RT
ACT2 A1_F1 9T UI 2
4 rows selected.
create table table110 (col1 varchar2(4000), colb varchar2(4000), colc number, cold varchar2(4000),
col2 varchar2(4000), col3 varchar2(4000), col4 varchar2(4000), col5 varchar2(4000),
col6 varchar2(4000), lvl number);
Table TABLE110 created.
Insert statement and outcome:
insert into table110
select col1, colb, colc, cold, null, null, null, null, null, 1
from table101
union all
select col1, null, null, null, col2, col3, col4, col5, col6, 2
from table102
;
commit;
select * from table110;
COL1 COLB COLC COLD COL2 COL3 COL4 COL5 COL6 LVL
---- ---- ---- ---- ----- ---- ---- ---- ---- ---
ACT1 UYT 876 KJH 1
ACT2 CFG 976 TRY 1
ACT1 A1_B1 98 UI 2 2
ACT2 C1 00 N 2
ACT2 D1_D4 1 PP Y RT 2
ACT2 A1_F1 9T UI 2 2
6 rows selected.
select * from table110;