Create table test123 (
CustId int,
[Level] int,
RowNum int,
USAFlag bit
)
insert into test123(CustId,[Level],RowNum,USAFlag)values
(101,1,1,0),
(102,2,1,0),
(102,2,2,1),
(103,3,1,0),
(103,3,2,1),
(103,3,3,0),
(104,4,1,1),
(104,4,2,0),
(104,4,3,0),
(104,4,4,1),
(105,2,1,1),
(105,2,2,0),
(106,2,1,0),
(106,2,2,0),
(107,3,1,0),
(107,3,2,0),
(107,3,3,1),
(108,1,1,1)
输出
CustID USARootLeaf
101 ONlyONeLevel_NonUSA
102 Leaf_USA
103 Root_Leaf_NonUSA
104 Root_Leaf_USA
105 Root_USA
106 Root_Leaf_NonUSA
107 Leaf_USA
108 OnlyOneLvel_USA
逻辑: 如果Level为1,则USARootLeaf值应为OnlyOneLvel_USA或OnlyOneLvel_NonUSA,基于USAFlag值
如果Level为> 1,则USARootLeaf值应为Root_Leaf_USA,Root_Leaf_NonUSA,Root_USA,Leaf_USA基于min(级别)和USAFlag的max(level)值为true / false
答案 0 :(得分:0)
这可以重构为更小,但这里是根据上述要求对实现的猜测。 请注意,我在我的DDL中将[Level]更改为thisLevel。
mysql> select q.custid, concat(q.type,concat('_',q.starsandstripes)) as type from (
-> select
-> z.custid,
-> case when minlevel = 1 and maxlevel = 1 then 'OnlyOneLevel'
-> else
-> case when lastflag = 1 and firstflag = 0 then 'Leaf'
-> when lastflag = 0 and firstflag = 1 then 'Root'
-> when lastflag = firstflag then 'Root_Leaf'
-> end
-> end as type,
-> starsandstripes
-> from
-> (
-> select
-> za.custid,
-> case when max(za.usaflag) = 1
-> then 'USA'
-> else 'NonUSA'
-> end
-> as starsAndStripes
-> from test123 za join
-> (
-> select
-> custid,
-> max(rownum) as maxrow,
-> min(rownum) as minrow
-> from test123 zc
-> group by custid
-> ) zb
-> on za.custid = zb.custid
-> and (za.rownum = zb.maxrow
-> or za.rownum = zb.minrow)
-> group by za.custid
-> ) z,
-> (
-> select
-> a.custid,
-> (select usaflag from test123 d where d.custid = a.custid and d.rownum = b.maxrow) as lastFlag,
-> (select usaflag from test123 d where d.custid = a.custid and d.rownum = b.minrow) as firstFlag,
-> min(thisLevel) as minLevel,
-> max(thisLevel) as maxLevel
-> from test123 a join
-> (
-> select custid, max(rownum) as maxrow, min(rownum) as minrow
-> from test123 c
-> group by custid
-> ) b
-> on a.custid = b.custid
-> group by custid,
-> (select usaflag from test123 d where d.custid = a.custid and d.rownum = b.maxrow),
-> (select usaflag from test123 d where d.custid = a.custid and d.rownum = b.minrow)
-> ) x
-> where z.custid = x.custid
-> ) q;
输出:
+--------+---------------------+
| custid | type |
+--------+---------------------+
| 101 | OnlyOneLevel_NonUSA |
| 102 | Leaf_USA |
| 103 | Root_Leaf_NonUSA |
| 104 | Root_Leaf_USA |
| 105 | Root_USA |
| 106 | Root_Leaf_NonUSA |
| 107 | Leaf_USA |
| 108 | OnlyOneLevel_USA |
+--------+---------------------+
8 rows in set (0.00 sec)
答案 1 :(得分:0)
感谢Bryan和Jason的快速投入。 我自己找到了一个更好的解决方案。
with one as
(
Select CustId,[Level],
STUFF((SELECT ',' + cast(USAFlag as char(1)) FROM test123 WHERE (
CustId=Result.CustId) FOR XML PATH ('')),1,1,'') AS USAList
From test123 AS Result
GROUP BY CustId,[Level]
)
Select CustId,[level],USAList,
case
when Level=1 and substring(USAList,1,1)='1' then 'ONlyONeLevel_USA'
when Level=1 and substring(USAList,1,1)='0' then 'ONlyONeLevel_NonUSA'
when Level>1 and substring(USAList,1,1)='1' and substring(USAList,level*2-
1,1)='1' then 'Root_Leaf_USA'
when Level>1 and substring(USAList,1,1)='0' and substring(USAList,level*2-
1,1)='0' then 'Root_Leaf_NonUSA'
when Level>1 and substring(USAList,1,1)='1' then 'Root_USA'
when Level>1 and substring(USAList,level*2-1,1)='1' then 'Leaf_USA'
else 'InvalidLevel'
end as USARootLeaf
from one