mysql contract_MYSQL必知必会学习笔记

8.1.1 百分号( %)通配符

最常使用的通配符是百分号( %)。在搜索串中, %表示任何字符出现

任意次数。例如,为了找出所有以词jet起头的产品,可使用以下SELECT

语句:

SELECT prod_id,prod_name FROM products WHERE prod_name LIKE 'jet%';

区分大小写 根据MySQL的配置方式,搜索可以是区分大小

写的。如果区分大小写, 'jet%' 与 JetPack 1000将不匹配。

搜索模式'%anvil%' 表示匹配任何位置包含文本anvil的值,而不论它之前或之后出现什么字符。

SELECT prod_id,prod_name FROM products WHERE prod_name LIKE '%anvil%';

通配符也可以出现在搜索模式的中间,虽然这样做不太有用。下面

的例子找出以s起头以e结尾的所有产品:

SELECT prod_name FROM products Where prod_name LIKE 's%e';

重要的是要注意到,除了一个或多个字符外, %还能匹配0个字符。 %

代表搜索模式中给定位置的0个、 1个或多个字符。

8.1.2 下划线(_)通配符

另一个有用的通配符是下划线(_)。下划线的用途与%一样,但下划

线只匹配单个字符而不是多个字符。

SELECT prod_id,prod_name FROM products WHERE prod_name LIKE '_ ton anvil';

任意字符

SELECT prod_id,prod_name FROM products WHERE prod_name LIKE '% ton anvil';

基本字符匹配

我们从一个非常简单的例子开始。下面的语句检索列prod_name包含

文本1000的所有行:

SELECT prod_name FROM products WHERE prod_name REGEXP '1000' ORDER BY prod_name;

REGEXP后所跟的东西作为正则表达式(与文字正文1000匹配的一个正则表达式)处理。

SELECT prod_name FROM products WHERE prod_name REGEXP '.000' ORDER BY prod_name;

SELECT prod_name FROM products WHERE prod_name REGEXP '1000|2000' ORDER BY prod_name;

匹配几个字符之一

SELECT prod_name FROM products WHERE prod_name REGEXP '[123] Ton' ORDER BY prod_name;

这里,使用了正则表达式[123] Ton。 [123] 定义一组字符,它

的意思是匹配1或2或3,因此, 1 ton和2 ton都匹配且返回(没

有3 ton)。

SELECT prod_name FROM products WHERE prod_name REGEXP '[1-5] Ton' ORDER BY prod_name;

要找出包含. 字符的值 为了匹配特殊字符,必须用\\为前导。 \\-表示查找-, \\. 表示查找. 。

SELECT vend_name FROM vendors WHERE vend_name REGEXP '\\.' ORDER BY vend_name;

正则表达式\\([0-9] sticks?\\) 需要解说一下。 \\(匹配( ,

[0-9] 匹配任意数字(这个例子中为1和5), sticks?匹配stick

和sticks( s后的?使s可选,因为?匹配它前面的任何字符的0次或1次出

现), \\) 匹配) 。没有?,匹配stick和sticks会非常困难。

SELECT prod_name FROM products WHERE prod_name REGEXP '\\([0-9]sticks?\\)'

[:digit:] 匹配任意数字,因而它为数字的一个集

合。 {4}确切地要求它前面的字符(任意数字)出现4次,所以

[[:digit:]]{4}匹配连在一起的任意4位数字。

SELECT prod_name FROM products WHERE prod_name REGEXP '[[:digit:]]{4}' ORDER BY prod_name;

上面的例子也可以如下编写:

SELECT prod_name FROM products WHERE prond_name REGEXP '[0-9][0-9][0-9][0-9]' ORDER BY prod_name;

^匹配串的开始。因此, ^[0-9\\.] 只在. 或任意数字为串中第

一个字符时才匹配它们。没有^, 则还要多检索出4个别的行(那

些中间有数字的行)。

SELECT prod_name FROM products WHERE prod_name REGEXP'^[0-9\\.]' ORDER BY prod_name;

简单的正则表达式测试 可以在不使用数据库表的情况下用

SELECT来测试正则表达式。 REGEXP检查总是返回0(没有匹配)

或1(匹配)。可以用带文字串的REGEXP来测试表达式,并试

验它们。相应的语法如下:

SELECT 'hello' REGEXP '[0-9]';

这个例子显然将返回0(因为文本hello中没有数字)。

SELECT Concat(vend_name,'(',vend_country,')') FROM vendors ORDER BY vend_name;

通过删除数据右侧多余的空格来整理数据,这可以

使用MySQL的RTrim() 函数来完成

SELECT CONCAT(RTRIM(vend_name), ' (',RTRIM(vend_country), ')') FROM vendors ORDER BY vend_name;

SELECT CONCAT(RTRIM(vend_name), ' (',RTRIM(vend_country), ')') AS vend_title FROM vendors ORDER BY vend_name;

SELECT prod_id,quantity,item_price FROM orderitems WHERE order_num = 20005;

SELECT prod_id,quantity,item_price,quantity*item_price AS expanded_price FROM orderitems WHERE order_num = 20005;

Upper()将文本转换为大写,因此本例子中每个供

应商都列出两次,第一次为vendors表中存储的值,第二次作

为列vend_name_upcase转换为大写。

SELECT vend_name,UPPER(vend_name) AS vend_name_upcase FROM vendors ORDER BY vend_name;

使用 Soundex()函数进行搜索,它匹配所有发音类似于

Y.Lie的联系名:

SELECT cust_name,cust_contract FROM customers WHERE SOUNDEX(cust_contract) = SOUNDEX('Y Lie');

SELECT cust_id, order_num FROM orders WHERE DATE(order_date) = '2005-09-01';

SELECT cust_id, order_num FROM orders WHERE YEAR(order_date) = 2005 AND MONTH(order_date) = 9;

下面的例子使用AVG() 返回products表中所有产品的平均价格:

SELECT AVG(prod_price) AS avg_price FROM products;

AVG() 也可以用来确定特定列或行的平均值。 下面的例子返回特定供

应商所提供产品的平均价格:

SELECT AVG(prod_price) AS avg_price FROM products WHERE vend_id = 1003;

AVG() 只能用来确定特定数值列的平均值, 而

且列名必须作为函数参数给出。为了获得多个列的平均值,

必须使用多个AVG() 函数.

返回customers表中客户的总数:

SELECT COUNT(*) AS num_cust FROM customers;

下面的例子只对具有电子邮件地址的客户计数:

SELECT COUNT(count_email) AS num_cust FROM customers;

MAX() 返回products表中最贵的物品的价格。

SELECT MAX(prod_price) AS max_price FROM products;

SELECT SUM(quantity) AS item_ordered FROM orderitems WHERE order_num = 20005;

SELECT SUM(item_price*quantity) AS total_price FROM orderitems WHERE order_num = 20005;

SELECT AVG(DISTINCT prod_price) AS avg_price FROM products WHERE vend_id = 1003;

SELECT COUNT(*) AS num_items,

MIN(prod_price) AS price_min,

MAX(prod_price) AS price_max,

AVG(prod_price) AS price_avg

FROM products;

SELECT COUNT(*) AS num_prods FROM products WHERE vend_id=1003;

SELECT vend_id,COUNT(*) AS num_prods FROM products GROUP BY vend_id;

GROUP BY子句必须出现在WHERE子句之后, ORDER BY子句之前。

HAVING和WHERE的差别 这里有另一种理解方法, WHERE在数据

分组前进行过滤, HAVING在数据分组后进行过滤。这是一个重

要的区别, WHERE排除的行不包括在分组中。这可能会改变计

算值,从而影响HAVING子句中基于这些值过滤掉的分组。

列出具有2个(含)以上、价格

为10(含)以上的产品的供应商:

SELECT vend_id,COUNT(*) AS num_prods FROM products WHERE prod_price>=10 GROUP BY vend_id HAVING COUNT(*)>=2;

COUNT(*) 函数返回在给定的选择中被选的行数。

检索包含物品TNT2的所有订单的编号。

SELECT order_num FROM orderitems WHERE prod_id = 'TNT2';

检索具有前一步骤列出的订单编号的所有客户的ID。

SELECT cust_id FROM orders WHERE order_num IN(20005,20007);

现在,把第一个查询(返回订单号的那一个)变为子查询组合两个

查询。请看下面的SELECT语句:

SELECT cust_id FROM orders WHERE order_num IN (SELECT order_num FROM orderitems WHERE prod_id='TNT2');

现在得到了订购物品TNT2的所有客户的ID。下一步是检索这些客户

ID的客户信息。检索两列的SQL语句为:

SELECT cust_name,cust_contract FROM customers WHERE cust_id IN (10001,10004);

可以把其中的WHERE子句转换为子查询而不是硬编码这些客户 ID:

SELECT cust_name,cust_contract FROM customers WHERE cust_id IN(SELECT cust_id FROM orders WHERE order_num IN(SELECT order_num FROM orderitems WHERE prod_id='TNT2'));

下面的代码对客户 10001的订单进行计数

SELECT COUNT(*) AS orders FROM orders WHERE cust_id = 10001;

为了对每个客户执行COUNT(*)计算,应该将COUNT(*)作为一个子查

询。请看下面的代码:

SELECT cust_name,cust_state,(SELECT COUNT(*) FROM orders WHERE orders.cust_id = customers.cust_id) AS orders FROM customers ORDER BY cust_name;

创建联结

SELECT vend_name, prod_name,prod_price FROM vendors,products WHERE vendors.vend_id = products.vend_id ORDER BY vend_name,prod_name;

SELECT vend_name, prod_name,prod_price FROM vendors INNER JOIN products ON vendors.vend_id = products.vend_id;

要检索所有客户及每个客户所

下的订单数,下面使用了COUNT()函数的代码可完成此工作:

SELECT customers.cust_name,customers.cust_id,COUNT(orders.order_num) AS num_ord FROM customers INNER JOIN orders ON customers.cust_id = orders.cust_id GROUP BY customers.cust_id;

此SELECT语句使用INNER JOIN将customers和orders表互相关联。

GROUP BY 子 句 按 客 户 分 组 数 据 , 因 此 , 函 数 调 用 COUNT

(orders.order_num)对每个客户的订单计数,将它作为num_ord返回。

有两种基本情况,其中需要使用组合查询:

 在单个查询中从不同的表返回类似结构的数据;

 对单个表执行多个查询,按单个查询返回数据。

SELECT vend_id,prod_id,prod_price FROM products WHERE prod_price <=5;

SELECT vend_id,prod_id,prod_price FROM products WHERE vend_id IN (1001,1002);

SELECT vend_id,prod_id,prod_price FROM products WHERE prod_price <=5 UNION SELECT vend_id,prod_id,prod_price FROM products WHERE vend_id IN (1001,1002);

进行全文本搜索

在索引之后,使用两个函数Match() 和Against() 执行全文本搜索,

其中Match() 指定被搜索的列, Against() 指定要使用的搜索表达式。

SELECT note_text FROM productnotes WHERE Match(note_text) Against('rabbit');

此SELECT语句检索单个列note_text。由于WHERE子句,一个全

文本搜索被执行。 Match(note_text) 指示MySQL针对指定的

列进行搜索, Against('rabbit') 指定词rabbit作为搜索文本。由于有

两行包含词rabbit,这两个行被返回。

SELECT note_text FROM productnotes WHERE note_text LIKE '%rabbit%';

客户 10005现在有了电子邮件地址,因此他的记录

需要更新,语句如下:

UPDATE customers SET count_email = 'elmer@fudd.com' WHERE cust_id = 10005;

UPDATE customers SET cust_name = 'The Fudds',count_email = 'elmer@fudd.com' WHERE cust_id = 10005;

CREATE PROCEDURE ordertotal(

IN onumber INT,

OUT ototal DECIMAL(8,2))

BEGIN

SELECT SUM(item_price*quantity)

FROM orderitems

WHERE order_num = onumber

INTO ototal;

END;

CALL ordertotal (20005,@total);

SELECT @total;

为了得到另一个订单的合计显示,需要再次调用存储过程,然后重

新显示变量:

CALL ordertotal(20009, @total);

SELECT @total;

考虑这个场景。你需要获得与以前一样的订单合计,但需要对合计

增加营业税,不过只针对某些顾客(或许是你所在州中那些顾客)。那么,

你需要做下面几件事情:

 获得合计(与以前一样);

 把营业税有条件地添加到合计;

 返回合计(带或不带税)。

存储过程不太牢靠

创建游标

CREATE PROCEDURE processorders()

BEGIN

DECLARE ordernumbers CURSOR

FOR

SELECT order_num FROM orders;

OPEN ordernumbers;

CLOSE ordernumbers;

END;

这个存储过程并没有做很多事情, DECLARE语句用来定义和命

名游标,这里为ordernumbers。 存储过程处理完成后,游标就

消失(因为它局限于存储过程)。

在定义游标之后,可以打开它。

OPEN ordernumbers;

游标处理完成后,应当使用如下语句关闭游标:

CLOSE ordernumbers;

DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;

触发器用CREATE TRIGGER语句创建。下面是一个简单的例子:

CREATE TRIGGER newproduct AFTER INSERT ON products FOR EACH ROW SELECT 'product added';

CREATE TRIGGER neworder AFTER INSERT ON orders FOR EACH ROW SELECT NEW.order_num;

下面的例子保证州名缩写总是大写(不管UPDATE语句中给出的是大

写还是小写):

CREATE TRIGGER updatevendor BEFORE UPDATE ON vendors FOR EACH ROW SET NEW.vend_state=Upper(NEW.vend_state);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值