zoukankan      html  css  js  c++  java
  • SQL分批查询UNION与UNION ALL 使用技巧

      union和union all都用于合并sql结果集操作,不管sql语句是否相同,但是返回字段最好一样,若不一样,字段名称只会以第一个为准

    这就要求sql语句拥有相同的列(数量及名称),相同的返回类型

    首先说下区别:

      union 查询结果不包含重复值,即若有重复只返回一个

      union all 查询结果包含所有值,重复多少个都会全部返回

    使用:使用多条件模糊(或者说筛选)查询方法较慢(数据量较大)可换用另一种精确(索引或某字段)定位但sql过长的情况下、或者where条件中in过长(一般查过1000个会报错)、或者sql语句过长的情况,可以考虑将其转化为多个sql合并的union

      示例1:指定每个小条件的索引作为id值(对于各组条件并不是完全不同或可能有没写条件拆分到多个sql的情况),每个sql中限定查询的成品个数,然后合并多个这样的sql

          如下php中sql查询代码组织:

         $sql="";

         foreach
    ($productUuidArray as $index => $productArray) { $editStatus = $productArray['edit']; $uuids = implode(",", $productArray['uuid']); if($uuids=="") { //无成品信息,直接跳过 continue; } $sql .= "SELECT $index AS id,COUNT(DISTINCT product_uuid) AS dis_number,MAX(create_time) AS dis_time FROM log_info WHERE customer_id=$customerId AND edit_status=$editStatus AND product_uuid IN (" . $uuids . ") UNION "; }

          sql语句:

          SELECT $index AS id,COUNT(DISTINCT product_uuid) AS dis_number,MAX(create_time) AS dis_time
                    FROM log_info
                    WHERE customer_id=$customerId
                    AND edit_status=$editStatus
                    AND product_uuid IN (" . $uuids . ")
                    UNION

           SELECT $index AS id,COUNT(DISTINCT product_uuid) AS dis_number,MAX(create_time) AS dis_time
                    FROM log_info
                    WHERE customer_id=$customerId
                    AND edit_status=$editStatus
                    AND product_uuid IN (" . $uuids . ")

          上述sql的条件为三个:customer_id、edit_status、product_uuid,其中关键在于product_uuid字段,若某一组customer_id与edit_status相同的sql中uuid个数多于1000个时,应拆分为另一sql,所以可能会将product_uuid拆分到两个或更多的sql,customer_id及edit_status相同、product_uuid不同的情况,这时使用相同的$index作为索引,之后对查询结果进行判断组织(相同id的结果集:count相加、dis_time取最大的那个)即可

          此方法应注意合并后的sql长度,一般sql行数5000行以内是没有问题的,大于5000行的情况,则应分多次查询数据库。极限的情况可能是每个in里只有一个uuid,这样,每次查询最多uuid为5000/6近似==800(一般取700以内)个,所以,组织$productUuidArray时,可以每0~700个查询一次数据库

      示例2:添加排序

           针对分批查询的数据排序,不能在每个小sql中排序,但可以在最后集中排序,示例如下:

            

    SELECT
        pi.channel_id,
        pi.column_id,
        pg.edit_status,
        pi.schema_id,
        pi.uuid,
        pi.play_start_time
    FROM
        product_info pi
    INNER JOIN product_progress_info pg ON pi.uuid = pg.product_uuid
    WHERE
        pi.channel_id = 80
    AND pi.column_id = 236
    AND pg.edit_status = 1
    AND pi.schema_id = 1
    AND (
        (
            pi.play_start_time >= '2013-07-29 00:00:00'
            AND pi.play_start_time <= '2013-07-29 23:59:59'
        )
    )
    UNION
        SELECT
            pi.channel_id,
            pi.column_id,
            pg.edit_status,
            pi.schema_id,
            pi.uuid,
            pi.play_start_time
        FROM
            product_info pi
        INNER JOIN product_progress_info pg ON pi.uuid = pg.product_uuid
        WHERE
            pi.channel_id = 80
        AND pi.column_id = 10465
        AND pg.edit_status = 1
        AND pi.schema_id = 1
        AND pi.play_start_time >= '2013-07-29 00:00:00'
        AND pi.play_start_time <= '2013-07-29 23:59:59'
    ORDER BY
            channel_id,
            column_id,
            edit_status,
            schema_id,
            play_start_time

        注:1.使用union的子sql不能包含排序语句

              2.排序的列名必须与第一个子sql的列名相同,保险起见,可以使用索引id,如上sql排序可写:ORDER BY 1,2,3,4,6 ASC

            3.排序字段列名不能带上表的别名,如channel_id不能写作pi.channel_id

           

     

          

  • 相关阅读:
    汉化DevExpress
    《苹果往事》的台式翻译
    说说《程序员》杂志的排版
    关于量化考核绩效
    as3 浅复制 深复制
    斜视角的讨论(转)
    斜角地图原理解释及斜角图形绘制实例细述(转)
    垃圾回收测试
    Flash务实主义(八)——减少数据传输量(转)
    翻译]游戏主循环
  • 原文地址:https://www.cnblogs.com/mucaiweiblog/p/3198035.html
Copyright © 2011-2022 走看看