Putting one SQL table on top of another using oracle SQL - sql

This is probably a very simple question but I cannot find the solution. I have two tables with identical column names and I wish to put one on top of the other. I have tried UNION but this appears not to work and I get the error 'ORA-01790: expression must have same datatype as corresponding expression'
I am using Oracle SQL Developer to access the data.
table1 =
column1
column2
column3
1111111
2222222
3333333
aaaaaaa
bbbbbbb
ccccccc
table2 =
column1
column2
column3
9999999
8888888
7777777
zzzzzzz
yyyyyyy
xxxxxxx
desired output
column1
column2
column3
1111111
2222222
3333333
aaaaaaa
bbbbbbb
ccccccc
9999999
8888888
7777777
zzzzzzz
yyyyyyy
xxxxxxx
I have tried the following script to get it - any assistance would be appreciated.
select * from table1
union
select * from table2

The data type problem might be fixed by explicitly listing out all columns in the select clause. In addition, you should introduce a computed column which maintains the order of the two halves of the union in the output.
SELECT column1, column2, column3
FROM
(
SELECT column1, column2, column3, 1 AS src
FROM table1
UNION ALL
SELECT column1, column2, column3, 2
FROM table2
) t
ORDER BY src;

Related

How to compare rows as lists in SQL?

I have a many to many table which has 3 primary keys shown below :
table1 : key_1, key_2, key_3
I want to compare rows as lists,
For Example :
table1 would be :
key_1 key_2 key_3
row1: 10 | 100 | 150
row2: 10 | 101 | 150
row3: 10 | 103 | 151
row4: 11 | 100 | 150
row5: 11 | 101 | 150
row6: 11 | 103 | 151
So what I'd like to achive is to compare my table filtered by key_1 and find duplicate list of rows.
So in this scenerio,
SELECT * FROM table1 where key_1 = 10;
returns 3 rows (row1, row2, row3) and
SELECT * FROM table1 where key_1 = 11;
also returns 3 rows (row4, row5, row6)
And as you see above, first result of 3 rows has same key_2 & key_3
values with the second result of 3 rows.
So how can I query this, get rows as lists and compare them?
I know that this question looks something stupid but please, I'd very glad if you help me. Thanks in advance :)
You can search for unmatched rows of a full outer join.
For example the following query finds any difference between group 10 and 11:
select *
from table1 a
full join table1 b on a.key2 = b.key2 and a.key3 = b.key3
where a.key2 is null or b.key2 is null
and a.key1 = 10 and b.key1 = 11
If the query returns no rows, then the groups are identical.
If you wanted to find key_2 and key_3 pairs which repeat for the two values of key_1:
select key_2, key_3
from table1
where key_1 in (10, 11)
group by key_2, key_3
having count(1) > 1
To find the values of key_1 for which same key_2 and key_3 exist:
select distinct key_1
from table1
inner join (
select key_2, key_3
from table1
group by key_2, key_3
having count(1) > 1
) t (key_2, key_3)
on table1.key_2 = t.key_2
and table1.key_3 = t.key_3
The above query only tells key_1 value has at least one other key which has the same key_2 and key_3. It does not tell you what is the other key_1 value or what are the key_2 and key3. It seems to be what you were asking for but I am not sure if that is very useful.

Get row for each user where the count of a value in a column is maximum ++

This question is an update to this question.
My column structure:
Column0 Column1 Column2
aaa abc a
aaa abc a
aaa abc b
aaa abc a
aaa abc b
aaa abc NA
aaa xyx b
aaa NA b
bbb fgh v
bbb fgh NA
bbb fgh NA
bbb NA m
bbb NA m
bbb NA m
bbb NA NA
bbb NA NA
ccc NA NA
ccc NA NA
ccc NA NA
What I wished to get earlier was foreach distinct 'Column0' data 'Column1' data whose count is max unless that data is NA in which case get the second highest.
If for a 'Column0' data all values of 'Column1' are NA then the value can be NA.
The same rule applies here as well. Moreover for 'Column2', I wish to apply the same rule over the expected answer of 'Column1'
So even though for 'Column0' value 'aaa' the number of 'Column2' values for b is more, I wish to get the answer for 'Column2' as a.
This is because the query result in 'Column1' is 'abc' for 'Column0' value 'aaa' and amongst the said 'Column1' values in 'Column2', 'a' is more.
Similarly, even though for 'Column0' value 'bbb' the number of 'Column2' values for m and NA is more, I wish to get the answer for 'Column2' as v.
As earlier we do not take the value NA into account unless all values are NA.
So expected value:
Column0 Column1 Column2
aaa abc a
bbb fgh v
ccc NA NA
All help is sincerely appreciated
Thanks
Same as used in the responses of the previous question, you can use the count window function, but add an extra count partitioned over all columns, and ordering the row_number first over the prevalent values in column1, and then over the prevalent values of both columns.
;WITH Counts AS
(
SELECT column0, column1, column2,
COUNT(nullif(column1,'NA')) OVER (PARTITION BY column0, column1) cntCol1,
COUNT(nullif(Column2,'NA')) OVER (PARTITION BY Column0, Column1, Column2) cntCol2
FROM #t
)
, ranked AS
(
SELECT column0, column1, column2,
row_number() OVER (PARTITION BY Column0 ORDER BY cntcol1 desc, cntcol2 desc) rnr
FROM counts
)
SELECT Column0, Column1, Column2
FROM ranked
where rnr = 1
The column2 records will be inside the prevalent column1 records because the first order by on cntcol1 forces those records to come first and because cntCol2 is based on both column2 and column1, its value will be based on the count of column2 inside column1 (and column0 which is the primary partition).
NullIf(column,'NA') is used to force 'NA' to get a lower value on both counts.

Selecting both matching Rows from 2 tables

I am linking two tables and I want matching rows from both tables displayed as separate rows in the output table.
Example:
Table 1
1 AAA
2 BBB
3 CCC
4 DDD
5 EEE
Table 2;
2 WWW
4 XXX
5 YYY
6 ZZZ
7 UUU
Output:
2 BBB
2 WWW
4 DDD
4 XXX
5 EEE
5 YYY
There are many ways to do this (combining two sets as one) but the first that comes to mind is to use a unionstatement:
SELECT Column1, Column2
FROM Table1
WHERE Column1 IN (SELECT Column1 FROM Table2)
UNION ALL -- union all returns all rows including duplicates
-- union without all returns all but no duplicates
SELECT Column1, Column2
FROM Table2
WHERE Column1 IN (SELECT Column1 FROM Table1)
ORDER BY Column1, Column2
Sample SQL Fiddle
In the example above I used INoperator with a subquery to determine what rows should be returned in each set; another, and potentially better performing option would be to use joins to limit the members of each set like this:
SELECT Column1, Column2
FROM Table1
INNER JOIN Table2 ON Table1.Column1 = Table2.Column1
UNION ALL
SELECT Column1, Column2
FROM Table2
INNER JOIN Table1 ON Table1.Column1 = Table2.Column1
ORDER BY Column1, Column2
The general concept with the union statement is that you form two similar (in that they have the same columns with the same data types) sets and then use the unionoperator to merge them together as one, optionally including duplicate rows by addingallto the operator.

Selecting distinct rows based on column

A particular query of mine results data this way.
Id Size
123 1
123 1
123 2
123 2
134 1
134 1
134 2
I want the results get me the count eliminating the duplicate size like
Id Size
123 1
123 2
134 1
134 2
Above was result of joining two tables. Problem is I cant use distinct in this case.
Here is how tables are
Table1:
Id Created ... .. .. ..
123 date1 ....
134 date2 ....
Table2:
Id Size
123 1
123 2
134 1
134 2
I have my query that select from Table1 based on CreatedDate, its like this
select count(*)
from table1
join table2
on table1.id = table2.id
where table1.creates between '' and ''.
How do you get the distinct sizes.
If I use select count(distinct table2.size), it only returns 1 and 2 for all rows.
SELECT DISTINCT Id, Size
FROM table1
This should give you a list of distinct Id and Size combinations.
select count(distinct table1.id, table2.size)
from table1
join table2
on table1.id = table2.id
where table1.creates between '' and ''
see it working live in an sqlfiddle
Sometimes the solution is so obvious... :)
UPDATE: another way
select count(*) from (
select distinct table1.id, table2.size
from table1
join table2
on table1.id = table2.id
where table1.creates between '' and ''
) sq

SQL Server - How to display values that differ in two similar tables

I have 2 tables in SQL Server (ver:2008). Both tables have similar structure. Second table has few extra columns. I want to write a query that displays the differences in these tables (for matching fields). Output should display columns from both tables side by side (for comparison).
I tried using EXCEPT which is displaying the results from table 1 that don't match the results in table2. But I need to display both results side-by-side.
Thank you.
You simply need to select the fields you wish to display:
select t1.*, t2.*
from table1 t1
inner join table2 t2 on t1.ID = t2.ID
where t1.field1 <> t2.field1 OR t1.field2 <> t2.field2
OR ...
For example, if you have 2 tables, Products1 and Products2, both with columns Name, Price, Color etc., and you want to list all different products, you can use this:
SELECT Name FROM Products1
UNION
SELECT Name FROM Products2
OR, you can use FULL JOIN keyword, it returns rows when there is a match in one of the tables. For example:
The “Cars” table:
P_Id Name Color Quality City
---- -------- ----- ------- -----------
1 BMW Red good Las Vegas
2 Lexus Blue bad Los Angeles
3 Mercedes Green good MIami
The "Orders" table:
O_Id OrderNo P_Id
---- ------- ----
1 123 3
2 234 3
3 345 1
4 456 1
5 689 18
Now we want to list all the cars and all the people with their orders.
We use:
SELECT Cars.Name, Cars.Color, Orders.OrderNo
FROM Cars
FULL JOIN Orders
ON Cars.P_Id=Orders.P_Id
ORDER BY Cars.Name
The result:
Cars Color OrderNo
-------- ----- -------
BMW Red 345
BMW Red 456
Mercedes Green 123
Mercedes Green 234
Lexus Blue -
- - 689
Give this a shot. It assumes that there's one column (a) that is identical between the tables, and the rest (b, c, ...) are potentially different.
SELECT t1.a, t2.a, t1.b, t2.b, t1.c, t2.c, ...
FROM table1 t1
JOIN table2 t2
ON t1.a = t2.a
AND NOT (t1.b = t2.b AND t1.c = t2.c ...)
SELECT * FROM
(
SELECT * FROM TABLE1
EXCEPT
SELECT * FROM TABLE2
) T1
UNION ALL
SELECT * FROM
(
SELECT * FROM TABLE2
EXCEPT
SELECT * FROM TABLE1
) T2