Im creating a Database from two sources , the sources are as follows
Create Table table_name1(Column_A VARCHAR(50), Column_B int, Column_C VARCHAR(50), Column_D VARCHAR(50));
Insert Into table_name1 Values
('A1',5,'C1','D1'),
('A1',23,'C2',null),
('A2',2,'C2','D1'),
('A12',23,'C2',null),
('A2',23,'C2',null),
('A12',12,'D2','C1');
Create Table table_name2(Column_A VARCHAR(50), Column_B int, Column_C VARCHAR(50), Column_D VARCHAR(50));
Insert Into table_name2 Values
('A1',5,'C1','D1'),
('A1',23,'C2',null),
('A1',21,'C2',null),
('A2',2,'C2','D1'),
('A2',34,'C2','D1'),
('A21',23,'C2','D1'),
('A2',23,'C2','D2'),
('A12',12,'D2','C1'),
('A12',23,'C2',null),;
Now i would like to union these two sources and generate ID's based on the business logic but at the same time i would like to know which data source is data coming from in a separate column 'table1' if it is from table1 and 'table2' if it is from table2 and if it is a common data then 'table1 & table2'
So far i wrote as follows
with t1 as(
select * from table_name1
union
select * from table_name2)
select dense_rank() over ( order by Column_B) as id_1,
dense_rank() over(order by t1.Column_A,t1.Column_C,t1.Column_D) as id_2, t1.Column_A,t1.Column_B,t1.Column_C, t1.Column_D
from t1
Expected Output:
Another solution (I am working in Mariadb and don't have the dense_rank function - you can add that):
EDITED to make the Source more exactly what the OP requested:
SELECT Column_A,
Column_B,
Column_C,
Column_D,
CONCAT("Table ",GROUP_CONCAT(TNAME1,TNAME2 ORDER BY TNAME2 SEPARATOR "&" )) AS Source
FROM
(SELECT Column_A,
Column_B,
Column_C,
Column_D,
"1" AS TNAME1,
"" AS TNAME2
FROM table_name1
UNION
SELECT Column_A,
Column_B,
Column_C,
Column_D,
"" AS TNAME1,
"2" AS TNAME2
FROM table_name2
) AS SQL1
GROUP BY Column_A,Column_B,Column_C,Column_D;
Would something like this work for you if #lemon's solution doesn't?
with cteConsolidate as (
select 'Table 1' as tabname, * from #table_name1
union
select 'Table 2' as tabname, * from #table_name2
)
select column_a, column_b, column_c, column_d, case when count(*) = 1 then min(tabname) else 'Both' end
from cteConsolidate
group by column_a, column_b, column_c, column_d
If EXCEPT and INTERSECT are operators available for your DBMS, like in PostgreSQL and MySQL, you can apply a union over the three separate sets:
records appearing in table1 but not in table2
records appearing in table2 but not in table1
records appearing in both tables
SELECT *, 'tab1' AS orig FROM table1 EXCEPT SELECT * FROM table2
UNION ALL
SELECT *, 'tab2' AS orig FROM table2 EXCEPT SELECT * FROM table1
UNION ALL
SELECT *, 'both' AS orig FROM table1 INTERSECT SELECT * FROM table2
QUESTION
When I save my table into a CTE, then use it with IN in another query it is considered as error.
WITH id_list AS (
SELECT DISTINCT tracking_id
FROM table_a
)
SELECT col_a, col_b, col_c
FROM table_b
WHERE tracking_id IN (id_list)
But in the same time, if I put the same query as subquery with IN it works correctly.
SELECT col_a, col_b, col_c
FROM table_b
WHERE tracking_id IN (
SELECT DISTINCT tracking_id
FROM table_a
)
I want to know the reason why this situation occur. Why can't we use CTE table directly with IN?
Thanks.
I have two tables something like this:
TABLE_1:
COL_A (int), COL_B (float), COL_C (float)
and
TABLE_2:
COL_A (int), COL_B (varchar), COL_C (varchar)
My query is using a UNION to get only COL_A(int) from table 2 like
SELECT COL_A, COL_B, COL_C FROM table1 UNION
SELECT COL_A FROM table2
It's throwing an error. How do we get the results?
All subquery members of a UNION must have the same number and types of columns. In your case the first subquery has three columns, but the second one has only one.
Solution: pad the second subquery with nulls.
For example:
select COL_A, COL_B, COL_C from table1
union
select COL_A, null, null from table2
I have to check the data in each column in 7000 tables.
So I want to insert into Temp_Table has Columns ( Table_name, Column_name, Data)
eg.
SELECT * FROM TABLE_A;
COL_A
COL_B
COL_C
DATA_A1
DATA_B1
DATA_C1
DATA_A2
DATA_B2
DATA_C2
I want to insert into Temp_table
eg.
TABLE_NM
COL_NM
DATA
TABLE_A
COL_A
DATA_A1
TABLE_A
COL_A
DATA_A2
TABLE_A
COL_B
DATA_B1
TABLE_A
COL_B
DATA_B2
TABLE_A
COL_C
DATA_C1
TABLE_A
COL_C
DATA_C2
Is there any way?
you can do this using union all from metadata.
select 'TABLE_A' TABLE_NM, 'COL_A' COL_NM, COL_A DATA from table_a
union all
select 'TABLE_A' TABLE_NM, 'COL_B' COL_NM, COL_B DATA from table_a
union all
select 'TABLE_A' TABLE_NM, 'COL_C' COL_NM, COL_C DATA from table_a
...
Put the list of table and columns in XL and then create a formula to create the whole query. But list of tables and columns - you need to get from metadata.
env: Oracle 12c
I have a query in Oracle that is a UNION between two tables: TABLE_A and TABLE_B.
select ID as COL_A,
VAL_B as COL_B,
VAL_C as COL_C,
VAL_D as COL_D,
VAL_E as COL_E
from TABLE_A
where VAL_E = 'XYZ12'
union
select NULL as COL_A,
NULL_B as COL_B,
VAL_C as COL_C,
NULL as COL_D,
VAL_E as COL_E
from TABLE_B
where VAL_E = 'XYZ12'
and ?????
COL_A COL_B COL_C COL_D COL_E
------ ------ ------ ----- -----
123 REQ1 REQ2 REQ3 XYZ12
REQ2 XYZ12
Based on the query above and where I am stuck is that if the record with 'XYZ12' and 'REQ1' exists then I only want to return this one record otherwise return the second record only, i.e. where 'XYZ12' exists but COL_B IS NULL
The primary record is the first one if it exists in TABLE_A. Based on my criteria, if it doesn't exist then return the second record alone from TABLE_B.
Based on the data and query in your question, table_a would seem to have at most one row. Hence you can simply add:
from TABLE_B
where VAL_E = 'XYZ12' and
not exists (select 1 from table_a a)
If you want to check for specific values in table_a, then you can add a filter to the subquery.