WHERE 2 manieren op 1 veld

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Nick Smit

Nick Smit

09/05/2014 10:42:28
Quote Anchor link
Hallo,


Ik ben bezig met een zoek systeem op mijn gebruikers tabel. Nu wil ik graag kunnen zoeken op het ID én op de naam van het permissie pakket. Nu heb ik de volgende query:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        SELECT
         user.id,
         username,
         email,
         DATE_FORMAT(reg_date, '%d-%m-%Y %k:%i') as reg_date,
         permission_pack.name
        FROM
         user
        LEFT JOIN
         permission_pack
        ON (user.permission_pack_id = permission_pack.id)
        WHERE
         user.id LIKE '%".$this->input->post('id')."%' AND
         username LIKE '%".$this->input->post('username')."%'  AND
         email LIKE '%".$this->input->post('email')."%' AND
         DATE_FORMAT(reg_date, '%d-%m-%Y %k:%i') LIKE '%".$this->input->post('reg_date')."%' AND
         permission_pack_id LIKE '%".$this->input->post('permission_pack')."%' OR
         permission_pack.name LIKE '%".$this->input->post('permission_pack')."%'
        LIMIT ".$limit_min.",".$limit_max


Nu moeten de laatste twee expressies van de WHERE clause in één zitten waardoor ik het ID maar ook de naam van het pakket kan vinden. Hoe kan ik dit doen?

Nick.
Gewijzigd op 09/05/2014 10:43:07 door Nick Smit
 
PHP hulp

PHP hulp

05/11/2024 15:57:06
 
Erwin H

Erwin H

09/05/2014 11:07:48
Quote Anchor link
Waarschijnlijk heb je een OR in plaats van een AND operator nodig. Als je AND gebruikt betekent het dat 1 record zowel moet matchen op naam, als op id. Als je de matches wilt hebben op naam of id heb je OR nodig. Let dan ook op het operator precedence, een AND operater gaat namelijk boven een OR operator, wat betekent dat deze twee statement niet hetzelfde resultaat zullen opleveren:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
WHERE id=1 OR naam='bla' AND email='iets'

WHERE (id=1 OR naam='bla') AND email='iets'


Daarnaast, als id een integer is (wat je meestal gebruikt voor een id), dan is een LIKE clause niet echt verstandig. Zo krijg je namelijk ook alle ids die er op lijken, zoek is dus op id=1, dan krijg ik niet alleen het record met id=1, maar alle records waar een 1 in het id zit (en dat is dus ongeveer 10% van alle records. Lijkt mij niet dat je dat wilt. Bedenk ook dat LIKE clauses erg traag zijn, omdat ze (met een wildcard aan het begin) geen gebruik meer kunnen maken van een index en in het geval van een int veld ook nog eens een cast moeten uitvoeren.
 
Nick Smit

Nick Smit

09/05/2014 11:37:48
Quote Anchor link
Bedankt voor je antwoord!

Ik heb het nu werkende gekregen. Het zal nog niet het meest efficient zijn maargoed.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
$search[] = (!empty($this->input->post('id')) ? "user.id = '".$this->input->post('id')."'" : '');
        $search[] = (!empty($this->input->post('username')) ? "username LIKE '%".$this->input->post('username')."%'" : '');
        $search[] = (!empty($this->input->post('email')) ? "email LIKE '%".$this->input->post('email')."%'" : '');
        $search[] = (!empty($this->input->post('reg_date')) ? "DATE_FORMAT(reg_date, '%d-%m-%Y %k:%i') LIKE '%".$this->input->post('reg_date')."%'" : '');
        $search[] = (!empty($this->input->post('permission_pack')) ? "(permission_pack_id = '".$this->input->post('permission_pack')."' OR permission_pack.name LIKE '%".$this->input->post('permission_pack')."%')" : '');
        
        $where = "";
        
        for($i=0; $i < count($search); $i++)
        {
            if(!empty($search[$i]))
            {
                if(!empty($where))
                {
                    $where .= " AND " . $search[$i];
                }
                else
                {
                    $where = " WHERE " . $search[$i];
                }
            }
        }
        
        $query =
        "SELECT
         user.id,
         username,
         email,
         DATE_FORMAT(reg_date, '%d-%m-%Y %k:%i') as reg_date,
         permission_pack.name
        FROM
         user
        LEFT JOIN
         permission_pack
        ON (user.permission_pack_id = permission_pack.id)
         ".$where."
        LIMIT ".$limit_min.",".$limit_max;
        return $this->db->query($query)->result();


EDIT Heb de for loop iets aangepast.
Gewijzigd op 09/05/2014 11:46:42 door Nick Smit
 
Erwin H

Erwin H

09/05/2014 12:28:18
Quote Anchor link
Als je die search array iets anders opbouwt kan je die where clause veel makkelijker doen:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php
if ( !empty($this->input->post('id') ) $search[] = "user.id = '".$this->input->post('id')."'";
//en de andere net zo

if ( count( $search ) > 0 ){
  $where = 'WHERE '.implode( ' AND ', $search );
}
  
?>
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.