How to use sql join where table1 has rows not present in table2 - sql

I have two tables record and share. record has columns: name and id. share has columns id.
I want to find the rows which are present in record but not present in share.
How can I do this?

SQL LEFT JOIN returns all rows from the left table even if there are no matches in the right table
SELECT name, id
FROM record r LEFT JOIN share s on r.id = s.id
WHERE s.id is null

You have this tables:
RECORD (ID, NAME)
SHARE(ID,VALUE)
If your SQL engine supports LEFT OUTER JOINS, the best way is:
SELECT RECORD.* FROM RECORD LEFT OUTER JOIN SHARE WHERE RECORD.ID=SHARE.ID
WHERE SHARE.ID IS NULL
Important
place an index on SHARE.ID
How it works:
SQL Engine span all the RECORD table looking for a record in SHARE, for each record in RECORD if it is found a "linked" record in SHARE the where clause is falso, so the record is not included in the result set, if no records are found in share the where clause is true and the RECORD.* is included in result set. This works thanks to LEFT OUTER JOIN.
Note:
Another way of doing the same thing is to use the WHERE RECORD.ID NOT IN (SELECT ID FROM SHARE).
Pay attention that depending on the sql engine you are using this may lead to serious performance issues because the internal engine can run the (SELECT ID FROM SHARE) once per record in RECORD table.

select Id from t1 where id not in (select id from t2)

SELECT * from RECORD where ID not in (SELECT DISTINCT ID FROM SHARE);
SELECT DISTINCT ID FROM SHARE - will get all the distinct IDs in the table share
SELECT * from RECORD where ID not in (SELECT DISTINCT ID FROM SHARE); would display all records whose ID is not in the first query.

Related

Left Join two tables with one common column and other diff columns

I have two tables where main table has 10+ columns and second table has 3 columns with one common field. My problem here is I am not able to get exact count with left outer join as main table. I am seeing more count than actual. It might be due to one of the field I am trying to get is not in main table which is in second table.
Table 1: master_table
Table 2: manager_table
Master_table :
ID,
Column1,
Column2,
...
Column10
manager_table:
ID,
Column2_different,
Column3_different
I am trying to join using Left Join to get same records as present in master table.
Select table1.columns, table2.columns
From table1
Left join table2 on table1.ID = table2.ID
The above is not giving me exact record count as in master table (table1) , it is giving me more count as the table 2 other field is not present in table 1 .
Can someone help me here ?
TIA
I believe that an INNER JOIN would be better than a LEFT JOIN. Need some sample data to be sure, but if you're getting a higher count than you'd expect upon joining the tables this is probably because the LEFT JOIN is returning everything from both tables. An INNER JOIN will only return data that appears in both tables.

SQL help, left join with filter

Please have a look at the SQL in the SQLFiddle link below.
http://sqlfiddle.com/#!9/22e094/4
My goal is to get all the records from Table1, and if SecId exists in Table2, join only if the status is 'Y'.
Result should be that it pulls from table 1: ID 1 and 2. And for ID 1, it successfully left joins Table2 and pulls 'Y'
As you can see in the fiddle, I tried 3 different ways but can't seem to get it.
It's got me stumped... Help would be awesome! :)
The left join, with just the join condition in the ON clause, is fine.
But then, you said you want to keep the rows where status is 'Y' only when the secid exists in table2. So this means you also want to keep the rows where the secid from table2 is NULL.
select * won't fly, because you have columns by the same name, secid, in both tables. You must distinguish them (by giving them aliases - or at least one of them; I gave aliases to both of them) if you need to reference them in the where clause, or anywhere else in the query, to break the ambiguity. And, since the aliases can only be given in the SELECT clause, which is evaluated after the WHERE clause, you need to do the left join in a subquery.
select id, secid_a, secid_b, status
from (
select a.id, a.secid as secid_a, b.secid as secid_b, b.status
from table1 a left join table2 b
on a.secid = b.secid
)
where status = 'Y' or secid_b is null;

multi-table query when there is no record in one table

What should I do if I want to:
For now, there are table A and table B,
A:
id, name, address //the id is unique
B
id, contact, email
Since one person may have more than one contact and email, or have no contact and email(which means no record in table B)
Now I want to count how many records for each id, even 0:
And the result will look like:
id, name, contact_email_total_count
How can I do that(for now the only place I can not figure out is how to count 0 record since there is no record in table B)?
For that case you will want to use a LEFT JOIN, then add an aggregate and a GROUP BY:
select a.id,
a.name,
count(b.id) as contact_email_total_count
from tablea a
left join tableb b
on a.id = b.id
group by a.id, a.name
See SQL Fiddle with Demo
If you need help learning join syntax here is a great visual explanation of joins.
Based on your comment the typical order of execution is as follows:
FROM
ON
JOIN
WHERE
GROUP BY
HAVING
SELECT
ORDER BY
Need to do a left join to maintain the records in table A regardless of B:
PostgreSQL: left outer join syntax
Need to aggregate the count of records in B:
PostgreSQL GROUP BY different from MySQL?

SQL statement selecting rows from a table dependent on information from another table

I have two different tables in a database, differing in number of columns. Now, I want to select a number of rows from the first table dependent on some variable (for example that the first column should have the value 1). However, I would also like to use information from my other table to select rows from my first table.
In my specific case, both table1 and table2contains the columns Group and Person. Table1 specify each person once, and declares what group he or she belongs to. However, people can also be part of secondary groups, which are listed in table2. That is, in table2, a person can be listed again with a new group number.
I would like to write an SQL statement where I select persons (that is, rows) from table1 (since I have more information about the persons in this table) that are members of a certain group, x. However, since a person can belong to several groups, I need to look through table2 as well, somehow.
How can I write this SQL statement?
select t1.person_id,t1.group_id
from table1
union all
select t2.person_id,t2.group_id
from table2
this will give you one table
person group
person1 group1
person1 group2
person2 group3
no matter what tables they belong to.
This architecture seems silly however if the same data is in both tables.
If i have understood your question correctly, this query below will get you a person's details where the person is a member of a group 'X' and that relationship between person and that particular group 'X'is coming from a record maintained in either table1 or table2.
SELECT t1.*
FROM table1 t1
LEFT OUTER JOIN table2 t2
ON t1.Person = t2.Person
WHERE t1.Person = 'Y'
AND (t1.Group = 'X' OR t2.Group = 'X')
You will need some sort of identifier in both tables - like a candidate key.
When you do your select you need to join the tables, example:
SELECT column_name(s)
FROM Table1 table_name1
INNER JOIN Table2 table_name2
ON table_name1.column_name=table_name2.column_name
WHERE table_name1.person = table_name2.person
You can use JOIN clause to combine rows from two or more tables, based on a related column between them.
Let's look at a selection in this example:
SELECT
       table1.user_name,
       table2.group_name,
       table1.address
FROM table1
INNER JOIN table2
ON table1.UserID = table2.ID;

Join two tables using HiveQL

These are two tables below-
CREATE EXTERNAL TABLE IF NOT EXISTS Table1 (This is the MAIN table through which comparisons need to be made)
(
ITEM_ID BIGINT,
CREATED_TIME STRING,
BUYER_ID BIGINT
)
CREATE EXTERNAL TABLE IF NOT EXISTS Table2
(
USER_ID BIGINT,
PURCHASED_ITEM ARRAY<STRUCT<PRODUCT_ID: BIGINT,TIMESTAMPS:STRING>>
)
As BUYER_ID and USER_ID they both are same thing.
I need to find the total COUNT and all those BUYER_ID that are not there in Table2 by comparing from Table1. So I think it's a kind of Left Outer Join Query. I am new to HiveSql stuff so I am having problem to figure out what should be the actual syntax to do this in HiveQL. I wrote the below SQL Query. Can anyone tell me whether the SQL query below is fine or not to achieve my scenario?
SELECT COUNT(BUYER_ID), BUYER_ID
FROM Table1 dw
LEFT OUTER JOIN Table2 dps ON (dw.BUYER_ID = dps.USER_ID)
GROUP BY BUYER_ID;
If I understand your requirements correctly, I think you are almost there. It seems you only need to add a condition checking if there's no match between the two tables:
SELECT COUNT(BUYER_ID), BUYER_ID
FROM Table1 dw
LEFT OUTER JOIN Table2 dps ON (dw.BUYER_ID = dps.USER_ID)
WHERE dps.USER_ID IS NULL
GROUP BY BUYER_ID;
The above will filter out BUYER_IDs that do have matches in Table2, and will show the remaining BUYER_IDs and their corresponding count values. (Well, that's what I understand you want.)