add new column with matching id in both Table 1 and Table 2 - sql

I have two tables,
in table1 I have 5 rows and
in table2 3 rows
table1:
#no---Name---value
1-----John---100
2-----Cooper-200
3-----Mil----300
4-----Key----200
5-----Van----300
Table 2:
#MemID-#no---FavID
19-----1-----2
21-----1-----3
22-----2-----5
Now expected result:
#no---name---value---MyFav
1-----John---100-----NULL
2-----Cooper-200-----1
3-----Mil----300-----1
4-----Key----200-----NULL
5-----Van----300-----NULL
1 indicates - My favorites
MyFav - new column ( alias)
This is the expected result, please suggest how to get it.

I think I understand the logic. You want MyFav to be marked as a 1 if that row is a favorite of John. You can do this with a left join and some more filtering:
select t1.*,
(case when t2.#no is not null then 1 end) as MyFav
from table1 t1 left join
table2 t2
on t1.#no = t2.FavId and
t2.#no = (select tt1.#no from table1 tt1 where tt1.Name = 'John');

Just use natural join for that, It will use your primary key as a mediator to join both the tables, as required. In your case, I think primary key is #no
For more information on natural join please visit SQL Joins

Related

Delete a record from a table referring to 2 or more columns from another table

Consider having 2 tables as follows.
Table 1:
Unit
SKU number
Active
A
1
Y
B
2
Y
c
3
Y
Table 2:
Unit
SKU number
description
X
4
Apple
B
2
Mango
Y
5
Grapes
z
6
Banana
I wanted to delete record B,2,Y from table 1 by referring to table 2 where values in columns Unit and SKU number match.
I tried using the following query but it didn't seem to work
DELETE FROM table1
WHERE (Unit, SKU_Number) IN (SELECT Unit, SKU_Number FROM table2);
The error was
An expression of non-boolean type specified in a context where a condition is expected, near ','
Can someone please help me understand what I am doing wrong here or help me rewrite the SQL query to achieve the required objective?
You could use similar logic with exists:
DELETE
FROM table1 t1
WHERE EXISTS (SELECT 1 FROM table2 t2
WHERE t2.Unit = t1.Unit AND t2.SKU_Number = t1.SKU_Number);
You can try using this query, assuming Unit of Table 1 is unique:
DELETE FROM table1
WHERE table1.Unit IN (
SELECT table1.Unit
FROM table1
LEFT JOIN table2 ON table1.Unit = table2.Unit
AND table1.SKU_Number = table2.SKU_Number
)
If unit is not an unique field, simply replace it with whichever field is unique, or with primary key of Table 1.
You can use inner join for delete:
DELETE t1
FROM table1 t1
INNER JOIN table2 t2
ON t1.unit=t2.unit and t1.SKU_Number = t2.SKU.Number

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

Join SQL Tables with Unique Data (Not same number of columns!)

How can I join three or four SQL tables that DO NOT have an equal amount of rows while ensuring that there are no duplicates of a primary/foreign key?
Structure:
Table1: id, first_name, last_name, email
Table2: id (independent of id in table 1), name, location, table1_id, table2_id
Table3: id, name, location
I want all of the data from table 1, then all of the data from table 2 corresponding with the table1_id without duplicates.
Kind of tricky for a new guy...
Not sure what do you want to do with Table3.
A LEFT JOIN returns all records from the LEFT table, and the matched records from the right table. If there is no match (from the right side), then the result is NULL.
So per example:
SELECT * FROM Table1 AS t
LEFT JOIN Table2 AS tt
ON t.id = tt.id
The LEFT table refers to the table statement before the LEFT JOIN, and the RIGHT table refers to the table statement after the LEFT JOIN. If you want to add in Table3 as well, use the same logic:
SELECT * FROM Table1 AS t
LEFT JOIN Table2 AS tt
ON t.id = tt.id
LEFT JOIN Table3 AS ttt
ON t.id = ttt.id
Note, that I use alias names for the tables (by using AS), so that I can more easily refer to a specific table. For example, t refers to Table1, tt refers to Table2, and ttt refers to Table3.
Joins are often used in SQL, therefore it is useful to look into: INNER JOIN, RIGHT JOIN, FULL JOIN, and SELF JOIN, as well.
Hope this helps.
Good luck with learning!
You will want to use an LEFT JOIN
SELECT * FROM table1 LEFT JOIN table2 ON Table1.ID = Table2.table1_id

How do I Write a SQL Query With a Condition Involving a Second Table?

Table1
...
LogEntryID *PrimaryKey*
Value
ThresholdID - - - Link to the appropriate threshold being applied to this log entry.
...
Table2
...
ThresholdID *PrimaryKey*
Threshold
...
All fields are integers.
The "..." thingies are there to show that these tables hold a lot more imformation than just this. They are set up this way for a reason, and I can't change it at this point.
I need write a SQL statement to select every record from Table1 where the Value field in that particular log record is less than the Threshold field in the linked record of Table2.
I'm newish to SQL, so I know this is a basic question.
If anyone can show me how this SQL statement would be structured, it would be greatly appreciated.
SELECT T1.*
FROM Table1 T1
JOIN Table2 T2 ON T2.ThresholdID = T1.ThresholdID
WHERE T2.Threshold > T1.Value
SELECT t1.*
FROM dbo.Table1 t1 INNER JOIN dbo.Table2 t2 ON t1.ThresholdID = t2.ThresholdID
WHERE t2.Threshold > t1.Value
SELECT * from table1 t1 join table2 t2 on (t1.thresholdId = t2.thresholdId)
where t1.value < t2.threshold;
SELECT t1.LogEntryID, t1.Value, t1.ThresholdID
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.ThresholdID = t2.ThresholdID
WHERE t1.Value < t2.threshold
SELECT * FROM Table1
JOIN Table2
ON table1.ThresholdID = table2.ThresholdID --(assuming table 2 holds the same value to link them together)
WHERE
value < thresholdvalue
A 'JOIN' connects 2 tables based on the 'ON' clause (which can be multipart, using 'AND' and 'OR')
If you have 3 entries in table 2 which share table1's primary key (a one-to-many association) you will receive 3 rows in your result set.
for the tables below, for example:
Table 1:
Key Value
1 Hi
2 Bye
Table 2:
Table1Key 2nd_word
1 You
1 fellow
1 friend
2 now
this query:
SELECT * FROM Table1
JOIN Table2
on table1.key = table2.table1key
gets this result set:
Key Value Table1Key 2nd_word
1 Hi 1 You
1 Hi 1 fellow
1 Hi 1 friend
2 Bye 2 now
Note that JOIN will only return results when there is a match in the 2nd table, it will not return a result if there is no match. You can LEFT JOIN for that (all fields from the second table will be NULL).
JOINs can also be strung together, the result from the previous JOIN is used in place of the original table.

Oracle: Check if rows exist in other table

I've got a query joining several tables and returning quite a few columns.
An indexed column of another table references the PK of one of these joined tables. Now I would like to add another column to the query that states if at least one row with that ID exists in the new table.
So if I have one of the old tables
ID
1
2
3
and the new table
REF_ID
1
1
1
3
then I'd like to get
ID REF_EXISTS
1 1
2 0
3 1
I can think of several ways to do that, but what is the most elegant/efficient one?
EDIT
I tested the performance of the queries provided with 50.000 records in the old table, every other record matched by two rows in the new table, so half of the records have REF_EXISTS=1.
I'm adding average results as comments to the answers in case anyone is interested. Thanks everyone!
Another option:
select O.ID
, case when N.ref_id is not null then 1 else 0 end as ref_exists
from old_table o
left outer join (select distinct ref_id from new_table) N
on O.id = N.ref_id
I would:
select distinct ID,
case when exists (select 1 from REF_TABLE where ID_TABLE.ID = REF_TABLE.REF_ID)
then 1 else 0 end
from ID_TABLE
Provided you have indexes on the PK and FK you will get away with a table scan and index lookups.
Regards
K
Use:
SELECT DISTINCT t1.id,
CASE WHEN t2.ref_id IS NULL THEN 0 ELSE 1 END AS REF_EXISTS
FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.ref_id = t1.id
Added DISTINCT to ensure only unique rows are displayed.
A join could return multiple rows for one id, as it does for id=1 in the example data. You can limit it to one row per id with a group by:
SELECT
t1.id
, COUNT(DISTINCT t2.ref_id) as REF_EXISTS
FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.ref_id = t1.id
GROUP BY t1.id
The group by ensures there's only one row per id. And count(distinct t2.ref_id) will be 1 if a row is found and 0 otherwise.
EDIT: You can rewrite it without a group by, but I doubt that will make things easer:
SELECT
t1.id
, CASE WHEN EXISTS (
SELECT * FROM TABLE_2 t2 WHERE t2.ref_id = t1.id)
THEN 1 ELSE 0 END as REF_EXISTS
, ....
FROM TABLE_1 t1