Microsoft Access 2003 SQL Question - sql

I need to union several tables with the different structure in Microsoft Access.
For example I have table:
table1 (column_a,column_b,column_c),
table2 (column_a,column_c),
table3 (column_d)
SQL looks like follows:
SELECT table1 column_a,column_b,column_c, Null as column_d FROM Table1
UNION
SELECT table2 column_a,Null as column_b, column_c, Null as column_d FROM Table2
UNION
SELECT table3 column_a, Null as column_b, Null as column_c, Null as column_d
FROM Table3;
But sometimes MS Access shows the error message about incompatible types.
I think this because of generated columns with null values in one SELECT have the type incompatible with corresponding not autogenerated columns in another SELECT
Is there way to specify type of the autogenerated column with null?

What about replacing the Null's with empty strings ('')?
e.g.,
SELECT col_a, col_b, col_c, '' as col_d FROM Table1
UNION
SELECT col_a, '' as col_b, col_c, '' as col_d FROM Table2
UNION
SELECT col_a, '' as col_b, '' as col_c, '' as col_d FROM Table3;

Related

To show from which table does the data come from with an union

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

SQL cannot use IN with CTE but works with the same subquery

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.

in oracle query, select only few columns with union

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

Can I use column names as data

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.

Oracle SQL Query based on a UNION

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.