Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2017
431
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 75.24 KB | None | 0 0
  1.  
  2. Contact MySQL | Login | Register
  3. The world's most popular open source database
  4.  
  5. MySQL.com Downloads Documentation Developer Zone
  6.  
  7. MySQL Server MySQL Enterprise Workbench InnoDB Cluster MySQL NDB Cluster Connectors More
  8.  
  9. Documentation Home
  10. MySQL 5.5 Reference Manual
  11.  
  12. Preface and Legal Notices
  13. General Information
  14. Installing and Upgrading MySQL
  15. Tutorial
  16. MySQL Programs
  17. MySQL Server Administration
  18. Security
  19. Backup and Recovery
  20. Optimization
  21. Language Structure
  22. Globalization
  23. Data Types
  24. Functions and Operators
  25. SQL Statement Syntax
  26. Data Definition Statements
  27. Data Manipulation Statements
  28. CALL Syntax
  29. DELETE Syntax
  30. DO Syntax
  31. HANDLER Syntax
  32. INSERT Syntax
  33. LOAD DATA INFILE Syntax
  34. LOAD XML Syntax
  35. REPLACE Syntax
  36. SELECT Syntax
  37. SELECT ... INTO Syntax
  38. JOIN Syntax
  39. UNION Syntax
  40. Subquery Syntax
  41. UPDATE Syntax
  42. Transactional and Locking Statements
  43. Replication Statements
  44. Prepared SQL Statement Syntax
  45. Compound-Statement Syntax
  46. Database Administration Statements
  47. Utility Statements
  48. The InnoDB Storage Engine
  49. Alternative Storage Engines
  50. High Availability and Scalability
  51. Replication
  52. MySQL NDB Cluster 7.2
  53. Partitioning
  54. Stored Programs and Views
  55. INFORMATION_SCHEMA Tables
  56. MySQL Performance Schema
  57. Connectors and APIs
  58. Extending MySQL
  59. MySQL Enterprise Edition
  60. MySQL Workbench
  61. MySQL 5.5 Frequently Asked Questions
  62. Errors, Error Codes, and Common Problems
  63. Restrictions and Limits
  64. Indexes
  65. MySQL Glossary
  66.  
  67. Related Documentation
  68. MySQL 5.5 Release Notes
  69. Download this Manual
  70. PDF (US Ltr) - 27.2Mb
  71. PDF (A4) - 27.2Mb
  72. PDF (RPM) - 26.1Mb
  73. HTML Download (TGZ) - 6.5Mb
  74. HTML Download (Zip) - 6.5Mb
  75. HTML Download (RPM) - 5.6Mb
  76. Man Pages (TGZ) - 170.5Kb
  77. Man Pages (Zip) - 278.9Kb
  78. Info (Gzip) - 2.6Mb
  79. Info (Zip) - 2.6Mb
  80. Excerpts from this Manual
  81.  
  82.  
  83. version 5.5
  84. MySQL 5.5 Reference Manual / ... / SELECT Syntax
  85. 13.2.9 SELECT Syntax
  86.  
  87. 13.2.9.1 SELECT ... INTO Syntax
  88. 13.2.9.2 JOIN Syntax
  89. 13.2.9.3 UNION Syntax
  90.  
  91. SELECT
  92. [ALL | DISTINCT | DISTINCTROW ]
  93. [HIGH_PRIORITY]
  94. [STRAIGHT_JOIN]
  95. [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
  96. [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
  97. select_expr [, select_expr ...]
  98. [FROM table_references
  99. [WHERE where_condition]
  100. [GROUP BY {col_name | expr | position}
  101. [ASC | DESC], ... [WITH ROLLUP]]
  102. [HAVING where_condition]
  103. [ORDER BY {col_name | expr | position}
  104. [ASC | DESC], ...]
  105. [LIMIT {[offset,] row_count | row_count OFFSET offset}]
  106. [PROCEDURE procedure_name(argument_list)]
  107. [INTO OUTFILE 'file_name'
  108. [CHARACTER SET charset_name]
  109. export_options
  110. | INTO DUMPFILE 'file_name'
  111. | INTO var_name [, var_name]]
  112. [FOR UPDATE | LOCK IN SHARE MODE]]
  113.  
  114. SELECT is used to retrieve rows selected from one or more tables, and can include UNION statements and subqueries. See Section 13.2.9.3, “UNION Syntax”, and Section 13.2.10, “Subquery Syntax”.
  115.  
  116. The most commonly used clauses of SELECT statements are these:
  117.  
  118. Each select_expr indicates a column that you want to retrieve. There must be at least one select_expr.
  119.  
  120. table_references indicates the table or tables from which to retrieve rows. Its syntax is described in Section 13.2.9.2, “JOIN Syntax”.
  121.  
  122. The WHERE clause, if given, indicates the condition or conditions that rows must satisfy to be selected. where_condition is an expression that evaluates to true for each row to be selected. The statement selects all rows if there is no WHERE clause.
  123.  
  124. In the WHERE expression, you can use any of the functions and operators that MySQL supports, except for aggregate (summary) functions. See Section 9.5, “Expression Syntax”, and Chapter 12, Functions and Operators.
  125.  
  126. SELECT can also be used to retrieve rows computed without reference to any table.
  127.  
  128. For example:
  129.  
  130. mysql> SELECT 1 + 1;
  131. -> 2
  132.  
  133. You are permitted to specify DUAL as a dummy table name in situations where no tables are referenced:
  134.  
  135. mysql> SELECT 1 + 1 FROM DUAL;
  136. -> 2
  137.  
  138. DUAL is purely for the convenience of people who require that all SELECT statements should have FROM and possibly other clauses. MySQL may ignore the clauses. MySQL does not require FROM DUAL if no tables are referenced.
  139.  
  140. In general, clauses used must be given in exactly the order shown in the syntax description. For example, a HAVING clause must come after any GROUP BY clause and before any ORDER BY clause. The exception is that the INTO clause can appear either as shown in the syntax description or immediately following the select_expr list. For more information about INTO, see Section 13.2.9.1, “SELECT ... INTO Syntax”.
  141.  
  142. The list of select_expr terms comprises the select list that indicates which columns to retrieve. Terms specify a column or expression or can use *-shorthand:
  143.  
  144. A select list consisting only of a single unqualified * can be used as shorthand to select all columns from all tables:
  145.  
  146. SELECT * FROM t1 INNER JOIN t2 ...
  147.  
  148. tbl_name.* can be used as a qualified shorthand to select all columns from the named table:
  149.  
  150. SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ...
  151.  
  152. Use of an unqualified * with other items in the select list may produce a parse error. To avoid this problem, use a qualified tbl_name.* reference
  153.  
  154. SELECT AVG(score), t1.* FROM t1 ...
  155.  
  156. The following list provides additional information about other SELECT clauses:
  157.  
  158. A select_expr can be given an alias using AS alias_name. The alias is used as the expression's column name and can be used in GROUP BY, ORDER BY, or HAVING clauses. For example:
  159.  
  160. SELECT CONCAT(last_name,', ',first_name) AS full_name
  161. FROM mytable ORDER BY full_name;
  162.  
  163. The AS keyword is optional when aliasing a select_expr with an identifier. The preceding example could have been written like this:
  164.  
  165. SELECT CONCAT(last_name,', ',first_name) full_name
  166. FROM mytable ORDER BY full_name;
  167.  
  168. However, because the AS is optional, a subtle problem can occur if you forget the comma between two select_expr expressions: MySQL interprets the second as an alias name. For example, in the following statement, columnb is treated as an alias name:
  169.  
  170. SELECT columna columnb FROM mytable;
  171.  
  172. For this reason, it is good practice to be in the habit of using AS explicitly when specifying column aliases.
  173.  
  174. It is not permissible to refer to a column alias in a WHERE clause, because the column value might not yet be determined when the WHERE clause is executed. See Section B.5.4.4, “Problems with Column Aliases”.
  175.  
  176. The FROM table_references clause indicates the table or tables from which to retrieve rows. If you name more than one table, you are performing a join. For information on join syntax, see Section 13.2.9.2, “JOIN Syntax”. For each table specified, you can optionally specify an alias.
  177.  
  178. tbl_name [[AS] alias] [index_hint]
  179.  
  180. The use of index hints provides the optimizer with information about how to choose indexes during query processing. For a description of the syntax for specifying these hints, see Section 8.9.3, “Index Hints”.
  181.  
  182. You can use SET max_seeks_for_key=value as an alternative way to force MySQL to prefer key scans instead of table scans. See Section 5.1.5, “Server System Variables”.
  183.  
  184. You can refer to a table within the default database as tbl_name, or as db_name.tbl_name to specify a database explicitly. You can refer to a column as col_name, tbl_name.col_name, or db_name.tbl_name.col_name. You need not specify a tbl_name or db_name.tbl_name prefix for a column reference unless the reference would be ambiguous. See Section 9.2.1, “Identifier Qualifiers”, for examples of ambiguity that require the more explicit column reference forms.
  185.  
  186. A table reference can be aliased using tbl_name AS alias_name or tbl_name alias_name:
  187.  
  188. SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
  189. WHERE t1.name = t2.name;
  190.  
  191. SELECT t1.name, t2.salary FROM employee t1, info t2
  192. WHERE t1.name = t2.name;
  193.  
  194. Columns selected for output can be referred to in ORDER BY and GROUP BY clauses using column names, column aliases, or column positions. Column positions are integers and begin with 1:
  195.  
  196. SELECT college, region, seed FROM tournament
  197. ORDER BY region, seed;
  198.  
  199. SELECT college, region AS r, seed AS s FROM tournament
  200. ORDER BY r, s;
  201.  
  202. SELECT college, region, seed FROM tournament
  203. ORDER BY 2, 3;
  204.  
  205. To sort in reverse order, add the DESC (descending) keyword to the name of the column in the ORDER BY clause that you are sorting by. The default is ascending order; this can be specified explicitly using the ASC keyword.
  206.  
  207. If ORDER BY occurs within a subquery and also is applied in the outer query, the outermost ORDER BY takes precedence. For example, results for the following statement are sorted in descending order, not ascending order:
  208.  
  209. (SELECT ... ORDER BY a) ORDER BY a DESC;
  210.  
  211. Use of column positions is deprecated because the syntax has been removed from the SQL standard.
  212.  
  213. If you use GROUP BY, output rows are sorted according to the GROUP BY columns as if you had an ORDER BY for the same columns. To avoid the overhead of sorting that GROUP BY produces, add ORDER BY NULL:
  214.  
  215. SELECT a, COUNT(b) FROM test_table GROUP BY a ORDER BY NULL;
  216.  
  217. Relying on implicit GROUP BY sorting (that is, sorting in the absence of ASC or DESC designators) is deprecated. To produce a given sort order, use explicit ASC or DESC designators for GROUP BY columns or provide an ORDER BY clause.
  218.  
  219. When you use ORDER BY or GROUP BY to sort a column in a SELECT, the server sorts values using only the initial number of bytes indicated by the max_sort_length system variable.
  220.  
  221. MySQL extends the GROUP BY clause so that you can also specify ASC and DESC after columns named in the clause:
  222.  
  223. SELECT a, COUNT(b) FROM test_table GROUP BY a DESC;
  224.  
  225. MySQL extends the use of GROUP BY to permit selecting fields that are not mentioned in the GROUP BY clause. If you are not getting the results that you expect from your query, please read the description of GROUP BY found in Section 12.16, “Aggregate (GROUP BY) Functions”.
  226.  
  227. GROUP BY permits a WITH ROLLUP modifier. See Section 12.16.2, “GROUP BY Modifiers”.
  228.  
  229. The HAVING clause is applied nearly last, just before items are sent to the client, with no optimization. (LIMIT is applied after HAVING.)
  230.  
  231. The SQL standard requires that HAVING must reference only columns in the GROUP BY clause or columns used in aggregate functions. However, MySQL supports an extension to this behavior, and permits HAVING to refer to columns in the SELECT list and columns in outer subqueries as well.
  232.  
  233. If the HAVING clause refers to a column that is ambiguous, a warning occurs. In the following statement, col2 is ambiguous because it is used as both an alias and a column name:
  234.  
  235. SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;
  236.  
  237. Preference is given to standard SQL behavior, so if a HAVING column name is used both in GROUP BY and as an aliased column in the output column list, preference is given to the column in the GROUP BY column.
  238.  
  239. Do not use HAVING for items that should be in the WHERE clause. For example, do not write the following:
  240.  
  241. SELECT col_name FROM tbl_name HAVING col_name > 0;
  242.  
  243. Write this instead:
  244.  
  245. SELECT col_name FROM tbl_name WHERE col_name > 0;
  246.  
  247. The HAVING clause can refer to aggregate functions, which the WHERE clause cannot:
  248.  
  249. SELECT user, MAX(salary) FROM users
  250. GROUP BY user HAVING MAX(salary) > 10;
  251.  
  252. (This did not work in some older versions of MySQL.)
  253.  
  254. MySQL permits duplicate column names. That is, there can be more than one select_expr with the same name. This is an extension to standard SQL. Because MySQL also permits GROUP BY and HAVING to refer to select_expr values, this can result in an ambiguity:
  255.  
  256. SELECT 12 AS a, a FROM t GROUP BY a;
  257.  
  258. In that statement, both columns have the name a. To ensure that the correct column is used for grouping, use different names for each select_expr.
  259.  
  260. MySQL resolves unqualified column or alias references in ORDER BY clauses by searching in the select_expr values, then in the columns of the tables in the FROM clause. For GROUP BY or HAVING clauses, it searches the FROM clause before searching in the select_expr values. (For GROUP BY and HAVING, this differs from the pre-MySQL 5.0 behavior that used the same rules as for ORDER BY.)
  261.  
  262. The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants, with these exceptions:
  263.  
  264. Within prepared statements, LIMIT parameters can be specified using ? placeholder markers.
  265.  
  266. Within stored programs, LIMIT parameters can be specified using integer-valued routine parameters or local variables as of MySQL 5.5.6.
  267.  
  268. With two arguments, the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1):
  269.  
  270. SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
  271.  
  272. To retrieve all rows from a certain offset up to the end of the result set, you can use some large number for the second parameter. This statement retrieves all rows from the 96th row to the last:
  273.  
  274. SELECT * FROM tbl LIMIT 95,18446744073709551615;
  275.  
  276. With one argument, the value specifies the number of rows to return from the beginning of the result set:
  277.  
  278. SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows
  279.  
  280. In other words, LIMIT row_count is equivalent to LIMIT 0, row_count.
  281.  
  282. For prepared statements, you can use placeholders. The following statements will return one row from the tbl table:
  283.  
  284. SET @a=1;
  285. PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?';
  286. EXECUTE STMT USING @a;
  287.  
  288. The following statements will return the second to sixth row from the tbl table:
  289.  
  290. SET @skip=1; SET @numrows=5;
  291. PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?, ?';
  292. EXECUTE STMT USING @skip, @numrows;
  293.  
  294. For compatibility with PostgreSQL, MySQL also supports the LIMIT row_count OFFSET offset syntax.
  295.  
  296. If LIMIT occurs within a subquery and also is applied in the outer query, the outermost LIMIT takes precedence. For example, the following statement produces two rows, not one:
  297.  
  298. (SELECT ... LIMIT 1) LIMIT 2;
  299.  
  300. A PROCEDURE clause names a procedure that should process the data in the result set. For an example, see Section 8.4.2.4, “Using PROCEDURE ANALYSE”, which describes ANALYSE, a procedure that can be used to obtain suggestions for optimal column data types that may help reduce table sizes.
  301.  
  302. A PROCEDURE clause is not permitted in a UNION statement.
  303.  
  304. The SELECT ... INTO form of SELECT enables the query result to be written to a file or stored in variables. For more information, see Section 13.2.9.1, “SELECT ... INTO Syntax”.
  305.  
  306. If you use FOR UPDATE with a storage engine that uses page or row locks, rows examined by the query are write-locked until the end of the current transaction. Using LOCK IN SHARE MODE sets a shared lock that permits other transactions to read the examined rows but not to update or delete them. See Section 14.8.2.4, “Locking Reads”.
  307.  
  308. Following the SELECT keyword, you can use a number of modifiers that affect the operation of the statement. HIGH_PRIORITY, STRAIGHT_JOIN, and modifiers beginning with SQL_ are MySQL extensions to standard SQL.
  309.  
  310. The ALL and DISTINCT modifiers specify whether duplicate rows should be returned. ALL (the default) specifies that all matching rows should be returned, including duplicates. DISTINCT specifies removal of duplicate rows from the result set. It is an error to specify both modifiers. DISTINCTROW is a synonym for DISTINCT.
  311.  
  312. HIGH_PRIORITY gives the SELECT higher priority than a statement that updates a table. You should use this only for queries that are very fast and must be done at once. A SELECT HIGH_PRIORITY query that is issued while the table is locked for reading runs even if there is an update statement waiting for the table to be free. This affects only storage engines that use only table-level locking (such as MyISAM, MEMORY, and MERGE).
  313.  
  314. HIGH_PRIORITY cannot be used with SELECT statements that are part of a UNION.
  315.  
  316. STRAIGHT_JOIN forces the optimizer to join the tables in the order in which they are listed in the FROM clause. You can use this to speed up a query if the optimizer joins the tables in nonoptimal order. STRAIGHT_JOIN also can be used in the table_references list. See Section 13.2.9.2, “JOIN Syntax”.
  317.  
  318. STRAIGHT_JOIN does not apply to any table that the optimizer treats as a const or system table. Such a table produces a single row, is read during the optimization phase of query execution, and references to its columns are replaced with the appropriate column values before query execution proceeds. These tables will appear first in the query plan displayed by EXPLAIN. See Section 8.8.1, “Optimizing Queries with EXPLAIN”. This exception may not apply to const or system tables that are used on the NULL-complemented side of an outer join (that is, the right-side table of a LEFT JOIN or the left-side table of a RIGHT JOIN.
  319.  
  320. SQL_BIG_RESULT or SQL_SMALL_RESULT can be used with GROUP BY or DISTINCT to tell the optimizer that the result set has many rows or is small, respectively. For SQL_BIG_RESULT, MySQL directly uses disk-based temporary tables if needed, and prefers sorting to using a temporary table with a key on the GROUP BY elements. For SQL_SMALL_RESULT, MySQL uses fast temporary tables to store the resulting table instead of using sorting. This should not normally be needed.
  321.  
  322. SQL_BUFFER_RESULT forces the result to be put into a temporary table. This helps MySQL free the table locks early and helps in cases where it takes a long time to send the result set to the client. This modifier can be used only for top-level SELECT statements, not for subqueries or following UNION.
  323.  
  324. SQL_CALC_FOUND_ROWS tells MySQL to calculate how many rows there would be in the result set, disregarding any LIMIT clause. The number of rows can then be retrieved with SELECT FOUND_ROWS(). See Section 12.14, “Information Functions”.
  325.  
  326. The SQL_CACHE and SQL_NO_CACHE modifiers affect caching of query results in the query cache (see Section 8.10.3, “The MySQL Query Cache”). SQL_CACHE tells MySQL to store the result in the query cache if it is cacheable and the value of the query_cache_type system variable is 2 or DEMAND. With SQL_NO_CACHE, the server does not use the query cache. It neither checks the query cache to see whether the result is already cached, nor does it cache the query result. (Due to a limitation in the parser, a space character must precede and follow the SQL_NO_CACHE keyword; a nonspace such as a newline causes the server to check the query cache to see whether the result is already cached.)
  327.  
  328. For views, SQL_NO_CACHE applies if it appears in any SELECT in the query. For a cacheable query, SQL_CACHE applies if it appears in the first SELECT of a view referred to by the query.
  329.  
  330. As of MySQL 5.5.3, these two modifiers are mutually exclusive and an error occurs if they are both specified. Also, these modifiers are not permitted in subqueries (including subqueries in the FROM clause), and SELECT statements in unions other than the first SELECT.
  331.  
  332. Before MySQL 5.5.3, for a query that uses UNION or subqueries, the following rules apply:
  333.  
  334. SQL_NO_CACHE applies if it appears in any SELECT in the query.
  335.  
  336. For a cacheable query, SQL_CACHE applies if it appears in the first SELECT of the query.
  337.  
  338. A SELECT from a partitioned table using a storage engine such as MyISAM that employs table-level locks locks all partitions of the table. This does not occur with tables using storage engines such as InnoDB that employ row-level locking. This issue is resolved in MySQL 5.6. For more information, see Section 19.5.4, “Partitioning and Table-Level Locking”.
  339.  
  340. PREV HOME UP NEXT
  341. User Comments
  342. Posted by Colin Nelson on February 26, 2003
  343. You can simulate a CROSSTAB by the following method:-
  344.  
  345. Use IF function to select the key value of the sub table as in:
  346.  
  347. SELECT
  348. SUM(IF(beta_idx=1, beta_value,0)) as beta1_value,
  349. SUM(IF(beta_idx=2, beta_value,0)) as beta2_value,
  350. SUM(IF(beta_idx=3, beta_value,0)) as beta3_value
  351. FROM alpha JOIN beta WHERE alpha_id = beta_alpha_id;
  352.  
  353. where alpha table has the form alpha_id, alpha_blah, alpha_blah_blah
  354. and beta table has the form beta_alpha_id, beta_other stuff,
  355. beta_idx, beta_value
  356.  
  357. This will create 3 columns with totals of beta values according to their idx field
  358. Posted by Corin Langosch on March 29, 2003
  359. when selecting a single random row you have to use a query like this: SELECT ... FROM my_table ORDER BY RAND() LIMIT 1.
  360. 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.
  361. couldn't this be optimized?!
  362. if not, may be add a syntax like SELECT RANDOM_ROW .... FROM my_table ...
  363. Posted by David Phillips on April 2, 2003
  364. This method of selecting a random row should be fast:
  365.  
  366. LOCK TABLES foo READ;
  367. SELECT FLOOR(RAND() * COUNT(*)) AS rand_row FROM foo;
  368. SELECT * FROM foo LIMIT $rand_row, 1;
  369. UNLOCK TABLES;
  370.  
  371. Unfortunately, variables cannot be used in the LIMIT clause, otherwise the entire thing could be done completely in SQL.
  372. Posted by on August 20, 2003
  373. In reply to David Philips:
  374.  
  375. If your tables are not all that big, a simpler method is:
  376. SELECT * FROM foo ORDER BY RAND(NOW()) LIMIT 1;
  377.  
  378. If it's a big table, your method will almost certainly be faster.
  379.  
  380. Posted by Count Henry De Havilland-Fortesque-Smedley on January 13, 2004
  381. If you want to find duplicates on a field that hasn't been uniquely indexed, you can do this:
  382.  
  383. SELECT BookISBN, count(BookISBN) FROM Books GROUP BY BookISBN HAVING COUNT(BookISBN)>1;
  384.  
  385. Posted by Count Henry De Havilland-Fortesque-Smedley on January 13, 2004
  386. Sometimes you want to retrieve the records that DONT match a select statement.
  387.  
  388. Consider this select:
  389. SELECT CarIndex FROM DealerCatalog, BigCatalog WHERE
  390. DealerCatalog.CarIndex=BigCatalog.CarIndex
  391.  
  392. This finds all the CarIndex values in the Dealer's catalog that are in the bigger distributor catalog.
  393.  
  394. How do I then find the dealer CarIndex values that ARE NOT in the bigger catalog?
  395.  
  396. The answer is to use LEFT JOIN - anything that doesn't join is given a NULL value , so we look for that:
  397.  
  398. SELECT CarIndex FROM DealerCatalog LEFT JOIN BigCatalog ON DealerCatalog.CarIndex=BigCatalog.CarIndex WHERE BigCatalog.CarIndex IS NULL
  399. Posted by Johann Eckert on February 11, 2004
  400. To find double entries in a table:
  401.  
  402. SELECT db1.*
  403. FROM tbl_data db1, tbl_data k2
  404. WHERE db1.id <> db2.id
  405. AND db1.name = db2.name
  406.  
  407. db1.id must be the PK
  408. db1.name must be the fields that should be verified as double entries.
  409.  
  410. (I'm not sure wether the code is correct but in my case it works)
  411.  
  412. Johann
  413. Posted by on March 2, 2004
  414. In order to anti-match fields by wildcards, one has to check whether the value of the field is not NULL:
  415.  
  416. For example: The table 'runs' contains 34876 rows. 205 rows have an 'info' field containing the string 'wrong'.
  417.  
  418. To select those rows for which the 'info' column does *NOT* contain the word 'wrong' one has to do:
  419.  
  420. mysql> select count(*) FROM runs WHERE info is null or info not like '%wrong%';
  421.  
  422. +----------+
  423. | count(*) |
  424. +----------+
  425. | 34671 |
  426. +----------+
  427.  
  428. but not:
  429. mysql> select count(*) FROM runs WHERE info not like %wrong%';
  430.  
  431. +----------+
  432. | count(*) |
  433. +----------+
  434. | 5537 |
  435. +----------+
  436.  
  437. which would lead to a much smaller number of selected rows.
  438. Posted by M M on March 4, 2004
  439. I have managed to select random records using php and MySQL like the following:
  440.  
  441. $min=1;
  442. $row=mysql_fetch_assoc(mysql_query("SHOW TABLE STATUS LIKE 'table';"));
  443. $max=$row["Auto_increment"];
  444.  
  445. $random_id=rand($min,$max);
  446. $row=mysql_fetch_assoc(mysql_query("SELECT * FROM table WHERE id='$random_id'");
  447.  
  448. Voila...
  449.  
  450. Cezar
  451. http://RO-Escorts.com
  452. Posted by Geert van der Ploeg on March 9, 2004
  453. Random records without PHP, only MySQL:
  454.  
  455. select * from mailinglists order by rand() limit 1
  456.  
  457. Regards,
  458. Geert van der Ploeg
  459. Posted by Cody Caughlan on May 26, 2004
  460. Sometimes it is nice to use the SELECT query options like SQL_CALC_FOUND_ROWS or SQL_CACHE, but to maintain compatibility across different databases or even older versions of MySQL which do not support those options, it is possible to enclose them in a comment block, e.g.:
  461.  
  462. SELECT /*! 40000 SQL_CALC_FOUND_ROWS */ foo,bar FROM some_table;
  463.  
  464. The /* construct will stop DBMS's other than MySQL from parsing the comment contents, while /*! will tell ALL MySQL versions to parse the "comment" (which is actually a non-comment to MySQL). The /*!40000 construct will tell MySQL servers starting from 4.0.0 (which is the first version to support SQL_CALC_FOUND_ROWS) to parse the comment, while earlier versions will ignore it.
  465. Posted by Boris Aranovich on June 9, 2004
  466. I am using this way to select random row or rows:
  467.  
  468. SELECT * [or any needed fileds], idx*0+RAND() as rnd_id FROM tablename ORDER BY rnd_id LIMIT 1 [or the number of rows]
  469.  
  470. Meanwhile, I didn't stumble in any problems with this usage.
  471. I picked this method in some forum, don't remember when, where or by who was it introduced :)
  472. Posted by Michal Nedoszytko on August 10, 2004
  473. My method of retrieving duplicate entries
  474.  
  475. In a database with personal information (name, surname, etc..) with an auto_increment index I wanted to retrieve all the entries with same name and surname field (duplicate names), which by accident were inserted to the base.
  476.  
  477. I used this syntax
  478.  
  479. SELECT name,surname,COUNT(name) AS cnt_n, COUNT(surname) AS cnt_s FROM the_table GROUP BY name HAVING cnt_n>1 AND cnt_s>1;
  480.  
  481. I hope this might be of help to anyone that wants to do some extended maintenance on the database
  482. Posted by Dmitri Mikhailov on August 24, 2004
  483. On the other hand, for this case it's simplier to engage an appropriate index if there is such:
  484.  
  485. CREATE INDEX ccr_news_insert_date_i ON ccr_news (insert_date DESC);
  486.  
  487. SELECT *
  488. FROM ccr_news
  489. WHERE insert_date > 0;
  490.  
  491. or, if for some reason MySQL still uses a full table scan:
  492.  
  493. SELECT *
  494. FROM ccr_news FORCE INDEX (ccr_news_insert_date_i)
  495. WHERE insert_date > 0;
  496.  
  497. Posted by Adam Tylmad on August 25, 2004
  498. If you want to ORDER BY [columnname] ASC
  499. and have the NULL rows in the bottom
  500. you can use ORDER BY -[columnname] DESC
  501. Posted by Edward Hermanson on October 6, 2004
  502. Select Name,Category FROM authors ORDER BY Category,Name;
  503.  
  504. Will allow you to sort by categories listed in a seperate table
  505. IF the category column in this primary table contains ID values
  506. from your ID column in your second reference table.
  507.  
  508. So your first "authors" table looks like:
  509.  
  510. id name category
  511. 1 Henry Miller 2
  512. 3 June Day 1
  513. 3 Thomas Wolf 2
  514.  
  515. and your second reference table looks like:
  516.  
  517. id category
  518. 1 Modern
  519. 2 Classics
  520.  
  521. Now when the order of categories is changed in the second table
  522. the order of categories will be reflected in the primary table.
  523.  
  524. Then just select the categories from the reference table and put
  525. the list into a numbered array. Then in your script when you run
  526. across a category number from the first recordset just reference
  527. the value from the index in the second array to obtain the value.
  528. In php in the above example it might look like:
  529.  
  530. foreach ($recordset as $key => $record) {
  531. echo $record["id"] . ":" . $record["name"] . ":" . $ordered_cats[$record["category"]];
  532. }
  533.  
  534. This may seem obvious to some but I was pulling my hair out
  535. trying to figure out how to order a recordset based on a list
  536. from a different table. Hope this helps someone.
  537.  
  538. Ed
  539. Posted by Greg Covey on December 2, 2004
  540. The LIMIT clause can be used when you would use TOP in Access or MS SQL.
  541. Posted by Kenan Bektas on December 14, 2004
  542. (LINUX) By default, if you don't specify absolute path for OUTFILE in
  543. select ... into OUTFILE "..."
  544.  
  545. It creates the file in "/var/lib/mysql/<database_name>"
  546.  
  547. Make sure current user has (NOT) a write permission in that directory.
  548. Posted by Kumar S on January 4, 2005
  549. If You want to find the rows which are having a column with identical values then,
  550.  
  551. SELECT managerId, count(company) FROM manager GROUP BY company HAVING COUNT(company)>=8 (say)
  552.  
  553. Regards,
  554. Kumar.S
  555. Posted by Imran Chaudhry on February 17, 2005
  556. I found a nifty way of influencing the ORDER of rows returned by a query that helps in displaying a list with frequently accessed items at the top.
  557.  
  558. An example is a name/address form where the country is a selectable list. If most of your users are from the UK and US you may want to do something like:
  559.  
  560. SELECT * FROM countries ORDER by iso_code IN ('UK', 'US') desc
  561.  
  562. Which returns something like:
  563.  
  564. +----------+----------------------------------------+
  565. | iso_code | name |
  566. +----------+----------------------------------------+
  567. | UK | United Kingdom |
  568. | US | United States |
  569. | AF | Afghanistan |
  570. | AL | Albania |
  571. | DZ | Algeria |
  572. | AS | American Samoa |
  573.  
  574. Hope this helps someone! megazoid@hotmail.com
  575. Posted by Fahed Bizzari on February 22, 2005
  576. It seems there is no way to select * from table where a certain field is distinct. In 2 sqls it is easy:
  577.  
  578. $sql9 = "SELECT DISTINCT field AS distinctfield FROM table ORDER BY distinctfield ";
  579. $res9= $db->execute($sql9);
  580. for($ll=0;$ll<$res9->getNumTuples();$ll++)
  581. {
  582. $row = $res9->getTupleDirect($ll);
  583. $distinctfield = $row[distinctfield];
  584. $sql8="select * from table WHERE field='distinctfield' ORDER BY distinctfield LIMIT 1";
  585. }
  586.  
  587. But not one!
  588.  
  589. Fahed
  590. Posted by M Berman on February 22, 2005
  591. reply to Fahed Bizzari's post, based on Havilland-Fortesque-Smedley's comment (above) the equivalent of select * while doing DISTINCT is:
  592.  
  593. select *, count(FIELD) from TABLE group by FIELD having count(FIELD)=1 into outfile 'foobar.txt';
  594.  
  595. then you can check the output. note that there are twice as many rows as records, because each unique row is followed by its count (in this case count=1). so just toss the .txt file into something and sort on the field containing the count and throw out all the rows =1. this is the same result as a select * distinct FIELD (as far as I can tell).
  596.  
  597. anyway, works for me. aloha. Lex
  598. Posted by M Berman on February 22, 2005
  599. oh, about the previous post, it's not correct because distinct should be
  600.  
  601. count(FIELD)=>1
  602.  
  603. which still doesn't solve the DISTINCT part
  604.  
  605. Lex
  606. Posted by Gregory Turner on March 10, 2005
  607. In regards to:
  608. _______________________________________________
  609. ******************************************
  610. I found a nifty way of influencing the ORDER of rows returned by a query that helps in displaying a list with frequently accessed items at the top.
  611.  
  612. An example is a name/address form where the country is a selectable list. If most of your users are from the UK and US you may want to do something like:
  613.  
  614. SELECT * FROM countries ORDER by iso_code IN ('UK', 'US') desc
  615.  
  616. Which returns something like:
  617.  
  618. +----------+----------------------------------------+
  619. | iso_code | name |
  620. +----------+----------------------------------------+
  621. | UK | United Kingdom |
  622. | US | United States |
  623. | AF | Afghanistan |
  624. | AL | Albania |
  625. | DZ | Algeria |
  626. | AS | American Samoa |
  627.  
  628. _______________________________________________
  629. ******************************************
  630. If found that if you also add in another 'iso_code' column in the order by statment after the first one containing the IN() statment, it will sort the remaining records:
  631. SELECT * FROM countries ORDER by iso_code IN ('UK', 'US') desc, iso_code
  632. Posted by Heywood on March 11, 2005
  633. When using the SELECT ... INTO OUTFILE syntax, use a UNION to add headers. Here's an example for CSV output:
  634.  
  635. SELECT 'Fiscal Year','Location','Sales'
  636. UNION
  637. SELECT FY, Loc, Sales INTO OUTFILE 'salesreport.csv'
  638. FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  639. FROM SalesTable;
  640.  
  641. This will add the text headers Fiscal Year, Location and Sales to your fields. Only caveat is with an ORDER BY statement, if you don't want your headers sorted along with your data you need to enclose it in parenthesis:
  642.  
  643. SELECT 'Fiscal Year','Location','Sales'
  644. UNION
  645. {SELECT FY, Loc, Sales INTO OUTFILE 'salesreport.csv'
  646. FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  647. FROM SalesTable
  648. ORDER BY Sales DESC);
  649.  
  650. Posted by on April 21, 2005
  651. To correct Lex one more time, it should be count(FIELD)>=1.
  652.  
  653. So the whole query for retrieving a whole row with one field distinct is:
  654.  
  655. select *, count(FIELD) from TABLE group by FIELD having count(FIELD)>=1;
  656.  
  657. Thanks, Lex. You are a lifesaver.
  658. Posted by Jerry Nelson on May 6, 2005
  659. As a newbie to MySQL and to dealing with BLOBs, I had a difficult time trying to determine how to extract a BLOB field from the database back to a file. It turns out to be quite simple by doing the following SQL:
  660.  
  661. select blobfield into dumpfile '/tmp/blobfile' from blobtable;
  662. Posted by joel boonstra on May 12, 2005
  663. In response to Heywood's tip about adding column headers to OUTFILEs...
  664.  
  665. Make sure that the format of the columns that match up with your headers doesn't limit the display of the headers. For instance, I was using the UNION tip to add a header to a column defined as char(2) (for storing a two-letter state code). The resulting CSV file only displayed the first two letters of my column header. The fix is simple, just use CAST() on the column in the second SELECT to convert it to the appropriate type. In my case, doing something like this:
  666.  
  667. SELECT 'state header' FROM table UNION SELECT CAST(state AS char) FROM table INTO OUTFILE [...]
  668.  
  669. worked just dandy. Hope that saves someone a little time.
  670. Posted by Rene Liethof on June 8, 2005
  671. Arbitrary Ordering
  672.  
  673. I came across this example at
  674. http://www.shawnolson.net/a/722/
  675. Neat way of using the CASE statement.
  676.  
  677. Example for ordering price information
  678. price is orderd ascending but the 0.00
  679. prices end up underneath
  680.  
  681. SELECT dienst.dienst, dienst.url, dienst.info, dienst_prijs.dienst_eenheid, dienst_prijs.prijs, dienst_prijs.inc_btw, dienst_prijs.dienst_optie,
  682. CASE dienst_prijs.prijs
  683. WHEN dienst_prijs.prijs = '0.00' THEN 1000
  684. WHEN dienst_prijs.prijs > '0.00' THEN 10
  685. ELSE NULL
  686. END AS orderme
  687. FROM dienst, dienst_prijs
  688. WHERE dienst.taal = 'nl' &&
  689. dienst.dienst_type = 'Internet toegang' &&
  690. dienst.dienst != 'alle diensten' &&
  691. dienst.publiceer != '' &&
  692. dienst_prijs.dienst_eenheid IN ( 'maand', 'jaar' ) &&
  693. dienst.dienst = dienst_prijs.dienst
  694. ORDER BY orderme, dienst_prijs.prijs
  695.  
  696. Posted by Callum Macdonald on June 27, 2005
  697. If you want to use ORDER BY before GROUP BY, the only way I've found to achieve it is with a subquery.
  698.  
  699. For example, if you want to get a list of users from a table UserActions sorted according to the most recent action (based on a field called Time) the query would be:
  700.  
  701. SELECT * FROM (SELECT * FROM UserActions ORDER BY Time DESC) AS Actions GROUP BY UserID ORDER BY Time DESC;
  702.  
  703. Without the subquery, the group is performed first, and so the first record that appears in the database (which is not necessarily in the order you want) will be used to determine the sort order. This caused me huge problems as my data was in a jumbled order within the table.
  704.  
  705. --Edit--
  706. This same result can be achieved with the use of MAX(Time), so the query would be:
  707.  
  708. SELECT *, MAX(Time) AS LatestAction GROUP BY UserID ORDER BY LatestAction DESC;
  709.  
  710. As far as I can see, the subquery model still holds up if you need more complex sorting before performing the GROUP.
  711. Posted by Paul Montgomery on August 13, 2005
  712. I've seen it asked elsewhere about how to select all duplicates, not just one row for each dupe.
  713.  
  714. CREATE TEMPORARY TABLE dupes SELECT * FROM tablename GROUP BY colname HAVING COUNT(*)>1 ORDER BY colname;
  715. SELECT t.* FROM tablename t, dupes d WHERE t.colname = d.colname ORDER BY t.colname;
  716. Posted by Wayne Smith on November 4, 2005
  717. Be careful about the "SELECT...INTO OUTFILE" options. They are similar to, but not exactly the same as, the mysqldump options.
  718.  
  719. Two things:
  720.  
  721. 1) The options in mysqldump can be in any order, because they are true command-line options (that is, they are conceptually used together, but syntactically separate on the mysqldump command line). The options in the SELECT...INTO OUTFILE need to be in the exact order as specified in the documentation above.
  722.  
  723. 2) The options MUST have dashes between the words (e.g., fields-enclosed-by) when use as options with the mysqldump utility, but MUST NOT have dashes when used as options with the SELECT...INTO OUTFILE. This may not be clear in the documentation above.
  724.  
  725. Wayne
  726.  
  727. Posted by Geoff on November 9, 2005
  728. In reply to Fahed Bizzari et al...
  729.  
  730. If you want to select all fields from distinct rows why not use:
  731. SELECT DISTINCT * FROM table GROUP BY field;
  732.  
  733. Don't forget the DISTINCT relates to the ORDER BY / GROUP BY and has nothing to do with the 'select_expr'
  734.  
  735. If you want the count as well then use:
  736. SELECT DISTINCT *, count(*) AS count FROM table GROUP BY field;
  737.  
  738. Posted by Kumar Mitra-Endres on November 22, 2005
  739. Where is the pagination code as offered by the google search machine????
  740.  
  741. Kumar/Germany
  742.  
  743. Posted by Flavio Ventura on December 9, 2005
  744. If you have a binary string type field and you want a case insensitive sorting you can use CAST() as follow:
  745.  
  746. case sensitive example (DECODE return a binary string):
  747. ----------------------------------------------------------------------------
  748. SELECT DECODE(EncodedField) AS DecodedField
  749. FROM TableWithEncodedField
  750. ORDER BY DecodedField;
  751.  
  752. case insensitive solution:
  753. ---------------------------------
  754. SELECT CAST(DECODE(EncodedField) AS CHAR) AS DecodedField
  755. FROM TableWithEncodedField
  756. ORDER BY DecodedField;
  757.  
  758. I hope it may be usefull.
  759. Posted by mike gieson on January 10, 2006
  760. To select specific rows from the table use the IN statement.
  761.  
  762. Example:
  763.  
  764. SELECT * FROM table WHERE myid IN (2, 16, 93,102);
  765.  
  766. This would return multiple rows based on specific criteria.
  767. Posted by Todd Farmer on January 22, 2006
  768. For large tables with auto incremented primary key values, I have found the following to be most efficient in obtaining one random row:
  769.  
  770. SELECT * FROM my_table
  771. WHERE pk_column >=
  772. (SELECT FLOOR( MAX(pk_column) * RAND()) FROM my_table)
  773. ORDER BY pk_column
  774. LIMIT 1;
  775. Posted by Vlado Kocan on January 28, 2006
  776. Reply to Edward Hermanson post (above):
  777.  
  778. I prefer this way of sorting table by column values listed in another table:
  779.  
  780. The accnumber column in primary table contains ID values from ID column in the secondary table.
  781.  
  782. Primary table "contacts":
  783. id name accnumber
  784. 1 Cooke 3
  785. 2 Peterson 3
  786. 3 Stevens 1
  787.  
  788. Secondary table "accounts":
  789. id accname
  790. 1 Company1
  791. 2 Company2
  792. 3 Company3
  793.  
  794. SELECT contacts.lname, accounts.accname
  795. FROM contacts, accounts
  796. WHERE contacts.accnumber = accounts.id ORDER BY accname;
  797. Posted by Lars-Erik Hoffsten on March 14, 2006
  798. ORDER BY textfield in natural order!?
  799. Lets say you want the following result:
  800. File1
  801. File2
  802. File10
  803.  
  804. I havn't found a way to do it in SQL, here is a way to do it in PHP (just replace 'order_by' to the field you want to order by):
  805.  
  806. $result = mysql_query("SELECT order_by,... FROM table");
  807. $rows = array();
  808. if($result)
  809. {
  810. while(($row = mysql_fetch_array($result, MYSQL_ASSOC)))
  811. $rows[] = $row;
  812. usort($rows, create_function('$a, $b', 'return strnatcasecmp($a["order_by"], $b["order_by"]);'));
  813. }
  814.  
  815. Posted by Michal Carson on March 19, 2006
  816. SELECT ... INTO OUTFILE requires the id to have the FILE privilege. That is,
  817.  
  818. GRANT SELECT, FILE ON * . * TO "[whomever]"@ "localhost";
  819.  
  820. As noted above, the output directory must be writable by the id under which the mysqld process is running. Use "grep user= /etc/my.cnf " to find it.
  821.  
  822. Posted by Andrew Culver on March 20, 2006
  823. Selecting a random row in SQL? Try:
  824.  
  825. set @a = (SELECT COUNT(*)-1 c FROM palette)*RAND() DIV 1;
  826. PREPARE STMT FROM 'SELECT * FROM palette LIMIT ?,1';
  827. EXECUTE STMT USING @a;
  828. Posted by on March 21, 2006
  829. If you want to keep field names, consider using mysqldump instead of SELECT INTO OUTFILE.
  830.  
  831. I use this method to transfer small amounts of data from our live database to our test database, for example when investigating a reported problem in our program code. (We cannot guarantee the field order across all our databases.)
  832.  
  833. rem Edit order number before running
  834. rem Give password when prompted
  835. rem Result files will be in current working directory
  836. \mysql\bin\mysqldump livedb -uliveuser -p --no-create-info --tables orderpayment --where=orderid=2712>resultp.txt
  837. \mysql\bin\mysqldump livedb -uliveuser -p --no-create-info --tables orderitem --where=orderid=2712>resulti.txt
  838. \mysql\bin\mysqldump livedb -uliveuser -p --no-create-info --tables orderheader --where=id=2712>resulth.txt
  839.  
  840. Posted by Zhao Xinyou on March 29, 2006
  841. when you meet more conditions, you may use the following code:
  842. select * from yourdatabase where fieldone='value1' and fieldtwo='value2';
  843. Posted by John Bachir on April 3, 2006
  844. Fahed Bizzari, that is not 2 queries, that is $res9->getNumTuples() + 1 queries!
  845. Posted by Michael Heyman on April 28, 2006
  846. To select the identifiers with the greatest value in each class (where each identifier falls into one class):
  847.  
  848. SELECT id_class,id FROM tbl,(SELECT MAX(val) AS val FROM tbl GROUP BY id_class) AS _tbl WHERE tbl.val = _tbl.val;
  849.  
  850. We had a table logging state changes for a series of objects and wanted to find the most recent state for each object. The "val" in our case was an auto-increment field.
  851.  
  852. This seems to be the simplest solution that runs in a reasonable amount of time.
  853. Posted by Rich Altmaier on May 4, 2006
  854. In a student signup list, use sql to find classes which are
  855. not full. Involves combined use of RIGHT JOIN, COUNT, WHERE, GROUP BY, HAVING, and ORDER BY.
  856.  
  857. CREATE TABLE `classdescription` (
  858. `ClassID` mediumint(9) NOT NULL auto_increment,
  859. `ClassType` varchar(10) NOT NULL default '',
  860. `ClassName` varchar(50) NOT NULL default '',
  861. `ClassDate` datetime NOT NULL default '0000-00-00 00:00:00',
  862. `ClassMax` mediumint(9) default NULL,
  863. PRIMARY KEY (`ClassID`)
  864. ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
  865.  
  866. CREATE TABLE `class_signups` (
  867. `s_PersonID` mediumint(9) NOT NULL default '0',
  868. `s_ClassID` mediumint(9) NOT NULL default '0',
  869. `s_Status` varchar(5) default NULL,
  870. KEY `s_ClassID` (`s_ClassID`),
  871. KEY `s_PersonID` (`s_PersonID`)
  872. ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
  873.  
  874. INSERT INTO `classdescription` VALUES (2, 'firstaid', '', '2005-01-02 11:00:00', 2);
  875. INSERT INTO `classdescription` VALUES (3, 'advanced-med', '', '2005-01-02 13:00:00', 1);
  876.  
  877. INSERT INTO `class_signups` VALUES (11, 2, '');
  878. INSERT INTO `class_signups` VALUES (12, 2, '');
  879.  
  880. Now use RIGHT JOIN to list all class descriptions along with signups if any,
  881. SELECT cs.s_ClassID, cs.s_PersonID, cd.ClassName, cd.ClassID, cd.ClassType, cd.ClassDate, cd.ClassMax
  882. from class_signups cs RIGHT JOIN
  883. classdescription cd on (cs.s_ClassID = cd.ClassID )
  884. in itself, not too useful, but you can see classes
  885. having no one signed up as a NULL.
  886.  
  887. To count the number of signups for each class:
  888. SELECT cs.s_ClassID, COUNT(s_ClassID) AS ClassTotal, cd.ClassName, cd.ClassID, cd.ClassType, cd.ClassDate, cd.ClassMax
  889. from class_signups cs RIGHT JOIN
  890. classdescription cd on (cs.s_ClassID = cd.ClassID )
  891. GROUP BY cd.ClassID
  892. The COUNT/GROUP BY options show a row per unique ClassID, and the COUNT is adding up
  893. non-null occurances of field s_ClassID. If we had used COUNT(*) then the class with
  894. no signups would have counted 1 record, rather than the desired 0/NULL for no
  895. signups.
  896.  
  897. Now we show only classes where the count of signups is less than ClassMax, meaning the
  898. class has openings!
  899. SELECT cs.s_ClassID, COUNT(s_ClassID) AS ClassTotal, cd.ClassName, cd.ClassID, cd.ClassType, cd.ClassDate, cd.ClassMax
  900. from class_signups cs RIGHT JOIN
  901. classdescription cd on (cs.s_ClassID = cd.ClassID )
  902. GROUP BY cd.ClassID
  903. HAVING ClassTotal < cd.ClassMax
  904. The HAVING clause limits the after-JOIN output rows to ones matching its criteria, discarding others!
  905.  
  906. We may want to look only at the firstaid ClassType, so add a WHERE clause to
  907. the JOIN,
  908. SELECT cs.s_ClassID, COUNT(s_ClassID) AS ClassTotal, cd.ClassName, cd.ClassID, cd.ClassType, cd.ClassDate, cd.ClassMax
  909. from class_signups cs RIGHT JOIN
  910. classdescription cd on (cs.s_ClassID = cd.ClassID ) WHERE cd.ClassType='firstaid'
  911. GROUP BY cd.ClassID
  912. HAVING ClassTotal < cd.ClassMax
  913. Now there are no outputs as firstaid is full, but
  914. suppose we are looking in this list with respect
  915. to a certain student PersonID==12. That is, we want to see classes this person can signup
  916. for, including the ones they are already in!
  917. In the case we need to disregard signups by PersonID==12 for e.g.,
  918.  
  919. SELECT cs.s_ClassID, COUNT(s_ClassID) AS ClassTotal, cd.ClassName, cd.ClassID, cd.ClassType, cd.ClassDate, cd.ClassMax
  920. from class_signups cs RIGHT JOIN
  921. classdescription cd on (cs.s_ClassID = cd.ClassID AND cs.s_PersonID <> 12) WHERE cd.ClassType='firstaid'
  922. GROUP BY cd.ClassID
  923. HAVING ClassTotal < cd.ClassMax
  924. In the join we drop out signups of PersonID 12, so they don't get counted.
  925.  
  926. Finally we probably want to show the available classes in date order:
  927.  
  928. SELECT cs.s_ClassID, COUNT(s_ClassID) AS ClassTotal , cd.ClassName, cd.ClassID, cd.ClassType, cd.ClassDate, cd.ClassMax
  929. from class_signups cs RIGHT JOIN
  930. classdescription cd on (cs.s_ClassID = cd.ClassID AND cs.s_PersonID <> 12)
  931. WHERE cd.ClassType='firstaid'
  932. GROUP BY cd.ClassID
  933. HAVING ClassTotal < cd.ClassMax ORDER BY ClassDate
  934.  
  935. I had fun figuring this out, I hope it works for you.
  936. (sorry it was so long).
  937. Rich
  938.  
  939. Posted by YI ZHANG on May 10, 2006
  940. If you cancel a long-time running query by Ctrl-C, you might find the CPU load of mysqld remains at 99%. That's because the query is still running on mysqld, and Ctrl-C only closes the client.
  941. Now, you can enter mysql again and use command SHOW PROCESSLIST to check the thread of the query, and kill the query by command KILL thread_id.
  942. I'm using mysql 5.0.21.
  943. Posted by Wade Bowmer on May 14, 2006
  944. Be aware that SQL_CALC_FOUND_ROWS disables ORDER BY ... LIMIT optimizations (see bugs http://bugs.mysql.com/bug.php?id=18454 and http://bugs.mysql.com/bug.php?id=19553). Until it's fixed, you should run your own benchmarks with and without it.
  945.  
  946. Posted by Marc Grue on June 24, 2006
  947. Since the LIMIT clause of a SELECT statement doesn't allow user variables you can use a prepared statement as in the example above in the manual. An alternative is to load all record ids of yourTable into a temporary table as shown below. This also has the benefit of getting all data necessary for pagination of your result set:
  948.  
  949. CREATE PROCEDURE `listData`(IN _limitstart INT, IN _limit INT)
  950. BEGIN
  951. -- make a 'row container'
  952. DROP TEMPORARY TABLE IF EXISTS AllRows;
  953. CREATE TEMPORARY TABLE AllRows (rownum INT, id INT, label VARCHAR(50)) ENGINE=MEMORY;
  954.  
  955. -- insert all ids (and optional labels (for use in a page selector))
  956. SET @a=-1;
  957. INSERT INTO AllRows SELECT @a:=@a+1 AS rownum, id, CONCAT(first_name, ' ', last_name) AS label FROM yourTable;
  958.  
  959. ## Output 1: total number of rows
  960. SELECT @a+1 AS total_rows;
  961.  
  962. ## Output 2: id/labels for pagination [see table 'NumberSeq' below]
  963. SELECT * FROM AllRows
  964. INNER JOIN NumberSeq ON AllRows.rownum = NumberSeq.n*_limit
  965. WHERE (n*_limit) < @a+1;
  966.  
  967. ## Output 3: data for list
  968. SELECT yourTable.* FROM yourTable
  969. INNER JOIN AllRows ON yourTable.id = AllRows.id
  970. WHERE rownum >= _limitstart AND rownum < (_limitstart+_limit);
  971.  
  972. DROP TEMPORARY TABLE AllRows;
  973. END
  974.  
  975. The NumberSeq table just contains the numbers 0, 1, 2, 3, ... 500 (or whatever limit you want to set on number of pages..):
  976.  
  977. CREATE PROCEDURE `createNumberSeq `()
  978. BEGIN
  979. DECLARE _n int default -1;
  980. DROP TABLE IF EXISTS NumberSeq;
  981. CREATE TABLE NumberSeq (n INT);
  982. loop1: LOOP
  983. SET _n = _n + 1;
  984. INSERT INTO NumberSeq (n) VALUES _n;
  985. IF _n >= 500 THEN
  986. LEAVE loop1;
  987. END IF
  988. END LOOP loop1;
  989. END
  990.  
  991. With smaller record sets the second approach is faster than the prepared statement approach. Haven't checked speed with bigger record sets, but suspect the first approach will win then...
  992.  
  993. Hope this helps to get around the limitations of the LIMIT clause. To the MySQL team: any plans to allow user variables in the LIMIT clause? (pleeeze!)
  994. Posted by Rene Lopez on June 23, 2006
  995. If you want to get the record in an specific order you can do it like this
  996.  
  997. SELECT * FROM table ORDER BY FIELD( id, 23, 234, 543, 23 )
  998.  
  999. +----------+---------------------------+
  1000. | id | name |
  1001. +----------+---------------------------+
  1002. | 23 | rene |
  1003. | 234 | miguel |
  1004. | 543 | ana |
  1005. | 23 | tlaxcala |
  1006.  
  1007. or if the table as a name
  1008.  
  1009. SELECT * FROM table ORDER BY FIELD( name, 'miguel', 'rene', 'ana', 'tlaxcala' )
  1010.  
  1011. +----------+---------------------------+
  1012. | id | name |
  1013. +----------+---------------------------+
  1014. | 234 | miguel |
  1015. | 23 | rene |
  1016. | 543 | ana |
  1017. | 23 | tlaxcala |
  1018.  
  1019. Posted by Marc Grue on June 24, 2006
  1020. Example of using dynamic column_name parameters in the ORDER BY clause of a SELECT statement in stored procedures:
  1021. http://dev.mysql.com/doc/refman/5.1/en/control-flow-functions.html
  1022. (go to posting by Marc Grue on June 24 2006)
  1023. Posted by Dennis Lindkvist on June 28, 2006
  1024. Or you could use this.
  1025.  
  1026. select [column], rand() as rnd from [table] order by rnd
  1027.  
  1028. Althoug there is still overhead compared to "order by null" its not as bad as "order by rand()".
  1029. Posted by Chris Whitten on July 14, 2006
  1030. I was trying to figure out how to sort a varchar field which contained both number string and alphanumeric string. I wanted to sort it so that the numbers would be in order and then the alphanumeric entries would be in order. Here is the query that helped me accomplish that:
  1031.  
  1032. SELECT partnum, comments , if( partnum >0, cast( partnum AS SIGNED ) , 0 ) AS numpart,
  1033. if( partnum >0, 0, partnum ) AS stringpart
  1034. FROM `part`
  1035. ORDER BY `numpart` , `stringpart`
  1036. Posted by Frank Flynn on October 6, 2006
  1037. If you wish to use OUTFILE or DUMPFILE with a variable for the file name you cannot simply put it in place - MySQL will not resolve the name.
  1038.  
  1039. But you can put the whole command into a variable and use "prepare" and "execute" for example:
  1040.  
  1041. SELECT @myCommand := concat("SELECT * into OUTFILE '/home/mysql/archive/daemonLog-", DATE_FORMAT(now(),'%Y%m%d-%H%i%s'), "' FROM daemonLog");
  1042. PREPARE stmt FROM @myCommand;
  1043. EXECUTE stmt;
  1044.  
  1045. This will work, Good luck.
  1046.  
  1047. Posted by Michael Ekoka on November 8, 2006
  1048. Just my little contribution when it comes to random row selection used with mysql & php. Based on the solution that consists of returning the count(*) of a table, then using that value to select a random row.
  1049.  
  1050. SELECT FLOOR(RAND() * COUNT(*)) AS rand_row FROM foo;
  1051. SELECT * FROM foo LIMIT {$rand_row}, 1;
  1052. or
  1053. SELECT COUNT(*) AS rows FROM foo;
  1054. SELECT * FROM foo LIMIT {rand(0,$rows-1)}, 1;
  1055.  
  1056. The problem with that solution from the MySQL standpoint is that there still remains the possibility of duplicate selections when we want more than one row, especially if the table is not that large (e.g. what are the chances of getting at least 2 duplicate rows while selecting 5 randomly, 1 at a time, out of a set of 10).
  1057.  
  1058. My approach is to rather generate unique random numbers from php, then fetch the corresponding table rows:
  1059.  
  1060. 1- Use the appropriate php methods to fetch the table count from MySQL as done before:
  1061. SELECT COUNT(*) FROM foo;
  1062.  
  1063. 2- Use php to generate some unique random numbers based on the count.
  1064.  
  1065. This is the php function that i use. It takes 3 arguments: the minimum and maximum range values, and the amount of unique random numbers to be returned. It returns these numbers as an array.
  1066.  
  1067.  
  1068. <?php
  1069. /*Array of Unique Random Numbers*/
  1070.  
  1071. function uniq_rand($min,$max,$size){
  1072. $randoms=array(); //this is our array
  1073.  
  1074. /*if ($min > $max) swap their value*/
  1075. if($min>$max){
  1076. $min=$min^$max;$max=$min^$max;$min=$min^$max;
  1077. }
  1078.  
  1079. /*if requested size of array is larger than possible
  1080. or if requested size of array is negative return*/
  1081. if ( (($max-$min)+1)<$size || $size<=0 ){return false;}
  1082.  
  1083. /*while array has not reached the requested size
  1084. keep generating random numbers and insert them
  1085. if they're not yet present in the array */
  1086. while (count($randoms)<$size){
  1087. $newval = rand($min,$max);
  1088. if(!in_array($newval,$randoms)){$randoms[] = $newval;}
  1089. }
  1090.  
  1091. return $randoms;
  1092. }
  1093. ?>
  1094.  
  1095.  
  1096.  
  1097. 3- Once you receive your set of randoms from the above function, perform a query for each random:
  1098.  
  1099.  
  1100. <?php
  1101. foreach($randoms as $random_row){
  1102. $query="SELECT * FROM foo LIMIT $random_row, 1;"
  1103. //perform query, retrieve values and move on to the next random row
  1104. ...
  1105. }
  1106. ?>
  1107.  
  1108.  
  1109.  
  1110. That's it
  1111. -----
  1112.  
  1113. On a side note regarding the php random number generation function that I have here, I'm sure it's not the best solution all the time. For example, the closer the amount of random numbers gets to the range of numbers available the less efficient the function gets, i.e. if you have a range of 300 numbers and you want 280 of them unique and random, the function could spend quite some time trying to get the last 10 numbers into the array. Some probabilities get involved here, but I suspect that it would be faster to insert the 300 numbers directly into an array, shuffle that array, then finally select the 280 first entries and return them.
  1114.  
  1115. Also, as pointed earlier in the thread, keep in mind that if your table isn't that large, just performing the following works very well (e.g. selecting 5 random rows on a moderately large table):
  1116. SELECT * FROM foo ORDER BY RAND() LIMIT 5;
  1117. Posted by Rustam Valiev on November 17, 2006
  1118. If you want use multilanguage queryies you cat use this:
  1119. Table 1
  1120. --------------
  1121. langid langname
  1122. --------------
  1123. 1 rus
  1124. 2 eng
  1125. 3 den
  1126. ---------------
  1127. Table 2 (catalog)
  1128. -----------------------
  1129. catid url
  1130. -----------------------
  1131. 1 www.google.com
  1132. 2 www.yandex.ru
  1133. 3 www.mysql.com
  1134. ------------------------
  1135. table 3 (titles of sites from Table 3)
  1136. -------------------------------------
  1137. langid catid title
  1138. -------------------------------------
  1139. 1 1 Poiskovaya sistema
  1140. 2 1 Search system
  1141. 1 2 Portal
  1142. 2 2 Portal
  1143. 3 2 Portal
  1144. 1 3 Sayt razrabotchikov MySQL
  1145. 2 3 Site of MySQL's team
  1146. 3 3 Bla bla bla
  1147. ------------------------------------
  1148. And you need select sites from table2 on any language (for example Denmark), but site google.com have not title by Denmark. Ok if you can't select title by current language, you should select title by default language (here russian). You can make in one query
  1149. SELECT *, (
  1150. SELECT title
  1151. FROM table3
  1152. WHERE table3.catid = table2.catid AND langid = 3
  1153. UNION
  1154. SELECT title
  1155. FROM table3
  1156. WHERE table3.catid = table2.catid AND langid = 1
  1157. LIMIT 1
  1158. ) as title
  1159. FROM table2
  1160.  
  1161. It very easy, but i think it query very big for MySQL if table2 contain around 1000-5000 rows, and site have 5000-6000 people per second.
  1162.  
  1163. You can make it another:
  1164. SELECT *, (SELECT title FROM table3 ORDER BY IF(langid='1',0,1) ASC LIMIT 1) as title FROM `table2`
  1165. i couldn't compare this queries, if anybody can compary spped of this method please write r.valiev@uzinfocom.uz (by russian (:^) .
  1166.  
  1167. Now my task more complexed, i need select any site from table2 :
  1168. 1 - On current language
  1169. 2 - If site have not title, Select title by default language
  1170. 3 - If site have not title on default, Select title by any language.
  1171. I think if will make it by thats method - it will very big for MySQL.
  1172. Posted by Ray Perea on December 8, 2006
  1173. In regards to:
  1174. Posted by Count Henry De Havilland-Fortesque-Smedley on January 13 2004 5:59am
  1175. --------------START QUOTE---------------------
  1176. Sometimes you want to retrieve the records that DONT match a select statement.
  1177.  
  1178. Consider this select:
  1179. SELECT CarIndex FROM DealerCatalog, BigCatalog WHERE
  1180. DealerCatalog.CarIndex=BigCatalog.CarIndex
  1181.  
  1182. This finds all the CarIndex values in the Dealer's catalog that are in the bigger distributor catalog.
  1183.  
  1184. How do I then find the dealer CarIndex values that ARE NOT in the bigger catalog?
  1185.  
  1186. The answer is to use LEFT JOIN - anything that doesn't join is given a NULL value , so we look for that:
  1187.  
  1188. SELECT CarIndex FROM DealerCatalog LEFT JOIN BigCatalog ON DealerCatalog.CarIndex=BigCatalog.CarIndex WHERE BigCatalog.CarIndex IS NULL
  1189. ------------------END QUOTE--------------------------
  1190.  
  1191. I have found that the Left Join is quite expensive when doing this type of SQL Query. It is great if you have less than 1000 records in each table that you want to compare. But the real hardship is realized when you have 100,000 records in each table. Trying to do this type of join takes forever because each and every record in 1 table has to be compared to each and every record in the other table. In the case of 100,000 records, MySQL will do 10 BILLION comparisons (from what I have read, I may be mistaken).
  1192.  
  1193. So I tried the sql query above to see which rows in 1 table do not have a corresponding value in the other table. (Note that each table had close to 100,000 rows) I waited for 10 minutes and the Query was still going. I have since came up with a better way that works for me and I hope it will work for someone else. Here goes....
  1194.  
  1195. 1: You must create another field in your base table. Let's call the new field `linked` (For the example above, we would perform this query ---ONLY ONCE--- to create the linked field in the DealerCatalog table.)
  1196.  
  1197. ALTER TABLE `DealerCatalog` ADD `linked` TINYINT NOT NULL ;
  1198.  
  1199. 2: Now to get your results, simply execute the following queries instead of the left join query stated above
  1200.  
  1201. UPDATE `DealerCatalog` SET `linked` = 0;
  1202. UPDATE `DealerCatalog`, `BigCatalog` SET `linked` = 1 WHERE `DealerCatalog`.`CarIndex` = `BigCatalog`.`CarIndex`;
  1203. SELECT `CarIndex` FROM `DealerCatalog` WHERE `linked` = 0;
  1204.  
  1205. I know it is 3 queries instead of 1 but I am able to achieve the same result with 100K rows in each table in about 3 seconds instead of 10 minutes (That is just how long I waited until I gave up. Who knows how long it actually takes) using the LEFT JOIN method.
  1206.  
  1207. I would like to see if anyone else has a better way of dealing with this type of situation. I have been looking for a better solution for a few years now. I haven't tried MySQL 5 yet to see if there is a way to maybe create a view to deal with this situation but I suspect MySQL developers know about the expensive LEFT JOIN....IS NULL situation on large tables and are doing something about it.
  1208.  
  1209. Until then, you have my contribution
  1210. Ray Perea
  1211.  
  1212. Posted by Frederic Theriault on December 8, 2006
  1213. Make sure you don't use stored functions in your WHERE clause if it is not necessary.
  1214.  
  1215. For our search feature, we needed to get an id using a stored function. Since it was in the WHERE clause, it reprocesses the function for every row! This could turn out to be pretty heavy.
  1216.  
  1217. If you can, do it in the FROM clause. Ex:
  1218. SELECT
  1219. ...
  1220. FROM
  1221. ...,
  1222. (select getSpecialID() as specialID) as tmp
  1223. WHERE
  1224. ...
  1225.  
  1226. In our case we went from 6.5 sec query to 0.48 sec. We have over 2 million rows in our tables.
  1227. Posted by Héctor Hugo Huergo on April 19, 2007
  1228. Hi! I'm using SELECT ... INTO OUTFILE. First I´ve permissions problems. Add to the user the FILE privileges... AND RESTART THE DAEMON :). Bye
  1229. Posted by Will Jaspers on May 4, 2007
  1230. For anyone utilizing two or more tables to create select boxes, I've finally (and painstakingly) found a way to check if the item is selected.
  1231.  
  1232. -- Sample table 1, we'll call this 'STATES'
  1233. CREATE TABLE states
  1234. (
  1235. state_id int auto_increment not null,
  1236. state_code char(2) not null,
  1237. state_name varchar(100) not null,
  1238. UNIQUE(state_code),
  1239. PRIMARY KEY(state_id)
  1240. );
  1241.  
  1242. CREATE TABLE drivers
  1243. (
  1244. driver id int not null auto_increment,
  1245. driver_name varchar(255) not null,
  1246. PRIMARY KEY(driver_id)
  1247. );
  1248.  
  1249. CREATE TABLE drove_to_states
  1250. (
  1251. state_id int not null,
  1252. driver_id int not null,
  1253. arrived datetime not null,
  1254. departed datetime not null,
  1255. notes text
  1256. );
  1257.  
  1258. -- Query
  1259. SELECT
  1260. s.`state_code`,
  1261. s.`state_name`,
  1262. IF(state_id IN
  1263. (SELECT d2s.state_id
  1264. FROM drove_to_states d2s
  1265. WHERE driver_id = '%u'
  1266. ), 1, null)
  1267. `selected`
  1268. FROM `states` s,
  1269. ORDER BY `state_name` ASC;
  1270.  
  1271. Using PHP's sprintf command, we can create a select field using this query:
  1272.  
  1273.  
  1274. <?php
  1275. [...]
  1276. $driver_id = 1;
  1277. define("QUERY", (SEE ABOVE) );
  1278. define("OPTION",'<option value="%s"%s>%s</option>');
  1279. $query = mysql_query(sprintf(QUERY, $driver_id), $connect);
  1280. echo '<select>';
  1281. while(list($code,$state,$selected) = mysql_fetch_row($query))
  1282. {
  1283. $selected = is_null($selected) ? null : ' selected';
  1284. echo sprintf(OPTION, $code, $selected, $state);
  1285. }
  1286. echo '</select>';
  1287. [...]
  1288. ?>
  1289.  
  1290.  
  1291.  
  1292. Hope this helps anyone.
  1293.  
  1294. If anyone has a better way of writing this, please post.
  1295. Posted by Martin Sarfy on August 14, 2007
  1296. SELECT INTO OUTFILE creates world-writable files. To avoid this security risk, you can create new subdirectory with +x rights for mysql and your user only (e.g. using chown me:mysql restricted_dir, chmod 770 restricted_dir), and then save the file into this directory. This way only you and mysql process can modify the file.
  1297. Posted by Dan Bogdan on October 27, 2007
  1298. If you want to copy a file from the server in other location you can use
  1299. select load_file('source_file') into OUTFILE 'target_file'
  1300. Security issue on windows ... you can copy any file from any folder even if you don't have access to that file
  1301. to an convenient folder where you have access !!
  1302.  
  1303. Posted by Drazen Djurisic on November 13, 2007
  1304. If you need names from second table for more then 1 columns in first table.
  1305. Select
  1306. table1.id,
  1307. table1.konto,
  1308. table2.name as name1,
  1309. table1.konto1,
  1310. table2_2.name as name2,
  1311. table1.konto3,
  1312. table2_3.naziv as name3,
  1313. from table1
  1314. left join table2 on (table1.konto=table2.id)
  1315. left join table2 as table2_2 on (table1.konto2=table2_2.id)
  1316. left join table2 as table2_3 on (table1.konto3=table2_3.id)
  1317.  
  1318. Posted by Rich Altmaier on February 16, 2008
  1319. As a variant on the random row selection question, I had the goal of reading out a limited set of rows, always in the same order, but starting at a different point in the sequence each time (like Facebook short list of members):
  1320. e.g. given records a, b, c, d, e, f
  1321. I want random selections of triplets such as:
  1322. b, c, d
  1323. c, d, e
  1324. f, a, b --> note I want wraparound!
  1325.  
  1326. The prior postings on random rows selections have shown:
  1327. SELECT * FROM foo ORDER BY count*RAND() LIMIT 5;
  1328. This will yield the 5 random rows, but not in the same record ordering.
  1329.  
  1330. To preserve order, including a wraparound,
  1331. we must UNION a pair of queries.
  1332. For e.g. to get 3 rows from a table of $counted rows,
  1333. where we have selected $start, which happens to be within
  1334. 3 of the end, we wrap as:
  1335.  
  1336. (SELECT * FROM `Ordering` ORDER BY something LIMIT $start, 1) UNION
  1337. (SELECT * FROM `Ordering` ORDER BY something LIMIT 0, 2)
  1338.  
  1339. suppose the table has 6 rows, and we decide
  1340. randomly to start with row 6, then concretely:
  1341. (SELECT * FROM `Ordering` ORDER BY something LIMIT 5, 1) UNION
  1342. (SELECT * FROM `Ordering` ORDER BY something LIMIT 0, 2)
  1343.  
  1344. Posted by engin karahan on February 17, 2008
  1345. As a variant on the random row selection question, I had the goal of reading out a limited set of rows, always in the same order, but starting at a different point in the sequence each time (like Facebook short list of members):
  1346. e.g. given records a, b, c, d, e, f
  1347. I want random selections of triplets such as:
  1348. b, c, d
  1349. c, d, e
  1350. f, a, b --> note I want wraparound!
  1351.  
  1352. The prior postings on random rows selections have shown:
  1353. SELECT * FROM foo ORDER BY count*RAND() LIMIT 5;
  1354. This will yield the 5 random rows, but not in the same record ordering.
  1355.  
  1356. To preserve order, including a wraparound,
  1357. we must UNION a pair of queries.
  1358. For e.g. to get 3 rows from a table of $counted rows,
  1359. where we have selected $start, which happens to be within
  1360. 3 of the end, we wrap as:
  1361.  
  1362. (SELECT * FROM `Ordering` ORDER BY something LIMIT $start, 1) UNION
  1363. (SELECT * FROM `Ordering` ORDER BY something LIMIT 0, 2)
  1364.  
  1365. suppose the table has 6 rows, and we decide
  1366. randomly to start with row 6, then concretely:
  1367. (SELECT * FROM `Ordering` ORDER BY something LIMIT 5, 1) UNION
  1368. (SELECT * FROM `Ordering` ORDER BY something LIMIT 0, 2)
  1369.  
  1370. Posted by Michael Yakobi on March 6, 2008
  1371. Rotating rows to columns - crosstab pivoted queries
  1372. Having the following tables where Attributes.objId refers to Objects.id:
  1373.  
  1374. | Objects Attributes
  1375. +----+------+------+ +-------+-----+-------+
  1376. | id | type | name | | objId | key | value |
  1377. +====+======+======+ +=======+=====+=======+
  1378. | 1 | T1 | O1 | | 1 | K1 | V1 |
  1379. | 2 | T2 | O2 | | 1 | K2 | V2 |
  1380. | 3 | T1 | O3 | | 2 | K3 | V3 |
  1381. | 4 | T2 | O4 | | 2 | K4 | V4 |
  1382. | | 2 | K5 | V5 |
  1383. | | 3 | K1 | V6 |
  1384. | | 3 | K2 | V7 |
  1385.  
  1386. The common approach for selecting the attributes of each object into a single result-row per object is to join Objects with Attributes multiple times. However, not only such SELECT can grow very big and ugly, with large tables it becomes very slow.
  1387. This could be dealt with using group-by functions, so to select all the objects of type T1, use the following SQL:
  1388.  
  1389. | SELECT
  1390. | o.id,
  1391. | o.name,
  1392. | MAX(IF(a.key='K1', a.value, null)) as K1,
  1393. | MAX(IF(a.key='K2', a.value, null)) as K2
  1394. | FROM
  1395. | Objects o,
  1396. | Attributes a
  1397. | WHERE
  1398. | o.id = a.objid and
  1399. | o.type = 'T1'
  1400. | GROUP BY
  1401. | a.id
  1402.  
  1403. The result will be:
  1404.  
  1405. +----+------+----+----+
  1406. | id | name | K1 | K2 |
  1407. +====+======+====+====+
  1408. | 1 | O1 | V1 | V2 |
  1409. | 3 | O3 | V6 | V7 |
  1410.  
  1411. Posted by Wiebe Cazemier on March 25, 2008
  1412. For those who don't fully understand the concept of joins, I wrote an article which might help.
  1413.  
  1414. http://www.halfgaar.net/sql-joins-are-easy
  1415. Posted by Sam on April 8, 2008
  1416. I just spent a few hours figuring this one out and there doesn't seem to be much info online about it so I thought I'd share.
  1417.  
  1418. You should use the following syntax to create a CSV file in the format expected by Microsoft Excel:
  1419.  
  1420. ... INTO OUTFILE '/temp.csv' FIELDS ESCAPED BY '""' TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\r\n';
  1421.  
  1422. However fields with carriage returns may break the CSV as MySQL will automatically close a field when the \r\n line break is found. To work around this, replace all \r\n breaks with \n. The field does not close on \n breaks and it will be read into a single cell in Excel. You can do this in the same SQL statement, for example:
  1423.  
  1424. SELECT REPLACE(field_with_line_breaks, '\r\n', '\n') FROM table INTO OUTFILE '/temp.csv' FIELDS ESCAPED BY '""' TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\r\n';
  1425.  
  1426. I also found that null values could break the CSV. These can be handled in a similar way:
  1427.  
  1428. SELECT IFNULL(possible_null_field, "") FROM table INTO OUTFILE '/temp.csv' FIELDS ESCAPED BY '""' TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\r\n';
  1429.  
  1430. Note: this replaces NULL values with an empty string which is technically not the same thing but it will give you an empty cell in Excel instead of breaking the CSV structure and shifting the following cells to the left.
  1431. Posted by Paris Alex on October 16, 2009
  1432. To create a SELECT statement that categorize and label its result set according to special rules, try this...
  1433.  
  1434. SELECT 'cheap' AS priceCat, productName productCount FROM MyProducts WHERE price < 1000
  1435. UNION
  1436. SELECT 'moderate' AS priceCat, productName FROM MyProducts WHERE price >= 1000 AND price <2000
  1437. UNION
  1438. SELECT 'expensive' AS priceCat, productName FROM MyProducts WHERE price >= 2000
  1439.  
  1440. It essentially returns a two column result set. The first column contains the word 'cheap', 'moderate' or 'expensive' depending on the price of the product. The second column is the product name. This query can easily be modified to return a count of number of products categorized by the price range:
  1441.  
  1442. SELECT 'cheap' AS priceCat, COUNT(*) productCount FROM MyProducts WHERE price < 1000
  1443. UNION
  1444. SELECT 'moderate' AS priceCat, COUNT(*) FROM MyProducts WHERE price >= 1000 AND price <2000
  1445. UNION
  1446. SELECT 'expensive' AS priceCat, COUNT(*) FROM MyProducts WHERE price >= 2000
  1447.  
  1448. It may sound like an obvious thing the an experienced SQL guy, but I think this tip will be useful to a beginner. Hope this tip helps a SQL developer soon! ;-)
  1449.  
  1450.  
  1451. Posted by Joseph Triplett on October 16, 2009
  1452. to pass the output of a SELECT into a variable array for further processing (PHP), do the following:
  1453.  
  1454. $array = ("SELECT ID, post_title, FROM Posts", ARRAY_A);
  1455.  
  1456. Notice the "ARRAY_A" declaration at the end of the variable assignment.
  1457.  
  1458. I have had issues passing SQL statements into arrays, when the "ARRAY_A" declaration is not made.
  1459. Posted by Yury Ramanouski on November 13, 2009
  1460. # To select a random row of the table `tbl`
  1461. # I call the following procedure:
  1462.  
  1463. CREATE PROCEDURE select_rnd()
  1464. BEGIN
  1465. START TRANSACTION;
  1466. SELECT FLOOR(RAND() * COUNT(*)) INTO @rnd FROM tbl;
  1467. PREPARE stmt FROM 'SELECT * FROM tbl LIMIT ?, 1';
  1468. EXECUTE stmt USING @rnd;
  1469. COMMIT;
  1470. END;
  1471. Posted by Peter Colclough on November 26, 2009
  1472. A really good speedup for those using 'Group By'. This is reported to MySql who are looking atr it, but can halve the speed of your query.
  1473.  
  1474. If you have a query that looks like:
  1475.  
  1476. Select col1, col2, col3
  1477. From tab1, tab2 ...
  1478. Group by col1, col2
  1479.  
  1480. You can add the following:
  1481. Group By col1, col2 WITH ROLLUP
  1482. Having (col1 IS NOT NULL) and (Col2 is not NUll)
  1483.  
  1484. This totals the 'groupings' but then removes those rows from the query. At the moment it is believed that an optimisation was performed for the 'WITH ROLLUP' that didn't make it into the main optimisation...
  1485.  
  1486. HTH
  1487.  
  1488. Posted by Jon Webb on December 7, 2009
  1489. Ordering the Order By...
  1490. SELECT country,population FROM places ORDER BY country='UK' DESC, country ASC
  1491. This gives:
  1492. UK
  1493. Agola
  1494. Belgium
  1495. etc
  1496. Posted by Michael Ash on December 17, 2009
  1497. Several users asked about including headers, i.e., column names or variable names, in the "INTO OUTFILE" syntax.
  1498.  
  1499. One approach is to use the "--column-names" option in the mysql invocation:
  1500.  
  1501. mysql --column-names -e 'SELECT * FROM mysql.user' > test.dat
  1502.  
  1503. (This creates a tab-delimited file test.dat with column names in the first row followed by the query results.)
  1504.  
  1505. Posted by Elliot Greene on June 4, 2010
  1506. I discovered a well placed parentheses can make a difference in output. This Query search at least three columns for data like the $query variable.
  1507.  
  1508. Example 1: (This doesn't work)
  1509.  
  1510. $query = "Whatever text";
  1511.  
  1512. $sql2 = "SELECT * FROM $tbl_name WHERE CompanyName LIKE '%". $query ."%' OR description LIKE '%". $query ."%' OR KeywordTags LIKE '%". $query ."%' AND Active='yes' AND State=Florida ";
  1513.  
  1514. Example 2: (Works for Me)
  1515. Notice the parentheses enclosing the "WHERE" section of the query separating it from the final "AND" Section.
  1516.  
  1517. $sql2 = "SELECT * FROM $tbl_name WHERE (CompanyName LIKE '%". $query ."%' OR description LIKE '%". $query ."%' OR KeywordTags LIKE '%". $query ."%' AND Active='yes') AND State=Florida ";
  1518.  
  1519. Regards,
  1520. Elliot
  1521. http://www.sioure.com
  1522. Posted by pablo uribe on January 10, 2011
  1523. You can use this example to look for uniques rows using distinct over a mix of fields. use concat .
  1524.  
  1525. para hacer un distinct de varias columnas se puede usar concat
  1526.  
  1527. SELECT distinct(concat(id_cliente,rut,fecha_cesion)), id_cliente,rut,fecha_cesion FROM `tmp_consolidado` WHERE 1
  1528.  
  1529. www.puribe.cl
  1530. Posted by Sagi Rozen on January 25, 2011
  1531. In order to select random rows from a table don't use the ORDER BY RAND() clause.
  1532. You can get a much better performing query if you use the RAND() function at the WHERE clause only. This query will not result in file sort and will stop as soon as it get to the limit.
  1533. See http://www.rndblog.com/how-to-select-random-rows-in-mysql/
  1534.  
  1535. Posted by erick ringot on March 31, 2011
  1536. RECURSION / RECURSIVE SELECT :
  1537.  
  1538. 1) Let `task` be a MySql table containing at least 2 columns: id (primary key), pid (parent id - may be NULL) so that the rows form a classic tree structure.
  1539.  
  1540. 2) Suppose you want to extract the tree relative to a particular actual id (constituted by itself and all its spawns) so that you need a recursive select which is unfortunately not implemented in MySql.
  1541.  
  1542. You can proceed by writing a recursive function as below.
  1543.  
  1544. CREATE PROCEDURE `TASKTREE`(tid INT UNSIGNED, flag BOOLEAN)
  1545. BEGIN
  1546. --
  1547. -- TASKTREE(id,flag)
  1548. -- recursive function, must be called with flag=FALSE
  1549. -- tid is the task (row) id
  1550. -- creation of a temporary table `tasktree`
  1551. -- containing the tree relative to tid
  1552. --
  1553. declare xid,xpid INT UNSIGNED;
  1554. declare tend BOOLEAN DEFAULT FALSE;
  1555. declare tcur CURSOR FOR SELECT id,pid FROM `task`
  1556. WHERE ((tid>0 AND pid=tid) OR (tid=0 AND pid IS NULL));
  1557. declare CONTINUE HANDLER FOR NOT FOUND SET tend=TRUE;
  1558. --
  1559. -- external call : flag MUST be FALSE
  1560. -- -> creation of the temporary table `tasktree`
  1561. --
  1562. IF (NOT flag) THEN
  1563. DROP TEMPORARY TABLE IF EXISTS `tasktree`;
  1564. CREATE TEMPORARY TABLE `tasktree` (
  1565. `id` int(10) unsigned NOT NULL,
  1566. `pid` int(10) unsigned,
  1567. PRIMARY KEY (`id`));
  1568. SELECT pid FROM `task` WHERE id=tid INTO xpid;
  1569. INSERT `tasktree` SET id=tid,pid=xpid;
  1570. END IF;
  1571. --
  1572. -- recursive (internal) call: flag MUST be TRUE
  1573. --
  1574. OPEN tcur;
  1575. tscan:LOOP
  1576. FETCH tcur INTO xid,xpid;
  1577. IF tend THEN LEAVE tscan; END IF;
  1578. INSERT `tasktree` SET id=xid,pid=xpid;
  1579. CALL TASKTREE(xid,TRUE);
  1580. END LOOP;
  1581. CLOSE tcur;
  1582. END
  1583.  
  1584. -----------------
  1585. Note: Don't omit to set the global variable max_sp_recursion_depth to an adequate positive value (for instance in the file 'my.ini').
  1586. Posted by Charles Peterson on February 22, 2012
  1587. Reply to Post by Heywood on March 11 2005 2:04pm
  1588. QUOTE
  1589. When using the SELECT ... INTO OUTFILE syntax, use a UNION to add headers. Here's an example for CSV output:
  1590.  
  1591. SELECT 'Fiscal Year','Location','Sales'
  1592. UNION
  1593. SELECT FY, Loc, Sales INTO OUTFILE 'salesreport.csv'
  1594. FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  1595. FROM SalesTable;
  1596.  
  1597. This will add the text headers Fiscal Year, Location and Sales to your fields. Only caveat is with an ORDER BY statement, if you don't want your headers sorted along with your data you need to enclose it in parenthesis:
  1598.  
  1599. SELECT 'Fiscal Year','Location','Sales'
  1600. UNION
  1601. {SELECT FY, Loc, Sales INTO OUTFILE 'salesreport.csv'
  1602. FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  1603. FROM SalesTable
  1604. ORDER BY Sales DESC);
  1605.  
  1606. END QUOTE...
  1607.  
  1608. Here is a more dynamic option for adding column_names to the top of output...
  1609.  
  1610. SELECT group_concat( column_name
  1611. SEPARATOR "," )
  1612. FROM information_schema.columns
  1613. WHERE table_name = 'SalesTable'
  1614. GROUP BY table_name
  1615. UNION
  1616. {SELECT * INTO OUTFILE 'salesreport.csv'
  1617. FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  1618. FROM SalesTable
  1619. ORDER BY Sales DESC);
  1620.  
  1621. Posted by Roland Giesler on June 23, 2012
  1622. In an effort to automate the exporting of data for a larger number of tables to .csv file by using SELECT ... INTO OUTFILE, I have created a stored procedure to facilitate this. It's somewhat bulky, but please refer to http://lifeboysays.wordpress.com/2012/06/23/mysql-how-to-export-data-to-csv-with-column-headers/ if you have need for this.
  1623. Sign Up
  1624. Login
  1625. You must be logged in to post a comment.
  1626. © 2017, Oracle Corporation and/or its affiliates
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement