SQL merge tables with matching columns - sql

How can I merge 2 tables with the same column names into 1 table? Something like this:
The 2nd table should fill in the 1st table.
This is as close as I got
SELECT * FROM
Animals
LEFT JOIN Best
ON Animals.species=Best.species;
http://sqlfiddle.com/#!5/d0a98/3
But it seems to concatenate the 2nd table on there.
Is LEFT JOIN really the correct way to do this?

You should list the columns in the SELECT. Then you would readily see that all you need is COALESCE():
SELECT a.price, a.species, COALESCE(b.name, a.name) as name
FROM Animals a LEFT JOIN
Best b
ON a.species = b.species;

Related

Having trouble joing to tables with different Column names. I have a Foreign key relationship between the tables but table A will not Join table B

My table names are Donut_Order and Order_History. Donut_Order has the data I want to JOIN to Order_History. Here's my code:
SELECT DonutOrder_Id
FROM Donut_Order
LEFT JOIN Order_History ON Donut_Order.Donut_ID = Order_History.DO_ID;
It always returns the DonutOrder_ID column with data, not the join on the Order_history table with the date in DO_ID column.
Your SELECT clause is selecting the DonutOrder_Id column from your Donut_Order table. You can SELECT * to grab all of the columns, or change your select to only return the columns you want.
Best practice for SQL JOINS is to alias your tables like so:
SELECT a.ColumnName, b.ColumnName
FROM TableA a
LEFT JOIN TableB b ON b.Id = a.Id
That way you don't have any confusion as to which tables the columns have come from
Try this:
SELECT
do.*,
oh.*
FROM
Donut_Order do
LEFT JOIN Order_History oh
ON do.DonutOrder_ID = oh.DO_ID;
I also changed Donut_ID to DonutOrder_ID. Let me know if that's incorrect. It might be do.ID = oh.DO_ID??? Not sure...
About the name change, this is why you name your columns the same in every table and don't abbreviate, so you can be sure joins are correct by the fact that the join uses the same-named column on both sides. Are you sure that Donut_ID is the key from the donut order table? It seems like it would be what donut was ordered... or is it just named deceptively? Donut_ID = DO.ID? Also, please use aliases as I have done, and it will be SO much easier to understand your queries.

Having issues using a Right Join in MS Access 2010 with two tables that have the same fields

I have two tables, Table A and Table B. Each table have 4 fields, the name of the fields are the same for both. Both tables are extracted from other tables, and each record acts as a primary key.
I want to write a query in MS Access 2010 that gets the data unique to Table B and not shared with Table A. I am using the following image as a reference, and it looks like I need to do a Right Join.
Hello. There is something not right with my SQL, I've tested it and I am getting the incorrect result. Below is the closest I've gotten:
SELECT DISTINCT TableB.*
FROM TableB RIGHT JOIN TableA ON (TableB.Field1 = TableA.Field1) AND (TableB.Field2 = TableA.Field2) AND (TableB.Field3 = TableA.Field3) AND (TableB.Field4 = TableA.Field4)
WHERE (((TableA.Field1) Is Null));
I think it would be clearer for you to use not exists:
select tableb.*
from tableb
where not exists (select 1
from tablea
where (TableB.Field1 = TableA.Field1) AND (TableB.Field2 = TableA.Field2) AND (TableB.Field3 = TableA.Field3) AND (TableB.Field4 = TableA.Field4)
);
Your use of RIGHT JOIN is incorrect. As phrased, you want a LEFT JOIN. That is, you want to keep all rows in the first table (the "left" table in the JOIN) regardless of whether or not a match exists in the second table. However, the NOT EXISTS does the same thing and the logic is a bit clearer.
You want to have right join if tablea is in your select statement, but as you have
SELECT DISTINCT TableB.*
you may want to have a left join instead. My suggestion would be changing your code from right to left join.
TableB acts like table A from venn diagrams above.

Getting way more results than expected in SQL left join query

My code is such:
SELECT COUNT(*)
FROM earned_dollars a
LEFT JOIN product_reference b ON a.product_code = b.product_code
WHERE a.activity_year = '2015'
I'm trying to match two tables based on their product codes. I would expect the same number of results back from this as total records in table a (with a year of 2015). But for some reason I'm getting close to 3 million.
Table a has about 40,000,000 records and table b has 2000. When I run this statement without the join I get 2,500,000 results, so I would expect this even with the left join, but somehow I'm getting 300,000,000. Any ideas? I even refered to the diagram in this post.
it means either your left join is using only part of foreign key, which causes row multiplication, or there are simply duplicate rows in the joined table.
use COUNT(DISTINCT a.product_code)
What is the question are are trying to answer with the tsql?
instead of select count(*) try select a.product_code, b.product_code. That will show you which records match and which don't.
Should also add a where b.product_code is not null. That should exclude the records that don't match.
b is the parent table and a is the child table? try a right join instead.
Or use the table's unique identifier, i.e.
SELECT COUNT(a.earned_dollars_id)
Not sure what your datamodel looks like and how it is structured, but i'm guessing you only care about earned_dollars?
SELECT COUNT(*)
FROM earned_dollars a
WHERE a.activity_year = '2015'
and exists (select 1 from product_reference b ON a.product_code = b.product_code)

Joining two tables where the join condition requires a substring

I am trying to join two oracle database tables where the columns to join on contain slightly different data.
For example Table A has a column 'ref' and Table B has a column 'id'.
A.ref contains data like A1234567890B and B.id contains data of the form 1234567890
I have tried joining the two based on the following query;
SELECT * FROM A INNER JOIN B
ON SUBSTR(A.ref, 2,10) = B.id;
But this has returned no results when I know that there is matching data from this substring.
Any ideas?
you could try something like this:
SELECT * FROM A INNER JOIN B
ON regexp_substr(A.ref, '^[[:alpha:]]+([[:digit:]]+)[[:alpha:]]+$',1,1,'c',1) = B.id
I was able to solve this in the end by padding out SUBSTR(A.ref, 2,10) to 12 characters.

SQL Selecting rows that are in both tables

How can I select rows that exist is two tables. The intersection I guess? Any help?
ProductosA and ProductosB, they're both tables with the exact same number and type of columns.
How can I select the things that are inside of both using a single select statement?
Try:
select * from ProductosA
intersect
select * from ProductosB
;
select a.column1, a.column2
from productosA a
join
productosB b
on
a.id = b.id
that will give you what you want
If there is a primary/composite key join the two tables where the keys match, if there is no primary key, join them using where "and"ing match for each column.
SELECT
ProductosATable.*
FROM
ProductosATable
INNER JOIN ProductosBTable
ON ProductosATable.NAME = ProductosBTable.NAME
Simply by specifying more than one table in your FROM clause you will get rows that exist in more than one table. Whether you get their entire rows, or just part of them, depends on how many of the columns you specify in the SELECT clause.