SELECT `emp_no`, `from_date`, `salary` FROM `salaries` WHERE `salary` = 60117;
SELECT `emp_no`, `from_date`, `salary` FROM `salaries` WHERE `salary` < 60117;
//--------------------------
SELECT `emp_no`, `from_date`, `salary` FROM `salaries` WHERE `salary` BETWEEN 60117 AND 60300;
-- 相当于
SELECT `emp_no`, `from_date`, `salary` FROM `salaries` WHERE `salary` <= 60300 AND `salary` >= 60117;
可以将多个条件组合起来,用于连接条件表达式
>#条件必须全部满足
SELECT `emp_no`, `from_date`, `salary` FROM `salaries`
WHERE `from_date` = "2000-01-01" AND `salary` < 40000;
> ***
>#条件满足其中之一就可:结果包含了 "2000-01-01"和"1995-01-01"
SELECT distinct `from_date` FROM `salaries`
WHERE `from_date` = "2000-01-01" OR `from_date` = "1995-01-01";
> ***
> #in与or的意义相同
SELECT distinct `from_date` FROM `salaries`
WHERE `from_date` in ("2000-01-01", "1995-01-01");
> ***
> #not表示对条件取反
SELECT distinct `from_date` FROM `salaries`
WHERE `from_date` not in ("2000-01-01", "1995-01-01");
SELECT row_name FROM table_name WHERE row_name = 值1 OR row_name=值2 AND row_name1 > 值3 ;
where子句中可以用任意个AND和OR来组织过滤条件,但是AND的优先级更高,因此此句相当于SELECT row_name FROM table_name WHERE row_name = 值1 OR (row_name=值2 AND row_name1 > 值3)。
在where子句中使用圆括号:因为圆括号具有比AND和OR操作符高的计算次序,DBMS会先过滤()内的条件。因此:任何时候使用具有AND和OR操作符的where子句,都应该使用()明确分组操作符,不要依赖默认计算次序,使用()没有什么坏处,它能消除歧义。
- WHERE中的NOT子句有且只有一个功能,就是否定它之后的所有的任何条件 MYSQL支持使用NOT对IN,BETWEEN和EXISTS子句取反,这与多数其他DBMS允许使用NOT对各种条件取反有很大的差别。
请不要滥用NOT
IN VS OR:
SELECT `emp_no`, `first_name` FROM `employees` WHERE `first_name` LIKE 'Chri%';
SELECT `emp_no`, `first_name` FROM `employees` WHERE `first_name` LIKE '%ri%';
SELECT `emp_no`, `first_name` FROM `employees` WHERE `first_name` LIKE 'C%el'; -- 用得少
SELECT `emp_no`, `first_name` FROM `employees` WHERE `first_name` LIKE '_ristine';
>SELECT `cust_id` FROM `customers` WHERE `cust_email` IS NULL;
> ***
>SELECT `cust_id` FROM `customers` WHERE `cust_email` IS NOT NULL;
存储在数据库表中的数据一般不是应用程序需要的格式,一般需要对结果进行拼接、大小写转换、计算总和等处理。
再数据库服务器上面完成这些操作比在客户机中完成要快很多,因为DBMS是设计来快速有效的完成这种处理的.
计算字段并不实际存在于数据库表中,计算字段是运行时在select语句内创建的。
SELECT CONCAT(
vend_name
, ‘(’,vend_country
, ‘)’) FROMvendors
ORDER BYvend_name
;
SELECT CONCAT(RTRIM(
vend_name
), ‘(’, LTRIM(vend_country
), ‘)’) AS vend_title FROMvendors
ORDER BYvend_name
;
注意:多数DBMS使用+或者||来实现拼接,MySQL使用Concat()函数来实现。
包含NULL的运算,其结果也是NULL
SELECT
prod_id
,quantity
,item_price
,quantity
*item_price
AS ‘单价’ FROMorderitems
WHEREorder_num
= 20005;
SELECT 100+90; 两个操作数都是数值型,则做加法运算
SELECT “100”+90; 如果其中一方为字符型,试图将字符型数值转换成数值型,如果转换成功,则做加法运算
SELECT “jo”+90; 如果转换失败,则将字符型数值转换成0
SELECT NULL + 10; 只要其中有一方为null,那么结果一定是null
SELECT IFNULL(
cust_email
, 0),cust_email
FROMcustomers
;
SELECT ISNULL(cust_email
),cust_email
FROMcustomers
;
字段
, newValue1):如果所查询的字段为空,则设置为newValue1concat:连接
substr:截取子串
upper:大写
lower:小写
replace:替换
length:获取字节长度
trim:去除前后空格
lpad:左填充
rpad:右填充
instr:获取子串第一次出现的索引
DATA()日期提取
SELECT
cust_id
,order_num
FROMorders
WHEREorder_date
= ‘2005-09-01’; #不建议使用
SELECT
cust_id
,order_num
FROMorders
WHERE DATE(order_date
) = ‘2005-09-01’; #推荐使用
#DATE表示从order_date中提取yyyy-mm-dd
#查询2005年9月的订单
SELECTcust_id
,order_num
FROMorders
WHERE YEAR(order_date
) = 2005 AND MONTH(order_date
) = 8;
可以获取指定的部分,年,月,日,小时,分钟,秒
SELECT YEAR(NOW()) 年, YEAR(‘1998-1-1’) AS ‘1998’;
SELECT YEAR(NOW()) 年, MONTH(NOW()) 月, DAY(NOW()) 日, HOUR(NOW()) 时, MINUTE(NOW()) 分, SECOND(NOW()) 秒;
SELECT MONTHNAME(NOW()) 月;
now:返回当前系统日期+时间
SELECT NOW();
curdate 返回当前系统日期,不包含时间
SELECT CURDATE();
curdate 返回当前系统时间,不包含时间日期
SELECT CURTIME();
str_to_data:将日期格式的字符转换成功指定格式的字符
SELECT STR_TO_DATE(‘1995-11-15’, ‘%Y-%c-%d’);
SELECT STR_TO_DATE(‘2002 11-15’, ‘%Y %c-%d’);
DATE_FORMAT:将日期转换成字符
SELECT DATE_FORMAT(NOW(), “%y年%m月%d日”);
日期和时间采用相应的数据类型和特殊的格式存储,以便能快速和有效的过滤,并且节省物理存储空间。一般来说,应用程序不使用用来存储日期和时间的格式,因此日期和时间函数总是被用来读取,统计和处理这些值。由于这个原因,日期和时间函数在MySQL语言中具有重要作用。
推荐,当指定插入删除或者过滤时,日期必须为yyyy-mm-dd[首选的日期格式]
varchar类型转换int类型或者浮点数
```sql
select * from gyzd_yysinfo order by cast(yysid as SIGNED INTEGER)
或者
select * from gyzd_yysinfo order by cast(yysid as UNSIGNED INTEGER)
浮点数
select cast("23333.3333" as decimal(9,2));
## 6.11、全文本搜索
并非所有的引擎的支持全文本搜索
两个最常用的引擎是:MyISAM(支持),InnoDB(不支持)
通配符和正则表达式的缺点:
性能:这两个匹配通常要求MySSQL尝试匹配表中所有行,而且这些搜索极少使用表索引--》查询耗时
明确控制:很难明确匹配什么和不匹配什么
等等
全文本搜索优点:
### 启动全文本搜索
```sql
>CREATE TABLE productnotes
(
note_id INT NOT NULL AUTO_INCREMENT,
prod_id CHAR(10) NOT NULL,
note_date DATETIME NOT NULL,
note_text TEXT NULL ,
PRIMARY KEY(note_id),
FULLTEXT(note_text)
) ENGINE=MYISAM;
SELECT
note_text
FROMproductnotes
WHERE MATCH(note_text
) AGAINST(‘raBBit’); #不区分大小写
SELECTnote_text
FROMproductnotes
WHEREnote_text
LIKE ‘%raBBit%’;
LIKE VS 全文本搜索
#不包含raBBit的rank=0,包含的会根据文本算出等级
SELECTnote_text
, MATCH(note_text
) AGAINST(‘raBBit’) AS rank FROMproductnotes
;
#查询所有提到anvils的注释
#1、全文本搜索:返回包含anvils
SELECTnote_text
FROMproductnotes
WHERE MATCH(note_text
) AGAINST(‘anvils’); #不区分大小写
#2、查询扩展:返回包含使用全文本扩展查询出来的句子中的某些单词的行
SELECTnote_text
FROMproductnotes
WHERE MATCH(note_text
) AGAINST(‘anvils’ WITH QUERY EXPANSION);
即使没有fulltext索引也可以用,但是很慢
#查询包含heavy的所有行
SELECTnote_text
FROMproductnotes
WHERE MATCH(note_text
) AGAINST(‘heavy’ IN BOOLEAN MODE);
#至少包含rabbit或者heavy中的一个的行
SELECTnote_text
FROMproductnotes
WHERE MATCH(note_text
) AGAINST(‘rabbit heavy’ IN BOOLEAN MODE);
#包含rabbit heavy的行。是匹配rabbit heavy一个词
SELECTnote_text
FROMproductnotes
WHERE MATCH(note_text
) AGAINST(’“rabbit heavy”’ IN BOOLEAN MODE);
#查询包含heavy但是不包含任意以extre开始的词的行
SELECTnote_text
FROMproductnotes
WHERE MATCH(note_text
) AGAINST(‘heavy -extre*’ IN BOOLEAN MODE);
SELECTnote_text
FROMproductnotes
WHERE MATCH(note_text
) AGAINST(’+rabbit, +gua*’ IN BOOLEAN MODE);
事务时需要在同一个处理单元中执行地一系列更新处理地集合。比如A给B转账。B增加地同时必须A减少。
DBMS地事务遵循ACID特性,也就是
事务并没有标准地开始执行,随着DBMS地不同而不同。
–MySQL
START TRANSACTION;
-- 运动T恤的销售单价下调1000日元
UPDATE Product
SET sale_price = sale_price - 1000
WHERE product_name = '运动T恤';
-- T恤的销售单价上浮1000日元
UPDATE Product
SET sale_price = sale_price + 1000
WHERE product_name = 'T恤';
COMMIT;
–SQL Server, PostgreSQL
BEGIN TRANSACTION;
-- 运动T恤的销售单价下调1000日元
UPDATE Product
SET sale_price = sale_price - 1000
WHERE product_name = '运动T恤';
-- T恤的销售单价上浮1000日元
UPDATE Product
SET sale_price = sale_price + 1000
WHERE product_name = 'T恤';
COMMIT;
Oracle, DB2
-- 运动T恤的销售单价下调1000日元
UPDATE Product
SET sale_price = sale_price - 1000
WHERE product_name = '运动T恤';
-- T恤的销售单价上浮1000日元
UPDATE Product
SET sale_price = sale_price + 1000
WHERE product_name = 'T恤';
ROLLBACK;