Reputation: 220
I have a field that lists all language descriptions that a product has and the field can contain data like:
EN;FR;DE
It will always be a two letter language code followed by a semi colon.
I then have a stored procedure that looks for all products with a particular language code. Simply done by:
WHERE
ext.languages LIKE '%' + @language + '%'
The @language variable might just represent the letters EN for example. Now when I want to find a product that has both French and English languages on I need to pass in 'FR, EN' for the language variable. Now I have a custom function in SQL that splits the language variable into rows so I effectively have
Row 1-EN
Row 2-FR
Now I need to check my ext.language field to see if both those values exist. I have attempted to do:
INNER JOIN MyFunctionsDatabase.dbo.listSplit(@language) as var1
ON ext.language LIKE '%'+var1.StringLiteral+'%'
This only brings back products where it contains either french or english I need it to bring back values where it contains both English and French.
Any advice would be greatly appreciated:
Upvotes: 0
Views: 250
Reputation: 4104
I would make your parameter a multi-select and have each individual language be a selection. You could even feed the parameter with values from the database so it would automatically update if there is a new language. I'm going to call this parameter @LangMultiSelect
Since you only want items that items that match all of the selections you need to pass in a second parameter with the number of items that have been selected. In the properties of your dataset you can add another parameter that is set by an expression. Name it @LangCount
and use the expression:
=Parameters!LangMultiSelect.Count
Then use a SQL query similar to this:
SELECT Name
FROM (
SELECT Name,
COUNT(*) OVER(PARTITION BY pt.id) AS lCount
FROM ProductTable AS pt
INNER JOIN MyFunctionsDatabase.dbo.listSplit(@language) AS var1 ON var1.id=pt.id
WHERE pt.language IN (@LangMultiSelect)
) AS t
WHERE t.lCount = @LangCount
That query uses the COUNT()
aggregate as a window function to determine the number of matches the item has and then only returns results that match all of the selections in the multi-select parameter.
It works because I am splitting the count by a field that is the same for all of the item names that are the same item but in a different language. If you don't have a field like that this won't work.
Upvotes: 0
Reputation: 1541
Try with below script, this i write for 3 language but can be done generic
Declare @Product AS Table(ProductID INT, [Language] Varchar(500))
Insert Into @Product Values(1,'EN;FR;DE'),(2,'EN'),(3,'EN;DE'),(4,'EN;FR')
SELECT * FROM
(
Select P.ProductID,L.Value
From @Product P
CROSS APPLY dbo.[udfSplit]([Language],';') L
) Product
PIVOT
(
Count(Value)
For Value in (EN,FR,DE)
)
AS PV
Where EN=1 AND FR=1
Upvotes: 1
Reputation: 1585
I'd be inclined to use a function that accepts a delimited string containing the language codes to check for and the string to check. It checks that each language code is in the string and returns false as soon as one of the desired languages isn't found. If everything is found it returns true.
Your sql would look like
select *
from mytable
where CheckHasAllLanguages(language, @languagesToCheck) = 1
Upvotes: 0