Mysql组合查询例子



组合查询例子

查询结果:


代码
drop database if exists cmms;
create database cmms;
use cmms;
drop table if exists bj;
create table bj(
id int not null auto_increment primay key,
sbid varchar(20) default null,
bjmc varchar(20) default null
)engine=InnoDB default charset=utf8 comment '备件表';
INSERT INTO `bj` VALUES (1,'1,3','轴承');
INSERT INTO `bj` VALUES (2,'2,4','弯管');
INSERT INTO `bj` VALUES (3,'1','球体');
INSERT INTO `bj` VALUES (4,'2','轴承');
INSERT INTO `bj` VALUES (5,'3,5','aaa');
INSERT INTO `bj` VALUES (6,'1','电机');
drop table if exists kc;
create table kc(
id int not null auto_increment primary key,
bjid int(11),
bjsl decimal(20,2) default 0,
ckbh varchar(20)
)engine=InnoDB default charset=utf8 comment '库存表';
INSERT INTO `kc` VALUES (1,1,2,'一库');
INSERT INTO `kc` VALUES (2,1,2,'二库');
INSERT INTO `kc` VALUES (3,2,3,'二库');
INSERT INTO `kc` VALUES (4,3,9,'三库');
INSERT INTO `kc` VALUES (5,4,1,'一库');
INSERT INTO `kc` VALUES (6,5,109,'一库');
INSERT INTO `kc` VALUES (7,6,76,'二库');
drop table if exists sb;
create table sb(
id int not null auto_increment primay key,
name varchar(20) default null
)engine=InnoDB default charset=utf8 comment '设备表';
INSERT INTO `sb` VALUES (1,'高炉');
INSERT INTO `sb` VALUES (2,'机修');
INSERT INTO `sb` VALUES (3,'炼铁');
INSERT INTO `sb` VALUES (4,'发电');

DROP FUNCTION IF EXISTS `func_split`;
CREATE DEFINER=`root`@`localhost` FUNCTION `func_split`(f_string varchar(1000),f_delimiter varchar(5),f_order int) RETURNS varchar(2000) CHARSET utf8
BEGIN
    # 拆分传入的字符串,返回拆分后的新字符串
        declare result varchar(255) default '';
        set result = reverse(substring_index(reverse(substring_index(f_string,f_delimiter,f_order)),f_delimiter,1));
        return result;
END;

DROP FUNCTION IF EXISTS `func_split_detailtable`;
CREATE DEFINER=`root`@`localhost` FUNCTION `func_split_detailtable`(s_id int ) RETURNS varchar(2000) CHARSET utf8
BEGIN
    # 得到传入备件编号的设备编号字段值     
 declare sbid varchar(2000) DEFAULT '';
 DECLARE stop  int DEFAULT 0;
declare cur_split CURSOR
FOR
SELECT s.sbid from bj s where s.id=s_id ;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET  stop=1;
open cur_split;
fetch cur_split into sbid;
close cur_split;
return sbid;
end;

CREATE DEFINER=`root`@`localhost` FUNCTION `func_split_TotalLength`(f_string varchar(1000),f_delimiter varchar(5)) RETURNS int(11)
BEGIN
    # 计算传入字符串的总length
    return 1+(length(f_string) - length(replace(f_string,f_delimiter,'')));
END;

CREATE DEFINER=`root`@`localhost` PROCEDURE `pro_split_mtable`()
BEGIN
declare sid int default 0;
DECLARE stop  int DEFAULT 0;
declare cur_split CURSOR
FOR
SELECT b.id from bj b order by b.id;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET  stop=1;
DROP TEMPORARY TABLE IF EXISTS tmp_sp;
create temporary table tmp_sp(
bid int,
bjmc varchar(120),
sbid varchar(128)
)DEFAULT CHARSET=utf8;
open cur_split;
fetch cur_split into sid;
while stop<>1 do
call pro_split_table(sid);
fetch cur_split INTO sid;
end while;
close cur_split;
end;

CREATE DEFINER=`root`@`localhost` PROCEDURE `pro_split_table`(s_id int)
BEGIN
declare sid int default 0;
declare str varchar(2000) default '';
declare sts varchar(2000) default '';
DECLARE stop  int DEFAULT 0;
declare cur_split CURSOR
FOR
SELECT s.id,s.bjmc,t.sbid from bj s,tmp_split t where s.id=s_id ;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET  stop=1;
call splitString(func_split_detailtable(s_id),',');
open cur_split;
fetch cur_split into sid, str,sts;
while stop<>1 do
INSERT into tmp_sp values(sid,str,sts);
fetch cur_split INTO sid,str,sts;
end while;
close cur_split;
end;

CREATE DEFINER=`root`@`localhost` PROCEDURE `splitString`(IN f_string varchar(1000),IN f_delimiter varchar(5))
BEGIN
# 拆分结果
declare cnt int default 0;
declare i int default 0;
set cnt = func_split_TotalLength(f_string,f_delimiter);
DROP TABLE IF EXISTS `tmp_split`;
create temporary table `tmp_split` (`sbid` varchar(128) not null) DEFAULT CHARSET=utf8;
while i < cnt
do
    set i = i + 1;
    insert into tmp_split(`sbid`) values (func_split(f_string,f_delimiter,i));
end while;
END;


#先把备件表化成明细表,再根据设备编号查询并组合出该设备下有哪些备件编号、名称及数量
call pro_split_mtable();
SELECT * from tmp_sp;
select k.bid,k.bjmc,k.sbname,m.bjsl from(
(select t.bid bid,s.id sbid,t.bjmc bjmc,s.name sbname from tmp_sp t,sb s where s.id=t.sbid)k,
(select b.id bid,sum(k.bjsl) bjsl,b.bjmc bjmc  from bj b, kc k where k.bjid=b.id GROUP by k.bjid)m
) where k.bid=m.bid and k.sbid=1;
<think>嗯,用户想了解MySQL组合查询,特别是UNION和JOIN的示例。首先,我需要确认用户的需求是什么。组合查询通常指的是将多个查询结果合并或者连接不同的表。UNION用于合并多个SELECT的结果,而JOIN用于连接不同的表。 首先,我应该回顾一下UNION和JOIN的基本概念。UNION操作符用于合并两个或多个SELECT语句的结果集,要求列的数量和数据类型必须兼容。默认情况下,UNION会去除重复的行,而UNION ALL会保留所有行,包括重复的。例如,用户可能需要从两个不同的表中合并客户列表,这时候可以用UNION。 然后是JOIN,这涉及到连接不同的表。JOIN有很多种类型,比如INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN等。LEFT JOIN会返回左表的所有记录,即使右表没有匹配的行,这时候右表的字段会是NULL。例如,用户可能需要连接订单表和客户表,以获取每个订单的客户信息。 用户可能需要具体的示例,所以我需要准备一些实际的SQL语句。比如,使用UNION合并两个查询的结果,或者用LEFT JOIN连接两个表并筛选出某些条件。同时,要确保示例的语法正确,符合MySQL的标准。 另外,考虑到用户可能对性能优化感兴趣,可以提到在使用UNION时,使用UNION ALL可能更高效,因为不需要去重。而在使用JOIN时,索引的使用对性能影响很大,特别是连接字段上的索引。 还需要注意用户提供的引用内容,比如引用[1]中的LEFT JOIN示例,引用[2]中提到的EXCLUDING JOIN,这些可能需要融入到回答中,或者作为补充说明。例如,LEFT EXCLUDING JOIN可以通过LEFT JOIN后加上WHERE条件来实现,排除右表中存在匹配的情况。 用户的问题中提到了示例,所以应该给出几个典型的例子,比如简单的UNION合并两个表的数据,或者LEFT JOIN获取左表所有记录并关联右表信息。同时,可能需要解释每个示例的作用和结果。 最后,要确保回答结构清晰,分点说明UNION和JOIN的用法,并提供示例代码。同时,生成相关问题,帮助用户进一步学习,比如性能优化、应用场景等。</think>### MySQL组合查询:UNION与JOIN详解 #### 1. **UNION查询** **用途**:合并多个`SELECT`结果,**列数量与数据类型需一致**。 **特点**:默认去重,使用`UNION ALL`保留重复值。 **示例**:合并两个表的客户名称: ```sql SELECT customer_name FROM customers_2023 UNION SELECT customer_name FROM customers_2024; ``` #### 2. **JOIN查询** **用途**:关联不同表的行数据。 **常见类型**: - **INNER JOIN**:仅返回两表匹配的行。 ```sql SELECT o.order_id, c.customer_name FROM orders o INNER JOIN customers c ON o.customer_id = c.id; ``` - **LEFT JOIN**:返回左表全部记录,右表无匹配则为`NULL`[^1]。 ```sql SELECT a0.article_id, a1.title FROM article a0 LEFT JOIN article a1 ON a1.category_id = a0.category_id AND a1.article_id > a0.article_id; ``` - **LEFT EXCLUDING JOIN**:筛选左表中无右表匹配的记录[^2]。 ```sql SELECT * FROM TableA LEFT JOIN TableB ON TableA.id = TableB.id WHERE TableB.id IS NULL; ``` #### 3. **UNION与JOIN结合** **示例**:合并不同年份的订单并关联客户信息: ```sql SELECT o.order_id, c.customer_name FROM orders_2023 o INNER JOIN customers c ON o.customer_id = c.id UNION SELECT o.order_id, c.customer_name FROM orders_2024 o LEFT JOIN customers c ON o.customer_id = c.id; ``` #### 4. **性能优化要点** - 使用`UNION ALL`替代`UNION`避免去重开销。 - 为`JOIN`字段(如`customer_id`)添加索引提升查询速度[^3]。 - 避免全表扫描,通过`WHERE`条件缩小数据集。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值