Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2005 Forums
 Transact-SQL (2005)
 Filter results based on preference

Author  Topic 

timgaunt
Posting Yak Master

115 Posts

Posted - 2009-07-08 : 10:52:05
I suspect this is something that's come up before but I've had a look around and I can't find anything similar so I apologise if there is.

We've inherited a site that allows users to save search parameters for a weekly email of matching records. There are about 30 variables which might be a True/False/Either, between two ranges or based on a matrix table. All searches are stored in another table.

At the moment, the entire query is built using IF statements which reduce the number of filter variables as much as possible and creates string SQL statement which is then executed from within the SProc.

This feels wrong to me and is horrendously inefficient as it requires about 5 calls to the database per search filter (currently about 40,000). How do others handle large numbers of filters (which might include a “not bothered”)?

Tim


----------------------------
I've finally started blogging (all be it badly!)

Check it out:
http://blogs.thesitedoctor.co.uk/tim/

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2009-07-08 : 10:55:22
you can make use boolean logic rather than set of if statements with dynamic sql. Can you give some sample data to explain scenario? then i will be able to provide more elaborate help
Go to Top of Page

timgaunt
Posting Yak Master

115 Posts

Posted - 2009-07-08 : 18:10:43
Thanks visakh, I've popped together the following script, by my reconing it should produce the matches below:


--The table that holds the Au Pair's languages
CREATE TABLE #AuPair(
AuPairId int,
PrimaryLanguage int,
Age tinyint,
Height tinyint,
Smoker bit
)
--The table that holds the Family's languages
CREATE TABLE #Family(
FamilyId int,
PrimaryLanguage int,
MinAge tinyint,
MaxAge tinyint,
MinHeight tinyint,
MaxHeight tinyint,
Smoker tinyint -- 0 = No, 1 = Yes, 2 = Either
)
--The table that holds the other languages the Au Pair can speak
CREATE TABLE #AuPairLanguage(
AuPairId int,
LanguageId int
)
--The table that holds the languages the Family would like
CREATE TABLE #FamilyLanguage(
FamilyId int,
LanguageId int
)

--Insert the dummy data
INSERT INTO #AuPair (AuPairId, PrimaryLanguage, Age, Height, Smoker)
SELECT 1, 3, 30, 115, 0 UNION ALL
SELECT 2, 3, 19, 100, 0 UNION ALL
SELECT 3, 4, 22, 135, 1

INSERT INTO #Family (FamilyId, PrimaryLanguage, MinAge, MaxAge, MinHeight, MaxHeight, Smoker)
SELECT 1, 1, 0, 255, 100, 130, 0 UNION ALL
SELECT 2, 2, 20, 25, 0, 255, 2 UNION ALL
SELECT 3, 2, 0, 255, 0, 255, 1

INSERT INTO #AuPairLanguage (AuPairId, LanguageId)
SELECT 1, 1 UNION ALL
SELECT 1, 2 UNION ALL
SELECT 2, 1 UNION ALL
SELECT 2, 2 UNION ALL
SELECT 3, 2

INSERT INTO #FamilyLanguage (FamilyId, LanguageId)
SELECT 2, 3 UNION ALL
SELECT 3, 1





DROP TABLE #AuPair
DROP TABLE #Family
DROP TABLE #UserInterests
DROP TABLE #FamilyLanguage



Family 1
--------------
Aupair 1 : Match (matches all and primary/secondary languages)
Aupair 2 : No Match (doesn't speak any of the languages)
Aupair 3 : No Match (too tall)

Family 2
--------------
Aupair 1 : No Match (too old)
Aupair 2 : No Match (too young)
Aupair 3 : Match

Family 3
--------------
Aupair 1 : No Match (not a smoker)
Aupair 2 : No Match (not a smoker)
Aupair 3 : Match


Is that what you were after? (This is a cut down version to try and keep things simple).

Tim

----------------------------
I've finally started blogging (all be it badly!)

Check it out:
http://blogs.thesitedoctor.co.uk/tim/
Go to Top of Page

timgaunt
Posting Yak Master

115 Posts

Posted - 2009-07-08 : 18:21:21
I meant to add where I got with it as I think it would help:


SELECT DISTINCT
f.*,
a.*
FROM
#Family f
LEFT JOIN #AuPair a
ON
a.Age BETWEEN f.MinAge AND f.MaxAge
AND
a.Height BETWEEN f.MinHeight AND f.MaxHeight
AND
(f.Smoker > 0) OR (a.Smoker = 0)
LEFT JOIN #AuPairLanguage al
ON f.PrimaryLanguage = al.LanguageId
LEFT JOIN #FamilyLanguage fl
ON fl.LanguageId = al.LanguageId AND f.FamilyId = fl.FamilyId



----------------------------
I've finally started blogging (all be it badly!)

Check it out:
http://blogs.thesitedoctor.co.uk/tim/
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2009-07-09 : 10:34:47
ok what are conditions you need to consider on where condition/
Go to Top of Page

timgaunt
Posting Yak Master

115 Posts

Posted - 2009-07-09 : 11:14:32
Well, in the case of the Age, it needs to be between MinAge and MaxAge, similar for height. For "Smoker", if the family sets 0 it needs to ensure that they're not a smoker, 2 they are a smoker and 3 they don't mind (Aupair values 0, 1, 0/1 respectively).

In the case of the languages, the aupair needs to speak at least one of the languages specified by the family/aupair. In the real scenario, there's another two tables -nationality and location which need to be taken into account.

Although I've done it on the joins there I'm not sure that's the best way to do it.

Basically we need to match all crietia (some of which are optional)

----------------------------
I've finally started blogging (all be it badly!)

Check it out:
http://blogs.thesitedoctor.co.uk/tim/
Go to Top of Page
   

- Advertisement -