Combining name columns LIKE another - sql-server

I have 2 name columns from table1.name and table2.name. I have names in table1.name like "Alex Testing" and in table2.name it's "Alexander Testing". I have the table do some other tricky stuff but it doesn't recognize that Alex and Alexander are the same people so it will not include the name in my report. I was wondering if there was a way I could get these 2 to inner join by first name or even by last name, like if another table had the same first name but different last name?
I've tried:
SELECT
Table1.[Name], Table2.[Time],
CASE WHEN myvariables here then 0 ELSE 1 END AS columnB
INTO NewTable
FROM
Table1 INNER JOIN Table2
ON Table1.[Name] LIKE ('%' + Table2.Name + '%')
however it still does not work, it wont recognize Alex's name.
I've also tried:
SELECT
Table1.[Name], Table2.[Time],
CASE WHEN myvariables here THEN 0 ELSE 1 END as columnB
INTO NewTable
FROM
Table1 INNER JOIN Table2
ON Table1.[Name] LIKE CONCAT('%',"Table2.Name", '%')

Try:
SELECT
Table1.[Name], Table2.[Time],
CASE WHEN myvariables here then 0 ELSE 1 END AS columnB
INTO NewTable
FROM
Table1 INNER JOIN Table2
ON SUBSTRING(Table1.[Name], CHARINDEX(' ', Table1.[Name]) + 1, LEN(Table1.[Name])) = SUBSTRING(Table2.[Name], CHARINDEX(' ', Table2.[Name]) + 1, LEN(Table2.[Name]))
If you have large volume tables you may want to use subqueries and select directly lastnames, and then use a join on lastnames.

Related

Searching in results SQL Server

I have two tables:
Table 1
Name | Surname
Table 2
Introduce | Type
Introduce from Table 2 contains either Name or Surname or both from Table1. I'm listing all records from Table1 that are not present in Introduce and that's working just fine.
What I'm trying to do is limit those results using Type from Table2.
I'm trying such code:
select t1.Name, t1.Surname
from Table1 t1
where not exists (select 1 Introduce
from Table2 t2
where (t2.Introduce like ('%' + t1.Name+ '%')
or t2.Introduce LIKE ('%' + t1.Surname + '%'))
)
and exists (select Type
from Table2
where Type in (90, 120))
But there's no difference if I'm using and exists... or not, same results.
Change you WHERE clause to
where not exists
( SELECT 1 Introduce
from Table2 t2
where (t2.Introduce like ('%' + t1.Name+ '%') or t2.Introduce LIKE ('%' + t1.Surname + '%'))
and T2.Type in (90, 120)
)
and your design needs changing. It shouldn't be denormalised
select t1.Name, t1.Surname
from Table1 t1
where not exists
( SELECT 1 Introduce
from Table2 t2
where (t2.Introduce like ('%' + t1.Name+ '%') or t2.Introduce LIKE ('%' + t1.Surname + '%'))
and T2.Type in (90, 120)
)
Try this:
select name, surname from table1 [t1]
left join (select * from table2 where type in (90, 120)) [t2]
on CHARINDEX([t1].name, [t2].Introduce) > 0 or CHARINDEX([t1].surname, [t2].Introduce) > 0
where [t2].introduce is null

SQL Server : Select statement with select case nested

I have two tables
Table 1, columns: A, B, C
Table 2, columns: A, D, E
I want to select all from table 1 with an additional field added.
If the contents of string column table_1.A exists in table_2.A, then TRUE, if not then FALSE.
I'd love to tell you what I've tried, but nothing is coming close. I can do this with a SELECT CASE statement, but I can't figure out how to select all at the same time.
Thanks
Try using CASE
SELECT
table1.A,
table1.B,
table1.C,
CASE WHEN table2.A IS NULL THEN 'FALSE' ELSE 'TRUE' END
FROM
table1
LEFT OUTER JOIN
table2
ON table1.A = table2.A
SELECT T1.*, IIF(T2.D IS NULL, 'FALSE', 'TRUE')
FROM Table1 T1
LEFT JOIN Table2 T2 ON T2.A LIKE '%' + T1.A + '%'
You need a left outer join and them compare both tables using the case when columnab is not null then true else false
This would give you only one row per record in Table1.
SELECT Table1.*,
ISNULL([Found],'False') [Found]
FROM Table1
OUTER APPLY (
SELECT TOP 1
'True' AS [Found]
FROM Table2
WHERE Table2.A LIKE '%' + Table1.A + '%'
)

SQL joins vs subqueries vs exists for matching and filtering rows

I have a table which has the following fields : Id, Name, Dept
Sample data :
ID Name Dept
1 John A
2 Mary A
3 Tom A
4 David A
5 Mary B
6 David B
I am trying to get the names which are in Dept'A' but NOT in Dept'B'
I was able to come up with a query which gives the desired results :
select Id, Name, Dept
from test
Where Dept= 'a' and name not in (
select name from test where Dept= 'b')
But how can I do the same with joins?
You can use LEFT JOIN:
SELECT t1.*
FROM test t1
LEFT JOIN test t2
ON t1.Name = t2.Name
AND t2.Dept = 'B'
WHERE
t1.Dept = 'A'
AND t2.ID IS NULL
But I prefer the NOT EXISTS approach:
SELECT *
FROM test t
WHERE
t.Dept = 'A'
AND NOT EXISTS(SELECT 1 FROM test WHERE Name = t.Name AND Dept = 'B')
Aaron Bertrand wrote an article comparing the different techniques to check for existence of a row, with NOT EXISTS typically being the best choice.
Should I use NOT IN, OUTER APPLY, LEFT OUTER JOIN, EXCEPT, or NOT EXISTS?
How about:
SELECT A.Id, A.Name, A.Dept
FROM test A, test B
WHERE A.Dept= 'a'
AND B.Dept = 'b'
AND A.Name <> B.Name

LEFT JOIN with CASE WHEN

I am trying to implement a way to replace "dynamic SQL" of WHERE clause.
That is, to create a temp table, "#FilterTable", which contains my WHERE's name and value.
Then, I use "left join" to map my target table #Hotel with #FilterTable.
However, I got an error when using the following code:
DECLARE #filterName varchar(50)='Id',
#filterValue int =13
CREATE TABLE #Hotel (Id varchar(50), DisplayName varchar(100))
CREATE TABLE #FilterTable (Name varchar(50), Value varchar(100))
INSERT INTO #Hotel(Id,DisplayName) VALUES ('1','California Inn'), ('13','Hilton Hotel')
INSERT INTO #FilterTable(Name,Value) VALUES ('Id','13'),('DisplayName','Hotel')
SELECT a.*
FROM #Hotel a WITH(NOLOCK)
LEFT JOIN #FilterTable b WITH(NOLOCK)
ON #filterName= b.Name
AND
CASE b.Name
WHEN 'Id' THEN CONVERT(varchar(10), a.Id) = b.Value
WHEN 'DisplayName' THEN a.DisplayName like b.Value END
DROP Table #Hotel
DROP Table #FilterTable
It always shows error in
WHEN 'Id' THEN CONVERT(varchar(10), a.Id) = b.Value
WHEN 'DisplayName' THEN a.DisplayName like b.Value END
I know if I change to
WHEN 'DisplayName' THEN CONVERT(varchar(10), a.Id) END = b.Value
, it will pass, but there is no way to add the second condition in "WHEN" clause under this situation.
Does anyone know what is the correct syntax to put those two "WHEN" clause togather?
My db version is SQL SERVER 2014 Enterprise.
Thank you.
Your syntax for CASE is incorrect. You're using it like a switch statement in C, Java, etc. You don't say case against a value, then switch on the value. Rather, it's like an if statement where each condition is independent.
SELECT a.*
FROM #Hotel a WITH(NOLOCK)
LEFT JOIN #FilterTable b WITH(NOLOCK)
ON #filterName= b.Name
AND
CASE
WHEN b.Name = 'Id' AND CONVERT(varchar(10), a.Id) = b.Value THEN 1
WHEN b.Name = 'DisplayName' AND a.DisplayName like b.Value THEN 1
ELSE 0
END = 1
This says, if b.Name is ID and the convert pattern matches, the row matches, or if b.Name is DisplayName and the display name is like b.Value, the row matches.
Give that a try.
I do have to point out that this is likely to not scale well given multiple rows. You should really have a separate query for each case so that SQL Server can use the appropriate indexes and statistics.
In your code:
WHEN 'Id' THEN CONVERT(varchar(10), a.Id) = b.Value
WHEN 'DisplayName' THEN a.DisplayName like b.Value END
= b.Value and like b.Value equals = b.Value. If you want to use LIKE you have to add: like '%' + b.Value + '%'
But if it doesn't mean then you can use:
b.Value = CASE b.Name
WHEN 'Id' THEN CONVERT(varchar(10), a.Id)
WHEN 'DisplayName' THEN a.DisplayName END

Combine multiple results in a subquery into a single comma-separated value

I've got two tables:
TableA
------
ID,
Name
TableB
------
ID,
SomeColumn,
TableA_ID (FK for TableA)
The relationship is one row of TableA - many of TableB.
Now, I want to see a result like this:
ID Name SomeColumn
1. ABC X, Y, Z (these are three different rows)
2. MNO R, S
This won't work (multiple results in a subquery):
SELECT ID,
Name,
(SELECT SomeColumn FROM TableB WHERE F_ID=TableA.ID)
FROM TableA
This is a trivial problem if I do the processing on the client side. But this will mean I will have to run X queries on every page, where X is the number of results of TableA.
Note that I can't simply do a GROUP BY or something similar, as it will return multiple results for rows of TableA.
I'm not sure if a UDF, utilizing COALESCE or something similar might work?
Even this will serve the purpose
Sample data
declare #t table(id int, name varchar(20),somecolumn varchar(MAX))
insert into #t
select 1,'ABC','X' union all
select 1,'ABC','Y' union all
select 1,'ABC','Z' union all
select 2,'MNO','R' union all
select 2,'MNO','S'
Query:
SELECT ID,Name,
STUFF((SELECT ',' + CAST(T2.SomeColumn AS VARCHAR(MAX))
FROM #T T2 WHERE T1.id = T2.id AND T1.name = T2.name
FOR XML PATH('')),1,1,'') SOMECOLUMN
FROM #T T1
GROUP BY id,Name
Output:
ID Name SomeColumn
1 ABC X,Y,Z
2 MNO R,S
1. Create the UDF:
CREATE FUNCTION CombineValues
(
#FK_ID INT -- The foreign key from TableA which is used
-- to fetch corresponding records
)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE #SomeColumnList VARCHAR(8000);
SELECT #SomeColumnList =
COALESCE(#SomeColumnList + ', ', '') + CAST(SomeColumn AS varchar(20))
FROM TableB C
WHERE C.FK_ID = #FK_ID;
RETURN
(
SELECT #SomeColumnList
)
END
2. Use in subquery:
SELECT ID, Name, dbo.CombineValues(FK_ID) FROM TableA
3. If you are using stored procedure you can do like this:
CREATE PROCEDURE GetCombinedValues
#FK_ID int
As
BEGIN
DECLARE #SomeColumnList VARCHAR(800)
SELECT #SomeColumnList =
COALESCE(#SomeColumnList + ', ', '') + CAST(SomeColumn AS varchar(20))
FROM TableB
WHERE FK_ID = #FK_ID
Select *, #SomeColumnList as SelectedIds
FROM
TableA
WHERE
FK_ID = #FK_ID
END
In MySQL there is a group_concat function that will return what you're asking for.
SELECT TableA.ID, TableA.Name, group_concat(TableB.SomeColumn)
as SomColumnGroup FROM TableA LEFT JOIN TableB ON
TableB.TableA_ID = TableA.ID
I think you are on the right track with COALESCE. See here for an example of building a comma-delimited string:
http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string
You may need to provide some more details for a more precise response.
Since your dataset seems kind of narrow, you might consider just using a row per result and performing the post-processing at the client.
So if you are really looking to make the server do the work return a result set like
ID Name SomeColumn
1 ABC X
1 ABC Y
1 ABC Z
2 MNO R
2 MNO S
which of course is a simple INNER JOIN on ID
Once you have the resultset back at the client, maintain a variable called CurrentName and use that as a trigger when to stop collecting SomeColumn into the useful thing you want it to do.
Assuming you only have WHERE clauses on table A create a stored procedure thus:
SELECT Id, Name From tableA WHERE ...
SELECT tableA.Id AS ParentId, Somecolumn
FROM tableA INNER JOIN tableB on TableA.Id = TableB.F_Id
WHERE ...
Then fill a DataSet ds with it. Then
ds.Relations.Add("foo", ds.Tables[0].Columns("Id"), ds.Tables[1].Columns("ParentId"));
Finally you can add a repeater in the page that puts the commas for every line
<asp:DataList ID="Subcategories" DataKeyField="ParentCatId"
DataSource='<%# Container.DataItem.CreateChildView("foo") %>' RepeatColumns="1"
RepeatDirection="Horizontal" ItemStyle-HorizontalAlign="left" ItemStyle-VerticalAlign="top"
runat="server" >
In this way you will do it client side but with only one query, passing minimal data between database and frontend
I tried the solution priyanka.sarkar mentioned and the didn't quite get it working as the OP asked. Here's the solution I ended up with:
SELECT ID,
SUBSTRING((
SELECT ',' + T2.SomeColumn
FROM #T T2
WHERE WHERE T1.id = T2.id
FOR XML PATH('')), 2, 1000000)
FROM #T T1
GROUP BY ID
Solution below:
SELECT GROUP_CONCAT(field_attr_best_weekday_value)as RAVI
FROM content_field_attr_best_weekday LEFT JOIN content_type_attraction
on content_field_attr_best_weekday.nid = content_type_attraction.nid
GROUP BY content_field_attr_best_weekday.nid
Use this, you also can change the Joins
SELECT t.ID,
t.NAME,
(SELECT t1.SOMECOLUMN
FROM TABLEB t1
WHERE t1.F_ID = T.TABLEA.ID)
FROM TABLEA t;
This will work for selecting from different table using sub query.
I have reviewed all the answers. I think in database insertion should be like:
ID Name SomeColumn
1. ABC ,X,Y Z (these are three different rows)
2. MNO ,R,S
The comma should be at previous end and do searching by like %,X,%

Resources