matchcombo
<code>
Code (php)
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
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
<?php
function match_Combo($een, $twee, $drie, $vier, $vijf) {
if (!isset($een)) {
$geselec = "SELECT id, Locatie, Werkervaring, Naam_Functie FROM vacatures WHERE";
$gesele = "SELECT id, Locatie, Werkervaring, Naam_Functie FROM vacatures WHERE";
if (!isset($twee)) { } else { $perc++;
$query .= $geselec . " Werkervaring LIKE '%".$twee."%'";
$geselec = " AND";
$quer .= $gesele . " Werkervaring LIKE '%".$twee."%'";
$gesele = " OR";
}
if (!isset($drie)) { } else { $perc++;
$query .= $geselec . " Werkervaring LIKE '%".$drie."%'";
$geselec = " AND";
$quer .= $gesele . " Werkervaring LIKE '%".$drie."%'";
$gesele = " OR";
}
if (!isset($vier)) { } else { $perc++;
$query .= $geselec . " Locatie LIKE '%".$vier."%'";
$geselec = " AND";
$quer .= $gesele . " Locatie LIKE '%".$vier."%'";
$gesele = " OR";
}
if (!isset($vijf)) { } else { $perc++;
$query .= $geselec . " Naam_functie LIKE '%".$vijf."%'";
$quer .= $gesele . " Naam_functie LIKE '%".$vijf."%'";
$gesele = " OR";
}
echo $query . "<br />";
$result3 = $mysqli->query($query);
echo $quer . "<br />";
$result33 = $mysqli->query($quer);
} else { echo "Fout"; }
echo " 1: " . $een . " 2: " . $twee . " 3: " . $drie . " 4: " . $vier . " 5: " . $vijf . "<br />";
return $perc;
}
?>
function match_Combo($een, $twee, $drie, $vier, $vijf) {
if (!isset($een)) {
$geselec = "SELECT id, Locatie, Werkervaring, Naam_Functie FROM vacatures WHERE";
$gesele = "SELECT id, Locatie, Werkervaring, Naam_Functie FROM vacatures WHERE";
if (!isset($twee)) { } else { $perc++;
$query .= $geselec . " Werkervaring LIKE '%".$twee."%'";
$geselec = " AND";
$quer .= $gesele . " Werkervaring LIKE '%".$twee."%'";
$gesele = " OR";
}
if (!isset($drie)) { } else { $perc++;
$query .= $geselec . " Werkervaring LIKE '%".$drie."%'";
$geselec = " AND";
$quer .= $gesele . " Werkervaring LIKE '%".$drie."%'";
$gesele = " OR";
}
if (!isset($vier)) { } else { $perc++;
$query .= $geselec . " Locatie LIKE '%".$vier."%'";
$geselec = " AND";
$quer .= $gesele . " Locatie LIKE '%".$vier."%'";
$gesele = " OR";
}
if (!isset($vijf)) { } else { $perc++;
$query .= $geselec . " Naam_functie LIKE '%".$vijf."%'";
$quer .= $gesele . " Naam_functie LIKE '%".$vijf."%'";
$gesele = " OR";
}
echo $query . "<br />";
$result3 = $mysqli->query($query);
echo $quer . "<br />";
$result33 = $mysqli->query($quer);
} else { echo "Fout"; }
echo " 1: " . $een . " 2: " . $twee . " 3: " . $drie . " 4: " . $vier . " 5: " . $vijf . "<br />";
return $perc;
}
?>
</code>
als ik dit uitvoer wordt de query:
SELECT id, Locatie, Werkervaring, Naam_Functie FROM vacatures WHERE Werkervaring LIKE '%hbo%' AND Werkervaring LIKE '%autocad%' AND Locatie LIKE '%zuid%' AND Naam_functie LIKE '%piping%'
LET OP: ik heb de waarde van $een niet ingevuld
Maar dit geeft 1 resultaat wat ik wil is een simpele oplossing zodat hij eerst kijkt naar:
$twee gecombineerd met $drie $vier en $vijf ( is bijv 1 resultaat dat is zoals de query bove nu is)
$twee gecombineerd met alleen $drie $vier of $vijf (afijn je snapt de bedoeling)
ZONDER dat er een resultaat/record word herhaald
Gewijzigd op 30/10/2012 11:39:06 door Francoi gckx
ik heb die topic helemaal doorgelezen voordat ik de nieuwe topict heb geopend maar ben er daar niet uitgekomen dus ik dacht geef een betere nieuwe uitleg hierin met nieuwe code
Copy/paste dit eens in phpMyadmin en zie wat er gebeurt.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
SELECT
id, Locatie, Werkervaring, Naam_Functie,
(Werkervaring LIKE '%hbo%') as match_1,
(Werkervaring LIKE '%autocad%') as match_2,
(Werkervaring LIKE '%zuid%') as match_3,
(Werkervaring LIKE '%piping%') as match_4
FROM vacatures
HAVING
(match_1 + match_2 + match_3 + match_4) > 0
ORDER BY
(match_1 + match_2 + match_3 + match_4) DESC
id, Locatie, Werkervaring, Naam_Functie,
(Werkervaring LIKE '%hbo%') as match_1,
(Werkervaring LIKE '%autocad%') as match_2,
(Werkervaring LIKE '%zuid%') as match_3,
(Werkervaring LIKE '%piping%') as match_4
FROM vacatures
HAVING
(match_1 + match_2 + match_3 + match_4) > 0
ORDER BY
(match_1 + match_2 + match_3 + match_4) DESC
Op deze manier: hoe meer items een match hebben, hoe meer bovenaan
Gewijzigd op 30/10/2012 12:58:55 door Kris Peeters
dus dan kan ik mijn functie van 150 lines weggooien:)
Ik kan je niet genoeg bedanken Kris
Oja in phpmyadmin krijg ik volgens mij de resultaat die ik wil hebben
dus als match_$x overal een 1 heb dan heeft die op al die woorden gematch toch???
Toevoeging op 30/10/2012 13:17:58:
o toch nog een vraag wat doet die HAVING statement eigenlijk?
Gewijzigd op 30/10/2012 13:09:57 door Francoi gckx
Francoi gckx op 30/10/2012 13:08:16:
o toch nog een vraag wat doet die HAVING statement eigenlijk?
Het zelfde als de WHERE.
Maar ... Bij WHERE gaat het om velden die in de tabel voorkomen; met HAVING kan je ook de berekende velden aanspreken.
De query van Kris kan ook heel goed, maar het nadeel daar aan is (vind ik)dat je dan in PHP moet uitvogelen hoeveel en welke kolommen gematched hebben, daarom doe ik dat altijd met UNION en GROUP BY:
Code (php)
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
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
SELECT
vid.id,
v.Naam_Functie
COUNT(*) AS total_matches,
GROUP_CONCAT(vid.matched_word) AS matched_words
FROM
(SELECT
id,
'hbo' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%hbo%'
UNION
SELECT
id,
'autocad' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%autocad%'
UNION
SELECT
id,
'zuid' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%zuid%'
UNION
SELECT
id,
'piping' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%piping%'
) AS vid
INNER JOIN
vacatures AS v
ON
vid.id = v.id
GROUP BY vid.id
ORDER BY total_matches DESC
vid.id,
v.Naam_Functie
COUNT(*) AS total_matches,
GROUP_CONCAT(vid.matched_word) AS matched_words
FROM
(SELECT
id,
'hbo' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%hbo%'
UNION
SELECT
id,
'autocad' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%autocad%'
UNION
SELECT
id,
'zuid' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%zuid%'
UNION
SELECT
id,
'piping' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%piping%'
) AS vid
INNER JOIN
vacatures AS v
ON
vid.id = v.id
GROUP BY vid.id
ORDER BY total_matches DESC
Gewijzigd op 30/10/2012 14:30:46 door Ger van Steenderen
Toevoeging op 30/10/2012 14:44:50:
Juist dit is super ik krijg total matches als kolom en de matchwoorden dit is precies wat ik wil hebben
de vorige code vond ik een beetje te ingewikkeld met fake foo enzo
Toevoeging op 30/10/2012 14:49:46:
wat is vid.id, =
Toevoeging op 30/10/2012 14:52:54:
Misschien vraag ik nu teveel maar zou je kunnen uitleggen hoe jou query ongeveer werkt
Gewijzigd op 30/10/2012 14:39:33 door Francoi gckx
Eerst:
Mijn code is een constructie die je vrij gemakkelijk kan opzetten, en die bruikbaar is voor alle gelijkaardige query's.
Je hebt het gevoel dat de clausules in de WHERE iets te streng of te los zijn. Al die clausules splits je op en je vormt ze om tot vlaggen ( http://en.wikipedia.org/wiki/Flag_(computing) ).
Eens het goed werkt, kan je zo'n constructie omvormen tot iets zoals Ger gedaan heeft. Dit laatste heb ik dus niet gedaan; laat ons zeggen dat het een gemakkelijkheidsoplossing is van mijnentwege.
Trouwens, nog iets extra wat je kan doen (je kan dit ook inwerken in Ger zijn query): je kan extra gewicht geven.
stel bv. dat je Autocad dubbel zo belangrijk vindt als de rest
Dan kan je dit doen:
-----
Dan, de subquery.
Het punt van de subquery is dit:
Een query zoekt rijen in een tabel. Het resultaat daarvan is echter opnieuw een tabel. Een tabel die eventueel minder velden heeft en minder rijen (anders kan ook hoor).
Die resulterende tabel is dus op zich prima bruikbaar om opnieuw een query op los te laten.
Een voorbeeld:
- STEL: je hebt een tabel twitteraars. 1 van de velden (posts) zegt hoeveel tweets de persoon heeft.
- Gevraagd: willekeurig drie twitteraars uit de top 10 (Probeer zelf maar eens ... niet zo'n evidente query)
Mochten we een tabel hebben waarin enkel de top 10 staat, al in volgorde van posts ... dan zou het gemakkelijk zijn:
Wel, met een subquery kunnen we exact dit doen; we kunnen tabel top_tien_in_volgorde tijdelijk aanmaken. Zo:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
SELECT id, tweet FROM (
SELECT id, tweet
FROM twitteraars
ORDER BY posts DESC
LIMIT 10
) AS top_tien_in_volgorde
ORDER BY RAND()
LIMIT 3
SELECT id, tweet
FROM twitteraars
ORDER BY posts DESC
LIMIT 10
) AS top_tien_in_volgorde
ORDER BY RAND()
LIMIT 3
( Ik probeer gewoon een punt te maken, uiteraard mag je die alias een kortere naam geven )
You see?
... en dus, met een aantal stappen extra raak je tot Ger zijn query
Gewijzigd op 30/10/2012 16:26:55 door Kris Peeters
@Ger en Kris: hoe komt het dat jullie zo goed zijn in het maken van queries? Kunnen jullie een bepaalde tutorial of boek aanraden?
Ter extra verduidelijking:
De subquery staat in de FROM en die moet je een alias geven (zo niet krijg je een error), zodat je het als een (virtuele) tabel kan behandelen, in dit geval heb ik vid als alias gebruikt.
Offtopic:
Bij mij komt het omdat ik zo slim ben :-P
Nee hoor, nu zonder gekheid, er zijn wel wat tutorials over SQL, maar die zijn vrij basic. Een boek over SQL heb ik nooit gehad, bij mij is het meer een kestie van veel doen en goed zoeken op internet
Gewijzigd op 30/10/2012 17:08:21 door Ger van Steenderen
maar bij Ger is het zo: ORDER BY total_matches
moet ik dan (een stukje code van ger):
<code>
SELECT
id,
'autocad' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%autocad%'
UNION
</code>
veranderen in
<code>
SELECT
id,
'autocad' AS matched_word
FROM
vacatures
WHERE
(Werkervaring LIKE '%autocad%') as match_3,
UNION
</code>
en dan als laatste (ongeveer)?:
<code>
ORDER BY (total_matches + 2 * match_3) DESC
</code>
Ik kan morgen pas testen
En dan de COUNT in SUM veranderen:
Code (php)
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
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
SELECT
vid.id,
v.Naam_Functie,
SUM(vid.weight) AS total_weight,
GROUP_CONCAT(vid.matched_word) AS matched_words
FROM
(SELECT
id,
'hbo' AS matched_word,
1 AS weight
FROM
vacatures
WHERE
Werkervaring LIKE '%hbo%'
UNION
SELECT
id,
'autocad' AS matched_word,
3 AS weight
FROM
vacatures
WHERE
Werkervaring LIKE '%autocad%'
SELECT
id,
'zuid' AS matched_word,
1 AS weight
FROM
vacatures
WHERE
Werkervaring LIKE '%zuid%'
UNION
SELECT
id,
'piping' AS matched_word,
1 AS weight
FROM
vacatures
WHERE
Werkervaring LIKE '%piping%'
) AS vid
INNER JOIN
vacatures AS v
ON
vid.id = v.id
GROUP BY vid.id
ORDER BY total_weight DESC
vid.id,
v.Naam_Functie,
SUM(vid.weight) AS total_weight,
GROUP_CONCAT(vid.matched_word) AS matched_words
FROM
(SELECT
id,
'hbo' AS matched_word,
1 AS weight
FROM
vacatures
WHERE
Werkervaring LIKE '%hbo%'
UNION
SELECT
id,
'autocad' AS matched_word,
3 AS weight
FROM
vacatures
WHERE
Werkervaring LIKE '%autocad%'
SELECT
id,
'zuid' AS matched_word,
1 AS weight
FROM
vacatures
WHERE
Werkervaring LIKE '%zuid%'
UNION
SELECT
id,
'piping' AS matched_word,
1 AS weight
FROM
vacatures
WHERE
Werkervaring LIKE '%piping%'
) AS vid
INNER JOIN
vacatures AS v
ON
vid.id = v.id
GROUP BY vid.id
ORDER BY total_weight DESC
Je kan namelijk gewoon vaste waardes in een SELECT list opgeven, dat hoeft niet persee een kolom te zijn.
Gewijzigd op 30/10/2012 19:18:18 door Ger van Steenderen
Elk SELECT t/m WHERE is een subquery? En UNION verbind de volgende SELECT (subquery)? en aan het einde (AS vid)
beslaat al die subqueries verbonden door UNIONs?
snap alleen dit stukje niet:
INNER JOIN
vacatures AS v
ON
vid.id = v.id
Gewijzigd op 30/10/2012 18:19:18 door Francoi gckx
De subquery is hetgeen tussen de haakjes staat - FROM ( ... ) AS vid -
Probeer de subquery maar eens uit in PhpAdmin dan zie je wat er gebeurd.
De INNER JOIN is niet noodzakelijk, eigenlijk niet eens nodig, je kan die kolommen ook in de union query's meenemen.
Gewijzigd op 30/10/2012 19:08:24 door Ger van Steenderen
Toevoeging op 31/10/2012 10:49:33:
Ok nu is mijn nieuwe functie zo geworden:
De foutmelding is dit: ver version for the right syntax to use near ') AS vid INNER JOIN vacatures AS v ON vid.id' at line 35
<code>
Code (php)
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<?php
function match_Combo($een, $twee, $drie, $vier, $vijf) {
global $result3;
include('includes/db-connectie-info.php');
$geselec = "SELECT
vid.id,
v.Naam_Functie,
COUNT(*) AS total_matches,
GROUP_CONCAT(vid.matched_word) AS matched_words
FROM
(";
if (isset($een)) {
$query .= $geselec .
"SELECT
id,
'$een' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%$een%'
UNION ";
$geselec = '';
}
if (isset($twee)) {
$query .= $geselec .
"SELECT
id,
'$twee' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%$twee%'
UNION ";
$geselec = '';
}
if (isset($drie)) {
$query .= $geselec .
"SELECT
id,
'$drie' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%$drie%'
UNION ";
$geselec = '';
}
if (isset($vier)) {
$query .= $geselec .
"SELECT
id,
'$vier' AS matched_word
FROM
vacatures
WHERE
Locatie LIKE '%$vier%'
UNION ";
$geselec = '';
}
if (isset($vijf)) {
$query .= $geselec .
"SELECT
id,
'$vijf' AS matched_word
FROM
vacatures
WHERE
Naam_Functie LIKE '%$vijf%'
UNION ";
$geselec = '';
}
$query .= ") AS vid
INNER JOIN
vacatures AS v
ON
vid.id = v.id
GROUP BY vid.id
ORDER BY total_matches DESC";
$result3 = $mysqli->query($query);
echo $query;
}
?>
function match_Combo($een, $twee, $drie, $vier, $vijf) {
global $result3;
include('includes/db-connectie-info.php');
$geselec = "SELECT
vid.id,
v.Naam_Functie,
COUNT(*) AS total_matches,
GROUP_CONCAT(vid.matched_word) AS matched_words
FROM
(";
if (isset($een)) {
$query .= $geselec .
"SELECT
id,
'$een' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%$een%'
UNION ";
$geselec = '';
}
if (isset($twee)) {
$query .= $geselec .
"SELECT
id,
'$twee' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%$twee%'
UNION ";
$geselec = '';
}
if (isset($drie)) {
$query .= $geselec .
"SELECT
id,
'$drie' AS matched_word
FROM
vacatures
WHERE
Werkervaring LIKE '%$drie%'
UNION ";
$geselec = '';
}
if (isset($vier)) {
$query .= $geselec .
"SELECT
id,
'$vier' AS matched_word
FROM
vacatures
WHERE
Locatie LIKE '%$vier%'
UNION ";
$geselec = '';
}
if (isset($vijf)) {
$query .= $geselec .
"SELECT
id,
'$vijf' AS matched_word
FROM
vacatures
WHERE
Naam_Functie LIKE '%$vijf%'
UNION ";
$geselec = '';
}
$query .= ") AS vid
INNER JOIN
vacatures AS v
ON
vid.id = v.id
GROUP BY vid.id
ORDER BY total_matches DESC";
$result3 = $mysqli->query($query);
echo $query;
}
?>
</code>