内容正文:
专题六 SELECT语句(二)
一、单项选择题
1.有 employees 表(emp_id, dept_id)和 departments 表(dept_id, dept_name),要查询每个员工所在部门的名称,合适的连接方式是( )
A. 内连接
B. 左连接
C. 右连接
D. 全连接
答案:A
解析:内连接用于返回两个表中匹配的记录。在这个场景中,我们要查询每个员工所在部门的名称,只有员工表中的 dept_id 和部门表中的 dept_id 匹配时才能获取到部门名称,所以内连接是合适的。左连接会返回左表(employees)的所有记录,即使右表(departments)中没有匹配的记录;右连接则相反;全连接会返回两个表的所有记录,无论是否匹配。
2.在 orders 表(order_id, customer_id)和 customers 表(customer_id, customer_name)中,若要查询所有订单及其对应的客户姓名,即使某些订单没有对应的客户信息,应使用( )。
A. SELECT * FROM orders INNER JOIN customers ON orders.customer_id = customers.customer_id;
B. SELECT * FROM orders LEFT JOIN customers ON orders.customer_id = customers.customer_id;
C. SELECT * FROM orders RIGHT JOIN customers ON orders.customer_id = customers.customer_id;
D. SELECT * FROM orders FULL JOIN customers ON orders.customer_id = customers.customer_id;
答案:B
解析:左连接会返回左表(orders)的所有记录,以及右表(customers)中匹配的记录。如果右表中没有匹配的记录,右表的列值会显示为 NULL。这符合题目要求,即查询所有订单及其对应的客户姓名,即使某些订单没有对应的客户信息。内连接只会返回两个表中匹配的记录;右连接会返回右表的所有记录;MySQL 不直接支持 FULL JOIN,但可以用 UNION 模拟。
3.在 products 表(product_id, category_id)和 categories 表(category_id, category_name)中,要查询没有任何产品的类别名称,应使用( )。
A. SELECT categories.category_name FROM products RIGHT JOIN categories ON products.category_id = categories.category_id WHERE products.product_id IS NULL;
B. SELECT categories.category_name FROM products LEFT JOIN categories ON products.category_id = categories.category_id WHERE products.product_id IS NULL;
C. SELECT categories.category_name FROM products INNER JOIN categories ON products.category_id = categories.category_id WHERE products.product_id IS NULL;
D. SELECT categories.category_name FROM products FULL JOIN categories ON products.category_id = categories.category_id WHERE products.product_id IS NULL;
答案:A
解析:右连接会返回右表(categories)的所有记录,以及左表(products)中匹配的记录。通过 WHERE products.product_id IS NULL 筛选出左表中没有匹配记录的情况,即没有任何产品的类别。左连接无法实现这个需求;内连接只会返回匹配的记录,不会包含没有产品的类别;FULL JOIN 虽然能包含所有情况,但筛选逻辑会更复杂。
4.有 employees 表(emp_id, manager_id, emp_name),可以通过自连接查询每个员工的上级姓名,以下正确的是( )。
A. SELECT e1.emp_name, e2.emp_name AS manager_name FROM employees e1 INNER JOIN employees e2 ON e1.manager_id = e2.emp_id;
B. SELECT e1.emp_name, e2.emp_name AS manager_name FROM employees e1 LEFT JOIN employees e2 ON e1.manager_id = e2.emp_id;
C. SELECT e1.emp_name, e2.emp_name AS manager_name FROM employees e1 RIGHT JOIN employees e2 ON e1.manager_id = e2.emp_id;
D. SELECT e1.emp_name, e2.emp_name AS manager_name FROM employees e1 FULL JOIN employees e2 ON e1.manager_id = e2.emp_id;
答案:A
解析:自连接是指一个表与自身进行连接。这里使用内连接,将 employees 表分别用别名 e1 和 e2 表示,通过 e1.manager_id = e2.emp_id 关联员工和其上级,能正确查询出每个员工的上级姓名。左连接会包含那些可能没有上级的员工,并且上级姓名显示为 NULL;右连接和全连接会引入不必要的额外记录。
5.在 customers 表(customer_id, country)和 orders 表(order_id, customer_id,order_amount)中,要查询每个国家的订单总金,应使用( )。
A. SELECT customers.country, SUM(orders.order_amount) FROM customers INNER JOIN orders ON customers.customer_id = orders.customer_id GROUP BY customers.country;
B. SELECT customers.country, SUM(orders.order_amount) FROM customers LEFT JOIN orders ON customers.customer_id = orders.customer_id GROUP BY customers.country;
C. SELECT customers.country, SUM(orders.order_amount) FROM customers RIGHT JOIN orders ON customers.customer_id = orders.customer_id GROUP BY customers.country;
D. SELECT customers.country, SUM(orders.order_amount) FROM customers FULL JOIN orders ON customers.customer_id = orders.customer_id GROUP BY customers.country;
答案:A
解析:内连接可以确保只统计有订单的客户所在国家的订单总金额。通过 GROUP BY customers.country 按国家分组,使用 SUM(orders.order_amount) 计算每个国家的订单总金额。左连接会包含那些可能没有订单的客户所在国家,右连接和全连接也会有类似问题,可能不符合只统计有订单国家的订单总金额的需求。
6.有 students 表(student_id, course_id)和 courses 表(course_id, course_name),要查询选修了所有课程的学生 ID,应使用( )。
A. 子查询和分组统计
B. 内连接和分组统计
C. 左连接和分组统计
D. 右连接和分组统计
答案:A
解析:要查询选修了所有课程的学生 ID,需要先统计每个课程的总数,然后统计每个学生选修的课程数,通过子查询和分组统计来比较两者是否相等。内连接、左连接和右连接本身不能直接实现这个功能,需要结合子查询和分组统计。
7.在 employees 表(emp_id, dept_id)和 departments 表(dept_id, dept_name)中,要查询部门名称为 'HR' 的员工数量,应使用( )。
A. SELECT COUNT(employees.emp_id) FROM employees INNER JOIN departments ON employees.dept_id = departments.dept_id WHERE departments.dept_name = 'HR';
B. SELECT COUNT(employees.emp_id) FROM employees LEFT JOIN departments ON employees.dept_id = departments.dept_id WHERE departments.dept_name = 'HR';
C. SELECT COUNT(employees.emp_id) FROM employees RIGHT JOIN departments ON employees.dept_id = departments.dept_id WHERE departments.dept_name = 'HR';
D. SELECT COUNT(employees.emp_id) FROM employees FULL JOIN departments ON employees.dept_id = departments.dept_id WHERE departments.dept_name = 'HR';
答案:A
解析:内连接可以确保只统计部门名称为 'HR' 的员工数量。通过内连接将 employees 表和 departments 表连接起来,然后使用 WHERE departments.dept_name = 'HR' 筛选出部门名称为 'HR' 的记录,最后使用 COUNT(employees.emp_id) 统计员工数量。左连接、右连接和全连接可能会包含不必要的记录。
8.有 products 表(product_id, supplier_id, price)和 suppliers 表(supplier_id, supplier_name),要查询每个供应商提供的产品平均价格,应使用( )。
A. SELECT suppliers.supplier_name, AVG(products.price) FROM products INNER JOIN suppliers ON products.supplier_id = suppliers.supplier_id GROUP BY suppliers.supplier_name;
B. SELECT suppliers.supplier_name, AVG(products.price) FROM products LEFT JOIN suppliers ON products.supplier_id = suppliers.supplier_id GROUP BY suppliers.supplier_name;
C. SELECT suppliers.supplier_name, AVG(products.price) FROM products RIGHT JOIN suppliers ON products.supplier_id = suppliers.supplier_id GROUP BY suppliers.supplier_name;
D. SELECT suppliers.supplier_name, AVG(products.price) FROM products FULL JOIN suppliers ON products.supplier_id = suppliers.supplier_id GROUP BY suppliers.supplier_name;
答案:A
解析:内连接可以确保只统计有产品的供应商提供的产品平均价格。通过内连接将 products 表和 suppliers 表连接起来,然后按供应商名称分组,使用 AVG(products.price) 计算每个供应商提供的产品平均价格。左连接、右连接和全连接可能会包含没有产品的供应商,影响平均价格的计算。
9.在 orders 表(order_id, customer_id)和 customers 表(customer_id, customer_name)中,要查询订单数量最多的客户姓名,应使用( )。
A. 内连接,然后按客户姓名分组,统计订单数量,再排序取最大值
B. 左连接,然后按客户姓名分组,统计订单数量,再排序取最大值
C. 右连接,然后按客户姓名分组,统计订单数量,再排序取最大值
D. 全连接,然后按客户姓名分组,统计订单数量,再排序取最大值
答案:A
解析:内连接可以确保只统计有订单的客户的订单数量。通过内连接将 orders 表和 customers 表连接起来,按客户姓名分组,使用 COUNT 函数统计每个客户的订单数量,然后排序取最大值,就能找出订单数量最多的客户姓名。左连接、右连接和全连接可能会包含没有订单的客户,增加不必要的处理。
10.有 employees 表(emp_id, dept_id,salary)和 departments 表(dept_id, dept_name),要查询每个部门的员工平均工资,应使用( )。
A. SELECT departments.dept_name, AVG(employees.salary) FROM employees INNER JOIN departments ON employees.dept_id = departments.dept_id GROUP BY departments.dept_name;
B. SELECT departments.dept_name, AVG(employees.salary) FROM employees LEFT JOIN departments ON employees.dept_id = departments.dept_id GROUP BY departments.dept_name;
C. SELECT departments.dept_name, AVG(employees.salary) FROM employees RIGHT JOIN departments ON employees.dept_id = departments.dept_id GROUP BY departments.dept_name;
D. SELECT departments.dept_name, AVG(employees.salary) FROM employees FULL JOIN departments ON employees.dept_id = departments.dept_id GROUP BY departments.dept_name;
答案:A
解析:内连接可以确保只统计有员工的部门的员工平均工资。通过内连接将 employees 表和 departments 表连接起来,按部门名称分组,使用 AVG(employees.salary) 计算每个部门的员工平均工资。左连接、右连接和全连接可能会包含没有员工的部门,影响平均工资的计算。
二、判断题
1.在多表查询中,JOIN 关键字只能用于内连接。( )
答案:错误
解析:JOIN 关键字在 MySQL 中默认是内连接,但也可以和 LEFT、RIGHT 等关键字结合,实现左连接、右连接等不同类型的连接。
2.右连接会返回右表的所有记录,以及左表中匹配的记录。( )
答案:正确
解析:右连接的定义就是返回右表的全部记录和左表中匹配的记录,若左表没有匹配记录,左表列值显示为 NULL。
3.全连接会返回两个表的所有记录,无论是否匹配。( )
答案:正确
解析:全连接会包含两个表的所有行,不匹配的部分用 NULL 填充。
4.在多表连接查询中,连接条件只能是相等条件。( )
答案:错误
解析:连接条件可以是各种比较条件,不局限于相等条件,例如大于、小于等。
5.自连接只能用于内连接。( )
答案:错误
解析:自连接可以使用内连接、左连接、右连接等各种连接方式。
6.在多表查询中,使用 GROUP BY 子句时,SELECT 列表中的非聚合列必须包含在 GROUP BY 子句中。( )
答案:正确
解析:这是 SQL 语法规则,保证分组的一致性和结果的准确性。
7.可以通过多个 JOIN 关键字在一个查询中连接多个表。( )
答案:正确
解析:在复杂查询中,常需要连接多个表,可通过多个 JOIN 关键字实现。
8.内连接和左连接在某些情况下查询结果可能相同。( )
答案:正确
解析:当左表的所有记录在右表都有匹配时,内连接和左连接结果相同。
9.多表查询中,ORDER BY 子句只能放在查询语句的最后。( )
答案:正确
解析:ORDER BY 用于对查询结果排序,通常放在最后执行。
10.在多表查询中,使用 COUNT(*) 统计记录数时,会统计所有连接后的记录。( )
答案:正确
解析:COUNT(*) 会对所有符合条件的记录进行计数,包括连接后的所有记录。
三、命令题
1.有 employees 表(emp_id, dept_id, salary)和 departments 表(dept_id, dept_name),查询每个部门的名称以及该部门员工的最高工资。
答案
SELECT
d.dept_name,
MAX(e.salary) AS max_salary
FROM
employees e
JOIN
departments d ON e.dept_id = d.dept_id
GROUP BY
d.dept_name;
2.有 products 表(product_id, category_id, price)和 categories 表(category_id, category_name),查询每个类别中价格低于该类别平均价格的产品名称和价格。
答案
SELECT
p.product_name,
p.price
FROM
products p
JOIN
categories c ON p.category_id = c.category_id
JOIN (
SELECT
category_id,
AVG(price) AS avg_price
FROM
products
GROUP BY
category_id
) sub ON p.category_id = sub.category_id AND p.price < sub.avg_price;
3.有 employees 表(emp_id, manager_id, salary),使用自连接查询每个员工及其上级的工资差。
答案
SELECT
e1.emp_id,
e1.salary - COALESCE(e2.salary, 0) AS salary_difference
FROM
employees e1
LEFT JOIN
employees e2 ON e1.manager_id = e2.emp_id;
4.有 books 表(book_id, author_id, publish_date)和 authors 表(author_id, author_name),查询 2023 年后出版过书籍的作者姓名和出版书籍数量。
答案
SELECT
a.author_name,
COUNT(b.book_id) AS book_count
FROM
books b
JOIN
authors a ON b.author_id = a.author_id
WHERE
b.publish_date > '2023-01-01'
GROUP BY
a.author_name;
5.有 employees 表(emp_id, dept_id, hire_date)和 departments 表(dept_id, dept_name),查询每个部门最早入职的员工姓名和入职日期。
答案
SELECT
e.emp_name,
e.hire_date,
d.dept_name
FROM
employees e
JOIN
departments d ON e.dept_id = d.dept_id
JOIN (
SELECT
dept_id,
MIN(hire_date) AS min_hire_date
FROM
employees
GROUP BY
dept_id
) sub ON e.dept_id = sub.dept_id AND e.hire_date = sub.min_hire_date;
学科网(北京)股份有限公司
$$
专题六 SELECT语句(二)
一、单项选择题
1.有 employees 表(emp_id, dept_id)和 departments 表(dept_id, dept_name),要查询每个员工所在部门的名称,合适的连接方式是( )
A. 内连接
B. 左连接
C. 右连接
D. 全连接
2.在 orders 表(order_id, customer_id)和 customers 表(customer_id, customer_name)中,若要查询所有订单及其对应的客户姓名,即使某些订单没有对应的客户信息,应使用( )。
A. SELECT * FROM orders INNER JOIN customers ON orders.customer_id = customers.customer_id;
B. SELECT * FROM orders LEFT JOIN customers ON orders.customer_id = customers.customer_id;
C. SELECT * FROM orders RIGHT JOIN customers ON orders.customer_id = customers.customer_id;
D. SELECT * FROM orders FULL JOIN customers ON orders.customer_id = customers.customer_id;
3.在 products 表(product_id, category_id)和 categories 表(category_id, category_name)中,要查询没有任何产品的类别名称,应使用( )。
A. SELECT categories.category_name FROM products RIGHT JOIN categories ON products.category_id = categories.category_id WHERE products.product_id IS NULL;
B. SELECT categories.category_name FROM products LEFT JOIN categories ON products.category_id = categories.category_id WHERE products.product_id IS NULL;
C. SELECT categories.category_name FROM products INNER JOIN categories ON products.category_id = categories.category_id WHERE products.product_id IS NULL;
D. SELECT categories.category_name FROM products FULL JOIN categories ON products.category_id = categories.category_id WHERE products.product_id IS NULL;
4.有 employees 表(emp_id, manager_id, emp_name),可以通过自连接查询每个员工的上级姓名,以下正确的是( )。
A. SELECT e1.emp_name, e2.emp_name AS manager_name FROM employees e1 INNER JOIN employees e2 ON e1.manager_id = e2.emp_id;
B. SELECT e1.emp_name, e2.emp_name AS manager_name FROM employees e1 LEFT JOIN employees e2 ON e1.manager_id = e2.emp_id;
C. SELECT e1.emp_name, e2.emp_name AS manager_name FROM employees e1 RIGHT JOIN employees e2 ON e1.manager_id = e2.emp_id;
D. SELECT e1.emp_name, e2.emp_name AS manager_name FROM employees e1 FULL JOIN employees e2 ON e1.manager_id = e2.emp_id;
5.在 customers 表(customer_id, country)和 orders 表(order_id, customer_id,order_amount)中,要查询每个国家的订单总金,应使用( )。
A. SELECT customers.country, SUM(orders.order_amount) FROM customers INNER JOIN orders ON customers.customer_id = orders.customer_id GROUP BY customers.country;
B. SELECT customers.country, SUM(orders.order_amount) FROM customers LEFT JOIN orders ON customers.customer_id = orders.customer_id GROUP BY customers.country;
C. SELECT customers.country, SUM(orders.order_amount) FROM customers RIGHT JOIN orders ON customers.customer_id = orders.customer_id GROUP BY customers.country;
D. SELECT customers.country, SUM(orders.order_amount) FROM customers FULL JOIN orders ON customers.customer_id = orders.customer_id GROUP BY customers.country;
6.有 students 表(student_id, course_id)和 courses 表(course_id, course_name),要查询选修了所有课程的学生 ID,应使用( )。
A. 子查询和分组统计
B. 内连接和分组统计
C. 左连接和分组统计
D. 右连接和分组统计
7.在 employees 表(emp_id, dept_id)和 departments 表(dept_id, dept_name)中,要查询部门名称为 'HR' 的员工数量,应使用( )。
A. SELECT COUNT(employees.emp_id) FROM employees INNER JOIN departments ON employees.dept_id = departments.dept_id WHERE departments.dept_name = 'HR';
B. SELECT COUNT(employees.emp_id) FROM employees LEFT JOIN departments ON employees.dept_id = departments.dept_id WHERE departments.dept_name = 'HR';
C. SELECT COUNT(employees.emp_id) FROM employees RIGHT JOIN departments ON employees.dept_id = departments.dept_id WHERE departments.dept_name = 'HR';
D. SELECT COUNT(employees.emp_id) FROM employees FULL JOIN departments ON employees.dept_id = departments.dept_id WHERE departments.dept_name = 'HR';
8.有 products 表(product_id, supplier_id, price)和 suppliers 表(supplier_id, supplier_name),要查询每个供应商提供的产品平均价格,应使用( )。
A. SELECT suppliers.supplier_name, AVG(products.price) FROM products INNER JOIN suppliers ON products.supplier_id = suppliers.supplier_id GROUP BY suppliers.supplier_name;
B. SELECT suppliers.supplier_name, AVG(products.price) FROM products LEFT JOIN suppliers ON products.supplier_id = suppliers.supplier_id GROUP BY suppliers.supplier_name;
C. SELECT suppliers.supplier_name, AVG(products.price) FROM products RIGHT JOIN suppliers ON products.supplier_id = suppliers.supplier_id GROUP BY suppliers.supplier_name;
D. SELECT suppliers.supplier_name, AVG(products.price) FROM products FULL JOIN suppliers ON products.supplier_id = suppliers.supplier_id GROUP BY suppliers.supplier_name;
9.在 orders 表(order_id, customer_id)和 customers 表(customer_id, customer_name)中,要查询订单数量最多的客户姓名,应使用( )。
A. 内连接,然后按客户姓名分组,统计订单数量,再排序取最大值
B. 左连接,然后按客户姓名分组,统计订单数量,再排序取最大值
C. 右连接,然后按客户姓名分组,统计订单数量,再排序取最大值
D. 全连接,然后按客户姓名分组,统计订单数量,再排序取最大值
10.有 employees 表(emp_id, dept_id,salary)和 departments 表(dept_id, dept_name),要查询每个部门的员工平均工资,应使用( )。
A. SELECT departments.dept_name, AVG(employees.salary) FROM employees INNER JOIN departments ON employees.dept_id = departments.dept_id GROUP BY departments.dept_name;
B. SELECT departments.dept_name, AVG(employees.salary) FROM employees LEFT JOIN departments ON employees.dept_id = departments.dept_id GROUP BY departments.dept_name;
C. SELECT departments.dept_name, AVG(employees.salary) FROM employees RIGHT JOIN departments ON employees.dept_id = departments.dept_id GROUP BY departments.dept_name;
D. SELECT departments.dept_name, AVG(employees.salary) FROM employees FULL JOIN departments ON employees.dept_id = departments.dept_id GROUP BY departments.dept_name;
二、判断题
1.在多表查询中,JOIN 关键字只能用于内连接。( )
2.右连接会返回右表的所有记录,以及左表中匹配的记录。( )
3.全连接会返回两个表的所有记录,无论是否匹配。( )
4.在多表连接查询中,连接条件只能是相等条件。( )
5.自连接只能用于内连接。( )
6.在多表查询中,使用 GROUP BY 子句时,SELECT 列表中的非聚合列必须包含在 GROUP BY 子句中。( )
7.可以通过多个 JOIN 关键字在一个查询中连接多个表。( )
8.内连接和左连接在某些情况下查询结果可能相同。( )
9.多表查询中,ORDER BY 子句只能放在查询语句的最后。( )
10.在多表查询中,使用 COUNT(*) 统计记录数时,会统计所有连接后的记录。( )
三、命令题
1.有 employees 表(emp_id, dept_id, salary)和 departments 表(dept_id, dept_name),查询每个部门的名称以及该部门员工的最高工资。
2.有 products 表(product_id, category_id, price)和 categories 表(category_id, category_name),查询每个类别中价格低于该类别平均价格的产品名称和价格。
3.有 employees 表(emp_id, manager_id, salary),使用自连接查询每个员工及其上级的工资差。
4.有 books 表(book_id, author_id, publish_date)和 authors 表(author_id, author_name),查询 2023 年后出版过书籍的作者姓名和出版书籍数量。
5.有 employees 表(emp_id, dept_id, hire_date)和 departments 表(dept_id, dept_name),查询每个部门最早入职的员工姓名和入职日期。
学科网(北京)股份有限公司
$$