Zoeken…


Invoering

SELECT wordt gebruikt om rijen gekozen uit een of meer tabellen op te halen.

Syntaxis

  • SELECTEER DISTINCT [uitdrukkingen] VAN Tabelnaam [WAAR voorwaarden]; /// Simple Select

  • SELECT DISTINCT (a), b ... is hetzelfde als SELECT DISTINCT a, b ...

  • SELECTEER [ALLES | ONDERSCHEIDEN | DISTINCTROW] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT | SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] expressies UIT tabellen [WHERE condities] [GROUP BY expressions] [HAVING condition] [ORDER BY expression [ASC | DESC]] [LIMIT [offset_value] number_rows | LIMIT aantal rijen OFFSET offset_waarde] [PROCEDURE procedure_name] [INTO [OUTFILE 'bestandsnaam' opties | DUMPFILE 'file_name' | @ variable1, @ variable2, ... @variable_n] [VOOR UPDATE | LOCK IN DELENMODUS]; /// Volledige selectie syntaxis

Opmerkingen

Raadpleeg MySQL Docs voor meer informatie over de SELECT instructie van MySQL .

SELECTEER op kolomnaam

CREATE TABLE stack(
    id INT,
    username VARCHAR(30) NOT NULL,
    password VARCHAR(30) NOT NULL
);

INSERT INTO stack (`id`, `username`, `password`) VALUES (1, 'Foo', 'hiddenGem');
INSERT INTO stack (`id`, `username`, `password`) VALUES (2, 'Baa', 'verySecret');

vraag

SELECT id FROM stack;

Resultaat

+------+
| id   |
+------+
|    1 |
|    2 |
+------+

SELECTEER alle kolommen (*)

vraag

SELECT * FROM stack;

Resultaat

+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
|    2 | stack    | stack    |
+------+----------+----------+
2 rows in set (0.00 sec)

U kunt alle kolommen uit één tabel in een join selecteren door het volgende te doen:

SELECT stack.* FROM stack JOIN Overflow ON stack.id = Overflow.id;

Best Practice Gebruik geen * tenzij u fouten opspoort of de rij (en) ophaalt in associatieve arrays, anders kunnen schemawijzigingen (ADD / DROP / kolommen herschikken) leiden tot vervelende toepassingsfouten. Als u de lijst met kolommen in uw resultatenset opgeeft, kan de queryplanner van MySQL vaak de query optimaliseren.

Voors:

  1. Wanneer u kolommen toevoegt / verwijdert, hoeft u geen wijzigingen aan te brengen waar u SELECT * hebt gebruikt
  2. Het is korter om te schrijven
  3. Je ziet ook de antwoorden, dus kan SELECT * -gebruik ooit gerechtvaardigd zijn?

nadelen:

  1. U retourneert meer gegevens dan u nodig hebt. Stel dat u een VARBINARY-kolom toevoegt die 200 k per rij bevat. U hebt deze gegevens slechts op één plaats nodig voor één record - met SELECT * krijgt u uiteindelijk 2 MB terug per 10 rijen die u niet nodig hebt
  2. Expliciet over welke gegevens worden gebruikt
  3. Als u kolommen opgeeft, krijgt u een foutmelding wanneer een kolom wordt verwijderd
  4. De queryprocessor moet wat meer werk doen - uitzoeken welke kolommen er op de tafel staan (bedankt @vinodadhikary)
  5. U kunt gemakkelijker vinden waar een kolom wordt gebruikt
  6. Je krijgt alle kolommen in joins als je SELECT * gebruikt
  7. U kunt ordinale verwijzingen niet veilig gebruiken (hoewel het gebruik van ordinale verwijzingen voor kolommen op zichzelf een slechte gewoonte is)
  8. In complexe query's met TEXT velden kan de query worden vertraagd door minder optimale tijdelijke tabelverwerking

SELECTEER MET WAAR

vraag

SELECT * FROM stack WHERE username = "admin" AND password = "admin";

Resultaat

+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
+------+----------+----------+
1 row in set (0.00 sec) 

Zoekopdracht met een geneste SELECT in de WHERE-component

De WHERE component kan elke geldige SELECT instructie bevatten om complexere query's te schrijven. Dit is een 'geneste' zoekopdracht

vraag

Geneste query's worden meestal gebruikt om enkele atomaire waarden uit query's te retourneren voor vergelijkingen.

SELECT title FROM books WHERE author_id = (SELECT id FROM authors WHERE last_name = 'Bar' AND first_name = 'Foo');

Selecteert alle gebruikersnamen zonder e-mailadres

SELECT * FROM stack WHERE username IN (SELECT username FROM signups WHERE email IS NULL);

Disclaimer: Overweeg het gebruik van joins voor prestatieverbeteringen bij het vergelijken van een hele resultaatset.

SELECTEER met LIKE (%)

CREATE TABLE stack
(  id int AUTO_INCREMENT PRIMARY KEY,
   username VARCHAR(100) NOT NULL
);

INSERT stack(username) VALUES 
('admin'),('k admin'),('adm'),('a adm b'),('b XadmY c'), ('adm now'), ('not here'); 

"adm" overal:

SELECT * FROM stack WHERE username LIKE "%adm%";  
+----+-----------+
| id | username  |
+----+-----------+
|  1 | admin     |
|  2 | k admin   |
|  3 | adm       |
|  4 | a adm b   |
|  5 | b XadmY c |
|  6 | adm now   |
+----+-----------+

Begint met "adm":

SELECT * FROM stack WHERE username LIKE "adm%";
+----+----------+
| id | username |
+----+----------+
|  1 | admin    |
|  3 | adm      |
|  6 | adm now  |
+----+----------+

Eindigt met "adm":

SELECT * FROM stack WHERE username LIKE "%adm"; 
+----+----------+
| id | username |
+----+----------+
|  3 | adm      |
+----+----------+

Net zoals het % -teken in een LIKE component overeenkomt met een willekeurig aantal tekens, komt het _ -teken overeen met slechts één teken. Bijvoorbeeld,

SELECT * FROM stack WHERE username LIKE "adm_n"; 
+----+----------+
| id | username |
+----+----------+
|  1 | admin    |
+----+----------+

Prestatie-opmerkingen Als er een index op de username , dan

  • LIKE 'adm' voert hetzelfde uit als `= 'adm'
  • LIKE 'adm% is een "bereik", vergelijkbaar met BETWEEN..AND.. Het kan goed gebruik maken van een index op de kolom.
  • LIKE '%adm' (of een variant met een leidend jokerteken) kan geen enkele index gebruiken. Daarom zal het langzaam zijn. Op tafels met veel rijen is het waarschijnlijk zo traag dat het nutteloos is.
  • RLIKE ( REGEXP ) is meestal langzamer dan LIKE , maar heeft meer mogelijkheden.
  • Hoewel MySQL FULLTEXT indexering op veel soorten tabellen en kolommen biedt, worden die FULLTEXT indexen niet gebruikt om zoekopdrachten met LIKE .

SELECTEER met Alias (AS)

SQL-aliassen worden gebruikt om de naam van een tabel of kolom tijdelijk te wijzigen. Ze worden meestal gebruikt om de leesbaarheid te verbeteren.

vraag

SELECT username AS val FROM stack; 
SELECT username val FROM stack;

(Opmerking: AS is syntactisch optioneel.)

Resultaat

+-------+
| val   |
+-------+
| admin |
| stack |
+-------+
2 rows in set (0.00 sec)

SELECTEER met een LIMIT-clausule

Query:

 SELECT *
   FROM Customers
  ORDER BY CustomerID 
  LIMIT 3;

Resultaat:

Klanten ID Klantnaam Contactnaam Adres stad Postcode land
1

Alfreds Futterkiste Maria Anders Obere Str. 57 Berlijn 12209 Duitsland
2 Ana Trujillo Emparedados y helados Ana Trujillo Avda. de la Constitución 2222 México DF 05021 Mexico
3 Antonio Moreno Taquería Antonio Moreno Mataderos 2312 México DF 05023 Mexico

Best Practice Gebruik altijd ORDER BY wanneer u LIMIT ; anders zijn de rijen die u krijgt onvoorspelbaar.

Query:

 SELECT *
   FROM Customers
  ORDER BY CustomerID 
  LIMIT 2,1;

Uitleg:

Wanneer een LIMIT clausule twee getallen bevat, wordt deze geïnterpreteerd als LIMIT offset,count . In dit voorbeeld slaat de query dus twee records over en retourneert een.

Resultaat:

Klanten ID Klantnaam Contactnaam Adres stad Postcode land
3 Antonio Moreno Taquería Antonio Moreno Mataderos 2312 México DF 05023 Mexico

Notitie:

De waarden in LIMIT clausules moeten constanten zijn; het zijn mogelijk geen kolomwaarden.

SELECTEER met DISTINCT

De clausule DISTINCT na SELECT elimineert dubbele rijen uit de resultatenset.

CREATE TABLE `car`
(   `car_id` INT UNSIGNED NOT NULL PRIMARY KEY, 
    `name` VARCHAR(20), 
    `price` DECIMAL(8,2)
);

INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (1, 'Audi A1', '20000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (2, 'Audi A1', '15000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (3, 'Audi A2', '40000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (4, 'Audi A2', '40000');

SELECT DISTINCT `name`, `price` FROM CAR;
+---------+----------+
| name    | price    |
+---------+----------+
| Audi A1 | 20000.00 |
| Audi A1 | 15000.00 |
| Audi A2 | 40000.00 |
+---------+----------+

DISTINCT werkt in alle kolommen om de resultaten te leveren, niet in afzonderlijke kolommen. Dit laatste is vaak een misvatting van nieuwe SQL-ontwikkelaars. Kortom, het is de onderscheidbaarheid op rijniveau van de resultatenset, niet de onderscheidbaarheid op kolomniveau. Om dit te visualiseren, kijk naar "Audi A1" in de bovenstaande resultatenset.

Voor latere versies van MySQL heeft DISTINCT gevolgen voor het gebruik ervan naast ORDER BY . De instelling voor ONLY_FULL_GROUP_BY komt in het spel zoals te zien op de volgende MySQL-handleiding met de titel MySQL Handling of GROUP BY .

SELECTEER met LIKE (_)

Een _ -teken in een LIKE clausulepatroon komt overeen met een enkel teken.

vraag

SELECT username FROM users WHERE users LIKE 'admin_';

Resultaat

+----------+
| username |  
+----------+
| admin1   |
| admin2   |
| admin-   |
| adminA   |
+----------+

SELECTEER met CASE of IF

vraag

SELECT st.name,
       st.percentage, 
       CASE WHEN st.percentage >= 35 THEN 'Pass' ELSE 'Fail' END AS `Remark` 
FROM student AS st ;

Resultaat

+--------------------------------+
|   name   | percentage | Remark |
+--------------------------------+
|   Isha   |     67     |  Pass  |
|   Rucha  |     28     |  Fail  |
|   Het    |     35     |  Pass  |
|   Ansh   |     92     |  Pass  |
+--------------------------------+

Of met ALS

SELECT st.name,
       st.percentage, 
       IF(st.percentage >= 35, 'Pass', 'Fail') AS `Remark` 
FROM student AS st ;

NB

IF(st.percentage >= 35, 'Pass', 'Fail')

Dit betekent: ALS st.percentage> = 35 WAAR is en dan 'Pass' retourneer ELSE return 'Fail'

SELECTEER MET TUSSEN

U kunt de BETWEEN-clausule gebruiken om een combinatie van voorwaarden voor "groter dan gelijk EN kleiner dan gelijk" te vervangen.

Gegevens

+----+-----------+
| id | username  |
+----+-----------+
|  1 | admin     |
|  2 | root      |
|  3 | toor      |
|  4 | mysql     |
|  5 | thanks    |
|  6 | java      |
+----+-----------+

Vraag met operators

SELECT * FROM stack WHERE id >= 2 and id <= 5; 

Soortgelijke zoekopdracht met TUSSEN

SELECT * FROM stack WHERE id BETWEEN 2 and 5; 

Resultaat

+----+-----------+
| id | username  |
+----+-----------+
|  2 | root      |
|  3 | toor      |
|  4 | mysql     |
|  5 | thanks    |
+----+-----------+
4 rows in set (0.00 sec)

Notitie

TUSSEN gebruikt >= en <= , niet > en < .

NIET TUSSEN gebruiken

Als u het negatieve wilt gebruiken, kunt u NOT . Bijvoorbeeld :

SELECT * FROM stack WHERE id NOT BETWEEN 2 and 5; 

Resultaat

+----+-----------+
| id | username  |
+----+-----------+
|  1 | admin     |
|  6 | java      |
+----+-----------+
2 rows in set (0.00 sec)

Notitie

NIET TUSSEN gebruikt > en < en niet >= en <= Dat wil zeggen, WHERE id NOT BETWEEN 2 and 5 is hetzelfde als WHERE (id < 2 OR id > 5) .

Als u een index hebt op een kolom die u gebruikt in een BETWEEN zoekopdracht, kan MySQL die index gebruiken voor een bereikscan.

SELECTEER met datumbereik

SELECT ... WHERE dt >= '2017-02-01'
             AND dt  < '2017-02-01' + INTERVAL 1 MONTH

Natuurlijk kan dit worden gedaan met BETWEEN en opname van 23:59:59 . Maar het patroon heeft deze voordelen:

  • U hoeft de einddatum niet vooraf te berekenen (dit is vaak een exacte lengte vanaf het begin)
  • U neemt niet beide eindpunten op (zoals BETWEEN doet) en typ ook '23: 59: 59 'niet om dit te vermijden.
  • Het werkt voor DATE , TIMESTAMP , DATETIME en zelfs de DATETIME(6) microseconden DATETIME(6) .
  • Het zorgt voor schrikkeldagen, einde van het jaar, etc.
  • Het is indexvriendelijk (dus BETWEEN ).


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow