left join where the primary key has both integer and string - google-bigquery

I need to join two tables where the primary keys have both integer and string value. When I use left join using id column as primary key 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. Can anyone assist please.
select t1.*
,t2.Position
from t1
left join t2
on t1.id=t2.id;
I am getting the output which related to id (integer) only.I would like to get the output for both integer id and string id.

how to use UNION DISTINCT here – Nrad
SELECT id FROM table1
UNION DISTINCT
SELECT id FROM table2
or
SELECT CAST(id AS CHAR) AS id FROM table2
UNION DISTINCT
SELECT id FROM table1
DISTINCT keyword is optional and may be skipped in both cases.
If you need the ordering shown then add
ORDER BY id + 0 = 0, id
to the end of a query.
i have some other different columns in both table that I need to take. – Nrad
SELECT id,
COALESCE (t1.name, t2.name) name,
t1.salary,
t2.position,
t1.department
FROM ( SELECT id FROM table1
UNION DISTINCT
SELECT id FROM table2 ) t0
LEFT JOIN table1 t1 USING (id)
LEFT JOIN table2 t2 USING (id)

Related

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

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)

Count unique rows

Im having this problem where im trying to count the number of entries by a unique value.
SELECT table1.PID, table2.CID
FROM table1
INNER JOIN table2 using (OID)
WHERE table1.PID IN (
SELECT table1.PID
FROM table1
JOIN table2 using (OID)
WHERE table2.CID = 'A'
) AND table2.CID != 'A'
what I would like to do is to count the number of unique table2.CID entries.
NOTE: I need to do grouping cause of duplicate values.
Just to help, here is a picture of the table i'm getting as an output. What I would like to have is the count of each name on unique ID values. So ERNSH should return 7 and not 15.
You want one record per CID, so group by CID. Then use COUNT. And as you want to count distinct values use COUNT(DISTINCT):
SELECT COUNT(DISTINCT table1.PID), table2.CID
FROM table1
INNER JOIN table2 using (OID)
WHERE table1.PID IN (
SELECT table1.PID
FROM table1
JOIN table2 using (OID)
WHERE table2.CID = 'A'
) AND table2.CID != 'A'
GROUP BY table2.CID;

mysql - union tables by unique field

I have two tables with the same structure:
id name
1 Merry
2 Mike
and
id name
1 Mike
2 Alis
I need to union second table to first with keeping unique names, so that result is:
id name
1 Merry
2 Mike
3 Alis
Is it possible to do this with MySQL query, without using php script?
This is not a join (set multiplication), this is a union (set addition).
SELECT #r := #r + 1 AS id, name
FROM (
SELECT #r := 0
) vars,
(
SELECT name
FROM table1
UNION
SELECT name
FROM table2
) q
This will select all names from table1 and combine those with all the names from table2 which are not in table1.
(
select *
from table1
)
union
(
select *
from table2 t2
left join table1 t1 on t2.name = t1.name
where t1.id is null
)
Use:
SELECT a.id,
a.name
FROM TABLE_A a
UNION
SELECT b.id,
b.name
FROM TABLE_B b
UNION will remove duplicates.
As commented, it all depends on what your 'id' means, cause in the example, it means nothing.
SELECT DISTINCT(name) FROM t1 JOIN t2 ON something
if you only want the names
SELECT SUM(something), name FROM t1 JOIN t2 ON something GROUP BY name
if you want to do some group by
SELECT DISTINCT(name) FROM t1 JOIN t2 ON t1.id = t2.id
if the id's are the same
SELECT DISTINCT COALESCE(t1.name,t2.name) FROM
mytable t1 LEFT JOIN mytable t2 ON (t1.name=t2.name);
will get you a list of unique names from the 2 tables. If you want them to get new ids (like Alis does in your desired results), that's something else and requires the answers to a couple of questions:
do any of the names need to maintain their previous id. And if they do, which table's id should be preferred?
why do you have 2 tables with the same structure? ie what are you trying to accomplish when you generate the unique name list?

What is the standard SQL Query to retrieve the intersection of tables?

Selecting the union:
select * from table1
union
select * from table1_backup
What is the query to select the intersection?
In SQL Server intersect
select * from table1
intersect
select * from table1_backup
SELECT *
FROM table1
WHERE EXISTS
(SELECT *
FROM table1_backup
WHERE table1.pk = table1_backup.pk)
works
For questions like this, I tend to go back to this visual resource:
A Visual Explanation of SQL Joins
inner join i think:
suppose T1 and T2 have the same structure:
select T1.* from
T1 inner join T2 on T1.pkField = T2.pkField
"intersect" is also part of standard SQL.
Inner join gives a different answer.
here is a solution for mySQL:
CREATE TABLE table1(
id INT(10),
fk_id INT(10),
PRIMARY KEY (id, fk_id),
FOREIGN KEY table1(id) REFERENCES another_table(id),
FOREIGN KEY table1(fk_id) REFERENCES other_table(id)
);
SELECT table1.* FROM table1 as t0
INNER JOIN table1 as a ON (t0.id = a.id and fk_id=1)
INNER JOIN table1 as b ON (t0.id = b.id and fk_id=2)
INNER JOIN table1 as c ON (t0.id = c.id and fk_id=3)
ORDER BY table1.id;
Basically you have an table of mathematical subsets (ie. 1={1, 2 ,3}, 2={3, 4, 2}, ... , n={1, 4, 7}) with an attribute id, which is the set number, and fk_ id, which references a PRIMARY KEY of a table of elements, the superset (meaning possible values for the numbers in the curly braces). For those not mathematically inclined, let's pretend you have a table, 'other_ table', which is a list of items, and another table, 'another_ table', which is a list of transaction numbers, and both tables form a many-to-many relationship, thus producing 'table1'. now let's pretend you wanted to know the id's in 'another_ table' which had items 1, 2, and 3. that's the query to do it.
An intersect on two identical tables a and b can be done in this manner:
SELECT a.id, a.name
FROM a INNER JOIN b
USING (id, name)
subqueries?! really?
to get the intersection of table1 and table2:
SELECT * FROM table1, table2 WHERE table1.pk=table2.pk;
select distinct * from (select * from table1 union select * from table1_backup)

An issue possibly related to Cursor/Join

Here is my situation:
Table one contains a set of data that uses an id for an unique identifier. This table has a one to many relationship with about 6 other tables such that.
Given Table 1 with Id of 001:
Table 2 might have 3 rows with foreign key: 001
Table 3 might have 12 rows with foreign key: 001
Table 4 might have 0 rows with foreign key: 001
Table 5 might have 28 rows with foreign key: 001
I need to write a report that lists all of the rows from Table 1 for a specified time frame followed by all of the data contained in the handful of tables that reference it.
My current approach in pseudo code would look like this:
select * from table 1
foreach(result) {
print result;
select * from table 2 where id = result.id;
foreach(result2) {
print result2;
}
select * from table 3 where id = result.id
foreach(result3) {
print result3;
}
//continued for each table
}
This means that the single report can run in the neighbor hood of 1000 queries. I know this is excessive however my sql-fu is a little weak and I could use some help.
LEFT OUTER JOIN Tables2-N on Table1
SELECT Table1.*, Table2.*, Table3.*, Table4.*, Table5.*
FROM Table1
LEFT OUTER JOIN Table2 ON Table1.ID = Table2.ID
LEFT OUTER JOIN Table3 ON Table1.ID = Table3.ID
LEFT OUTER JOIN Table4 ON Table1.ID = Table4.ID
LEFT OUTER JOIN Table5 ON Table1.ID = Table5.ID
WHERE (CRITERIA)
Join doesn't do it for me. I hate having to de-tangle the data on the client side. All those nulls from left-joining.
Here's a set-based solution that doesn't use Joins.
INSERT INTO #LocalCollection (theKey)
SELECT id
FROM Table1
WHERE ...
SELECT * FROM Table1 WHERE id in (SELECT theKey FROM #LocalCollection)
SELECT * FROM Table2 WHERE id in (SELECT theKey FROM #LocalCollection)
SELECT * FROM Table3 WHERE id in (SELECT theKey FROM #LocalCollection)
SELECT * FROM Table4 WHERE id in (SELECT theKey FROM #LocalCollection)
SELECT * FROM Table5 WHERE id in (SELECT theKey FROM #LocalCollection)
Ah! Procedural! My SQL would look like this, if you needed to order the results from the other tables after the results from the first table.
Insert Into #rows Select id from Table1 where date between '12/30' and '12/31'
Select * from Table1 t join #rows r on t.id = r.id
Select * from Table2 t join #rows r on t.id = r.id
--etc
If you wanted to group the results by the initial ID, use a Left Outer Join, as mentioned previously.
You may be best off to use a reporting tool like Crystal or Jasper, or even XSL-FO if you are feeling bold. They have things built in to handle specifically this. This is not something the would work well in raw SQL.
If the format of all of the rows (the headers as well as all of the details) is the same, it would also be pretty easy to do it as a stored procedure.
What I would do: Do it as a join, so you will have the header data on every row, then use a reporting tool to do the grouping.
SELECT * FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.resultid -- this could be a left join if the table is not guaranteed to have entries for t1.id
INNER JOIN table2 t3 ON t1.id = t3.resultid -- etc
OR if the data is all in the same format you could do.
SELECT cola,colb FROM table1 WHERE id = #id
UNION ALL
SELECT cola,colb FROM table2 WHERE resultid = #id
UNION ALL
SELECT cola,colb FROM table3 WHERE resultid = #id
It really depends on the format you require the data in for output to the report.
If you can give a sample of how you would like the output I could probably help more.
Join all of the tables together.
select * from table_1 left join table_2 using(id) left join table_3 using(id);
Then, you'll want to roll up the columns in code to format your report as you see fit.
What I would do is open up cursors on the following queries:
SELECT * from table1 order by id
SELECT * from table1 r, table2 t where t.table1_id = r.id order by r.id
SELECT * from table1 r, table3 t where t.table1_id = r.id order by r.id
And then I would walk those cursors in parallel, printing your results. You can do this because all appear in the same order. (Note that I would suggest that while the primary ID for table1 might be named id, it won't have that name in the other tables.)
Do all the tables have the same format? If not, then if you have to have a report that can display the n different types of rows. If you are only interested in the same columns then it is easier.
Most databases have some form of dynamic SQL. In that case you can do the following:
create temporary table from
select * from table1 where rows within time frame
x integer
sql varchar(something)
x = 1
while x <= numresults {
sql = 'SELECT * from table' + CAST(X as varchar) + ' where id in (select id from temporary table'
execute sql
x = x + 1
}
But I mean basically here you are running one query on your main table to get the rows that you need, then running one query for each sub table to get rows that match your main table.
If the report requires the same 2 or 3 columns for each table you could change the select * from tablex to be an insert into and get a single result set at the end...