Select Values Based on ItemID OR String Value
-
21-12-2019 - |
Question
I am wanting to build a query that looks at an existing Models table.
Table Structure:
ModelID | ManufacturerID | CategoryID | ModelName
What I want to do is pass two things to the query, ModelID
and ModelName
, so that it returns the specific model and also similar models.
ModelName could be made up of several words e.g iPhone 5s 16GB, so what I would like my query to do is:
SELECT
M.*
FROM
Models AS M
WHERE
(M.ModelID = 1840 OR M.ModelName LIKE '%iPhone%'
OR M.ModelName LIKE '%5s%' OR M.ModelName LIKE '%16GB%')
Is there a way that I can pass the ModelName to the query as a string and then have the query split the string to generate the OR statements?
Solution 2
OK, so I managed to get this working, following the advice given by Kevin Suchlicki re. fn_Split.
I have made this function even more complex than i intended to, but in order to help others out in a similar situation, here is my final solution:
DECLARE @CategoryID int = 1
DECLARE @ManufacturerID int = 3
DECLARE @ModelName varchar(100) = 'iPhone 5s 16GB'
DECLARE @ModelID int = 1840
DECLARE @Carrier varchar(10) = NULL
DECLARE @Colour varchar(10) = NULL
SELECT
I.*
FROM
(
SELECT
DISTINCT M.*
FROM
Models AS M
JOIN
dbo.fn_Split(@ModelName,' ') AS N
ON M.ModelID = @ModelID OR lower(M.ModelName) LIKE '%'+ Lower(N.value) + '%'
WHERE
M.CategoryID = @CategoryID AND M.ManufacturerID = @ManufacturerID
) AS A
LEFT OUTER JOIN
Items AS I ON A.ModelID = I.ModelID
WHERE
I.Barred <> 1
AND I.Locked <> 1
AND I.Ber <> 1
AND I.Condition = 'Working'
AND (LOWER(I.Colour) = LOWER(ISNULL(@Colour, I.Colour)) OR I.Colour IS NULL)
AND (LOWER(I.Carrier) = LOWER(ISNULL(@Carrier, I.Carrier)) OR I.Carrier IS NULL)
I will now create this as a stored procedure to complete the job.
For reference, HERE is a link to the fn_Split function.
OTHER TIPS
Do a web search for T-SQL split function. There are loads out there. They take a string (comma-delimited or space delimited or whatever) and return a table of values. Then just do a JOIN against that result set.
SELECT DISTINCT M.*
FROM Models AS M
JOIN dbo.fn_split(@model_name, ' ') AS model_names
ON M.ModelID = @model_id OR m.ModelName LIKE '%' + model_names.value + '%';