mysql 连接查询和子查询

        学习了mysql基本查询, 接着学习连接查询和子查询。

4,连接查询

        连接是关系数据库模型的主要特点。连接查询是关系数据库中最主要的查询,主要包括内连接、外连接等。通过连接运算符可以实现多个表查询。在关系数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的所有信息存放在一个表中。当查询数据时,通过连接操作查询出存放在多个表中的不同实体的信息。当两个或多个表中存在相同意义的字段时,便可以通过这些字段对不同的表进行连接查询。本节将介绍多表之间的内连接查询、外连接查询以及复合条件连接查询。

1,内连接查询

        内连接(INNER JOIN)使用比较运算符进行表间某((些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行,组合成新记录,也就是说,在内连接查询中,只有满足条件的记录才能出现在结果关系中。

首先创建数据表suppliers,SQL语句如下:

CREATE TABLE suppliers(
  s_id int NOT NULL AUTO_INCREMENT,
  s_name char(50) NOT NULL,
  s_city char (50) NULL,
  s_zip char(10) NULL,
  s_call CHAR(50) NOT NULL,
  PRIMARY KEY (s_id)
);

插入数据,SQL语句如下:

INSERT INTO suppliers(s_id, s_name, s_city, s_zip, s_call)
VALUES(101,'FastFruit Ine.', 'Tianjin', '300000', '148075'),
(102, 'LT Supplies', 'Chongqing', '400000', '44333'),
(103, 'ACME', 'Shanghai', '200000', '90046'),
(104, 'FNK Ine.', 'Zhongshan', '528437', '11111'),
(105, 'Good Set', 'Taiyuang', '030000', '22222'),
(106, 'Just Eat ours', 'Beijing' , '010', '45678'),
(107, 'DK inc.', 'Zhengzhou', '450000', '33332');

        【例46】在fruits表和suppliers表之间使用内连接查询。查询之前,查看两个表的结构:

DESC fruits;

​​​​​​​DESC suppliers;

        由结果可以看到 fruits表和 suppliers 表中都有相同数据类型的字段s_id两个表通过s_id字段建立联系。接下来从 fruits表中查询f_name、f_price字段,从suppliers表中查询s_id、s_name,SQL语句如下:

SELECT suppliers.s_id, s_name,f_name, f_price
FROM fruits, suppliers
WHERE fruits.s_id=suppliers.s_id;

        在这里,SELECT语句与前面所介绍的一个最大的差别是:SELECT后面指定的列分别属于两个不同的表,(f_name,f_price)在表 fruits中,而另外两个字段在表supplies中;同时FROM子句列出了两个表fruits和 suppliers。WHERE子句在这里作为过滤条件,指明只有两个表中的 s_id字段值相等的时候才符合连接查询的条件。从返回的结果可以看到,显示的记录是由两个表中不同列值组成的新记录。

        提示:因为fruits 表和suppliers表中有相同的字段s_id,因此在比较的时候,需要完全限定表名(格式为“表名.列名”),如果只给出s_id,MySQL将不知道指的是哪一个,并返回错误信息。

        下面的内连接查询语句返回与前面完全相同的结果。

        【例47】在 fruits表和 suppliers表之间,使用INNER JOIN语法进行内连接查询,SQL语句如下:

SELECT suppliers.s_id, s_name,f_name, f_price
FROM fruits INNER JOIN suppliers
ON fruits.s_id = suppliers.s_id;

        在这里的查询语句中,两个表之间的关系通过INNER JOIN 指定。使用这种语法的时候,连接的条件使用ON子句给出而不是WHERE,ON和 WHERE后面指定的条件相同。

        使用WHERE子句定义连接条件比较简单明了,而 INNER JOIN语法是ANSI SQL的标准规范,使用INNER JOIN连接语法能够确保不会忘记连接条件,而且,WHERE子句在某些时候会影响查询的性能。

        如果在一个连接查询中,涉及的两个表都是同一个表,这种查询称为自连接查询。自连接是一种特殊的内连接,它是指相互连接的表在物理上为同一张表,但可以在逻辑上分为两张表。

        【例48】查询供应f_id='al'的水果供应商提供的水果种类,SQL语句如下:

SELECT f1.f_id, f1.f_name
FROM fruits AS f1, fruits AS f2
WHERE f1.s_id = f2.s_id AND  f2.f_id = 'a1';

        此处查询的两个表是相同的表,为了防止产生二义性,对表使用了别名,ftuits 表第Ⅰ次出现的别名为fl,第2次出现的别名为f2,使用SELECT语句返回列时明确指出返回以fl为前缀的列的全名,WHERE 连接两个表,并按照第2个表的f_id对数据进行过滤,返回所需数据。

2,外连接查询

        外连接查询将查询多个表中相关联的行,内连接时,返回查询结果集合中的仅是符合查询条件和连接条件的行。但有时候需要包含没有关联的行中数据,即返回查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左外连接或左连接)、右表(右外连接或右连接)或两个连接表(全外连接)中的所有数据行。外连接分为左外连接或左连接和右外连接或右连接:

        LEFT JOIN(左连接):返回包括左表中的所有记录和右表中连接字段相等的记录,

        RIGHT JOIN(右连接):返回包括右表中的所有记录和左表中连接字段相等的记录。

1,LEFT JOIN(左连接)

        左连接的结果包括LEFT OUTER子句中指定的左表的所有行,而不仅仅是连接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果行中,右表的所有选择列表列均为空值。

        首先创建表orders,SQL语句如下:

CREATE TABLE orders
(
  o_num int NOT NULL AUTO_INCREMENT,
  o_date datetime NOT NULL,
  c_id int NOT NULL,
  PRIMARY KEY (o_num)
);

插入数据,SQL语句如下:

INSERT INTO orders(o_num,o_date, c_id)
VALUES(30001, '2008-09-01', 10001),
(30002, '2008-09-12', 10003),
(30003, '2008-09-30', 10004),
(30004, '2008-10-03', 10005),
(30005, '2008-10-08', 10001);

        【例49】在customers表和 orders 表中,查询所有客户,包括没有订单的客户,SQL语句如下:

SELECT customers.c_id, orders.o_num
 FROM customers LEFT OUTER JOIN orders 
ON  orders.c_id = customers.c_id;

        结果显示了5条记录,ID 等于10002的客户目前并没有下订单,所以对应的orders 表中并没有该客户的订单信息,所以该条记录只取出了customers 表中相应的值,而从 orders表中取出的值为空值NULL。

2,RIGHT JOIN(右连接)

        右连接是左连接的反向连接,将返回右表的所有行。如果右表的某行在左表中没有匹配行,左表将返回空值。

        【例50】在 customers表和 orders表中,查询所有订单,包括没有客户的订单,SQL语句如下:

SELECT customers.c_id, orders.o_num
 FROM customers RIGHT OUTER JOIN orders 
ON  orders.c_id = customers.c_id;

        结果显示了5条记录,订单号等于30004的订单的客户可能由于某种原因取消了该订单,对应的customers 表中并没有该客户的信息,所以该条记录只取出了ordes 表中相应的值。而从customers表中取出的值为空值NULL。

3,复合条件连接查询

        复合条件连接查询是在连接查询的过程中,通过添加过滤条件,限制查询的结果,使查询的结果更加准确。

        【例51】在 customers表和 orders表中,使用 INNER JOIN语法查询customers表中 ID为10001的客户的订单信息,SQL语句如下:

SELECT customers.c_id, orders.o_num
 FROM customers INNER JOIN orders 
ON customers.c_id = orders.c_id 
AND customers.c_id = 10001;

        结果显示,在连接查询时指定查询客户ID为10001的订单信息,添加了过滤条件之后返回的结果将会变少,因此返回结果只有两条记录。

        使用连接查询,并对查询的结果进行排序。

        【例52】在 fruits表和 suppliers表之间,使用INNER JOIN语法进行内连接查询,并对查询结果排序,SQL语句如下:

SELECT suppliers.s_id, s_name, f_name, f_price
FROM fruits INNER JOIN suppliers
ON fruits.s_id = suppliers.s_id  
ORDER BY fruits.s_id;

        由结果可以看到,内连接查询的结果按照 suppliers.s_id字段进行了升序排序。

5,子查询

        子查询指一个查询语句嵌套在另一个查询语句内部的查询,这个特性从MySQL 4.1开始引入。在SELECT子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一个表或者多个表。子查询中常用的操作符有ANY (SOME)、ALL、IN、EXISTS。子查询可以添加到SELECT、UPDATE 和DELETE 语句中,而且可以进行多层嵌套。子查询中也可以使用比较运算符,如“<”、“<=”、“>”、“>=”和“!=”等。本节将介绍如何在SELECT语句中嵌套子查询。

1,带ANY、SOME关键字的子查询

        ANY和 SOME关键字是同义词,表示满足其中任一条件,它们允许创建一个表达式对子查询的返回值列表进行比较,只要满足内层子查询中的任何一个比较条件,就返回一个结果作为外层查询的条件。

下面定义两个表num_tb1和 num_tb2:

CREATE table num_tb1 (num1 INT NOT NULL);


CREATE table num_tb2 (num2 INT NOT NULL);

分别向两个表中插入数据:

INSERT INTO num_tb1 values(1), (5), (13), (27);
INSERT INTO num_tb2 values(6), (14), (11), (20);

        ANY 关键字接在一个比较操作符的后面,表示若与子查询返回的任何值比较为TRUE,则返回TRUE。

        【例53】返回num_tb2表的所有num2列,然后将num_tbl中的num1的值与之进行比较,只要大于num2的任何1个值,即为符合查询条件的结果。

 SELECT num1 FROM num_tb1 WHERE num1 > ANY(SELECT num2 FROM num_tb2);

        在子查询中,返回的是num_tb2表的所有num2列结果(6,14,11,20),然后将num_tbl中的num1列的值与之进行比较,只要大于num2列的任意一个数即为符合条件的结果。

2,带ALL关键字的子查询

        ALL关键字与ANY和SOME不同,使用ALL时需要同时满足所有内层查询的条件。例如,修改前面的例子,用ALL关键字替换ANY。

        ALL关键字接在一个比较操作符的后面,表示与子查询返回的所有值比较为TRUE,则返回TRUE。

        【例54】返回num_tb1表中比 num_tb2表num2列所有值都大的值,SQL语句如下:

SELECT num1 FROM num_tb1 WHERE num1 > ALL (SELECT num2 FROM num_tb2);

        在子查询中,返回的是 num_tb2的所有num2列结果(6,14,11,20),然后将num_tbl 中的num1列的值与之进行比较,大于所有num2列值的num1值只有27,因此返回结果为27。

3,带EXISTS关键字的子查询

        EXISTS关键字后面的参数是一个任意的子查询,系统对子查询进行运算以判断它是否返回行,如果至少返回一行,那么EXISTS的结果为true,此时外层查询语句将进行查询;如果子查询没有返回任何行,那么EXISTS返回的结果是false,此时外层语句将不进行查询。

        【例55】查询suppliers表中是否存在.s_id=107的供应商,如果存在,则查询fruits 表中的记录,SQL语句如下:

SELECT * FROM fruits
WHERE EXISTS (SELECT s_name FROM suppliers WHERE s_id = 107);

        由结果可以看到,内层查询结果表明suppliers表中存在s_id=107的记录,因此EXISTS表达式返回true;外层查询语句接收 true之后对表fruits进行查询,返回所有的记录。

        EXISTS 关键字可以和条件表达式一起使用。

        【例56】查询suppliers表中是否存在s_id=107的供应商,如果存在,则查询fruits 表中的f_price大于10.20的记录,SQL语句如下:

SELECT * FROM fruits
WHERE f_price>10.20 
AND EXISTS (SELECT s_name FROM suppliers WHERE s_id = 107);

        由结果可以看到,内层查询结果表明suppliers表中存在s_id=107的记录,因此EXISTS表达式返回 true;外层查询语句接收true之后根据查询条件f _price > 10.20对fruits 表进行查询,返回结果为4条f _price大于10.20的记录。

        NOT EXISTS与 EXISTS使用方法相同,返回的结果相反。子查询如果至少返回一行,那么NOT EXISTS的结果为 false,此时外层查询语句将不进行查询;如果子查询没有返回任何行,那么NOT EXISTS返回的结果是true,此时外层语句将进行查询。

        【例57】查询suppliers表中是否存在s_id=107的供应商,如果不存在则查询fruits表中的记录,SQL语句如下:

SELECT * FROM fruits
WHERE NOT EXISTS (SELECT s_name FROM suppliers WHERE s_id = 107);

        查询语句“SELECT s_name FROM supplicrs WHEREs_id = 107”,对suppliers 表进行查询返回了一条记录,NOT EXISTS表达式返回false,外层表达式接收false,将不再查询 fruits表中的记录。

        提示:EXISTS和 NOT EXISTS的结果只取决于是否会返回行,而不取决于这些行的内容,所以这个子查询输入列表通常是无关紧要的。

4,带IN关键字的子查询

        IN关键字进行子查询时,内层查询语句仅仅返回一个数据列,这个数据列里的值将提供给外层查询语句进行比较操作。

        【例58】在 order_items表中查询f_id为c0的订单号,并根据订单号查询具有订单号的客户c_id,SQL语句如下:

 SELECT c_id FROM orders WHERE o_num IN
(SELECT o_num FROM order_items wHERE  f_id = 'c0')

        查询结果的c_id有两个值,分别为10001和10004。上述查询过程可以分步执行,首先内层子查询查出order_items表中符合条件的订单号,单独执行内查询,查询结果如下:

SELECT o_num FROM order_items wHERE  f_id = 'c0';

        可以看到,符合条件的 o_num列的值有两个:30003和 30005,然后执行外层查询,在orders表中查询订单号等于30003或30005的客户c_id。嵌套子查询语句还可以写为如下形式,实现相同的效果:

SELECT c_id FROM orders 
WHERE o_num IN (30003,30005);

        这个例子说明在处理SELECT语句的时候,MySQL 实际上执行了两个操作过程,即先执行内层子查询,再执行外层查询,内层子查询的结果作为外部查询的比较条件。

        SELECT语句中可以使用NOT IN关键字,其作用与IN正好相反。

        【例59】与前一个例子类似,但是在SELECT语句中使用NOT IN关键字,SQL语句如下:

SELECT c_id FROM orders WHERE o_num NOT IN
(SELECT o_num FROM order_items WHERE f_id = 'c0');

        这里返回的结果有3条记录,由前面可以看到,子查询返回的订单值有两个,即 30003和30005,但为什么这里还有值为10001的c_id呢?这是因为c_id等于10001的客户的订单不止一个,可以查看订单表orders中的记录。

SELECT * FROM orders;

        可以看到,虽然排除了订单号为30003和 30005的客户c_id,但是o_num为 30001的订单与30005都是10001号客户的订单。所以结果中只是排除了订单号,但是仍然有可能选择同一个客户。

        子查询的功能也可以通过连接查询完成,但是子查询使得MySQL代码更容易阅读和编写。

5,带比较运算符的子查询

        在前面介绍的带ANY、ALL关键字的子查询时使用了“>”比较运算符,子查询时还可以使用其他的比较运算符,如“<”、“<=”、“=”、“>=”和“!=”等。

        【例60】在 suppliers表中查询s_city等于“Tianjin”的供应商s_id,然后在 fruits表中查询所有该供应商提供的水果的种类,SQL语句如下:

SELECT s_id, f_name FROM fruits
WHERE s_id=
(SELECT s.s_id FROM suppliers AS s WHERE s.s_city = 'Tianjin');

        该嵌套查询首先在 suppliers 表中查找s_city 等于Tianjin的供应商的s_id,单独执行子查询查看s_id的值,执行下面的操作过程:

SELECT s.s_id FROM suppliers AS s WHERE s.s_city = 'Tianjin';

        然后在外层查询时,在fruits表中查找s_id等于101的供应商提供的水果的种类,查询结果如下:

        结果表明,“Tianjin”地区的供应商提供的水果种类有3种,分别为“apple”、“blackberry”、 “cherry”。

        【例61】在suppliers 表中查询s_city等于“Tianjin”的供应商s_id,然后在 fruits表中查询所有非该供应商提供的水果的种类,SQL语句如下:

SELECT s_id,f_name FROM fruits
WHERE s_id <>
(SELECT s.s_id FROM suppliers As s WHERE s.s_city = 'Tianjin');

        该嵌套查询执行过程与前面相同,在这里使用了不等于“心”运算符,因此返回的结果和前面正好相反。

6,合并查询结果

        利用UNION关键字,可以给出多条SELECT语句,并将它们的结果组合成单个结果集。合并时,两个表对应的列数和数据类型必须相同。各个SELECT语句之间使用UNION或UNION ALL关键字分隔。UNION不使用关键字ALL,执行的时候删除重复的记录,所有返回的行都是唯一的;使用关键字ALL的作用是不删除重复行也不对结果进行自动排序。基本语法格式如下:

SELECT column, . FROM tab1e1 UNION [ALL]
SELECT column, .. FROM table2

        【例62】查询所有价格小于9的水果的信息,查询s_id等于101和103所有的水果的信息,使用UNION 连接查询结果,SQL语句如下:

SELECT s_id, f_name, f_price
FROM fruits
WHERE f_price < 9.0
UNION ALL
SELECT s_id, f_name, f_price
FROM fruits
WHERE s_id IN(101,103);

        合并查询结果如下:

        如前所述,UNION将多个SELECT语句的结果组合成一个结果集合。可以分开查看每个SELECT语句的结果:

SELECT s_id, f_name, f_price
FROM fruits
WHERE f_price < 9.0;
SELECT s_id, f_name, f_price
FROM fruits
WHERE s_id IN(101,103);

        由分开查询的结果可以看到,第1条SELECT语句查询价格小于9的水果,第2条SELECT语句查询供应商101和103提供的水果。使用UNION将两条SELECT语句分隔开,执行完毕之后把输出结果组合成单个的结果集,并删除重复的记录。

        使用UNION ALL包含重复的行,在前面的例子中,分开查询时,两个返回结果中有相同的记录。UNION从查询结果集中自动去除了重复的行,如果要返回所有匹配行,而不进行删除,可以使用UNION ALL。

        【例63】查询所有价格小于9的水果的信息,查询s_id等于101和103的所有水果的信息,使用UNION ALL连接查询结果,SQL语句如下:

SELECT s_id, f_name, f_price
FROM fruits
WHERE f_price < 9.0
UNION ALL
SELECT s_id, f_name, f_price FROM fruits
WHERE s_id IN(101,103);

        查询结果如下:

        由结果可以看到,这里总的记录数等于两条SELECT语句返回的记录数之和,连接查询结果并没有去除重复的行。

        提示: UNION和 UNION ALL的区别:使用UNION ALL的功能是不删除重复行,加上ALL关键字语句执行时所需要的资源少,所以尽可能地使用它,因此知道有重复行但是想保留这些行,确定查询结果中不会有重复数据或者不需要去掉重复数据的时候,应当使用UNIONALL以提高查询效率。

7,为表和字段取别名

        在前面介绍分组查询、聚合函数查询和嵌套子查询章节中,读者注意到有的地方使用了AS关键字为查询结果中的某一列指定一个特定的名字。在内连接查询时,则对相同的表fruits分别指定两个不同的名字,这里可以为字段或者表取一个别名,在查询时,使用别名替代其指 定的内容。

1,为表取别名

        当表名字很长或者执行一些特殊查询时,为了方便操作或者需要多次使用相同的表时,可以为表指定别名,用这个别名替代表原来的名称。为表取别名的基本语法格式为:

表名 [AS] 表别名

        “表名”为数据库中存储的数据表的名称,“表别名”为查询时指定的表的新名称,AS关键字为可选参数。

        【例64】为orders表取别名o,查询30001订单的下单日期,SQL语句如下:

SELECT * FROM orders AS o
WHERE o.o_num = 30001;

        在这里orders As o代码表示为 orders表取别名为o,指定过滤条件时直接使用o代替orders,查询结果如下:

  【例65】为customers和 orders表分别取别名,并进行连接查询,SQL语句如下:

SELECT c.c_id, o.o_num
FROM customers AS C LEFT OUTER JOIN orders AS  o ON c.c_id =o.c_id;

        由结果看到,MySQL可以同时为多个表取别名,而且表别名可以放在不同的位置,如WHERE子句、SELECT 列表、ON子句以及ORDER BY子句等。

        在前面介绍内连接查询时指出自连接是一种特殊的内连接,在连接查询中的两个表都是同一个表,其查询语句如下:

SELECT f1.f_id, f1.f_name
FROM fruits AS f1, fruits AS f2
WHERE  f1.s_id = f2.s_id AND f2.f_id = 'a1';

        在这里,如果不使用表别名,MySQL 将不知道引用的是哪个fruits表实例,这是表别名的一个非常有用的地方。

        提示:在为表取别名时,要保证不能与数据库中的其他表的名称冲突。

2,为字段取别名

        在使用SELECT语句显示查询结果时,MySQL会显示每个 SELECT后面指定的输出列,在有些情况下,显示的列的名称会很长或者名称不够直观,MySQL可以指定列别名,替换字段或表达式。为字段取别名的基本语法格式为:

列名 [AS] 列别名

        “列名”为表中字段定义的名称,“列别名”为字段新的名称,AS关键字为可选参数。

        【例66】查询fruits表,为f_name取别名fruit_name,f_price取别名 fruit_price,为 fruits表取别名fl,查询表中f _price <8的水果的名称,SQL语句如下:

SELECT f1.f_name AS fruit_name, f1.f_price AS fruit_price
FROM fruits AS f1
WHERE f1.f_price <8;

        也可以为SELECT子句中的计算字段取别名,例如,对使用COUNT聚合函数或者CONCAT等系统函数执行的结果字段取别名。

        【例67】查询suppliers表中字段s_name和 s_city,使用CONCAT函数连接这两个字段值,并取列别名为suppliers_title。

        如果没有对连接后的值取别名,其显示列名称将会不够直观,SQL语句如下:

SELECT CONCAT(TRIM(s_name), ' (', TRIM(s_city), ' )')
FROM suppliers
ORDER BY S_name;

        由结果可以看到,显示结果的列名称为SELECT子句后面的计算字段,实际上计算之后的列是没有名字的,这样的结果让人很不容易理解,如果为字段取一个别名将会使结果清晰,SQL语句如下:

SELECT CONCAT (TRIM(s_name),' (',TRIM(S_city),' )') As suppliers_title
FROM suppliers
ORDER BY s_name;

        由结果可以看到,SELECT子句计算字段值之后增加了AS suppliers_title,它指示 MySQL为计算字段创建一个别名suppliers_title,显示结果为指定的列别名,这样就增强了查询结果的可读性。

        提示:表别名只在执行查询的时候使用,并不在返回结果中显示,而列别名定义之后,将返回给客户端显示,显示的结果字段为字段列的别名。

8,疑问解答:

疑问1:DISTINCT可以应用于所有的列吗?

        查询结果中,如果需要对列进行降序排序,可以使用DESC,这个关键字只能对其前面的列进行降序排列。例如,要对多列都进行降序排序,必须要在每一列的列名后面加DESC 关键字。

        而DISTINCT不同,DISTINCT不能部分使用。换句话说,DISTINCT关键字应用于所有列而不仅是它后面的第一个指定列。例如,查询3个字段s_id,f_name,f_price,如果不同记录的这3个字段的组合值都不同,则所有记录都会被查询出来。

疑问2:ORDER BY可以和LIMIT混合使用吗?

        在使用ORDER BY子句时,应保证其位于FROM子句之后,如果使用LIMIT,则必须位于ORDER BY之后,如果子句顺序不正确,MySQL将产生错误消息。

疑问3:什么时候使用引号?

        在查询的时候,会看到在 WHERE子句中使用条件,有的值加上了单引号,而有的值未加。单引号用来限定字符串,如果将值与字符串类型列进行比较,则需要限定引号;而用来与数值进行比较则不需要用引号。

疑问4∶在WHERE子句中必须使用圆括号吗?

        任何时候使用具有AND和OR操作符的WHERE子句,都应该使用圆括号明确操作顺序。如果条件较多,即使能确定计算次序,默认的计算次序也可能会使SQL语句不易理解,因此使用括号明确操作符的次序,是一个良好的习惯。

疑问5:为什么使用通配符格式正确,却没有查找出符合条件的记录?

        MySQL中存储字符串数据时,可能会不小心把两端带有空格的字符串保存到记录中,而在查看表中记录时,MySQL不能明确地显示空格,数据库操作者不能直观地确定字符串两端是否有空格。例如,使用LIKE '%e'匹配以字母e结尾的水果的名称,如果字母e后面多了一个空格,则LIKE语句不能将该记录查找出来。解决的方法是使用TRIM函数,将字符串两端的空格删除之后再进行匹配。

9,查询实战:

1,数据准备:

建表

创建数据表employee和dept。

CREATE TABLE dept
(
  d_no INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  d_name VARCHAR(50) NOT NULL,
  d_location VARCHAR(100)
);

        由于employee表dept _no依赖于父表dept的主键d_no,因此需要先创建dept 表,然后创建employec表。

DROP TABLE employee;


CREATE TABLE employee(
  e_no INT(11) NOT NULL PRIMARY KEY,
  e_name VARCHAR(50) NOT NULL,
  e_gender CHAR(2),
  dept_no INT(11) NOT NULL,
  e_job VARCHAR(50) NOT NULL,
  e_salary INT(11) NOT NULL,
  hireDate DATE NOT NULL,
  CONSTRAINT dno_fk FOREIGN KEY(dept_no) 
  REFERENCES dept(d_no)
);

插入数据

将指定记录分别插入两个表中。向dept表中插入数据,SQL语句如下:

INSERT INTO dept
VALUES (10, 'ACCOUNTING', 'ShangHai'),
(20, 'RESEARCH', 'BeiJing'),
(30, 'SALES ', 'Shenzhen'),
(40, 'OPERATIONS', 'FuJian');

向employee表中插入数据,SQL语句如下:

INSERT INTO employee
VALUES (1001, 'SMTTB', 'm',20, 'CLERK', 800, '2005-11-12'),
(1002, 'ALLEN', 'f', 30,  'SALESMAN', 1600, '2003-05-12'),
(1003, 'WARD', 'f', 30, 'SALESMAN', 1250, '2003-05-12'),
(1004, 'JONES', 'm', 20, 'MANAGER', 2975, '1998-05-18'),
(1005, 'MARTIN', 'm', 30, 'SALESMAN', 1250, '2001-06-12'),
(1006, 'BLAKE', 'f', 30, 'MANAGER', 2850, '1997-02-15'),
(1007, 'CLARK', 'm', 10, 'MANAGER', 2450, '2002-09-12'),
(1008, 'SCOTT', 'm', 20, 'ANALYST', 3000, '2003-05-12'),
(1009, 'KING', 'f', 10, 'PRESTDENT', 5000, '1995-01-01'),
(1010, 'TURNER', 'f', 30, 'SALESMAN', 1500, '1997-10-12'),
(1011, 'ADAMS', 'm', 20, 'CLERK', 1100, '1999-10-05'),
(1012, 'JAMES', 'm', 30, 'CLERK', 950, '2008-06-15');

2,查询

1,在employee表中,查询每个部门最高工资的员工信息。
SELECT dept_no, MAX(e_salary) FROM employee GROUP BY dept_no;

2,查询员工 BLAKE所在部门和部门所在地。
SELECT d_no, d_location FROM dept WHERE d_no=
(SELECT dept_no FROM employee WHERE e_name='BLAKE');

3,在employee表中,查询员工姓名以字母‘A’或‘S’开头的员工的信息。
SELECT * FROM employee WHERE e_name REGEXP '^[as]';

4,在employee表中,查询到目前为止,工龄大于等于10年的员工信息。
SELECT * FROM employee where YEAR(CURDATE())-YEAR(hireDate)>= 15;

总结:

        学习了查询,后面就是多练习,不断实战。再结合后面查询优化的地方,把sql写好。

        上一篇《MYSQL 基本查询​​​​​​​》

        下一篇《myql join连接 全部》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/526108.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

rsync实时同步(上行同步)

目录 一、实现实时同步 1. 定期同步的不足 2. 实时同步的优点 3. Linux内核的inotify机制 4. 发起端配置rsyncinotify 4.1 修改rsync源服务器配置文件 4.2 调整inotify内核参数 4.3 安装inotify-tools 4.4 在另一个终端编写触发式同步脚本 4.5 验证 二、使用rsync实现…

直播美颜SDK:AI视觉技术在直播平台中的创新与实践

在直播平台里&#xff0c;主播们通过各种形式的内容吸引着观众&#xff0c;而其中一项重要的技术创新便是直播美颜SDK的应用。本文将探讨这一技术在直播平台中的创新与实践。 一、直播美颜SDK的背景 随着社交媒体的兴起&#xff0c;人们对于自己的形象越来越注重&#xff0c;尤…

【php开发支付宝web支付】

首先介绍下 我用的框架ci 在吐槽下百度的其他人的写的都很垃圾&#xff0c;还不如自己看支付宝的开发手册了 1、composer安装支付宝的sdk composer require alipay/alipay-sdk-php安装完毕 不多哔哔 代码展示 先点地址登录支付宝以后再上我这重点下 支付宝沙箱地址 $ord…

C/C++中局部变量static用法实例

1. 普通局部变量存储于进程栈空间&#xff0c;使用完毕会立即释放&#xff0c;静态局部变量使用static修饰符定义&#xff0c;即使在声明时未赋初值&#xff0c;编译器也会把它初始化为0&#xff0c;并且静态局部变量存储于进程的全局数据区&#xff0c;即使函数返回&#xff0…

企业3D数字化网络展馆成为企业文化传承与发扬的圣地

在河北这片古老而富饶的土地上&#xff0c;文明的火种薪火相传&#xff0c;燕赵之风历久弥新。河北企业也多年持续稳居我国第五的宝座&#xff0c;企业文化展馆不仅是企业形象的展示窗口&#xff0c;更是企业文化传承与发扬的圣地。 与短暂的行业展会不同&#xff0c;企业展馆是…

Mac下载的软件显示文件已损坏,如何解决文件已损坏问题

当在Mac上下载的软件显示文件已损坏时&#xff0c;这可能是因为多种原因导致的&#xff0c;包括网络问题、下载中断、软件未完整下载、文件传输错误等。解决这个问题需要采取一些步骤来排除可能的原因&#xff0c;并尝试修复文件。下面将详细介绍一些常见的解决方法&#xff1a…

让WIN7运行WIN10软件的插件

GitHub - vxiiduu/VxKex: Windows 7 API Extensions 安装包才5.23M。 程序 - 属性 - VxKex&#xff1a;勾选 Enable Qt6版的Raptor登录后报错Device offline OpenSCAD的WIN10版

交易要想成功澳福总结几点

100%使用基本面分析的投资者能保证每次交易都能成功吗&#xff1f;100%使用技术分析的投资者能保证每次交易都能成功吗&#xff1f;在fpmarkets澳福看来无论是基本面分析还是技术分析都不能保证100%交易成功。 投资者不能只依赖一种分析进行投资交易。在fpmarkets澳福看来成功的…

vue3中项目优化(Web Worker的使用)

1.Web Worker的作用 本人的理解&#xff1a;js是单线程执行代码&#xff0c;也就是代码需要从上往下执行&#xff0c;而使用Web Worker后相当于分了一条线程出来执行代码&#xff0c;那么两条线程肯定是比一条线程执行的快。 2.新建Web Worker文件 在public文件夹下新建work…

【第二十六篇】Burpsuite实现请求方式修改+请求体文件选取

有时我们想将请求包的请求方法或请求体进行修改,这些操作可以由burpsuite完成,以节省时间。 文章目录 修改请求方法请求体文件选取修改请求方法 例如,某请求包的请求方法为GET: 如果我们想将其修改为POST且传递POST参数、上传文件,可以按以下步骤: 1、修改请求方法 2…

避雷!网络安全学习五大误区,你还不知道?

尽管安全问题老生常谈&#xff0c;但一些普遍存在的误区仍然可能让企业随时陷入危险境地。 为了有效应对当前层出不穷且不断变换的网络威胁&#xff0c;最大程度规避潜在风险&#xff0c;深入了解网络安全的发展趋势必不可少。即使部署了最新且最先进的硬件和解决方案并严格遵守…

LeetCode-热题100:138. 随机链表的复制

题目描述 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都设为其对应的原节点的值。…

【数据结构与算法】力扣 142. 环形链表 II

题目描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统…

倒计时 抢登CCF-C NSPW’24论文战场,4月12日截稿,等你来征服

会议之眼 快讯 2024年NSPW&#xff08;The New Security Paradigms Workshop&#xff09;即新安全范式研讨会将于 2024 年 9月16日-18日在美国宾夕法尼亚州贝德福德举行&#xff01;NSPW是一个专注于信息安全领域的年度会议&#xff0c;该会议旨在为那些挑战计算机安全领域主流…

小小算式(1 + 2) * (3 + 4)背后的大道理

目录 前缀表示法&#xff08;波兰表达式&#xff09; 中缀表达法 后缀表达法&#xff08;逆波兰表达式&#xff09; 三种表达法的相互转换 练习&#xff1a;逆波兰表达式求值 前缀表示法&#xff08;波兰表达式&#xff09; 波兰表示法&#xff08;英语&#xff1a;Polis…

第四十七周:文献阅读+AGCN+Wavenet network

目录 摘要 Abstract 文献阅读&#xff1a;结合自适应图卷积和CNN-LSTM的多站点水质预测模型 现有问题 提出方法 方法论 Adaptive graph convolution network&#xff08;自适应图卷积网络&#xff09; WaveNet network&#xff08;WaveNet网络&#xff09; CNN-LSTM混…

php反序列化漏洞——phar反序列化漏洞

一.什么是phar文件 类比java语言 JAR是开发Java程序一个应用&#xff0c;包括所有的可执行、可访问的文件&#xff0c;都打包进了一个JAR文件里使得部署过程十分简单。 PHAR("Php ARchive")是PHP里类似于JAR的一种打包文件 对于PHP 5.3 或更高版本&#xff0c;Ph…

【UE 网络】DS框架学习路线

目录 0 引言1 如何学习DS框架1. 熟悉Unreal Engine基础2. 学习网络编程基础3. 掌握UE网络概念4. 实践和实验5. 加入社区和论坛6. 官方示例和案例研究7. 专业书籍和在线课程 2 DS框架重要知识点有哪些1. 网络复制2. 远程过程调用&#xff08;RPC&#xff09;3. 客户端服务器架构…

0点起C语言

用sizeof()来查看在你的平台上到底占用多少你多少字节的内存。 Int x sizeof(int); Int xsizeof(shrt int); Int xsizeof(long); Int xsizeof(long double); 等等。 http://www.enet.com.cn/article/2012/0822/A20120822153730_2.shtml #—是个预处理的标志&#xff0c;表示对文…

如何本地搭建Discuz论坛并实现无公网IP远程访问

文章目录 前言1.安装基础环境2.一键部署Discuz3.安装cpolar工具4.配置域名访问Discuz5.固定域名公网地址6.配置Discuz论坛 前言 Crossday Discuz! Board&#xff08;以下简称 Discuz!&#xff09;是一套通用的社区论坛软件系统&#xff0c;用户可以在不需要任何编程的基础上&a…