数据研发应该具备的能力-SQL(1)

rick    2020-08-18 00:35

        作为数据研发,SQL应该是吃饭的家伙,Structured Query Language:结构化查询语言是一种特定目的编程语言,网上关于他的介绍和教程已经很多了,不再一一赘述。
        这里单独说一下跟数据研发相关的sql知识,首先不管是hadoop,spark,flink都是有Sql Api的,是什么意思呢?就是说不管hadoop底层怎么map reduce; 不管spark底层RDD怎么旋转跳跃成DAG; 不管Flink底层怎么state存储,我们都可以用一句简单的 select * from table 实现我们的基本业务需求。有同学要问了,写sql感觉很不cool,学的知识也少了,但是同学,在面对紧急业务需求时还是要以完成需求为首要目标,工作不是学习,职场不是实验室,降低开发维护成本才是真~ 要什么自行车,能用就行,真想学还是靠自己平时业余时间积累的。
        言归正传,下面来几个实际工作中遇到的点(以HiveSQL为例)

1. Null值处理
        Null值不管在java和sql中都是个很令人头疼的数据,sql中不能用<> null进行圈选,要用is,或者is not, 同时在count时,null值还会分情况计算
        count(*):所有行进行统计,包括NULL行
        count(1):所有行进行统计,包括NULL行
        count(col):对col中非Null进行统计
        count(distinct col): 对col中非Null进行统计

2. 语句执行顺序
(5)SELECT (6)DISTINCT <col>
(1)FROM <table>
(2)WHERE <condition>
(3)GROUP BY <col>
(4)HAVING <condition>
(7)ORDER BY <col>
(8)LIMIT <num>
3. Case when 和 row_number的合用
-- sql1
SELECT * 
      ,CASE WHEN platform='tm' THEN ROW_NUMBER() OVER(
                PARTITION BY shop_name 
                ORDER BY pay_amt)
       ELSE NULL END AS tm_order_rank  
FROM table 
-- where platform='tm'

-- sql2
SELECT * 
      ,CASE WHEN platform='tm' THEN ROW_NUMBER() OVER(
                PARTITION BY CASE WHEN platform='tm' THEN shop_name ELSE NULL END
                ORDER BY pay_amt)
       ELSE NULL END AS tm_order_rank  
FROM table
-- where platform='tm' 
两端sql都是对tm平台的门店按照金额排序,首先我们需要知道row_number() over()的发生时间,首先使用该函数时,over()里的分组排线执行晚于where,group by,order by,因此当限制where platform条件和case when的一致时结果一样,但是当去掉条件时,结果会不同,sql1的结果不是连续排名,sql2是连续的,原因是什么?

问题在于内外层的case when的效果是不同的:
        内层的case when进行条件限制分组, 意思是只有满足case when条件的才进行分组, 否则都是null
        外层的case when作用是判读结果是否符合,即满足条件的显示排名结果,否则不显示
因此两端sql都只会显示platform=tm的排名数据,而只有内部加了case when的条件排序结果是1,2,3,4,内部没有case when的按照全部shop_name排序,只展示platform=tm的排名

4. 数据倾斜常用处理手段
        a. 改参数
        b. 大小表关联用mapjoin
        c. 少用count distinct
        d. 少用动态分区
        e. 特殊值单独处理再union all
        f. 对主键做md5之后分组处理

5. 有主键的情况下如何找脏数据
SELECT rowkey
FROM TABLE 
GROUP BY rowkey
HAVING count(1) > 1;

6. GROUPING SET
表 c1, c2, c3, cnt, 要求对c1, c2, c3分别统计,如何快速编写SQL
 select  c1
        ,c2
        ,c3
        ,Grouping__ID as group_id
        ,sum(cnt)
    from table
group by c1
        ,c2
        ,c3
grouping sets(
    (c1)
    ,(c2)
    ,(c3)
    ,(c1,c2)
    ,(c2,c3)
    ,(c1,c3)
    ,(c1,c2,c3)
)     
Last Modified: 2021-01-16 20:33
Views: 1.4K

[[total]] comments

Post your comment
  1. [[item.time]]
    [[item.user.username]] [[item.floor]]Floor
  2. Click to load more...
  3. Post your comment