Sql join on similar columns, but not same - sql

Suppose i have column a in one table and column 2 in another. They are both navchar. Column 2 ends with '-US'. How do I join the two tables, provided that column 1 is the same as 2 but without the us ending?

You could do either
SELECT
a.Field1
,a.Field2
,b.Field3
FROM TableA a
JOIN TableB b
ON a.Fieldname + '-US' = b.FieldName
or if it's not always going to end in -US then you could try this
SELECT
a.Field1
,a.Field2
,b.Field3
FROM TableA a
JOIN TableB b
ON b.FieldName LIKE a.FieldName + '%'

The obvious thing to do is to take the -US suffix into account:
on t2.c2 = t1.c1 + '-US'
or perhaps:
on t1.c1 = left(t2.c2, len(t2.c2) - 3)
If you want performance, you might consider a computed column with an index. Something like this:
alter table t1 add c1_us as (c1 + '-US');
create index t1_c1_us on t1(c1_us);
This would then allow an index to be used for a condition such as:
on t2.c2 = t1.c1_us

Related

Add two string columns from different tables

I am trying to add two columns together of char data type in order to combine their code with description.
table1 has all of the data I need and I am only referencing table2 in order to get the description.
For example, table1 has column:
Code
1
2
and table 2 has columns:
Code Description
1 Football
2 Soccer
I'm basically trying to write a query where I can have one column show
1 - Football
2 - Soccer
I have tried:
SELECT
a.Code + ' - ' + b.Description
FROM table1 a
LEFT JOIN table2 b
ON a.Code = b.Code
and while this does add the columns together, it also generates a lot of duplicate rows for some reason, I am assuming because of the LEFT JOIN.
Basically I am just wanting that whatever code is in table1, to match that code in table2 and to bring over that Description.
With the Left Join you get the values in Table A that may not exist in Table B. To eliminate the duplicates you could try
SELECT DISTINCT
a.Code + ' - ' + b.Description
FROM table1 a
LEFT JOIN table2 b
ON a.Code = b.Code
OR
SELECT
a.Code + ' - ' + b.Description
FROM table1 a
LEFT JOIN table2 b
ON a.Code = b.Code
GROUP BY a.Code, b.Description
You could use ISNULL to handle missing value from table2:
SELECT
a.Code + ISNULL(' - ' + b.Description, '')
FROM table1 a
LEFT JOIN table2 b
ON a.Code = b.Code
use coalesce in case of null for 2nd table and use distinct incase of avoid duplicate
SELECT distinct a.Code +' - ' + coalesce(b.Description,'')
FROM table1 a
LEFT JOIN table2 b
ON a.Code = b.Code
or try like below and i dont think you needed join you can do it just by using 2nd tabale
SELECT
b.Code ||' - ' || b.Description)
from
table2 b
What is the relationship between table1 and table2? The only way I see the above query returning duplicates is: If relationship between table1 and table2 is 1:Many. Meaning one row in table1 can match to multiple rows in table2.
Do you need to fetch a code that exists in table1 even if it does not have a corresponding description in table2? If so, use a LEFT JOIN like below.
If table2 has direct duplicates, then using a DISTINCT will remove
duplicates in the final result:
SELECT DISTINCT
a.Code + ' - ' + COALESCE(b.Description, '')
FROM table1 a
LEFT JOIN table2 b
ON a.Code = b.Code;
If one code has multiple different descriptions in table2, then your
final resultset is expected to have multiple rows for the same code
but with different description by running the above query because of
the nature of data in the tables.
Do you need to fetch a code that exists in table1 only if it has a corresponding description in table2? If so, use a INNER JOIN like below.
SELECT DISTINCT
a.Code + ' - ' + b.Description
FROM table1 a
INNER JOIN table2 b
ON a.Code = b.Code;

SQL Server Update sub query with formula not quite right

I have a table (table1) of names and their frequencies
Name-----Frequency
Mike-------0.56
Fred-------0.30
Nancy------0.14
and a Cartesian product (table2) where the names are paired in two columns and a third column where I would like to sum the frequencies from table1 by matching the names in the first two columns back to table1.
Name1-------Name2------sum
Mike--------Fred
Mike--------Nancy
Fred--------Nancy
I want to update the sum column of table2 using the frequencies in table 1 with a subquery in the update for the matching names (Or so this is how I imagine I need to do it). If there is a better way please let me know.
I have:
UPDATE table2
SET sum = (SELECT dbo.table1.Frequency WHERE Name1 = dbo.table1.Name) +
(SELECT dbo.table1.Frequency WHERE Name2 = dbo.table1.Name)
FROM table1
I get a table full of NULLs instead of the frequency sums.
Am I going about this the right way? Am I totally missing how to do this and there is a better way to do it?
Try updating from a join like this:
update a
set a.sum=isnull(b.frequency,0)+isnull(c.frequency,0)
from table2 a
left join table1 b on a.name1=b.name
left join table1 c on a.name2=c.name
Your method is fine. If all names match:
UPDATE t2
SET sum = (SELECT f.frequency FROM dbo.table1.Frequency f WHERE t2.Name1 = f.Name) +
(SELECT f.frequency FROM dbo.table1.Frequency f WHERE t2.Name2 = f.Name)
FROM table2 t2;
If they don't, then use isnull() (or coalesce(), but isnull() is more efficient):
UPDATE t2
SET sum = isnull( (SELECT f.frequency FROM dbo.table1.Frequency f WHERE t2.Name1 = f.Name), 0) +
isnull( (SELECT f.frequency FROM dbo.table1.Frequency f WHERE t2.Name2 = f.Name), 0)
FROM table2 t2;

Joining tables using concat column

So I have two tables I want to join using SQL.
Since they did not have a common column I used
SELECT NEW_ID = CONCAT ('0',table1.ID)
Now that I have the new column with matching data in both tables, how do I join both tables? Is there any way to use the NEW_ID column as a temporary column so that I do not have to alter table 1?
In your case, suitable. of course in terms of performance it is not the best solution ( compare fields with diffrent types)
Select *
From Table1 As t1 inner join Table2 as t2
ON t1.ID = CAST(t2.ID AS INT)
Different ways, here's one:
;WITH CTE AS
(
SELECT NEW_ID = CONCAT ('0',table1.ID) FROM TableA
)
SELECT * FROM CTE AS C INNER JOIN TableB AS B ON C.New_ID = B.ID
You Can Just give the Concrete Expression in the Join.You Don't have to add a new Column For that. Like this
SELECT
*
FROM Table1 A
INNER JOIN Table2 B
ON RIGHT('00'+A.Id,2) = RIGHT('00'+B.Id,2)

Join based on temp column

I have two tables that need to be joined, but the only similar column has excess data that needs to be stripped. I would just modify the tables, but I only have read access to them. So, I strip the unneeded text out of the table and add a temp column, but I cannot join to it. I get the error:
Invalid column name 'TempJoin'
SELECT
CASE WHEN CHARINDEX('- ExtraText',a.Column1)>0 THEN LEFT(a.Column1, (CHARINDEX('- ExtraText', a.Column1))-1)
WHEN CHARINDEX('- ExtraText',a.Column1)=0 THEN a.Column1
END AS TempJoin
,a.Column1
,b.Column2
FROM Table1 as a
LEFT JOIN Table2 as b WITH(NOLOCK) ON b.Column2=TempJoin
Easiest way would be to wrap this in a CTE. Also, be careful using NOLOCK, unless you have an explicit reason.
WITH cte AS (
SELECT
CASE WHEN CHARINDEX('- ExtraText',a.Column1) > 0
THEN LEFT(a.Column1, (CHARINDEX('- ExtraText', a.Column1))-1)
WHEN CHARINDEX('- ExtraText',a.Column1) = 0
THEN a.Column1
END AS TempJoin,
a.Column1
FROM Table1 AS a
)
SELECT *
FROM cte
LEFT JOIN Table2 AS b WITH(NOLOCK) ON b.Column2 = TempJoin;

Getting the value upon match from the ref table

I have 2 tables
Select distinct
ID
,ValueA
,Place (How to get the Place value from the table 2 based on the Match between 2 columns ValueA and ValueB
Here Table2 is just a ref Table I''m using)
,Getdate() as time
Into #Temp
From Table1
For example when we receive value aa in ValueA column - I want the value of "Place" = "LA"
For example when we receive value bb in ValueA column - I want the value of "Place" = "TN"
Thanks in advance!
SELECT A.ID
, A.ValueA
, B.Place
, GETDATE() INTO #TempTable
FROM Table1 A INNER JOIN Table2 B
ON A.ValueA = B.ValueB
You can do this dude:
Select ID, ValueA, Place, getdate() as Date FROM Table1 INNER JOIN Table2 on Table1.ValueA = table2.ValueB.
Hope this works dude!!!
Regards...
Select
t1.ID
,t1.ValueA
,t2.Place
,Getdate() as time
Into #Temp
From Table1 t1
inner join Table2 t2 on t1.ValueA = t2.ValueB
I believe you are looking to do an inner join:
SELECT Table1.ID, Table1.ValueA, Table2.Place
FROM Table1
INNER JOIN Table2 ON Table1.ValueA = Table2.ValueB
Assumption: ValueB on table 2 is the primary key (or at least UNIQUE and therefore a candidate key).
Also, the DISTINCT is redundant assuming that ID is a primary key. Furthermore, you more than likely do not need a temporary table since a join can be used as an inner SELECT in most databases.
The exact syntax may depend on your particular database engine.