Functioneel: een gebruiker kan in een zoekvak door middel van een kernwoord/en organisaties opzoeken. Dit kernwoord kan de naam van de organisatie zijn, maar ook een rubriek/specialisatie waar de organisatie aangelinked is, eventuele aliassen (denk aan meervoudsvormen/synoniemen/andere spelling/...) van deze rubriek, beroepen gelinked aan deze rubrieken en aliassen van deze beroepen
De gebruiker kan bijvoorbeeld in hetzelfde zoekvak zoeken op "Garage Janssens", "reparaties", "garagist", enz...
Na lang zoeken en benchmarken heb ik er uiteindelijk een zeer performante query voor geschreven:
MAAR nu zou ik graag hebben dat de gebruiker ook een postcode kan opgeven met een radius waarin gezocht kan worden, omdat de basisquery zoveel organisaties teruggeeft die niet relevant zijn voor de gebruiker.
Het verkrijgen van de postcodes binnen een bepaalde radius is vrij eenvoudig:
Het opzoeken van organisaties binnen een bepaalde radius is dus ook niet veel moeilijker:
Idealiter was er zoiets dat een echte UNIE (enkel de rijen overhouden die beide tabellen gemeen hebben) doet tussen twee queries want UNION doet eigenlijk niet veel meer dan twee queries mergen en de dubbels eruithalen (by default). Een soort van EXCLUSIVE UNION dus.
Ik heb dus de volgende query geschreven om dit te omzeilen. Het werkt, maar het is lelijk (maar dat vind ik niet zo erg) en traag (dat vind ik véél erger). Dan weer niet verschrikkelijk traag (tussen de 1 à 2 seconden), maar ik heb het gevoel dat dit sneller moet kunnen.
Mijn uiteindelijke query:
Pfoe
De gebruiker kan bijvoorbeeld in hetzelfde zoekvak zoeken op "Garage Janssens", "reparaties", "garagist", enz...
Na lang zoeken en benchmarken heb ik er uiteindelijk een zeer performante query voor geschreven:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| ( SELECT O.* FROM tblOrganisation O INNER JOIN tblOrganisation_Interest OI ON O.OrgID = OI.OrgID INNER JOIN tblInterest I ON OI.InterestID = I.InterestID WHERE I.Name LIKE '<%zoektekst%>' ) UNION ( SELECT O.* FROM tblOrganisation O INNER JOIN tblOrganisation_Interest OI ON OI.OrgID = O.OrgID INNER JOIN tblInterest_Alias IA ON IA.InterestID = OI.InterestID INNER JOIN tblAlias A ON A.AliasID = IA.AliasID WHERE A.Name LIKE '<%zoektekst%>' ) UNION ( SELECT O.* FROM tblOrganisation O INNER JOIN tblOrganisation_Interest OI ON OI.OrgID = O.OrgID INNER JOIN tblInterest I ON I.InterestID = OI.InterestID INNER JOIN tblOccupation_Interest OCI ON OCI.InterestID = I.InterestID INNER JOIN tblOccupation OC ON OC.OccupationID = OCI.OccupationID WHERE OC.Name LIKE '<%zoektekst%>' ) UNION ( SELECT O.* FROM tblOrganisation O INNER JOIN tblOrganisation_Interest OI ON OI.OrgID = O.OrgID INNER JOIN tblOccupation_Interest OCI ON OCI.InterestID = OI.InterestID INNER JOIN tblOccupation_Alias OCA ON OCA.OccupationID = OCI.OccupationID INNER JOIN tblAlias A ON A.AliasID = OCA.AliasID WHERE A.Name LIKE '<%zoektekst%>' ) UNION ( SELECT * FROM tblOrganisation O WHERE Name LIKE '<%zoektekst%>' ) ORDER BY Name; |
MAAR nu zou ik graag hebben dat de gebruiker ook een postcode kan opgeven met een radius waarin gezocht kan worden, omdat de basisquery zoveel organisaties teruggeeft die niet relevant zijn voor de gebruiker.
Het verkrijgen van de postcodes binnen een bepaalde radius is vrij eenvoudig:
SQL:
1
2
3
4
| SELECT x2.PostalCode FROM tblplace x1, tblplace x2 WHERE x1.PostalCode = '<postcode>' AND ACOS(SIN(x1.LatitudeRadians) * SIN(x2.LatitudeRadians) + COS(x1.LatitudeRadians) * COS(x2.LatitudeRadians) * COS(x2.LongitudeRadians - x1.LongitudeRadians)) * 6378 <= <radius> |
Het opzoeken van organisaties binnen een bepaalde radius is dus ook niet veel moeilijker:
SQL:
1
2
3
4
5
6
| SELECT * FROM tblOrganisation WHERE PostalCode IN ( SELECT x2.PostalCode FROM tblplace x1, tblplace x2 WHERE x1.PostalCode = '<postcode>' AND ACOS(SIN(x1.LatitudeRadians) * SIN(x2.LatitudeRadians) + COS(x1.LatitudeRadians) * COS(x2.LatitudeRadians) * COS(x2.LongitudeRadians - x1.LongitudeRadians)) * 6378 <= <radius>) |
Idealiter was er zoiets dat een echte UNIE (enkel de rijen overhouden die beide tabellen gemeen hebben) doet tussen twee queries want UNION doet eigenlijk niet veel meer dan twee queries mergen en de dubbels eruithalen (by default). Een soort van EXCLUSIVE UNION dus.
Ik heb dus de volgende query geschreven om dit te omzeilen. Het werkt, maar het is lelijk (maar dat vind ik niet zo erg) en traag (dat vind ik véél erger). Dan weer niet verschrikkelijk traag (tussen de 1 à 2 seconden), maar ik heb het gevoel dat dit sneller moet kunnen.
Mijn uiteindelijke query:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
| ( SELECT O.* FROM tblOrganisation O INNER JOIN tblOrganisation_Interest OI ON O.OrgID = OI.OrgID INNER JOIN tblInterest I ON OI.InterestID = I.InterestID WHERE I.Name LIKE '<%zoektekst%>' AND O.PostalCode IN ( SELECT x2.PostalCode FROM tblplace x1, tblplace x2 WHERE x1.PostalCode = '<postcode>' AND ACOS(SIN(x1.LatitudeRadians) * SIN(x2.LatitudeRadians) + COS(x1.LatitudeRadians) * COS(x2.LatitudeRadians) * COS(x2.LongitudeRadians - x1.LongitudeRadians)) * 6378 <= <radius>) ) UNION ( SELECT O.* FROM tblOrganisation O INNER JOIN tblOrganisation_Interest OI ON OI.OrgID = O.OrgID INNER JOIN tblInterest_Alias IA ON IA.InterestID = OI.InterestID INNER JOIN tblAlias A ON A.AliasID = IA.AliasID WHERE A.Name LIKE '<%zoektekst%>' AND O.PostalCode IN ( SELECT x2.PostalCode FROM tblplace x1, tblplace x2 WHERE x1.PostalCode = '<postcode>' AND ACOS(SIN(x1.LatitudeRadians) * SIN(x2.LatitudeRadians) + COS(x1.LatitudeRadians) * COS(x2.LatitudeRadians) * COS(x2.LongitudeRadians - x1.LongitudeRadians)) * 6378 <= <radius>) ) UNION ( SELECT O.* FROM tblOrganisation O INNER JOIN tblOrganisation_Interest OI ON OI.OrgID = O.OrgID INNER JOIN tblInterest I ON I.InterestID = OI.InterestID INNER JOIN tblOccupation_Interest OCI ON OCI.InterestID = I.InterestID INNER JOIN tblOccupation OC ON OC.OccupationID = OCI.OccupationID WHERE OC.Name LIKE '<%zoektekst%>' AND O.PostalCode IN ( SELECT x2.PostalCode FROM tblplace x1, tblplace x2 WHERE x1.PostalCode = '<postcode>' AND ACOS(SIN(x1.LatitudeRadians) * SIN(x2.LatitudeRadians) + COS(x1.LatitudeRadians) * COS(x2.LatitudeRadians) * COS(x2.LongitudeRadians - x1.LongitudeRadians)) * 6378 <= <radius>) ) UNION ( SELECT O.* FROM tblOrganisation O INNER JOIN tblOrganisation_Interest OI ON OI.OrgID = O.OrgID INNER JOIN tblOccupation_Interest OCI ON OCI.InterestID = OI.InterestID INNER JOIN tblOccupation_Alias OCA ON OCA.OccupationID = OCI.OccupationID INNER JOIN tblAlias A ON A.AliasID = OCA.AliasID WHERE A.Name LIKE '<%zoektekst%>' AND O.PostalCode IN ( SELECT x2.PostalCode FROM tblplace x1, tblplace x2 WHERE x1.PostalCode = '<postcode>' AND ACOS(SIN(x1.LatitudeRadians) * SIN(x2.LatitudeRadians) + COS(x1.LatitudeRadians) * COS(x2.LatitudeRadians) * COS(x2.LongitudeRadians - x1.LongitudeRadians)) * 6378 <= <radius>) ) UNION ( SELECT * FROM tblOrganisation WHERE Name LIKE '<%zoektekst%>' AND PostalCode IN ( SELECT x2.PostalCode FROM tblplace x1, tblplace x2 WHERE x1.PostalCode = '<postcode>' AND ACOS(SIN(x1.LatitudeRadians) * SIN(x2.LatitudeRadians) + COS(x1.LatitudeRadians) * COS(x2.LatitudeRadians) * COS(x2.LongitudeRadians - x1.LongitudeRadians)) * 6378 <= <radius>) ); |
Pfoe

[ Voor 1% gewijzigd door Oberon op 20-11-2009 21:52 . Reden: Kleine correctie ]
TOGAF, ArchiMate, DEMO, ITILF, VCE, MCSE, CCA, CCAA, CCEE, CCIA