MySQL 学习笔记

--使用正则表达式
-- ^ 开始 , . 任意字符
SELECT Name, Continent, Population FROM Country WHERE Name REGEXP '^.[a-e].*' ORDER BY Name;
-- $ 结尾
SELECT Name, Continent, Population FROM Country WHERE Name REGEXP '.*g$' ORDER BY Name;
SELECT Name, Continent, Population FROM Country WHERE Name REGEXP 'o.o' ORDER BY Name;
-- + 匹配一个或多个前一个字符
SELECT Name, Continent, Population FROM Country WHERE Name REGEXP 'oc+o' ORDER BY Name;
SELECT Name, Continent, Population FROM Country WHERE Name REGEXP 'oc*o' ORDER BY Name;
-- ? 匹配零个或多个前一个字符
SELECT Name, Continent, Population FROM Country WHERE Name REGEXP 'oc?o' ORDER BY Name;
SELECT Name, Continent, Population FROM Country WHERE Name REGEXP '^.[aeiou].*' ORDER BY Name;
SELECT Name, Continent, Population FROM Country WHERE Name REGEXP '^.[a-e].*' ORDER BY Name;
SELECT Name, Continent, Population FROM Country WHERE Name REGEXP '^.[^a-e].*' ORDER BY Name;
--中间的[:space:]表示匹配空格
SELECT Name, Continent, Population FROM Country WHERE Name REGEXP '[[:space:]]' ORDER BY Name;
SELECT Name, Continent, Population FROM Country WHERE Name RLIKE '[[:space:]]' ORDER BY Nam
-- 可以查看官方网站帮助获得更多内容 http://dev.mysql.com/doc/refman/5.6/en/regexp.html

--字符串
SELECT 'hello, world';
SELECT 'hello' ', ' 'world';
SELECT "hello, world";
SELECT 'hello, "world"';
SELECT 'hello, ''world''';
SELECT 'hello, \'world\'';

--创建表

DROP TABLE IF EXISTS test;
CREATE TABLE test (
     id INTEGER not null default 47,
    -- id INTEGER AUTO_INCREMENT primary key,
    -- 其中 INTEGER AUTO_INCREMENT primary key 可以简写为SERIAL (4.1 以前的版本不支持)唯一的区别是integer的大小由11变为了20
     a VARCHAR(255) unique not null,
     b VARCHAR(255) unique,
     stamp TIMESTAMP,  -- 默认会随记录更新而更新
    INDEX(a) ,
    FOREIGN KEY (a) REFERENCES client(id)
);
INSERT INTO TEST ( id, a, b ) VALUES ( 1, 'one', 'two' );
INSERT INTO TEST ( id, a, b ) VALUES ( 2, 'two', 'three' );
INSERT INTO TEST ( id, a, b ) VALUES ( 3, 'three', 'four' );

DESCRIBE test; --查看表结构
SHOW TABLE STATUS; -- 显示数据库中所有表的状态
SHOW TABLE STATUS like ‘test'; -- 显示某个表的状态
SHOW CREATE TABLE test; --显示创建test表的sql语句
SHOW INDEXES FROM test;  -- 显示test表的索引
SELECT LAST_INSERT_ID() ; – 显示最后插入的id,注意这个是全局的,所以要看的话需要在插入后面调用

-- ENUM

DROP TABLE IF EXISTS test;
CREATE TABLE test (
  id SERIAL,
  a ENUM( 'Pablo', 'Henri', 'Jackson' )
);
INSERT INTO test ( a ) VALUES ( 'Pablo' );
INSERT INTO test ( a ) VALUES ( 'Henri' );
INSERT INTO test ( a ) VALUES ( 'Jackson' );
INSERT INTO test ( a ) VALUES ( 1 );
INSERT INTO test ( a ) VALUES ( 2 );
INSERT INTO test ( a ) VALUES ( 3 );

SELECT * FROM test;

-- SET

DROP TABLE IF EXISTS test;
CREATE TABLE test (
  id SERIAL,
  a SET( 'Pablo', 'Henri', 'Jackson' )
);
INSERT INTO test ( a ) VALUES ( 'Pablo' );
INSERT INTO test ( a ) VALUES ( 'Henri' );
INSERT INTO test ( a ) VALUES ( 'Jackson' );
INSERT INTO test ( a ) VALUES ( 'Pablo,Jackson,Henri,Henri,Henri' );
INSERT INTO test ( a ) VALUES ( 1 );
INSERT INTO test ( a ) VALUES ( 2 );
INSERT INTO test ( a ) VALUES ( 3 );
INSERT INTO test ( a ) VALUES ( 4 );
INSERT INTO test ( a ) VALUES ( 5 );
INSERT INTO test ( a ) VALUES ( 6 );
INSERT INTO test ( a ) VALUES ( 7 );
SELECT COUNT(*) FROM test;
SELECT * FROM test;
DESCRIBE test;
SHOW CREATE TABLE test;

函数
length()  --计算长度 bytes
CHAR_LENGTH()  --计算长度 字符数,运算时间比length()长,因为要解析unicode
mid(name,2,3)
concat(Name, localname) -- 字符串拼接
concat_ws(‘,’,name,locaname) -- 可以设置分隔符

SELECT GROUP_CONCAT(Name) FROM Country WHERE Region = 'Western Europe';
SELECT GROUP_CONCAT(Name) FROM Country GROUP BY Region;
SELECT GROUP_CONCAT(DISTINCT Continent ORDER BY Continent SEPARATOR '/') FROM Country;

SELECT SUBSTR(a, 1, 2) AS State, SUBSTR(a, 3) AS SCode, SUBSTR(b, 1, 2) AS Country,
  SUBSTR(b, 3) AS CCode FROM t;

locate(‘bar’,’foobarbaz’) – 显示bar在foobarbaz的位置
reverse(name) -- 反转大小写
select 7 DIV 3  --整除

SELECT CURRENT_TIMESTAMP();
SELECT UNIX_TIMESTAMP(); – 表示19700101至今过去的秒数
SELECT UTC_TIMESTAMP();

SELECT DAYNAME(NOW());
SELECT DAYOFMONTH(NOW());
SELECT DAYOFWEEK(NOW());
SELECT DAYOFYEAR(NOW());
SELECT MONTHNAME(NOW());

SELECT TIME_TO_SEC('00:03:00');  -- 时间变秒
SELECT SEC_TO_TIME(180); --秒变时间

SELECT ADDTIME('1:00:00', '00:29:45');
SELECT SUBTIME('1:30:00', '00:15:00');

SELECT ADDDATE('2008-01-02', INTERVAL 31 DAY);
SELECT SUBDATE('2008-01-02', INTERVAL 31 DAY);

--时区
-- 可以在https://en.wikipedia.org/wiki/List_of_tz_database_time_zones 发现所有时区清单
SHOW VARIABLES LIKE '%time_zone%';
SELECT NOW();
SET time_zone = 'US/Eastern';
SHOW VARIABLES LIKE '%time_zone%';
SELECT NOW();

--时间格式
SELECT DATE_FORMAT(NOW(), '%W, %D of %M, %Y');
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %T');


-- 事务
-- 使用事务会增加性能
START TRANSACTION;
INSERT INTO widgetSales ( inv_id, quan, price ) VALUES ( 1, 5, 500 );
UPDATE widgetInventory SET onhand = ( onhand - 5 ) WHERE id = 1;
COMMIT;

START TRANSACTION;
INSERT INTO widgetInventory ( description, onhand ) VALUES ( 'toy', 25 );
ROLLBACK;

--  触发器
--  01 Updating a table with a trigger

CREATE TABLE widgetCustomer ( id SERIAL, name VARCHAR(255), last_order_id BIGINT );
CREATE TABLE widgetSale ( id SERIAL, item_id BIGINT, customer_id BIGINT, quan INT, price DECIMAL(9,2) );

INSERT INTO widgetCustomer (name) VALUES ('Bob');
INSERT INTO widgetCustomer (name) VALUES ('Sally');
INSERT INTO widgetCustomer (name) VALUES ('Fred');

SELECT * FROM widgetCustomer;

CREATE TRIGGER newWidgetSale AFTER INSERT ON widgetSale
    FOR EACH ROW
    UPDATE widgetCustomer SET last_order_id = NEW.id WHERE id = NEW.customer_id
;

INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (1, 3, 5, 19.95);
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (2, 2, 3, 14.95);
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (3, 1, 1, 29.95);
SELECT * FROM widgetSale;
SELECT * FROM widgetCustomer;

-- 02 Preventing automatic updates with a trigger
DROP TABLE IF EXISTS widgetSale;

CREATE TABLE widgetSale ( id SERIAL, item_id BIGINT, customer_id BIGINT, quan INT, price DECIMAL(9,2), reconciled INT );
INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (1, 3, 5, 19.95, 0);
INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (2, 2, 3, 14.95, 1);
INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (3, 1, 1, 29.95, 0);
SELECT * FROM widgetSale;

-- 下面DELIMITER 做用时允许在语句中出现分号,不至于被当作语句结束而执行。
DELIMITER //
CREATE TRIGGER updateWidgetSale BEFORE UPDATE ON widgetSale
    FOR EACH ROW
    BEGIN
        IF ( SELECT reconciled FROM widgetSale WHERE id = NEW.id ) > 0 THEN
            -- 这里 signal xxxx  是抛出异常
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Error: cannot update reconciled row in widgetSale';
         END IF;
    END
//
DELIMITER ;

START TRANSACTION;
UPDATE widgetSale SET quan = quan + 9 WHERE id = 2;
COMMIT;

SELECT * FROM widgetSale;

-- Alternate error code for MySQL versions prior to 5.5
        IF ( SELECT reconciled FROM widgetSale WHERE id = NEW.id ) > 0 THEN
            UPDATE `Error: cannot update reconciled row in widgetSale` SET x=1;
        END IF;

-- 03 Logging transactions with a trigger

DROP TABLE IF EXISTS widgetSale;

CREATE TABLE widgetSale ( id SERIAL, item_id BIGINT, customer_id BIGINT, quan INT, price DECIMAL(9,2) );
CREATE TABLE widgetLog ( id SERIAL, stamp TIMESTAMP, event VARCHAR(255), username VARCHAR(255),
    tablename VARCHAR(255), table_id BIGINT);

DELIMITER //
CREATE TRIGGER stampSale AFTER INSERT ON widgetSale
    FOR EACH ROW
    BEGIN
        UPDATE widgetCustomer SET last_order_id = NEW.id
            WHERE widgetCustomer.id = NEW.customer_id;
        INSERT INTO widgetLog (event, username, tablename, table_id)
            VALUES ('INSERT', 'TRIGGER', 'widgetSale', NEW.id);
    END
//
DELIMITER ;

INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (1, 3, 5, 19.95);
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (2, 2, 3, 14.95);
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (3, 1, 1, 29.95);

Stored Routines
--  stored functions 

DROP FUNCTION IF EXISTS track_len;
CREATE FUNCTION track_len(seconds INT)
RETURNS VARCHAR(16) DETERMINISTIC
    RETURN CONCAT_WS(':', seconds DIV 60, LPAD(seconds MOD 60, 2, '0' ));

SELECT title, track_len(duration) FROM track;

-- stored procedures

-- with parameter
DROP PROCEDURE IF EXISTS list_albums;

DELIMITER //
CREATE PROCEDURE list_albums (a VARCHAR(255))
  BEGIN
    SELECT a.artist AS artist,
        a.title AS album,
        t.title AS track,
        t.track_number AS trackno,
        track_len(t.duration) AS length
      FROM track AS t
      JOIN album AS a
        ON a.id = t.album_id
       WHERE a.artist LIKE a
      ORDER BY artist, album, trackno
    ;
  END //

DELIMITER ;
CALL list_albums('%hendrix%');

-- with output parameter
DROP PROCEDURE IF EXISTS total_duration;

DELIMITER //
CREATE PROCEDURE total_duration (a VARCHAR(255), OUT d VARCHAR(255))
  BEGIN
    SELECT track_len(SUM(duration)) INTO d
      FROM track
      WHERE album_id IN (SELECT id FROM album WHERE artist LIKE a)
    ;
  END //

DELIMITER ;
CALL total_duration('%hendrix%', @dur);
SELECT @dur;

posted @ 2015-09-04 10:42  Haseo  阅读(271)  评论(0编辑  收藏  举报