LIKE operator instead of IN operator when checking tables - sql

I am working on an SQL script to add the ID of a customer if the phone number is found inside a table.
Below is a snippet of my code:
CREATE TABLE #Customers ( AccountNumber nvarchar(20))
CREATE TABLE #Phones ( Number nvarchar(30))
INSERT INTO #Customers (AccountNumber)
SELECT AccountNumber
FROM CustomerTable
WHERE
(CustomerTable.PhoneNumber IN (SELECT DISTINCT Number FROM #Phones))
OR
(CustomerTable.PhoneNumber2 IN (SELECT DISTINCT Number FROM #Phones))
GO
However, using those statement I am only able to check if the exact record is met within the table. For example:
If Phones.Number has a record '123456' and CustomerTables.PhoneNumber has a record '123456 7', this record record will not be obtained, even if it contains the number.
Are their any modifications I can do to my current snippet in order to apply similar logic to the LIKE operator?

This can't be done directly with the in operator, but using a query inside the exists operator should do the trick:
INSERT INTO #Customers (AccountNumber)
SELECT AccountNumber
FROM CustomerTable ct
WHERE EXISTS (SELECT *
FROM #Phones p
WHERE ct.PhoneNumber LIKE '%' + p.Number + '%' OR
ct.PhoneNumber2 LIKE '%' + p.Number + '%')

SELECT AccountNumber
FROM CustomerTable c
join #Phones p
on c.PhoneNumber like p.Number + '%' OR c.PhoneNumber2 like p.Number + '%'

I think this will also work, but i have not tested.
WITH Customers AS
(
SELECT AccountNumber , Len(PhoneNumber) as PhoneSize
FROM
)
INSERT INTO #Customers (AccountNumber)
SELECT AccountNumber
FROM CustomerTable a
Join Customers b on a.AccountNumber = b.AccountNumber
WHERE
(CustomerTable.PhoneNumber IN (SELECT DISTINCT LEft(Number,b.PhoneSize) FROM #Phones))
OR
(CustomerTable.PhoneNumber2 IN (SELECT DISTINCT LEft(Number,b.PhoneSize) FROM #Phones))

Related

Full outer join not including results from the second table?

I have 2 employee tables and trying to look up a user from both of them. For example:
Employees1
username full_name
fbar Foo Bar
Employees2
email full_name
sname#test.com Some Name
I'm trying to do something like this:
DECLARE #testuser VARCHAR(100)
SET #testuser = 'sname'
SELECT isnull(a.full_name, b.full_name) as full_name
FROM Employees1 as a
FULL OUTER JOIN Employees2 as b ON b.email LIKE #testuser + '%'
WHERE a.username = #testuser
If I run this then it comes out blank. But if I run the following then it shows the correct name:
SELECT full_name FROM Employees2 WHERE email LIKE #testuser + '%'
Is there a reason the full outer join isn't showing a result but the second select statement is?
If you have limiting conditions on individual tables that are separate from the outer join condition, you will need to put them in a subselect for them to work as expected.
I believe what you want is something like:
DECLARE #testuser VARCHAR(100) = 'sname'
SELECT isnull(a.full_name, b.full_name) as full_name
FROM (
SELECT *
FROM Employees1
WHERE username = #testuser
) as a
FULL OUTER JOIN (
SELECT *
FROM Employees2
WHERE email LIKE #testuser + '%'
) as b
ON b.full_name = a.full_name
Or perhaps you may just need a UNION:
SELECT full_name
FROM Employees1
WHERE username = #testuser
UNION
SELECT full_name
FROM Employees2
WHERE email LIKE #testuser + '%'
I added the full_name join condition, as I believe that is what you intended.
See this db<>fiddle.

Join table with another table and fetch and replace the values which are ';' seperated

I am trying to join a table that has a column with data as a string and replace the values with the values from the joined table.
Tab 1
ID
Name
Categories
1
Programmer
1;2
2
Analyst
3;2
Tab 2
id
Firstname
lastname
1
john
kele
2
ajay
kashid
3
shubham
sharma
I need a query that will fetch the "Id,name and categories" from the first table but in the form like:
Id
Name
Categories
1
Programmer
john,kele ajay,kashid
2
Analyst
shubham,sharma ajay,kashid
I have written this one but this gives only the first entry, not for all the entries
SELECT
sc.Id,sc.Application,u.u_LastName + ', ' + u.u_FirstName 'coeowner '
FROM
Supportcentral AS sc
outer apply [dbo].[FN_split](sc.CoeOwner, ';',0) s
left join udcenter.dbo.[Users] u on u.u_Login COLLATE DATABASE_DEFAULT in (select s.item COLLATE DATABASE_DEFAULT)
For SQL Server 2017+, you may try the following:
SELECT T.ID, T.Name,
STRING_AGG(CONCAT(D.Firstname,' ',D.lastname),',') Categories
FROM
tab1 T JOIN tab2 D
ON D.ID IN (SELECT value FROM STRING_SPLIT(T.Categories, ';'))
GROUP BY T.ID, T.Name
ORDER BY T.ID
See a demo.
I think that you misplaced the comma in your posted output, if you want exactly the posted output use this STRING_AGG(CONCAT(D.Firstname,',',D.lastname),' ').
For older versions of SQL Server you may use for xml path to simulate the STRING_AGG function as the following:
WITH CTE AS
(
SELECT T.ID, T.Name, CONCAT(D.Firstname,' ',D.lastname) fullname FROM
tab1 T JOIN tab2 D
ON CONCAT(';', T.Categories,';') LIKE CONCAT('%;', D.ID, ';%')
)
SELECT id, name, STUFF(
(SELECT ',' + CAST(T.fullname as VARCHAR(MAX))
FROM CTE T WHERE T.ID = D.ID
FOR xml PATH ('')
), 1, 1, ''
) Categories
FROM CTE D
GROUP BY ID, Name
ORDER BY ID
See a demo.
Try this Query,
SELECT Id, Name, (SELECT STRING_AGG(Name,',') FROM #Users WHERE Id IN (SELECT Value FROM string_split(SC.Categories,';'))) AS Categories
FROM #Supportcentral SC

how can select unique row using where/having cluse and compare with another table

i cant understand how can take unique column (remove duplication) from a table
which compare with another table data.
in my case
i have two table
i want to get unique rows from tblproduct after compireing with tblviewer as
[in table viewer first taking viewerid after that taking productid in viewer table afterthat compire with tblproduct.
actualy like that
if i take vieweris=123 two row productid select 12001&11001 after that this tblproduct productid and finaly taking the row from tblproduct which maching.
select *
from tblproduct
where productid =
(
select distinct(productid)
from tblviewer
where viewerid = 123
)
There are a few ways to do this. You can do a standard INNER JOIN to the table to filter the results:
Select Distinct P.*
From tblProduct P
Join tblViewer V On V.ProductId = P.ProductId
Where V.ViewerId = 123
Alternatively, you could use EXISTS as well - this eliminates the need to use a DISTINCT altogether:
Select *
From tblProduct P
Where Exists
(
Select *
From tblViewer V
Where V.ProductId = P.ProductId
And V.ViewerId = 123
)
Or, you could also use an IN, as suggested by the other answers:
Select *
From tblProduct
Where ProductId In
(
Select ProductId
From tblViewer
Where ViewerId = 123
)
I think you just want to use an IN clause, you will not need to use distinct
select *
from tblproduct
where productid in
(
select productid
from tblviewer
where viewerid = 123
)
I'm not sure what you're asking, but I think it is,
select *
from tblproduct
where productid in
(
select distinct(productid)
from tblviewer
)

Query for a group of IDs

I use the simple query below to output a list of partIDs based on a modelID that we get from a printout on a sheet of paper.
We've always just used one modelId at a time like this:
SELECT gm.partId, 343432346 as modelId
FROM dbo.systemMemberTable sm
WHERE gm.partID NOT IN (SELECT partID FROM systemsPartTable)
Is there a way to create a query that uses 10 modelIds at a time?
I can't think of a way because the modelIds are not in any table, just a printout that is handed to us.
Thanks!
SELECT gm.partId, T.number as modelId
FROM ( values (4),(9),(16),(25)
) as T(number)
CROSS JOIN dbo.systemMemberTable sm
WHERE gm.partID NOT IN (SELECT partID FROM systemsPartTable)
op said getting an error but this is the test that runs for me
SELECT T.number as [modelID]
,[main].[name]
FROM ( values (4),(9),(16),(25)
) as T(number)
cross join [Gabe2a_ENRONb].[dbo].[docFieldDef] as [main]
where [main].[ID] not in (1)
insert model ids into a table variable and then do the join with this table variable
Also use not exists instead of not in as not in doesn't work if there are null values in the parts table.
declare #modelIds table
(
model_id int
)
insert into #modelIds values (343432346) , (123456)
your select would be
As you want same model id repeated for all parts, you can just use cross join
select gm.partId, m.model_id
from dbo.systemMeberTable sm
cross join #modelIds m
where not exists ( select 1 from systemPartsTable SPT where SPT.partId = gm.PartID )
Try this:
DECLARE #T TABLE (ModelId INT);
INSERT INTO #T (ModelID)
VALUES (343432346), (343432347) -- And so on and so forth
SELECT gm.partId, T.ModelId
FROM dbo.systemMemberTable sm
INNER JOIN #T AS T
ON T.ModelId = SM.ModelID
WHERE gm.partID NOT IN (SELECT partID FROM systemsPartTable)
Create table #tempmodelTable
(
#modelid int
)
insert all modelid here, then use join with your select query
INSERT INTO #tempmodelTable values(123123)
INSERT INTO #tempmodelTable values(1232323)
INSERT INTO #tempmodelTable values(1232343123)
SELECT gm.partId, modelId
FROM dbo.systemMemberTable gm inner join #tempmodelTable
WHERE gm.partID NOT IN (SELECT partID FROM systemsPartTable)

Search 'AS' alias in SQL Server

I have a sql query that pulls the customers full name from the customers table based on the customer ID in the sales table and binds the info to an asp.net listview. I now want to search the records by the customers full name. I used the query below but it keeps telling me that the column "Fullname" is an invalid column name. How do I go about modifying this query to work?
SELECT
tbl_Sales.SaleID, tbl_Sales.CustomerID,
(SELECT Firstname + ' ' + Lastname
FROM tbl_Customers
WHERE CustomerID = tbl_Sales.CustomerID) AS CustomerName,
tbl_Sales.Price
FROM
tbl_Sales
WHERE
CustomerName LIKE '%John%'
Thanks in advance.
You cannot use the Alias name in the same select statement because where will be processed before the select.
Make the original query as sub select and use the alias name in where clause.Try this.
SELECT *
FROM (SELECT tbl_Sales.SaleID,
tbl_Sales.CustomerID,
(SELECT Firstname + ' ' + Lastname
FROM tbl_Customers
WHERE CustomerID = tbl_Sales.CustomerID) AS CustomerName,
tbl_Sales.Price
FROM tbl_Sales) A
WHERE CustomerName LIKE '%John%'
or use Cross apply
SELECT tbl_Sales.SaleID,
tbl_Sales.CustomerID,
t.CustomerName,
tbl_Sales.Price
FROM tbl_Sales
CROSS apply (SELECT Firstname + ' ' + Lastname AS CustomerName
FROM tbl_Customers
WHERE CustomerID = tbl_Sales.CustomerID) t
WHERE t.CustomerName LIKE '%John%'
You are not allowed to pass ALIAS name in WHERE clause instead of that you should use JOIN
Try this:
SELECT S.SaleID, S.CustomerID, (C.Firstname + ' ' + C.Lastname) AS CustomerName, S.Price
FROM tbl_Sales S
INNER JOIN tbl_Customers C ON S.CustomerID = C.CustomerID
WHERE (C.Firstname + ' ' + C.Lastname) LIKE '%John%'
Instead of checking the combined value, you could check each column like this. Combining the columns and comparing is not SARGable, and will result in bad performance:
SELECT
tbl_Sales.SaleID,
tbl_Sales.CustomerID,
cus.Firstname + ' ' + cus.Lastname CustomerName,
tbl_Sales.Price
FROM
tbl_Sales
JOIN
tbl_Customers cus
ON
cus.CustomerID = tbl_Sales.CustomerID
WHERE
(cus.Firstname LIKE '%John%' or
cus.Lastname LIKE '%John%')