Search the MySQL manual:
Subscribe to the monthly
MySQL Newsletter!

6.4.1 Синтаксис оператора SELECT

Оператор SELECT имеет следующую структуру:

SELECT [STRAIGHT_JOIN]
       [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
       [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] [HIGH_PRIORITY]
       [DISTINCT | DISTINCTROW | ALL]
    select_expression,...
    [INTO {OUTFILE | DUMPFILE} 'file_name' export_options]
    [FROM table_references
      [WHERE where_definition]
      [GROUP BY {unsigned_integer | col_name | formula} [ASC | DESC], ...]
      [HAVING where_definition]
      [ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC], ...]
      [LIMIT [offset,] rows | rows OFFSET offset]
      [PROCEDURE procedure_name(argument_list)]
      [FOR UPDATE | LOCK IN SHARE MODE]]

SELECT применяется для извлечения строк, выбранных из одной или нескольких таблиц. Выражение select_expression задает столбцы, в которых необходимо проводить выборку. Кроме того, оператор SELECT можно использовать для извлечения строк, вычисленных без ссылки на какую-либо таблицу. Например:

mysql> SELECT 1 + 1;
        -> 2

При указании ключевых слов следует точно соблюдать порядок, указанный выше. Например, выражение HAVING должно располагаться после всех выражений GROUP BY и перед всеми выражениями ORDER BY.

Главы

User Comments

Posted by Colin Nelson on February 26 2003 2:10am[Delete] [Edit]

You can simulate a CROSSTAB by the following method:-

Use IF function to select the key value of the sub table as in:

SELECT
SUM(IF(beta_idx=1, beta_value,0)) as beta1_value,
SUM(IF(beta_idx=2, beta_value,0)) as beta2_value,
SUM(IF(beta_idx=3, beta_value,0)) as beta3_value
FROM alpha JOIN beta WHERE alpha_id = beta_alpha_id;

where alpha table has the form alpha_id, alpha_blah, alpha_blah_blah
and beta table has the form beta_alpha_id, beta_other stuff,
beta_idx, beta_value

This will create 3 columns with totals of beta values according to their idx field

Posted by [name withheld] on March 29 2003 3:49am[Delete] [Edit]

when selecting a single random row you have to use a query like this: SELECT ... FROM my_table ORDER BY RAND() LIMIT 1.
as explain shows, mysql optimizes this VERY badly (or may be better said, doens't optimize it at all): it uses an temporary table and an extra filesort.
couldn't this be optimized?!
if not, may be add a syntax like SELECT RANDOM_ROW .... FROM my_table ...

Posted by David Phillips on April 2 2003 11:15am[Delete] [Edit]

This method of selecting a random row should be fast:

LOCK TABLES foo READ;
SELECT FLOOR(RAND() * COUNT(*)) AS rand_row FROM foo;
SELECT * FROM foo LIMIT $rand_row, 1;
UNLOCK TABLES;

Unfortunately, variables cannot be used in the LIMIT clause, otherwise the entire thing could be done completely in SQL.

Posted by [name withheld] on August 6 2003 6:26pm[Delete] [Edit]

If you want to produce a CSV file of the data in a table, the following should accomplish it:

select INTO OUTFILE 'filename' fields terminated by ',' optionally enclosed by '"' escaped by '\\' from tablename;

Remember that the CSV file will be created on the box that mysql is running on. The user that mysqld is running as must have permission to create the file.

If you wish to convert the '\N' in the file which is output to some other string like 'NULL' the following perl script will do that:

#!/usr/bin/perl

while (<>) {
s/\\N/NULL/g;
print;
}

Posted by [name withheld] on August 21 2003 2:55am[Delete] [Edit]

In reply to David Philips:

If your tables are not all that big, a simpler method is:
SELECT * FROM foo ORDER BY RAND(NOW()) LIMIT 1;

If it's a big table, your method will almost certainly be faster.

Posted by remko de knikker on November 22 2003 2:35pm[Delete] [Edit]

For previous/next navigation to find previous or next records I use the following queries:

// get previous id
$str_qry_prev="SELECT * FROM `tab_name` WHERE id < ".$current_id." ORDER by id DESC LIMIT 1"/

// get next id
$str_qry_next="SELECT * FROM `tab_name` WHERE id > ".$current_id." ORDER by id ASC LIMIT 1";

remko de knikker - caprio
http://www.szirine.com

Posted by [name withheld] on December 10 2003 1:51pm[Delete] [Edit]

If you need to look if there are one or more specific rows in a table or not you can speed up SELECTs on big tables.

I have a script that needs to know if there is a result (or more) or not. I had troubles with table locks.

Now I've added "LIMIT 1" and this speeded my query up a lot!

Posted by Sean Gates on January 5 2004 9:34pm[Delete] [Edit]

I figured this out tonight and thought it would be useful to someone. It is a way to select multiple rows without looping through code.

SELECT *
FROM products
WHERE stock_num
IN ( '3934', '3884', '3883', '3882' )

Posted by Count Henry De Havilland-Fortesque-Smedley on January 13 2004 7:41am[Delete] [Edit]

If you want to find duplicates on a field that hasn't been uniquely indexed, you can do this:

SELECT BookISBN, count(BookISBN) FROM Books GROUP BY BookISBN HAVING COUNT(BookISBN)>1;

Posted by Count Henry De Havilland-Fortesque-Smedley on January 13 2004 7:59am[Delete] [Edit]

Sometimes you want to retrieve the records that DONT match a select statement.

Consider this select:
SELECT CarIndex FROM DealerCatalog, BigCatalog WHERE
DealerCatalog.CarIndex=BigCatalog.CarIndex

This finds all the CarIndex values in the Dealer's catalog that are in the bigger distributor catalog.


How do I then find the dealer CarIndex values that ARE NOT in the bigger catalog?

The answer is to use LEFT JOIN - anything that doesn't join is given a NULL value , so we look for that:

SELECT CarIndex FROM DealerCatalog LEFT JOIN BigCatalog ON DealerCatalog.CarIndex=BigCatalog.CarIndex WHERE BigCatalog.CarIndex IS NULL

Posted by A P on February 4 2004 5:56pm[Delete] [Edit]

There seems to be no published known limit to the number of items, or the length therein of the IN() clause when not using subqueries.

Posted by Johann Eckert on February 11 2004 2:14pm[Delete] [Edit]

To find double entries in a table:

SELECT db1.*
FROM tbl_data db1, tbl_data k2
WHERE db1.id <> db2.id
AND db1.name = db2.name

db1.id must be the PK
db1.name must be the fields that should be verified as double entries.

(I'm not sure wether the code is correct but in my case it works)

Johann

Posted by [name withheld] on March 2 2004 8:10am[Delete] [Edit]

In order to anti-match fields by wildcards, one has to check whether the value of the field is not NULL:

For example: The table 'runs' contains 34876 rows. 205 rows have an 'info' field containing the string 'wrong'.

To select those rows for which the 'info' column does *NOT* contain the word 'wrong' one has to do:

mysql> select count(*) FROM runs WHERE info is null or info not like '%wrong%';

+----------+
| count(*) |
+----------+
| 34671 |
+----------+

but not:
mysql> select count(*) FROM runs WHERE info not like %wrong%';
+----------+
| count(*) |
+----------+
| 5537 |
+----------+

which would lead to a much smaller number of selected rows.

Posted by Marian Vasile on March 5 2004 1:28am[Delete] [Edit]

I have managed to select random records using php and MySQL like the following:

$min=1;
$row=mysql_fetch_assoc(mysql_query("SHOW TABLE STATUS LIKE 'table';"));
$max=$row["Auto_increment"];

$random_id=rand($min,$max);
$row=mysql_fetch_assoc(mysql_query("SELECT * FROM table WHERE id='$random_id'");

Voila...

Cezar
http://RO-Escorts.com

Posted by [name withheld] on March 9 2004 7:44am[Delete] [Edit]

Random records without PHP, only MySQL:

select * from mailinglists order by rand() limit 1


Regards,
Geert van der Ploeg

Posted by [name withheld] on March 10 2004 6:05pm[Delete] [Edit]

Note that SELECT DISTINCT is case-insenstitive.

Posted by Marian Vasile on March 11 2004 6:21pm[Delete] [Edit]

All examples about selecting random row like:
SELECT * FROM foo ORDER BY RAND() LIMIT 1;
SELECT * FROM foo ORDER BY RAND(NOW()) LIMIT 1;

are not usefull when it's about selecting a range of rows from a table.
For example, if the table has 1000 records, and we want to select one record randomly but from only 2 records from table (based on a WHERE clause), the above examples fail because the same row is returned all the time.

This is my version in this special case...

<?php
mopen
();
$result=mysql_query("SELECT * FROM foo WHERE fieldx='value'");
$min=1; $max=mysql_num_rows($result);
if(
$max>0)
    {
    
mysql_data_seek($result,rand($min,$max)-1);
    
$row=mysql_fetch_assoc($result);
    
echo_or_use_random_record_which_is_ $row ...
    }
mclose();
?>


This code is selecting the needed rows, and picks one of the rows randomly.

Cezar
http://ro-escorts.com

Add your own comment.