SQL commando in php werkt niet goed
Maar het onderstaande commando werkt helemaal, heeft iemand enig idee?
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$zoekquery =
"SELECT DISTINCT
od_id,
od_naam,
od_prijs,
system_auto_id,
system_naam,
system_prijs
FROM
onderdelen,
systemen
WHERE
((LOWER(od_naam) LIKE '%" . mysql_real_escape_string ($zoek) . "%')
AND
od_removed = 'N' AND
od_show = 'Y')
OR
((LOWER(system_naam) LIKE '%" . mysql_real_escape_string ($zoek) . "%')
AND
system_removed = 'N' AND
system_show = 'Y')
ORDER BY
od_id, system_auto_id
DESC
";
"SELECT DISTINCT
od_id,
od_naam,
od_prijs,
system_auto_id,
system_naam,
system_prijs
FROM
onderdelen,
systemen
WHERE
((LOWER(od_naam) LIKE '%" . mysql_real_escape_string ($zoek) . "%')
AND
od_removed = 'N' AND
od_show = 'Y')
OR
((LOWER(system_naam) LIKE '%" . mysql_real_escape_string ($zoek) . "%')
AND
system_removed = 'N' AND
system_show = 'Y')
ORDER BY
od_id, system_auto_id
DESC
";
Wat werkt er niet? Zo is het een beetje de speld in de hooiberg vinden. Dus wat krijg je eruit en wat had je verwacht (of gewild) eruit te krijgen?
Het script geeft wel output, maar geeft dezelfde rij 100+ * weer waar het zoekwoord in voorkomt.
Daarnaast worden de overige producten waarin het zoekterm niet in voorkwam 1x weergegeven (met andere worden alle producten).
product a
product a
product a
product a
product a
Etc....
product b
product b
Etc....
Toevoeging op 05/06/2013 16:43:31:
Patrick cos op 05/06/2013 16:42:21:
Ja sorry,
Het script geeft wel output, maar geeft dezelfde rij 100+ * weer waar het zoekwoord in voorkomt.
Daarnaast worden de overige producten waarin het zoekterm niet in voorkwam 1x weergegeven (met andere worden alle producten).
product a
product a
product a
product a
product a
Etc....
product b
product b
Etc....
Het script geeft wel output, maar geeft dezelfde rij 100+ * weer waar het zoekwoord in voorkomt.
Daarnaast worden de overige producten waarin het zoekterm niet in voorkwam 1x weergegeven (met andere worden alle producten).
product a
product a
product a
product a
product a
Etc....
product b
product b
Etc....
Nog iets:
Toen ik het onderstaande gebruikte voor alleen de onderdelen werkte het script wel goed, maar sinds ik systemen toegevoegd heb niet meer.
Code (php)
1
2
3
4
2
3
4
((LOWER(od_naam) LIKE '%" . mysql_real_escape_string ($zoek) . "%')
AND
od_removed = 'N' AND
od_show = 'Y')
AND
od_removed = 'N' AND
od_show = 'Y')
Gewijzigd op 05/06/2013 16:44:09 door patrick cos
Dat is het nadeel van impliciete joins, je vergeet heel makkelijk de join condities, dus je moet altijd een
onderdelen.systeem_id = systemen.systeem_id
in je where hebben staan, anders heb je een cross join, en dat wil zeggen dat elke rij in tabel A aan alle rijen in tabel B wordt gekoppeld.
Gewijzigd op 05/06/2013 16:56:47 door Ger van Steenderen
Hoe zou ik dat in deze query moeten verwerken?
Dan kan je beter een UNION gebruiken. Dus selecteer eerst alle rijen van de een, dan van de ander en voeg ze samen met een UNION. Daarop kan je dan eventueel nog een sorteer actie uitvoeren.
Maar beter kan je de database opzet veranderen, kortom ervoor zorgen dat die twee tabellen wel een relatie krijgen.
Als voorbeeld:
Een systeem heeft meerdere onderdelen, en een onderdeel kan ook in meerdere sytemen voorkomen.
Dit is een meer - meer relatie, dus dan heb je ALTIJD een extra tabel nodig.
Voor de rest werkt het systeem gewoon goed, maar de onderdelen kunnen wel in systemen geplaatst worden...?
Hoe is het bijvoorbeeld mogelijk om op prijs of prijs te sorteren, waarbij de gebruiker dit kan bepalen?
Alvast bedankt!
Voorbeeldje:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
function setOrderBy($order) {
if ($order !== 0) {
if ($order == 1 || $order == 2) {
$this->_order_by = 'b.brand_name';
$this->_order_by .= ($order == 2) ? ' DESC' : '';
}
if ($order == 3 || $order == 4) {
$this->_order_by = 'p.product_new_price';
$this->_order_by .= ($order == 4) ? ' DESC' : '';
}
$this->_order_by .= ', p.product_id DESC';
}
}
?>
function setOrderBy($order) {
if ($order !== 0) {
if ($order == 1 || $order == 2) {
$this->_order_by = 'b.brand_name';
$this->_order_by .= ($order == 2) ? ' DESC' : '';
}
if ($order == 3 || $order == 4) {
$this->_order_by = 'p.product_new_price';
$this->_order_by .= ($order == 4) ? ' DESC' : '';
}
$this->_order_by .= ', p.product_id DESC';
}
}
?>
Ik nog niet niet echt zo gevorderd met php en sql (ik ben meer van de Python, etc..)
ASC is oplopend, dat is de default dus mag je weglaten, DESC is aflopend.
Dus bv:
maar deze staat er toch echt wel bij?
Hoe kan ik dit het beste oplossen?
Zodat er op naam, prijs en indien mogelijk op onderdelen of systemen alleen gezocht kan worden...
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
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
$zoekquery =
"SELECT DISTINCT
od_id,
od_naam,
od_prijs
FROM
onderdelen
WHERE
((LOWER(od_naam) LIKE '%" . mysql_real_escape_string ($zoek) . "%')
AND
od_removed = 'N' AND
od_show = 'Y')
UNION
SELECT DISTINCT
system_auto_id,
system_naam,
system_prijs
FROM
systemen
WHERE
((LOWER(system_naam) LIKE '%" . mysql_real_escape_string ($zoek) . "%')
AND
system_removed = 'N' AND
system_show = 'Y')
ORDER BY
system_prijs DESC
LIMIT 100
";
"SELECT DISTINCT
od_id,
od_naam,
od_prijs
FROM
onderdelen
WHERE
((LOWER(od_naam) LIKE '%" . mysql_real_escape_string ($zoek) . "%')
AND
od_removed = 'N' AND
od_show = 'Y')
UNION
SELECT DISTINCT
system_auto_id,
system_naam,
system_prijs
FROM
systemen
WHERE
((LOWER(system_naam) LIKE '%" . mysql_real_escape_string ($zoek) . "%')
AND
system_removed = 'N' AND
system_show = 'Y')
ORDER BY
system_prijs DESC
LIMIT 100
";
Toevoeging op 07/06/2013 14:14:23:
maar op od_prijs kan ik raar genoeg wel sorteren
Dat is niet vreemd, het uiteindelijke resultaat van de union heeft de kolomnamen van de eerste select statement.
Oh okej, nu heb de id van systemen boven geplaats onder ondelen en dan krijg ik not correct use of UNION
Wat je krijgt als je een union gebruikt is dat de kolomnamen zoals in de eerste query gegeven de kolomnamen worden voor de hele resultset. Je kan immers niet dezelfde kolom eerst met de ene naam en vervolgens met een andere naam hebben. In jouw geval krijg je dus od_id, od_naam en od_prijs als namen. In je order by kun je dus alleen die kolommen gebruiken. Wat je eventueel nog wel kan doen (regelmatig handig), is een extra virtuele kolom opnemen waaruit je later nog kan afleiden wat voor record je hebt:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
SELECT DISTINCT
od_id,
od_naam,
od_prijs,
'onderdeel' AS record_type
...
UNION
SELECT DISTINCT
system_auto_id,
system_naam,
system_prijs,
'system'
...
od_id,
od_naam,
od_prijs,
'onderdeel' AS record_type
...
UNION
SELECT DISTINCT
system_auto_id,
system_naam,
system_prijs,
'system'
...
Zo weet je dus als je de rijen aan het uitlezen bent of het id van een onderdeel is, of van een system. Hier kan je dan ook nog op sorteren.
Gewijzigd op 07/06/2013 16:22:05 door Erwin H
En om je volgende vraag voor te zijn, om te kunnen bepalen of het een systeem of een onderdeel is, voeg je een literal toe aan de SELECT, dus:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT
'onderdeel' AS soort,
od_id,
.....
FROM
onderdelen
....
SELECT
'systeem' AS soort,
system_id,
.....
FROM
systemen
....
'onderdeel' AS soort,
od_id,
.....
FROM
onderdelen
....
SELECT
'systeem' AS soort,
system_id,
.....
FROM
systemen
....
Gewijzigd op 07/06/2013 16:23:49 door Ger van Steenderen
Gelukkig hebben we nog steeds elke keer dezelfde tips :-)
Toevoeging op 07/06/2013 17:01:00:
PS.
SELECT DISTINCT hoeft niet, de DISTINCT zit al in de UNION