I have two tables
Table 1:
color_id | label
---------|------
2 | 0
3 | 0
2 | 0
1 | 0
4 | 1
4 | 1
5 | 0
Table 2:
color_id
--------
2
1
4
I want a query that just gives me results for color_ids that are present in Table 2
So, I wrote:
SELECT *
FROM table1
LEFT JOIN table2
ON table1.color_id = table2.color_id
WHERE table2.color_id IS NOT NULL
however, the above gives duplicates as well. Meaning I get
2 | 0
2 | 0
1 | 0
4 | 1
4 | 1
I don't want the duplicates in the results. I just want unique items.
I want a query that just gives me results for color_ids that are present in Table 2
So, you shouldn't use LEFT JOIN in this case:
SELECT DISTINCT a.color_id, a.label
FROM table_1 a JOIN table_2 b
ON a.color_id = b.color_id
When you add the keyword Left (or Right or full) to a join specifier, you make the join an outer join. This means that you get all the rows from one side of the join, and only those rows from the other side that match. If you only want the rows from table_1 where the color_id is in table_2, then you want an inner join, specified by writing inner join or just writing join, without a left, right or full.
to eliminate duplicates, add the keyword distinct to the select clause...
Select distinct color_id, label
From table1 t1
join table2 t2
on t2.color_id = t1.color_id
Try the below query
SELECT DISTINCT color_id
FROM table_1 T1
WHERE EXISTS (SELECT 1 FROM table_2 T2 where T1.color_id = T2.color_id)
Use an inner join and a distinct clause:
SELECT DISTINCT table1.color_id, table1.label
FROM table1
INNER JOIN table2
ON table1.color_id = table2.color_id
What you are looking for is an INNER JOIN combined with a
SELECT distinct table1.color_id, tabl1.label
FROM table1
INNER JOIN table2 ON table1.color_id = table2.color_id
This eliminates any item in table1 not present in table 2 and duplicated rows.
the reason of that is you used Left Join, which will keep all obs in table1.
Try this:
SELECT table1.* FROM table1 Inner JOIN table2 ON table1.color_id = table2.color_id
this should works as actually all table2 obs are in table1. To be more serious, if table2 has obs that are not in table1 and you do want to keep them, replace inner join with right join.
Related
I have two tables identical to each other like below
table 1
col1
1
2
3
4
5
table 2
col1
1
2
3
4
5
is there way to write a SQL query to join every row of table 1 to every row of table 2?
Do you want a Cartesian product? If so, use cross join:
select t1.col1, t2.col2
from table1 t1 cross join
table2 t2;
It sounds like an inner join as they are identical tables:
select t1.col, t2.col, ...
from table t1
inner join t2 on t1.col = t2.col
Could anyone help with how to take a single column:
ID
1
2
3
4
and show all possible distinct pairings in 2 columns:
ID ID
1 2
1 3
1 4
2 3
2 4
3 4
You can join the column on itself and arbitrarily decide that the left hand side will always be smaller than the right hand side (as the example shows):
SELECT t1.col, t2.col
FROM mytable t1
JOIN mytable t2 ON t1.col < t2.col
do self join
select t.id,t2.id from t t1 join t t2 on t.id<t1.id
A Simple Cartesian product should do
select distinct a.id as id_a, b.id as id_b
from test a, test b
where a.id<b.id;
I'm not sure how to explain what I need but here's the data first:
Table 1
District
-1
3
2
1
3
Table 2
ID ID_Name
1 Main 1
2 Main 2
3 Main 3
How do I join the tables so that it looks like this?
District
-1
Main 3
Main 2
Main 1
Main 3
I'm assuming the second column is named Name for this, but you can do it with a COALESCE and a LEFT JOIN:
Select Coalesce(T2.Name, Str(T1.District)) As District
From Table1 T1
Left Join Table2 T2 On T1.District = T2.Id
assuming table 2 have
Table 2
ID col2
1 Main 1
2 Main 2
3 Main 3
you could use a left join
select table1.Distric, table2.col2
from table1
left join table2 on table1.dictrict = t2.ID
order by table2 col2
You can use left join:
Select coalesce(t2.col, t1.District) from table1 t1
left join table2 t2 on t1.District = t2.Id
I have a table that contains the following columns:
ID
Master ID
The Master ID can be shared between different rows with different IDs.
E.g.:
ID | Master ID
1 | 1
2 | 1
3 | 1
4 | 2
Knowing the ID I want to retrieve all the rows that share the same master ID
I managed to do it using this query:
Select *
FROM table t
LEFT JOIN table t2
ON t.MASTER_ID = t2.MASTER_ID
Where t.ID = '1'
Then I also tried using:
Select *
FROM table t
LEFT JOIN table t2
ON t.MASTER_ID = t2.MASTER_ID and t.ID = '1'
In that case, it was much slower. Can anyone explain why?
The queries are doing different things, the first you are saying:
1. give me all rows from `table` where `id = 1`
2. Also give me rows from t2 with a matching master ID
In the second you are saying
1. Give me all rows from `table`
2. Return rows from `t2` with a matching master ID and where `t1.ID = 1`
In a simple example you might have
ID Master_ID
------------------------
1 1
2 1
3 1
4 2
So your first query will return:
t1.ID t1.Master_ID t2.ID t2.Master_ID
--------------------------------------------
1 1 1 1
1 1 2 1
1 1 3 1
Your second query will return
t1.ID t1.Master_ID t2.ID t2.Master_ID
--------------------------------------------
1 1 1 1
1 1 2 1
1 1 3 1
2 1 NULL NULL
3 1 NULL NULL
4 2 NULL NULL
So basically in the first query you are returning a limited number of rows from your table, whereas in the second you return all rows, but only join to some of them.
If the t.ID = '1' condition is in the WHERE clause the t.ID='1' condition only has to be evaluated for the number of rows in t. If the t.ID='1' condition is put into the ON clause for the join it must be evaluated for all rows in t2. If there are a lot of rows in t2 this can significantly increase the run time of the query.
You shouldn't include t.ID = '1' in JOIN ON condition since it's not the joined table. condition on the table in FROM part should stay in WHERE clause; whereas condition belongs to joined table should be moved to join on clause so to get a proper outer join effect rather a inner join effect.
You don't need an OUTER JOIN. The reason is simple, your are joining the same table on the same column - there can't be a non-match!
The query to use is therefore
Select *
FROM T
INNER JOIN T t2
ON T.MasterID = t2.MasterID
Where t.ID = 1
I am attempting to do something using MSSQL that I believe is possible (easily) but I do not know how to vocalize the correct search string. I have the situation below.
Table A
UID | Value....
1 | a
2 | b
3 | c
Table B
PartTypes_uid_fk | Value....
1 | a
1 | b
1 | c
1 | d
1 | e
3 | 67
3 | 1354
I am attempting to get the following result, query Table A for all results {TableA.*} and on the same row result show the number of table b references {count TableB.tableA_fk}
What I have so far is the following.
SELECT DISTINCT t1.uid, CONVERT(varchar(MAX), t1.Name) AS Name, CONVERT(varchar(MAX), t1.Description) AS Description,
Count(t2.Items_uid_fk) OVER (Partition By t2.PartTypes_uid_fk) as Count
FROM [Table1] as t1 left outer join Table2 as t2 on t2.PartTypes_uid_fk=t1.uid;
This works for all of Table A records with an associated record in Table B but if there are 0 entries in Table B it won't work. The conversion of the varchars was required due to the fact they are ntext format and it was distinct.
Thank you for all your help in advance.
Stephen
Instead of running into problems with the GROUP BY on N/TEXT columns, and to run faster, you would want to pre-aggregate the B table and LEFT JOIN that against A.
select t1.*, ISNULL(t2.c, 0) AS CountOfB
from table1 t1
left join
(
select parttypes_uid_fk, count(*) c
from table2
group by parttypes_uid_fk
) t2 on t2.PartTypes_uid_fk=t1.uid
It's easier than that:
SELECT t1.uid, t1.Name, COUNT(*)
FROM [Table1] t1
LEFT JOIN [Table2] t2 ON t2.PartTypes_uid_fk = t1.uid
GROUP BY t1.uid, t1.Name
Your query should be
SELECT t1.uid,
CONVERT(varchar(MAX), t1.Name) AS Name,
CONVERT(varchar(MAX), t1.Description) AS Description,
Count(t2.Items_uid_fk) CountItems
FROM [Table1] as t1 left outer join Table2 as t2 on t1.uid = t2.PartTypes_uid_fk
GROUP BY uid, t1.name, t1.Description;