I have two tables that have identical columns. One table houses imported data, the other table houses data specific to my application:
IMPORT_TABLE MY_TABLE
COL1 COL2 COL1 COL2
"A" "1" "A" "2"
"B" "1" "B" "1"
What I need to do is write a single query that will tell me, for a given value in COL1, I have differing values in COL2 across the tables. So, when I run the query I woud get back the value "A" for COL1. This tells me that I need to insert "A" "1" into MY_TABLE.
How can I accomplish the query? I know how to do a Group By on a single table but not across tables.
If you just want to get the rows in IMPORT_TABLE that don't exist in MY_TABLE
SELECT col1, col2
FROM import_table
MINUS
SELECT col1, col2
FROM my_table
If col1 is unique, you could also do
SELECT import.col1, import.col2 imported_col2, mytbl.col2 my_col2
FROM import_table import
FULL OUTER JOIN my_table mytbl ON (mytbl.col1 = import.col1)
Related
How can I achieve this to Select to one row only dynamically since
the objective is to get the uniqueness even on multiple columns
select distinct
coalesce(least(ColA, ColB),cola,colb) A1, greatest(ColA, ColB) B1
from T
The best solution is to use UNION
select colA from your_table
union
select colB from your_table;
Update:
If you want to find the duplicate then use the EXISTS as follows:
SELECT COLA, COLB FROM YOUR_TABLE T1
WHERE EXISTS (SELECT 1 FROM YOUR_tABLE T2
WHERE T2.COLA = T1.COLB OR T2.COLB = T1.COLA)
If I correctly understand words: objective is to get the uniqueness even on multiple columns, number of columns may vary, table can contain 2, 3 or more columns.
In this case you have several options, for example you can unpivot values, sort, pivot and take unique values. The exact code depends on Oracle version.
Second option is listagg(), but it has limited length and you should use separators not appearing in values.
Another option is to compare data as collections. Here I used dbms_debug_vc2coll which is simple table of varchars. Multiset except does main job:
with t as (select rownum rn, col1, col2, col3,
sys.dbms_debug_vc2coll(col1, col2, col3) as coll
from test )
select col1, col2, col3 from t a
where not exists (
select 1 from t b where b.rn < a.rn and a.coll multiset except b.coll is empty )
dbfiddle with 3-column table, nulls and different test cases
I have two different table:
Table1, Table2.
Two tables have different columns and nothing in common. What I am looking to get is
if Table1 is empty/null then
output Table2
else
output table1
Is it possible to get it done in Oracle? Any leads would be appreciated.
Accordingly to your phrase:
if Table1 is empty/null then output Table2 else output table1
I think the solution is (I briefed Table1, Table2 by A, B respectively ):
--I created this tables to test the solution
create table A( id number, val varchar2(5));
create table B( code varchar2(5), event_dt date);
insert into b(code, event_dt)
values ('test', sysdate);
--query(1)
select b.code, to_char(b.event_dt,'yyyy-mm-dd')
from b
where not exists (select 1 from a)
union
select to_char(id), to_char(val)
from a
;
--now insert data on the other table (to test purposes)
insert into A(id, val)
values(1, 'TestA');
--run the query(1) again
The key is "union", kind of repeat your query when the first portion deals to no data
found.
Please remember to CAST your columns to achieve the same DATA-TYPES required by UNION
Best regards.
First of all let's setup a test environment:
CREATE TABLE IF NOT EXISTS source_table (
`col1` TIMESTAMP,
`col2` STRING
);
CREATE TABLE IF NOT EXISTS dest_table (
`col1` TIMESTAMP,
`col2` STRING,
`col3` STRING
)
PARTITIONED BY (day STRING)
STORED AS AVRO;
INSERT INTO TABLE source_table VALUES ('2018-03-21 17:08:04.401', 'test1'), ('2018-03-22 12:02:04.222', 'test2'), ('2018-03-22 07:21:04.111', 'test3');
How could I list the column names during insertion and put the partition value dynamically? The following command doesn't work:
INSERT INTO TABLE dest_table(col1, col2) PARTITION(day) SELECT col1, col2, date_format(col1, 'yyyy-MM-dd') FROM source_table;
By the way, without listing the columns of dest_table inside the INSERT INTO command, having two tables with the same columns number, everything works fine. What if my dest_table has more fields than the source_table?
Thank you for helping me.
P.S.
Ok, if I hardcode NULL this works. I leave the question opened because there might be better ways to achieve that.
INSERT INTO TABLE dest_table PARTITION(day) SELECT col1, col2, NULL, date_format(col1, 'yyyy-MM-dd') FROM source_table;
Anyway, this method is strictly bounded with columns order? In a real-life scenario, how could I handle lots of columns specifying a mapping, to avoid mistakes?
The syntax for inserting into a partitioned table when you want to list the specific columns is shown below. You don't need to put null on col3 since Hive will put a default value NULL since it is not in the column list during insert.
INSERT INTO TABLE dest_table PARTITION (day)(col1, col2, day)
SELECT col1, col2, date_format(col1, 'yyyy-MM-dd') FROM source_table;
Result:
col1 col2 col3 day
2018-03-22 12:02:04.222 test2 NULL 2018-03-22
2018-03-22 07:21:04.111 test3 NULL 2018-03-22
2018-03-21 17:08:04.401 test1 NULL 2018-03-21
Is there any way to compare values for one partition with another partition of the same table? Requirement is like I have a table and suppose there are 5 partitions, table having two columns(not null). Suppose Col1 having all the distinct values and in col2 there can be a duplicate values. So while comparing one partition with other or we can say rest of the 4 partitions on the basis of distinct col2 values according to the partition name, if the value match between two partition then a new table will create with union of the two partition.
And if there is no match between the col2 values of one partition and with rest of the partition then new table will create of same structure(without any union).
Note:
I want to automate this process through PLSQL code.
Currently what I am doing manually:
I have one table having five partition, for example Table structure:
create table PART_TEST1
(col1 int not null,
col2 int not null)
partition by range (col2)
(partition part1 values less than (10),
partition part2 values less than (20),
partition part3 values less than (30),
partition part4 values less than (40),
partition part5 values less than (maxvalue));
Data distribution:
col1 having distinct values like- 1, 2, 3....so on.
col2 having values like- 1, 2, -1, 1, 2, 3, 4, 1...so on
col2 has duplicate values and my goal is to find the distinct values according to the name of the partition like:
select distinct col2 from PART_TEST1 partition (part1);
For example output of above query is:
Col2
1
2
Again I am querying for finding matching values in other partition:
select distinct col2 from PART_TEST1 partition (part2);
For example output of above query is:
Col2
2
3
So now part 1 and part2 has one same value '2' and two non common values 1 and 3.
so my final query is:
create table 'TABLE_NAME' as select * from part_test1 where col2 = 1;
create table 'TABLE_NAME' as select * from part_test1 where col2 = 3;
create table 'TABLE_NAME' as
(select * from part_test1 where col2 = 2
union
select * from part_test1 where col2 = 2);
Hopefully now you will get some clarity about my problem. I am new to PLSQL and not able to compare the partition values. Also if I am able to compare the values then how can I store the output of the comparison query and then finally create the table? And also I am thinking that I need to compare one partition with rest of the partition like some kind of loop operation.
I am having a simple table with 5 columns
id
id_user
col1
col2
col3
how can make Linq query to select an id_user and sum up all the col1, col2, col3 integers to make an average of those 3 columns ?
Thanks
Assuming you already have your table something along these lines should do it:
from row in table
let avgTotal = (new [] {row.col1, row.col2, row.col3}).Average()
select new {row.user_id, avgTotal}