sql 留着看

本文深入解析了一段复杂的SQL查询语句,涵盖了用户信息、订单数据的联表查询,以及多种条件筛选,包括地理位置、购买行为、活跃度和注册方式等。通过对SQL语句的逐行分析,揭示了其背后的业务逻辑和技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 select user_id
      from
          (select
                u.user_id,
    			u.integral,
    			SUM(o.rough_amount) totalPrice,
    			COUNT(o.id) orderNum
            FROM
            	t_user u
            LEFT JOIN t_user_info info ON u.user_id = info.user_id
            LEFT JOIN t_order o on u.user_id = o.user_id and o.status in (5,6,51)
            LEFT JOIN t_address a on u.user_id = a.user_id and a.enable = 1
            <where>
            <if test="storeId != null and storeId != ''">and u.store_id = #{storeId}</if>
            <if test="sex != null and sex != ''">and u.sex = #{sex}</if>
            <if test="birthdayCon != null">and SUBSTR(u.birthday,6,2) in
                <foreach collection="birthdayCon" index="index" item="item" open="(" separator="," close=")">
                      #{item}
                </foreach>
            </if>
            <if test="ageMin != null and ageMin != ''">and TIMESTAMPDIFF(YEAR, u.birthday, CURDATE()) <![CDATA[>=]]> #{ageMin}</if>
            <if test="ageMax != null and ageMax != ''">and TIMESTAMPDIFF(YEAR, u.birthday, CURDATE()) <![CDATA[<=]]> #{ageMax}</if>
            <if test="cityCon != null"> and
                <foreach collection="cityCon" index="index" item="item" open="(" separator="or" close=")">
                      (info.province = #{item.province}
                      and info.city = #{item.city}
                      and info.area = #{item.area})
                </foreach>
            </if>
            <if test="receiveAddCon != null"> and
                <foreach collection="receiveAddCon" index="index" item="item" open="(" separator="or" close=")">
                      (a.province_code = #{item.province}
                      and a.city_code = #{item.city}
                      and a.area_code = #{item.area})
                </foreach>
    
            </if>
            <if test="recBuyCon != null and recBuyCon != ''">
              <choose>
               <when test="recBuyCon == 1">and DATE_SUB(CURDATE(), INTERVAL 7 DAY) <![CDATA[<=]]> o.create_time</when>
               <when test="recBuyCon == 2">
                  and DATE_SUB(CURDATE(), INTERVAL 30 DAY) <![CDATA[<=]]> o.create_time
                  and DATE_SUB(CURDATE(), INTERVAL 7 DAY) <![CDATA[>]]> o.create_time
               </when>
               <when test="recBuyCon == 3">
                  and DATE_SUB(CURDATE(), INTERVAL 90 DAY) <![CDATA[<=]]> o.create_time
                  and DATE_SUB(CURDATE(), INTERVAL 30 DAY) <![CDATA[>]]> o.create_time
               </when>
               <when test="recBuyCon == 4">
                  and DATE_SUB(CURDATE(), INTERVAL 180 DAY) <![CDATA[<=]]> o.create_time
                  and DATE_SUB(CURDATE(), INTERVAL 90 DAY) <![CDATA[>]]> o.create_time
               </when>
              </choose>
            </if>
            <if test="recActiveCon != null and recActiveCon != ''">
              <choose>
               <when test="recActiveCon == 1">and DATE_SUB(CURDATE(), INTERVAL 7 DAY) <![CDATA[<=]]> u.login_time</when>
               <when test="recActiveCon == 2">
                  and DATE_SUB(CURDATE(), INTERVAL 30 DAY) <![CDATA[<=]]> u.login_time
                  and DATE_SUB(CURDATE(), INTERVAL 7 DAY) <![CDATA[>]]> u.login_time
               </when>
               <when test="recActiveCon == 3">
                  and DATE_SUB(CURDATE(), INTERVAL 90 DAY) <![CDATA[<=]]> u.login_time
                  and DATE_SUB(CURDATE(), INTERVAL 30 DAY) <![CDATA[>]]> u.login_time
               </when>
               <when test="recActiveCon == 4">
                  and DATE_SUB(CURDATE(), INTERVAL 180 DAY) <![CDATA[<=]]> u.login_time
                  and DATE_SUB(CURDATE(), INTERVAL 90 DAY) <![CDATA[>]]> u.login_time
               </when>
              </choose>
            </if>
            <if test="regTimeCon != null and regTimeCon != ''">
              <choose>
               <when test="regTimeCon == 1">and DATE_SUB(CURDATE(), INTERVAL 7 DAY) <![CDATA[<=]]> u.create_time</when>
               <when test="regTimeCon == 2">
                  and DATE_SUB(CURDATE(), INTERVAL 30 DAY) <![CDATA[<=]]> u.create_time
                  and DATE_SUB(CURDATE(), INTERVAL 7 DAY) <![CDATA[>]]> u.create_time
               </when>
               <when test="regTimeCon == 3">
                  and DATE_SUB(CURDATE(), INTERVAL 90 DAY) <![CDATA[<=]]> u.create_time
                  and DATE_SUB(CURDATE(), INTERVAL 30 DAY) <![CDATA[>]]> u.create_time
               </when>
               <when test="regTimeCon == 4">
                  and DATE_SUB(CURDATE(), INTERVAL 180 DAY) <![CDATA[<=]]> u.create_time
                  and DATE_SUB(CURDATE(), INTERVAL 90 DAY) <![CDATA[>]]> u.create_time
               </when>
              </choose>
            </if>
            <if test="regWayCon != null and regWayCon != ''">
                <if test="regWayCon == 1">and u.origin = 8</if>
                <if test="regWayCon == 2">and u.origin in (0,1,2,3,4,5)</if>
            </if>
            </where>
            GROUP BY u.user_id) a
        <where>
          <if test="buyTrade != null"> or orderNum <![CDATA[>=]]> #{buyTrade}</if>
          <if test="buyMoney != null"> or totalPrice <![CDATA[>=]]> #{buyMoney}</if>
          <if test="buyIntegral != null"> or integral <![CDATA[>=]]> #{buyIntegral}</if>
        </where>

 

### SQL IN 查询中去除重复项 在处理 `IN` 子查询时,如果子查询返回的结果集中存在重复值,则会影响外层查询的性能和准确性。为了确保 `IN` 子查询只返回唯一值,可以采用多种方法。 #### 方法一:使用 DISTINCT 关键字 最简单的方式是在子查询中加入 `DISTINCT` 来消除重复值: ```sql SELECT column_name(s) FROM table1 WHERE column_name IN ( SELECT DISTINCT sub_column_name FROM table2 ); ``` 这种方法适用于大多数情况下不需要考虑顺序的情况[^1]。 #### 方法二:利用聚合函数与 GROUP BY 当需要基于某些条件筛选出唯一的组合时,可以通过 `GROUP BY` 和聚合函数实现更复杂的逻辑控制: ```sql SELECT t1.column_name(s) FROM table1 AS t1 WHERE EXISTS( SELECT 1 FROM ( SELECT MIN(id), other_columns... FROM table2 WHERE condition GROUP BY other_columns... )AS t2 WHERE t1.matching_condition = t2.some_value; ); ``` 此方式适合于多列联合去重场景,并且可以根据业务需求灵活调整分组依据[^4]。 #### 方法三:窗口函数 ROW_NUMBER() 对于较新的数据库版本支持窗口函数的情况下,还可以通过 `ROW_NUMBER()` 实现高效的数据过滤: ```sql WITH RankedData AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY key_column ORDER BY sort_column) as rn FROM source_table ) SELECT * FROM RankedData WHERE rn = 1 AND target_column IN ( SELECT value_to_match FROM another_query_or_table ); ``` 这种方式不仅能够有效去除重复记录,还能保持原始数据集中的特定排序关系[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值