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

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;

Related

Using While SQL Server

I have two tables and both contains columns Names and ID_Number.
table1 contains columns Names, ID_Number, Price_date
table2 contains columns Names, ID_Number, historical_date, comments
I am trying to do a loop such that it will start from the first value in ID_Number column in table1 and see if it matches with any value in ID_number column in table2.
If there is a match, then compare the 'Names' for the two tables for that particular ID_number. If the names does not matched, then in the comments column, enter the Name from table1 and enter the Price_date from table1 to historical_date in table2.
Don't use loops in SQL, as long as you can avoid them. SQL is a set-based language, that is not optimized for iterative processes.
From your explanation, it seems like you want an update statement with a join. This should do what you want:
update t2
set t2.comments = t1.names, t2.historical_date = t1.price_date
from table2 t2
inner join table1 t1
on t1.id_number = t2.id_number
and t1.names <> t2.names

Why would LEFT JOIN on a field to then later filter it out in WHERE clause?

Query
SELECT ID, Name, Phone
FROM Table1
LEFT JOIN Table2 ON Table1.ID = Table2.ID
WHERE Table2.ID IS NULL
Problem
Finding it hard to understand why someone would left join on an ID
and then set it to NULL in the where clause?
Am I missing something here? Is there any significance to this?
Could we just omit the Table2 altogether? As in not join at all?
Any help would be much appreciated.
The query you have in the question is basically equivalent to the following query:
SELECT ID, Name, Phone
FROM Table1
WHERE NOT EXISTS
(
SELECT 1
FROM Table2
WHERE Table1.ID = Table2.ID
)
Meaning it selects all the records in Table1 that does not have a correlated record in Table2.
The execution plan for both queries will most likely be the same (Personally, I've never seen a case when they produce a different execution plan, but I don't rule that out), so both queries should be equally efficient, and it's up to you to decide whether the left join or the exists syntax is more readable to you.
I think you should have an alias for you table and specify which table each column is coming from.
Assuming Name is from table one and Phone is form table two and ID is common in both, then the Left join mentioned above may help get all users that do not have phone numbers.
Table 1
Id Name
1 John Smith
2 Jane Doe
Table 2
Id Phone
2 071 555 0863
Left Join without the where clause
ID Name Phone
1 John Smith NULL
2 Jane Doe 071 555 0863
Left Join with the where clause
ID Name Phone
1 John Smith NULL
This is one of the ways to implement the relational database operation of antijoin, called anti semi join within sql server's terminology. This is essentially "bring rows from one table that are not in another table".
The ways I cant think of doing this are:
select cols from t1 left join t2 on t1.key=t2.key where t2.key is null
select cols from t1 where key not in (select key from t2)
select cols from t1 where not exists (select 1 from t2 where t1.key=t2.key)
and even
select * from t1 where key in (select key from t1 except select key from t2)
There are some differences between these methods (most notably, the danger of null handling in the case of not in), but they generally do the same.
To address your points:
Finding it hard to understand why someone would left join on an ID and
then set it to NULL in the where clause?
As mentioned, in order to exclude results from t1 that are present in t2
Could we just omit the Table2 altogether? As in not join at all?
If you don't use the join (or any of its equivelant alternatives), you will get more results, as the rows in table1 that have the same id with any rows in table2 will be returned, too.
If joining condition column is having null value specifically ID then it is bad database design per my understanding.
As per your query below. Here are the possible scnario why where clause make sense
I am assuming that your name and phone number are coming from table2 and then you are trying to find the name and phone number whose ID is null.
If name and phone number is coming from table1 and table 2 is just having ID join and not selecting anything from table 2 then where clause is total waste.
SELECT
ID,
Name,
Phone
FROM
Table1
LEFT JOIN
Table2
ON
Table1.ID = Table2.ID
WHERE
Table2.ID IS NULL
Essentially in the above common business scenario, developers put where clause filter criteria in left join when any value is coming from right side is having non relevance data and not required to be the part of dataset then filter it out.

Not able to Get data from multiple independent tables that have a common column and yet do not depend on each other

I have 8 tables all with equal number of columns and with a common column. I want to fetch data from all tables in a single query.
My table structure is TABLE1, TABLE2, TABLE3, ..... TABLE 8.
that have columns COLUMNA, COLUMNB... COLUMNE and a COMMON_COLUMN
I need to get data with a where clause where COMMON_COLUMN='X'
I will need all columns from all tables.
I used a query that goes like this..
SELECT TABLE1.*, TABLE2.*, TABLE3.*
FROM TABLE1 T1
LEFT JOIN TABLE2 T2 ON T1.COMMON_COLUMN = T2.COMMON_COLUMN,
LEFT JOIN TABLE3 T3 ON T1.COMMON_COLUMN = T3.COMMON_COLUMN
WHERE T1.COMMON_COLUMN='X' AND T2.COMMON_COLUMN='X' AND T3.COMMON_COLUMN='X'
The above query is not giving any results even if one of the tables do not have any rows. I do not want to use inner join because although the tables have a common column they do not depend on each other and I need data from all tables with a certain common column.
Also, the tables have unequal number of rows.
What am I doing wrong?
correct me if i am wrong - as you do not attach any sample data and desired result
but i assume that you simply need union all tables. You write in the title that tables are independent
SELECT T1.*
FROM TABLE1 T1
WHERE T1.COMMON_COLUMN='X'
UNION ALL
SELECT T2.*
FROM TABLE2 T2
WHERE T2.COMMON_COLUMN='X'
UNION ALL
SELECT T3.*
FROM TABLE3 T3
WHERE T3.COMMON_COLUMN='X'
...

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;

Microsoft Access query - not returning all data

Suppose I have the following tables:
Table1: FLP, FNAME, LNAME
Table2: FLP, Job, Company, Location
Table3: FLP, Status, Salary, Position
All are linked together by the FLP.
When I am trying to query to get all fields in all tables suppose my query is the following
Select *
From Table1, Table2, Table3
Where Table1.FLP = Table2.FLP AND Table1.FLP = Table3.FLP
However, suppose that one of the tables does not contain information or the record thus doesn't have an FLP.
For example: If i inserted into table1 johndoe1, john, doe,
and into table2 johndoe1, developer, comp, usa,
but did not insert anything into table 3 since the information is optional
my query will not fetch the result since it will fail at Table1.FLP= Table3.FLP
Sometimes table2 does not contain any information
If i tried my query as follows
Select *
From Table1, Table2, Table3
Where Table1.FLP = Table2.FLP OR Table1.FLP = Table3.FLP
then it will fetch all the results but mixes them up for example johndoe1 will have information from table3 that isn't equal to johndoe1 thus creating multiple results with different values.
If needed more explanation or the real table design please let me know.
You should use LEFT JOIN:
Select * From Table1 LEFT JOIN Table2 ON Table1.FLP = Table2.FLP LEFT JOIN Table3 ON Table1.FLP = Table3.FLP;
This will give you a null entry whenever there is no matching element in a right hand table.
See: http://msdn.microsoft.com/en-us/library/bb208894%28v=office.12%29.aspx