Sök…


Introduktion

SELECT används för att hämta rader valda från en eller flera tabeller.

Syntax

  • VÄLJ DISTINCT [uttryck] FRÅN Tabellnamn [VAR villkor]; /// Enkelt Välj

  • SELECT DISTINCT (a), b ... är samma som SELECT DISTINCT a, b ...

  • VÄLJ [ALLA | DISTINKT | DISTINCTROW] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT | SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] uttryck FRÅN tabeller [VAR villkor] [GRUPP AV uttryck] [HAVING villkor] [ORDER BY uttryck [ASC | DESC]] [LIMIT [offset_value] number_rows | LIMIT number_rows OFFSET offset_value] [PROCEDURE procedure_name] [INTO [OUTFILE 'file_name' options | DUMPFIL 'filnamn' | @ variabel1, @ variabel2, ... @variabelt_n] [FÖR UPPDATERING | LOCK IN SHARE MODE]; /// Full Välj syntax

Anmärkningar

Mer information om MySQL: s SELECT uttalande finns i MySQL Docs .

VÄLJ efter kolumnnamn

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');

Fråga

SELECT id FROM stack;

Resultat

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

VÄLJ alla kolumner (*)

Fråga

SELECT * FROM stack;

Resultat

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

Du kan välja alla kolumner från en tabell i en sammanfogning genom att göra:

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

Bästa praxis Använd inte * såvida du inte felsöker eller hämtar raden / raderna i associerande matriser, annars kan schematändringar (ADD / DROP / omarrangera kolumner) leda till otäcka applikationsfel. Om du ger en lista över kolumner du behöver i din resultatsats kan MySQLs frågeformulär ofta optimera frågan.

Fördelar:

  1. När du lägger till / tar bort kolumner behöver du inte göra ändringar där du använde SELECT *
  2. Det är kortare att skriva
  3. Du ser också svaren, så kan SELECT * -bruk någonsin vara motiverat?

Nackdelar:

  1. Du returnerar mer data än du behöver. Säg att du lägger till en VARBINARY-kolumn som innehåller 200 000 per rad. Du behöver bara dessa data på ett ställe för en enda post - med SELECT * du hamna tillbaka 2 MB per 10 rader som du inte behöver
  2. Explicit om vilka data som används
  3. Att ange kolumner innebär att du får ett fel när en kolumn tas bort
  4. Frågefrocessorn måste göra lite mer arbete - ta reda på vilka kolumner som finns på bordet (tack @vinodadhikary)
  5. Du kan hitta en kolumn lättare
  6. Du får alla kolumner i sammanfogningar om du använder VÄLJ *
  7. Du kan inte använda ordinära referenser på ett säkert sätt (men det är dåligt att använda ordinära referenser för kolumner i sig)
  8. I komplexa frågor med TEXT fält kan frågan bromsas ner med mindre optimal temp-tabellbehandling

VÄLJ med VAR

Fråga

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

Resultat

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

Fråga med en kapslad SELECT i WHERE-klausulen

WHERE klausulen kan innehålla valfritt SELECT uttalande för att skriva mer komplexa frågor. Detta är en "kapslad" fråga

Fråga

Kapslade frågor används vanligtvis för att returnera enstaka atomvärden från frågor för jämförelser.

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

Väljer alla användarnamn utan e-postadress

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

Friskrivningsklausul: Överväg att använda joins för prestandaförbättringar när du jämför en hel resultatuppsättning.

VÄLJ med 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" var som helst:

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   |
+----+-----------+

Börjar med "adm":

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

Avsluts med "adm":

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

Precis som % -tecknet i en LIKE klausul matchar valfritt antal tecken, _ tecknet bara ett tecken. Till exempel,

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

Prestandeanmärkningar Om det finns ett index på username , då

  • LIKE 'adm' utför samma sak som '=' adm '
  • LIKE 'adm% är ett "intervall", liknande BETWEEN..AND.. Det kan utnyttja ett index i kolumnen bra.
  • LIKE '%adm' (eller någon variant med ett ledande jokertecken) kan inte använda något index. Därför kommer det att bli långsamt. På bord med många rader är det troligtvis så långsamt att det är värdelöst.
  • RLIKE ( REGEXP ) tenderar att vara långsammare än LIKE , men har fler möjligheter.
  • Medan MySQL erbjuder FULLTEXT indexering på många typer av bord och kolumn, de FULLTEXT är index inte användas för att uppfylla frågor med hjälp LIKE .

VÄLJ med Alias (AS)

SQL-alias används för att tillfälligt byta namn på en tabell eller en kolumn. De används vanligtvis för att förbättra läsbarheten.

Fråga

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

(Obs: AS är syntaktiskt valfritt.)

Resultat

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

VÄLJ med en begränsningsklausul

Fråga:

 SELECT *
   FROM Customers
  ORDER BY CustomerID 
  LIMIT 3;

Resultat:

Kundnummer Köparens namn Kontaktnamn Adress Stad Postnummer Land
1

Alfreds Futterkiste Maria Anders Obere Str. 57 Berlin 12209 Tyskland
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

Bästa praxis Använd alltid ORDER BY när du använder LIMIT ; annars kommer raderna du får vara oförutsägbara.

Fråga:

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

Förklaring:

När en LIMIT klausul innehåller två siffror tolkas den som LIMIT offset,count . Så i detta exempel hoppar frågan över två poster och returnerar en.

Resultat:

Kundnummer Köparens namn Kontaktnamn Adress Stad Postnummer Land
3 Antonio Moreno Taquería Antonio Moreno Mataderos 2312 México DF 05023 mexico

Notera:

Värdena i LIMIT klausuler måste vara konstanter; de kanske inte är kolumnvärden.

VÄLJ med DISTINCT

DISTINCT klausulen efter SELECT eliminerar duplicerade rader från resultatuppsättningen.

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 fungerar över alla kolumner för att leverera resultaten, inte enskilda kolumner. Det senare är ofta en missuppfattning av nya SQL-utvecklare. I korthet är det distinensen på resultatsatsens radnivå som spelar roll, inte distinensen på kolumnivån. För att visualisera detta, titta på "Audi A1" i ovanstående resultatuppsättning.

För senare versioner av MySQL har DISTINCT konsekvenser för dess användning tillsammans med ORDER BY . Inställningen för ONLY_FULL_GROUP_BY kommer in i spelet enligt följande MySQL Manual-sida med titeln MySQL-hantering av GROUP BY .

VÄLJ med LIKE (_)

Ett _ tecken i ett LIKE klausulmönster matchar ett enda tecken.

Fråga

SELECT username FROM users WHERE users LIKE 'admin_';

Resultat

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

VÄLJ med fall eller IF

Fråga

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

Resultat

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

Eller med IF

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

NB

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

Detta betyder: IF st.percentage> = 35 är SANT och sedan returnera 'Pass' ELSE return 'Fail'

VÄLJ med MELLAN

Du kan använda MELLAN-klausulen för att ersätta en kombination av "större än lika OCH mindre än lika" villkor.

Data

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

Fråga med operatörer

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

Liknande fråga med MELLAN

SELECT * FROM stack WHERE id BETWEEN 2 and 5; 

Resultat

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

Notera

MELLAN använder >= och <= , inte > och < .

Använd INTE MELLAN

Om du vill använda det negativa kan du använda NOT . Till exempel :

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

Resultat

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

Notera

INTE MELLAN använder > och < och inte >= och <= Det vill säga WHERE id NOT BETWEEN 2 and 5 är samma som WHERE (id < 2 OR id > 5) .

Om du har ett index i en kolumn som du använder i en BETWEEN sökning kan MySQL använda det indexet för en avstandsskanning.

VÄLJ med datumintervall

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

Visst, detta kan göras med BETWEEN och inkludering av 23:59:59 . Men mönstret har följande fördelar:

  • Du har inte förberäknat slutdatumet (som ofta är en exakt längd från början)
  • Du inkluderar inte båda slutpunkterna (som BETWEEN gör) och skriver inte heller '23: 59: 59 'för att undvika det.
  • Det fungerar för DATE , TIMESTAMP , DATETIME och till och med den mikrosekunder som ingår DATETIME(6) .
  • Det tar hand om språngdagar, årets slut etc.
  • Det är indexvänligt (så är BETWEEN ).


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow