MYSQL中子查询有多个结果返回怎么处理

问题
1. 查询条件不同,返回多个结果整合
在查询的时候,有时候常常须要用到子查询,好比查询今天的订单数量, 7天的订单数量,31天的订单数量, 这种条件不同,可是非要整在一个表中来显示就须要不少子查询来实现了:java

select(select xx from xx where 条件一) as 结果一,
select(select xx from xx where 条件二) as 结果二,
select(select xx from xx where 条件三) as 结果三


这个时候咱们须要在一条sql将这三个结果查出来,可使用UNION和UNION ALLmysql

UNION 用于合并两个或多个 SELECT 语句的结果集,并消去表中任何重复行。当 ALL 随 UNION 一块儿使用时(即 UNION ALL),不消除重复行sql

也就是咱们能够拼成一个表,好比如今有这么一个表:数组


若是咱们须要分别查出年龄小于18和大于18的人数,因为查询条件不同,因此须要用到两个查询函数

SELECT 
  COUNT(*) 
FROM
  USER 
WHERE age < 18 ;

SELECT 
  COUNT(*) 
FROM
  USER 
WHERE age >= 18 ;


使用UNION:code

SELECT 
  * 
FROM
  (SELECT 
    COUNT(*) 
  FROM
    USER 
  WHERE age < 18 
  UNION
  SELECT 
    COUNT(*) 
  FROM
    USER 
  WHERE age >= 18) a


可是查出来的结果是在一列里面,没法得知哪一个是18如下的字符串

咱们能够拼接一个0使其为两个字段(两列),这里注意两条子查询的别名都要同样string

SELECT 
  * 
FROM
  (SELECT 
    COUNT(*) AS '18如下人数',
    0 AS '18以上人数' 
  FROM
    USER 
  WHERE age < 18 
  UNION
  SELECT 
    0 AS '18如下人数',
    COUNT(*) AS '18以上人数' 
  FROM
    USER 
  WHERE age >= 18) a

这个时候是两条记录,分别使用SUM获得总数就能够变成一条记录了it

2. 查询条件同样,返回多个结果整合
可是有时候, 几个结果的条件是同样的, 可是子查询只能返回一个结果, 也就是咱们须要分红多个子查询来查询相同的条件table

SELECT(SELECT xx FROM xx WHERE 条件一) AS 结果一,
SELECT(SELECT xx FROM xx WHERE 条件一) AS 结果二,
SELECT(SELECT xx FROM xx WHERE 条件一) AS 结果三,
SELECT(SELECT xx FROM xx WHERE 条件二) AS 结果四


处理
在网上搜罗一圈后, 有一个解决办法挺新颖的, 大概就是先把一样条件的多个结果, 先拼接成一个, 再在外面进行拆分, 在java里面好比是"aa,bb,cc".split(",")

select 
SUBSTRING_INDEX(temp.结果一,',',1) as 第一列数据,
SUBSTRING_INDEX(SUBSTRING_INDEX(temp.结果一,','2),',',-1) as 第二列数据,
SUBSTRING_INDEX(temp.结果一,','-1) as 第三列数据,
temp.结果二 as 第四列数据
FROM(
    select(select concat_ws(',',数据一, 数据二,数据三)  from xx where 条件一) as 结果一,
    select(select xx from xx where 条件二) as 结果二
)temp



[补充]关于substring_index的用法
SUBSTRING_INDEX('待切割的字符串', '截取分割的字符,好比逗号' , 长度)
长度为负数,从右边开始, 好比"a,b,c,d", 长度为-1取得是"d"(能够理解为在java中,利用split分割以后,取数组中的前几个元素)

取a: SUBSTRING_INDEX("a,b,c,d" , "," , 1)
取b: SUBSTRING_INDEX(SUBSTRING_INDEX("a,b,c,d" , "," , 2) ,",",-1) 先拿到前2位,再取最后一位
取d: SUBSTRING_INDEX("a,b,c,d" , "," , -1)
取cd: SUBSTRING_INDEX("a,b,c,d" , "," , -2)


示例1:

SELECT
    SUBSTRING_INDEX(temp.today, ",", 1) AS `今日加购量`,
    SUBSTRING_INDEX(temp.today, "," ,- 1) AS `今日加购商家数`
FROM
    (
        SELECT
            CONCAT_WS(
                ',',
                COUNT(*),
                COUNT(DISTINCT c.MALL_STORE_ID)
            ) AS today
        FROM
            mall_goods_cart c
        WHERE
            STR_TO_DATE(c.CREATE_TIME, '%Y-%m-%d') = CURDATE()
    ) AS temp

mysql日期函数函数:

SELECT NOW(),CURDATE(),CURTIME()
NOW() CURDATE() CURTIME()
2008-12-29 16:25:46 2008-12-29 16:25:46

 

示例2:需求:关联查询另外一个大表数据的某些(一个以上)字段

方案:因关联查询的表数据太大。多表查询影响效率,单个子查询又有些多余。因此采用多列拼接子查询,而后根据SUBSTRING_INDEX(SOURCE,SEPARETOR,INDEX+1)。

原理:子查询返回拼接列;函数截取还原列

SELECT
SUBSTRING_INDEX(temp.temp_column,",",1) showFirst,
SUBSTRING_INDEX(temp.temp_column,",",-1) showOver,
SUBSTRING_INDEX(SUBSTRING_INDEX(temp.temp_column,',',2),',',-1) showTwo,
temp.*
FROM
(
  SELECT (
  SELECT CONCAT_WS(',','12','23','34','45')) temp_column
) temp;

固然,若是仅仅只是在返回的多行数据之中随便抽取一列便可,可使用limit,,找到一个符合条件的就能够了

select * from table1 where table1.colums=(select columns from table2 limit 1);

或者使用any函数:

select * from table1 where table1.colums=any(select columns from table2);
相关文章
相关标签/搜索