다음은 MySQL을 사용하여 몇 가지 일반적인 문제를 해결하는 방법에 대한 몇 가지 예입니다.
일부 예에서는 데이터베이스 테이블 "shop"이 특정 판매자(딜러)의 각 품목(품목 번호) 가격을 저장하는 데 사용됩니다. 각 판매자가 각 항목에 대해 고정 가격을 갖고 있다고 가정하면 (항목, 판매자)가 레코드의 기본 키입니다.
명령줄 도구 mysql을 시작하고 데이터베이스를 선택합니다:
shell> mysql your-database-name
(대부분의 MySQL에서는 테스트 데이터베이스를 사용할 수 있습니다).
다음 문을 사용하여 샘플 테이블을 생성할 수 있습니다.
mysql> CREATE TABLE shop ( -> article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL, -> dealer CHAR(20) DEFAULT '' NOT NULL, -> price DOUBLE(16,2) DEFAULT '0.00' NOT NULL, -> PRIMARY KEY(article, dealer)); mysql> INSERT INTO shop VALUES -> (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45), -> (3,'C',1.69),(3,'D',1.25),(4,'D',19.95);
문을 실행한 후 테이블에는 다음이 포함되어야 합니다.
mysql> SELECT * FROM shop; +---------+--------+-------+ | article | dealer | price | +---------+--------+-------+ | 0001 | A | 3.45 | | 0001 | B | 3.99 | | 0002 | A | 10.99 | | 0003 | B | 1.45 | | 0003 | C | 1.69 | | 0003 | D | 1.25 | | 0004 | D | 19.95 | +---------+--------+-------+
1. 열의 값
“가장 큰 항목 번호는 무엇입니까?”
SELECT MAX(article) AS article FROM shop; +---------+ | article | +---------+ | 4 | +---------+
2. 특정 열의 최대값이 있는 행
과제: 번호 찾기 가장 비싼 품목, 판매자 및 가격. 하위 쿼리를 사용하면 쉽습니다.
SELECT article, dealer, price FROM shop WHERE price=(SELECT MAX(price) FROM shop);
또 다른 해결책은 모든 행을 가격별로 내림차순으로 정렬하고 MySQL 관련 LIMIT 절이 있는 첫 번째 행만 가져오는 것입니다.
SELECT article, dealer, price FROM shop ORDER BY price DESC LIMIT 1;
참고: 가장 비싼 품목이 여러 개 있는 경우(예: 각 품목의 가격은 19.95), LIMIT 솔루션은 그 중 하나만 표시합니다!
3. 열의 최대값: 그룹별
작업: 각 항목의 최대 가격은 얼마입니까?
SELECT 기사, MAX(가격) AS 가격
FROM shop
GROUP BY 기사
+---------+-------+ | article | price | +---------+-------+ | 0001 | 3.99 | | 0002 | 10.99 | | 0003 | 1.69 | | 0004 | 19.95 | +---------+-------+
4. 최대 가치
과제: 각 품목에 대해 가장 비싼 품목의 딜러를 찾으십시오.
다음과 같은 하위 쿼리로 이 문제를 해결할 수 있습니다.
SELECT article, dealer, price FROM shop s1 WHERE price=(SELECT MAX(s2.price) FROM shop s2 WHERE s1.article = s2.article);
5. 사용자 변수 사용
MySQL 사용자 변수를 지워 결과를 저장하지 않고 기록할 수 있습니다. . 클라이언트 측의 임시 변수에 저장됩니다.
예를 들어 가격이 가장 높거나 낮은 항목을 찾는 방법은 다음과 같습니다.
mysql> SELECT @min_price:=MIN(price),@max_price:=MAX(price) FROM shop; mysql> SELECT * FROM shop WHERE price=@min_price OR price=@max_price; +---------+--------+-------+ | article | dealer | price | +---------+--------+-------+ | 0003 | D | 1.25 | | 0004 | D | 19.95 | +---------+--------+-------+
6. 외래 키 사용
MySQL에서는 InnoDB 테이블 외부 키워드 제약 조건 확인을 지원합니다.
두 테이블을 조인할 때는 외부 키워드가 필요하지 않습니다. InnoDB 유형이 아닌 테이블의 경우 REFERENCES tbl_name(col_name) 절을 사용하여 열을 정의할 때 외부 키워드를 사용할 수 있습니다. 이 절은 실제 효과가 없으며 현재 정의 중인 열을 상기시키기 위한 메모나 설명으로만 사용됩니다. 테이블의 다른 A 열을 가리킵니다. 이 명령문을 실행할 때 다음을 구현하는 것이 중요합니다.
MySQL은 정의 중인 테이블의 행에 대한 작업에 대한 응답으로 행을 삭제하는 등의 작업을 tbl_name 테이블에서 수행하지 않습니다. 구문 ON DELETE 또는 ON UPDATE 동작이 발생하지 않습니다. REFERENCES 절에 ON DELETE 또는 ON UPDATE 절을 작성하면 무시됩니다.
· 이 구문은 열을 생성할 수 있지만 인덱스나 키워드는 생성하지 않습니다.
· 이 구문을 사용하여 InnoDB 테이블을 정의하면 오류가 발생합니다.
다음과 같이 조인 열로 생성된 열을 사용할 수 있습니다.
CREATE TABLE person ( id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, name CHAR(60) NOT NULL, PRIMARY KEY (id) ); CREATE TABLE shirt ( id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, style ENUM('t-shirt', 'polo', 'dress') NOT NULL, color ENUM('red', 'blue', 'orange', 'white', 'black') NOT NULL, owner SMALLINT UNSIGNED NOT NULL REFERENCES person(id), PRIMARY KEY (id) ); INSERT INTO person VALUES (NULL, 'Antonio Paz'); SELECT @last := LAST_INSERT_ID(); INSERT INTO shirt VALUES (NULL, 'polo', 'blue', @last), (NULL, 'dress', 'white', @last), (NULL, 't-shirt', 'blue', @last); INSERT INTO person VALUES (NULL, 'Lilliana Angelovska'); SELECT @last := LAST_INSERT_ID(); INSERT INTO shirt VALUES (NULL, 'dress', 'orange', @last), (NULL, 'polo', 'red', @last), (NULL, 'dress', 'blue', @last), (NULL, 't-shirt', 'white', @last); SELECT * FROM person; +----+---------------------+ | id | name | +----+---------------------+ | 1 | Antonio Paz | | 2 | Lilliana Angelovska | +----+---------------------+
SELECT * FROM 셔츠;
+--- -+ ---------+---------+
| ID | 색상 | 소유자 |
+--- ------+---------+
| 폴로 | 1 |
| 드레스 | 🎜>| 티셔츠 | 1 |
| 5 | 빨간색 | 🎜>| 7 | 티셔츠 | 흰색 |
+----+---------+-----+
s.* FROM 사람 p, 셔츠 s
WHERE p.name LIKE 'Lilliana%'
AND s.owner = p.id
+----+-------+---------+-----+
| ID | 소유자 |
+-----+--------+-------+
+-----+--- -----+
이 방법을 사용하면 REFERENCES 절이 열 정의의 SHOW CREATE TABLE 또는 DESCRIBE:
출력에 표시되지 않습니다. REFERENCES를 다음과 같이 사용 이러한 방식의 주석 또는 "힌트"는 MyISAM 및 BerkeleyDB 테이블에서 작동합니다.
7. 根据两个键搜索
可以充分利用使用单关键字的OR子句,如同AND的处理。
一个比较灵活的例子是寻找两个通过OR组合到一起的关键字:
SELECT field1_index, field2_index FROM test_table WHERE field1_index = '1' OR field2_index = '1'
该情形是已经优化过的。
还可以使用UNION将两个单独的SELECT语句的输出合成到一起来更有效地解决该问题。
每个SELECT只搜索一个关键字,可以进行优化:
SELECT field1_index, field2_index FROM test_table WHERE field1_index = '1' UNION SELECT field1_index, field2_index FROM test_table WHERE field2_index = '1';
8. 根据天计算访问量
下面的例子显示了如何使用位组函数来计算每个月中用户访问网页的天数。
CREATE TABLE t1 (year YEAR(4), month INT(2) UNSIGNED ZEROFILL, day INT(2) UNSIGNED ZEROFILL); INSERT INTO t1 VALUES(2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2), (2000,2,23),(2000,2,23);
示例表中含有代表用户访问网页的年-月-日值。可以使用以下查询来确定每个月的访问天数:
SELECT year,month,BIT_COUNT(BIT_OR(1<<day)) AS days FROM t1 GROUP BY year,month;
将返回:
+------+-------+------+ | year | month | days | +------+-------+------+ | 2000 | 01 | 3 | | 2000 | 02 | 2 | +------+-------+------+
该查询计算了在表中按年/月组合的不同天数,可以自动去除重复的询问。
9. 使用AUTO_INCREMENT
可以通过AUTO_INCREMENT属性为新的行产生唯一的标识:
CREATE TABLE animals ( id MEDIUMINT NOT NULL AUTO_INCREMENT, name CHAR(30) NOT NULL, PRIMARY KEY (id) ); INSERT INTO animals (name) VALUES ('dog'),('cat'),('penguin'), ('lax'),('whale'),('ostrich'); SELECT * FROM animals;
将返回:
+----+---------+ | id | name | +----+---------+ | 1 | dog | | 2 | cat | | 3 | penguin | | 4 | lax | | 5 | whale | | 6 | ostrich | +----+---------+
你可以使用LAST_INSERT_ID()SQL函数或mysql_insert_id() C API函数来查询最新的AUTO_INCREMENT值。这些函数与具体连接有关,因此其返回值不会被其它执行插入功能的连接影响。
注释:对于多行插入,LAST_INSERT_ID()和mysql_insert_id()从插入的第一行实际返回AUTO_INCREMENT关键字。在复制设置中,通过该函数可以在其它服务器上正确复制多行插入。
对于MyISAM和BDB表,你可以在第二栏指定AUTO_INCREMENT以及多列索引。此时,AUTO_INCREMENT列生成的值的计算方法为:MAX(auto_increment_column) + 1 WHERE prefix=given-prefix。如果想要将数据放入到排序的组中可以使用该方法。
CREATE TABLE animals ( grp ENUM('fish','mammal','bird') NOT NULL, id MEDIUMINT NOT NULL AUTO_INCREMENT, name CHAR(30) NOT NULL, PRIMARY KEY (grp,id) ); INSERT INTO animals (grp,name) VALUES ('mammal','dog'),('mammal','cat'), ('bird','penguin'),('fish','lax'),('mammal','whale'), ('bird','ostrich'); SELECT * FROM animals ORDER BY grp,id;
将返回:
+--------+----+---------+ | grp | id | name | +--------+----+---------+ | fish | 1 | lax | | mammal | 1 | dog | | mammal | 2 | cat | | mammal | 3 | whale | | bird | 1 | penguin | | bird | 2 | ostrich | +--------+----+---------+
请注意在这种情况下(AUTO_INCREMENT列是多列索引的一部分),如果你在任何组中删除有最大AUTO_INCREMENT值的行,将会重新用到AUTO_INCREMENT值。对于MyISAM表也如此,对于该表一般不重复使用AUTO_INCREMENT值。
如果AUTO_INCREMENT列是多索引的一部分,MySQL将使用该索引生成以AUTO_INCREMENT列开始的序列值。。例如,如果animals表含有索引PRIMARY KEY (grp, id)和INDEX(id),MySQL生成序列值时将忽略PRIMARY KEY。结果是,该表包含一个单个的序列,而不是符合grp值的序列。
要想以AUTO_INCREMENT值开始而不是1,你可以通过CREATE TABLE或ALTER TABLE来设置该值,如下所示:
mysql> ALTER TABLE tbl AUTO_INCREMENT = 100;