我有一个相对比较复杂的表mytable,如下所示:
Snos Column1 Column2 Column3 Column4 Column5 Column6 1 AD AD1 C1 2011 P1 6435200 2 AD AD1 C1 2010 P1 234 3 AD AD1 C1 2009 P1 6435 4 BD AD2 C2 2010 P2 198448333 5 CD AD3 C3 2011 P3 194414870
我想执行一个查询,这个查询会补充Column4和Column5的数据。这里可以看出来,Column4其实是年份,而Column5是季度。对于缺失的信息,如2009,P2,重复Column1-3的内容,Column6补充0。
即对于上述表,我想查询得出如下的结果集:
Snos Column1 Column2 Column3 Column4 Column5 Column6 1 AD AD1 C1 2011 P1 6435200 2 AD AD1 C1 2010 P1 234 3 AD AD1 C1 2009 P1 6435 4 AD AD1 C1 2011 P2 0 5 AD AD1 C1 2010 P2 0 6 AD AD1 C1 2009 P2 0 7 AD AD1 C1 2011 P3 0 8 AD AD1 C1 2010 P3 0 9 AD AD1 C1 2009 P3 0 10 BD AD2 C2 2010 P2 198448333 11 BD AD2 C2 2009 P2 0 12 BD AD2 C2 2011 P2 0 13 BD AD2 C2 2010 P1 0 14 BD AD2 C2 2009 P1 0 15 BD AD2 C2 2011 P1 0 16 BD AD2 C2 2010 P3 0 17 BD AD2 C2 2009 P3 0 18 BD AD2 C2 2011 P3 0 19 CD AD3 C3 2011 P3 194414870 20 CD AD3 C3 2009 P3 0 21 CD AD3 C3 2010 P3 0 22 CD AD3 C3 2011 P1 0 23 CD AD3 C3 2009 P1 0 24 CD AD3 C3 2010 P1 0 25 CD AD3 C3 2011 P2 0 26 CD AD3 C3 2009 P2 0 27 CD AD3 C3 2010 P2 0
我尝试使用临时表辅助查询操作:
CREATE TEMPORARY TABLE tmptable_1 SELECT * FROM table WHERE *Some Condition*; Some If Else Then UPDATE tmptable_1 SET Column6 = 0; INSERT INTO table SELECT * FROM tmptable_1; DROP TEMPORARY TABLE IF EXISTS tmptable_1;
但是不能获取所需的结果,这样的SQL应该怎么写呢?
本题来源StackOverFlow
此题要求补齐完整的结果集,那么首先需要想办法生成完整的结果集,然后根据以往经验,使用左关联即可,这样能够保证结果集的完整,又可以根据左表与右表的关联,来设置缺失的值。接下来的问题是:如何生成完整的结果集?使用过关联的读者都知道笛卡尔积,它会将表关联的所有可能性生成,即A表M条数据,B表N条数据,A表与B表笛卡尔积就会生成M*N条数据,从而包括所有记录组合情况。这正符合这里的场景!
注:笛卡尔积正常情况下很少被使用,通常关联表都是会有筛选条件,而笛卡尔积就是没有筛选条件的表关联操作!在大表上需要避免这类操作,因为中间结果或者最终结果量可能巨大!此题要求的完整结果集,应该是(Column1,Column2,Column3的所有可能性)*(Column4的所有可能性)*(Column5的所有可能性)。而补充的数据Column6填充0,利用Left Outer Join+Case When即可解决。
一种具体写法如下:
注:笛卡尔积正常情况下很少被使用,通常关联表都是会有筛选条件,而笛卡尔积就是没有筛选条件的表关联操作!在大表上需要避免这类操作,因为中间结果或者最终结果量可能巨大!此题要求的完整结果集,应该是(Column1,Column2,Column3的所有可能性)*(Column4的所有可能性)*(Column5的所有可能性)。而补充的数据Column6填充0,利用Left Outer Join+Case When即可解决。
一种具体写法如下:
SELECT C.c1, C.c2, C.c3, A.c4, D.c5, CASE WHEN B.c6 is null THEN 0 ELSE B.c6 END AS c6 FROM (SELECT '2011' as c4 UNION ALL SELECT '2010' as c4 UNION ALL SELECT '2009' as c4 ) A INNER JOIN (SELECT DISTINCT c5 FROM mytable) D INNER JOIN ( SELECT DISTINCT c1,c2,c3 FROM mytable ) C LEFT OUTER JOIN mytable B ON A.c4 = B.c4 AND D.c5 = B.c5 AND C.c1 = B.c1 AND C.c2 = B.c2 AND C.c3 = B.c3 ;
The post 如何插入遗失的数据将表补充完整? appeared first on SQLParty.