how to join where primary key has both integer and string value - google-bigquery

I have two tables as shown in the image. I need to join two tables using the id from table 1 and id_number from table 2 as primary key. The primary key of Table 1 has both integer and string value.
When I use LEFT JOIN, I am getting the records related to the integer only. I would like to get the output for both integer and string as shown in the output table. There are million of rows in both Table 1 and Table 2. Can anyone assist please. I am using google bigquery. My code is as follows:
select t1.* ,t2.District,t2.Division,t2.Country
from t1
left join t2 on t1.id = t2.id;

It seems like you want rows from both tables, so this suggests a full join:
select id, t1.name, t1.postition, t1.department, t1.salary, t2.district, t2.division, t2.country
from t1
full join t2 using(id)
This can be shortened with handy except extension:
select id, t1.* except(id), t2.* except(id)
from t1
full join t2 using(id)

Related

Sql query with join on table with ID not match

I have two tables.
Table 1
Id
UpdateId
Name
Table 2
Table1ID
UpdateID
Address
Each time user update, system will insert record to table1. But for table2, system only insert record when there is update in address.
Sample data
Table 1
1,1,name1
1,2,name1
1,3,name1update
1,4,name1update
1,5,name1
1,6,name2
Table 2
1,1,address
1,4,addressupdate
I want to get the result as following
1,1,name1,address
1,2,name1,address
1,3,name1update,address
1,4,name1update,addressupdate
1,5,name1,addressupdate
1,6,name2,addressupdate
How to make use of join condition to achieve as above?
You can use a correlated subquery. Here is standard syntax, but it can be easily adapted to any database:
select t1.*,
(select t2.addressid
from table2 t2
where t2.table1id = t1.id and
t2.updateid <= t1.updateid
order by t2.updateid desc
fetch first 1 row only
) as addressid
from table1 t1;
you can use left join when you want to take all columns from left table t1 even though it doesn't match with the other table with column updateid on t2 table.
select t1.id,t1.updateid,t1.name,t2.address from table1 t1
left join table2 t2
on t2.updateid= t1.updateid
you can read more about joins here

Does increasing the number of fields in JOIN statement increase/decrease the speed of execution?

I have two tables with 3.5 million rows of data. I am creating a left join between the two to create a new view.
Code 1:
SELECT t1.c1,t1.c2,t2.c3,t2.c4
from table1 as t1
left join table2 as t2
on t1.Location=t2.Location and t1.OrderNumber=t2.OrderNumber and t1.Customer=t2.Customer
Code 2:
SELECT t1.c1,t1.c2,t2.c3,t2.c4
from table1 as t1
left join table2 as t2
on t1.OrderNumber=t2.OrderNumber
Both snippets of code give the same desired result as the Order number field in table 2 has only unique values.
Is it better to give more fields to JOIN compared to only one?
SELECT t1.c1,t1.c2,t2.c3,t2.c4
from table1 as t1
left join table2 as t2
on t1.Location = t2.Location
and t1.OrderNumber = t2.OrderNumber
and t1.Customer = t2.Customer
If OrderNumber is the PK of either table then adding additional fields will not change the results and it will not improve performance unless an index as not present on the other side.
If Order number field in table 2 has only unique values it would not change the query. If it is a PK or has a unique constraint/index then addition fields would not help unless what Table2.OrderNumber was joined to was not indexed.

SQL join to return a table with multiple columns from other tables replacing its own

I am trying to write an SQL query that will return Table1, which has 10 columns. This table consists of a primary key id, 4 foreign key Id columns, and 5 other columns that I want to return but not change. The goal is to do a join to replace the foreign key Ids with their descriptions that are held in other tables.
Here is one attempt with the first FK Id:
Select * from Table1 t1
left join Table2 t2
on t1.BranchId = t2.BranchId;
This left join returns the description from table2, but does not replace it.
Here is another with the first FK Id:
Select t2.BranchName from Table1 t1
left join Table2 t2
on t1.BranchId = t2.BranchId;
This returns the name I want, but does not return table1 fully.
For the sake of an example you could pretend that OtherName3, OtherName4, OtherName5 are in tables Table3, Table4, Table5, respectively.
This may seem trivial for experienced SQL devs, but I am having a hard time figuring out the syntax.
Thanks!
I'm not sure what you mean by replace it.
I think you just need to list out all the columns you want:
Select t1.col1, t1.col2, t1.col3, . . .,
t2.name
from Table1 t1 left join
Table2 t2
on t1.BranchId = t2.BranchId;
I don't know what you mean by 'replace' but you just need to qualify what columns from which table you want. That goes for all tables you are joined to, especially if they have the same column name in multiple tables. I put junk columns in since I don't know your tables but you should get the general idea.
Select t2.BranchName, t1.BranchId, t1.Name, t1.Amount, t2.BranchLocation from Table1 t1
left join Table2 t2
on t1.BranchId = t2.BranchId;
I think this is what you are looking for:
select t1.*, t2.BranchName from Table1 t1
left join Table2 t2
on t1.BranchId = t2.BranchId;
Return Table1 fully (all columns) and only the description (BranchName) from Table2.
If using SQL Server, see all syntax options for the SELECT clause here:
https://msdn.microsoft.com/en-us/library/ms176104.aspx

How to get key of the maximal record in group?

I have two tables in my database, one holds the names of files, and other holds records of information described in them, inincluding sizes of sections. it can be descrived as:
Table1: id as integer, name as varchar
Table2: recid as integer primary key, file_id as integer, score as float
Between the tables there is an one-to-many link, from Table1.id to table2.file_id. What i need is for every file which name matches a certain pattern retrieve the id of the linked record with the maximum score and the score itself.
So far i have used:
SELECT name,MAX(score)
FROM Table1
LEFT OUTER JOIN Table2 ON Table2.file_id=Table1.id
WHERE name LIKE :pattern
GROUP BY name
but i cannot retrieve the id of the record in Table2 this way.
The dialect i am using is Sqlite.
What query should be used to retrieve data on the record that has maximum score for every file?
Update:
With this query, i am getting close to what i want:
SELECT name,score,recid
FROM Table1
LEFT OUTER JOIN Table2 ON file_id=id
WHERE name LIKE :pattern
GROUP BY name
HAVING score=MAX(score)
However, this leaves out the entries in the first table that have no corresponding entries in the second table out. How can i ensure they are in the end result anyway? Should i use UNION, and if so - how?
This can actually be achieved without a GROUP BY by using a brilliantly simple technique described by #billkarwin here:
SELECT name, t2.score
FROM Table1 t1
LEFT OUTER JOIN Table2 t2 ON t2.file_id = t1.id
LEFT OUTER JOIN Table2 t2copy ON t2copy.file_id = t2.file_id
AND t2.score < t2copy.score
WHERE name LIKE :pattern
AND t2copy.score IS NULL
See SQL Fiddle demo.
I think that you must use a subquery
SELECT name, recid, score
FROM Table1
LEFT OUTER JOIN Table2 ON Table2.file_id=Table1.id
WHERE name LIKE :pattern AND score = (SELECT MAX(score) FROM Table2.score)
I think the easiest way to do this is with a correlated subquery:
SELECT name, recid, score
FROM Table1 LEFT OUTER JOIN
Table2
ON Table2.file_id=Table1.id
WHERE name LIKE :pattern AND
score = (SELECT MAX(t2.score)
FROM Table1 t1 LEFT OUTER JOIN
Table2 t2
ON t2.file_id=t1.id
where t1.name = table1.name
);
Note that you need table aliases to distinguish the tables in the inner query from the outer query. I am guessing which tables the columns are actually coming from.

Join tables with Two foreign keys

I am searching for a real scenario problem that I faced last night while joining two tables with foreign keys. Actually I want to get all values from second table on behalf of foreign key.
Here are my two tables let suppose:
table1 (id_user_history(PK),id_user(FK), order_no, p_quantity)
table2 (id_shoping_cart(PK), id_user(FK),order_id, prod_quantity)
Now I want to get all values from table2 by joining these tables with table1(id_user(Fk)) and table2( id_user(FK))
SELECT *
FROM table2 t2
LEFT JOIN
table1 t1
on t1.id_user = t2.id_user
all records from table 2 and only those record which match on table 1.
SQL is mainly set logic. Here's a link which helps visualize.
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
Looks like a simple join fits the bill:
select *
from table1 t1
left join
table2 t2
on t1.id_user = t2.id_user