Ricerca…


introduzione

SELECT è usato per recuperare le righe selezionate da una o più tabelle.

Sintassi

  • SELECT DISTINCT [espressioni] FROM TableName [WHERE conditions]; /// Selezione semplice

  • SELECT DISTINCT (a), b ... è uguale a SELECT DISTINCT a, b ...

  • SELEZIONA [TUTTI | DISTINCT | DISTINCTROW] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT | SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] espressioni FROM tabelle [WHERE condizioni] [GROUP BY espressioni] [condizione HAVING] [espressione ORDER BY [ASC | DESC]] [LIMIT [offset_value] number_rows | LIMIT number_rows OFFSET offset_value] [PROCEDURE procedure_name] [INTO [OUTFILE 'file_name' opzioni | DUMPFILE 'nome_file' | @ variable1, @ variable2, ... @variable_n] [FOR UPDATE | LOCK IN SHARE MODE]; /// Full Select Sintassi

Osservazioni

Per ulteriori informazioni sull'istruzione SELECT di MySQL, consultare MySQL Docs .

SELEZIONA per nome colonna

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

domanda

SELECT id FROM stack;

Risultato

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

SELEZIONA tutte le colonne (*)

domanda

SELECT * FROM stack;

Risultato

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

Puoi selezionare tutte le colonne da una tabella in un join facendo:

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

Best Practice Non usare * meno che non si stia eseguendo il debug o il recupero delle righe in array associativi, altrimenti le modifiche dello schema (ADD / DROP / riarrangia le colonne) possono causare errori di applicazione. Inoltre, se si fornisce l'elenco di colonne necessario nel set di risultati, il pianificatore di query di MySQL spesso può ottimizzare la query.

Professionisti:

  1. Quando aggiungi / rimuovi colonne, non devi apportare modifiche dove hai usato SELECT *
  2. È più breve da scrivere
  3. Vedi anche le risposte, quindi SELECT * -usage può essere mai giustificato?

Contro:

  1. Stai restituendo più dati del necessario. Supponiamo che tu aggiunga una colonna VARBINARY che contiene 200k per riga. Hai solo bisogno di questi dati in un unico posto per un singolo record - utilizzando SELECT * puoi finire con la restituzione di 2 MB per 10 righe che non ti servono
  2. Esplicito su quali dati vengono utilizzati
  3. Specificare colonne significa ottenere un errore quando una colonna viene rimossa
  4. Il processore di query deve fare ancora un po 'di lavoro - capire quali colonne esistono sul tavolo (grazie @vinodadhikary)
  5. Puoi trovare dove una colonna è usata più facilmente
  6. Ottieni tutte le colonne in join se usi SELECT *
  7. Non è possibile utilizzare in modo sicuro la referenziazione ordinale (sebbene l'uso di riferimenti ordinali per le colonne sia di per sé una cattiva pratica)
  8. Nelle query complesse con campi TEXT , la query può essere rallentata dall'elaborazione della tabella temporanea meno ottimale

SELEZIONA con DOVE

domanda

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

Risultato

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

Interrogazione con SELECT nidificato nella clausola WHERE

La clausola WHERE può contenere qualsiasi istruzione SELECT valida per scrivere query più complesse. Questa è una query 'annidata'

domanda

Le query annidate vengono solitamente utilizzate per restituire valori atomici singoli da query per confronti.

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

Seleziona tutti i nomi utente senza indirizzo email

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

Dichiarazione di non responsabilità: prendere in considerazione l'utilizzo di join per migliorare le prestazioni quando si confronta un intero set di risultati.

SELEZIONA con 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" ovunque:

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

Inizia con "adm":

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

Termina con "adm":

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

Proprio come il carattere % in una clausola LIKE corrisponde a qualsiasi numero di caratteri, il carattere _ corrisponde a un solo carattere. Per esempio,

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

Note sulle prestazioni Se c'è un indice sul username , allora

  • LIKE 'adm' lo stesso effetto di `= 'adm'
  • LIKE 'adm% è un "range", simile a BETWEEN..AND.. Può fare buon uso di un indice sulla colonna.
  • LIKE '%adm' (o qualsiasi variante con un carattere jolly iniziale) non possono utilizzare un indice. Quindi sarà lento. Sui tavoli con molte file, è probabile che sia così lento che è inutile.
  • RLIKE ( REGEXP ) tende ad essere più lento di LIKE , ma ha più capacità.
  • Mentre MySQL offre l'indicizzazione FULLTEXT su molti tipi di tabelle e colonne, quegli indici FULLTEXT non vengono utilizzati per soddisfare le query utilizzando LIKE .

SELEZIONA con Alias ​​(AS)

Gli alias SQL vengono utilizzati per rinominare temporaneamente una tabella o una colonna. Sono generalmente utilizzati per migliorare la leggibilità.

domanda

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

(Nota: AS è sintatticamente opzionale).

Risultato

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

SELEZIONA con una clausola LIMIT

Query:

 SELECT *
   FROM Customers
  ORDER BY CustomerID 
  LIMIT 3;

Risultato:

Identificativo del cliente Nome del cliente Nome del contatto Indirizzo Città Codice postale Nazione
1

Alfreds Futterkiste Maria Anders Obere Str. 57 Berlino 12209 Germania
2 Ana Trujillo Emparedados y helados Ana Trujillo Avda. de la Constitución 2222 Messico DF 05021 Messico
3 Antonio Moreno Taquería Antonio Moreno Mataderos 2312 Messico DF 05023 Messico

Best Practice Utilizzare sempre ORDER BY quando si utilizza LIMIT ; altrimenti le righe che otterrai saranno imprevedibili.

Query:

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

Spiegazione:

Quando una clausola LIMIT contiene due numeri, viene interpretata come LIMIT offset,count . Quindi, in questo esempio la query salta due record e ne restituisce uno.

Risultato:

Identificativo del cliente Nome del cliente Nome del contatto Indirizzo Città Codice postale Nazione
3 Antonio Moreno Taquería Antonio Moreno Mataderos 2312 Messico DF 05023 Messico

Nota:

I valori nelle clausole LIMIT devono essere costanti; potrebbero non essere valori di colonna.

SELEZIONA con DISTINCT

La clausola DISTINCT dopo SELECT elimina le righe duplicate dal set di risultati.

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 funziona su tutte le colonne per fornire i risultati, non singole colonne. Quest'ultimo è spesso un equivoco di nuovi sviluppatori SQL. In breve, è la distinzione a livello di riga del set di risultati che conta, non la distinzione a livello di colonna. Per visualizzarlo, guarda "Audi A1" nel set di risultati sopra.

Per le versioni successive di MySQL, DISTINCT ha implicazioni con il suo uso insieme a ORDER BY . L'impostazione di ONLY_FULL_GROUP_BY entra in gioco come mostrato nella seguente pagina del manuale MySQL intitolata Gestione MySQL di GROUP BY .

SELEZIONA con LIKE (_)

Un carattere _ in un modello di clausola LIKE corrisponde a un singolo carattere.

domanda

SELECT username FROM users WHERE users LIKE 'admin_';

Risultato

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

SELEZIONA con CASE o SE

domanda

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

Risultato

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

O con 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')

Ciò significa: IF st.percentage> = 35 è TRUE, quindi restituire 'Pass' ELSE return 'Fail'

SELEZIONA CON BETWEEN

È possibile utilizzare la clausola BETWEEN per sostituire una combinazione di condizioni "maggiore di uguale AND inferiore di uguale".

Dati

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

Interrogare con gli operatori

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

Query simile con BETWEEN

SELECT * FROM stack WHERE id BETWEEN 2 and 5; 

Risultato

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

Nota

TRA utilizza >= e <= , non > e < .

Usando NON TRA

Se vuoi usare il negativo puoi usare NOT . Per esempio :

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

Risultato

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

Nota

NON TRA usi > e < e non >= e <= Cioè, WHERE id NOT BETWEEN 2 and 5 è uguale a WHERE (id < 2 OR id > 5) .

Se hai un indice su una colonna che usi in una ricerca BETWEEN , MySQL può usare quell'indice per una scansione di intervallo.

SELEZIONA con l'intervallo di date

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

Certo, questo potrebbe essere fatto con BETWEEN e l'inclusione di 23:59:59 . Ma il modello ha questi vantaggi:

  • Non hai pre-calcolare la data di fine (che spesso è una lunghezza esatta dall'inizio)
  • Non si includono entrambi gli endpoint (come BETWEEN ), né si digita '23: 59: 59 'per evitarlo.
  • Funziona per DATE , TIMESTAMP , DATETIME e persino DATETIME(6) incluso nel microsecondo.
  • Si occupa dei giorni bisestili, della fine dell'anno, ecc.
  • È indice-friendly (quindi è BETWEEN ).


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow