网站建设知识
mysql或者hive实现分层向下统计功能
2025-07-22 10:02  点击:0

mysql或者hive实现分层向下统计功能。原因:作为一名数据人员,经常会碰到类似这样的表结构:

city_id city_code   city_name   parent_id   citylevel1   中国  中国  0   02   110000  北京市 1   03   120000  天津市 1   04   130000  河北省 1   05   140000  山西省 1   06   150000  内蒙古自治区  1   07   210000  辽宁省 1   08   220000  吉林省 1   09   230000  黑龙江省    1   

其中parent_id代表本条数据的上一层级id,citylevel代表本条数据的所属层级,这样的表结构会把含有多个层级的数据放在一张表中,层级关系用parent_id和citylevel来表示,这种类似于码表的数据(如城市码表,标签码表)后台开发的同学往往会设计成这样的表结构。
但是对于应用数据的同学来说,这样的表结构非常让人头疼,因为往往他需要的是一层一层平铺开来的数据,比如全国、省、市、县的订单量各有多少,想实现像数据透视表那样的效果,比如:

区(县)id  区(县)    市id 市   省id 省   全国id    全国  单量110101  东城区 110000  北京市 110000  北京市 0   全国  3598110102  西城区 110000  北京市 110000  北京市 0   全国  4973110105  朝阳区 110000  北京市 110000  北京市 0   全国  4033110106  丰台区 110000  北京市 110000  北京市 0   全国  3731110107  石景山区    110000  北京市 110000  北京市 0   全国  4159110108  海淀区 110000  北京市 110000  北京市 0   全国  4426110109  门头沟区    110000  北京市 110000  北京市 0   全国  3370110111  房山区 110000  北京市 110000  北京市 0   全国  3922110112  通州区 110000  北京市 110000  北京市 0   全国  3188110113  顺义区 110000  北京市 110000  北京市 0   全国  3902110114  昌平区 110000  北京市 110000  北京市 0   全国  3257110115  大兴区 110000  北京市 110000  北京市 0   全国  3193110116  怀柔区 110000  北京市 110000  北京市 0   全国  3319110117  平谷区 110000  北京市 110000  北京市 0   全国  3103110228  密云县 110000  北京市 110000  北京市 0   全国  4589110229  延庆县 110000  北京市 110000  北京市 0   全国  4463130102  长安区 130100  石家庄市    130000  河北省 0   全国  4273130103  桥东区 130100  石家庄市    130000  河北省 0   全国  3483

如何实现这样的效果呢?即将一个纵向关系表变为一个横向关系表?
可以这样写:

#orders代表订单表 tags代表城市码表(假设tags有三层)select       substr(c.finish_time,1,10)    ,t1.name    ,t2.name    ,t3.name,count(c.id) from tags t1 left join tags t2 on t2.parent_id=t1.id left join tags t3 on t3. parent_id=t2.id left join orders c on (c.tag_id=t3.id or c.tag_id=t2.id or c.tag_id=t1.id)              where t1.level=1 group by c.tag_id,substr(c.finish_time,1,10)

结论:对于纵向表,可以先将其转化为横向的码表,不论什么样的码表不管有几层,只要有level 和parent_id这样的,都可以用如下方式转化:

SELECT     t1.name    ,t2.name    ,t3.nameFROM tags t1 LEFT JOIN tags t2 ON t2.parent_id=t1.id LEFT JOIN tags t3 ON t3. parent_id=t2.id WHERE t1.level=1 

或者:

SELECT     a.`name`    ,b.`name`    ,c.`name`FROM `tags` a LEFT JOIN tags b ON a.`id`=b.`parent_id`LEFT JOIN tags c ON b.`id`=c.`parent_id`WHERE a.`parent_id` IS NULL

上述sql的层级均为三级,如果还有更多的层级,继续向下join就行了,只要切记在最后的where中限定parent_id或者level即可。