感谢您的回答
但是我认为我的所需输出混乱了。 这就是我想要的(因为我正在使用ORacle DB)
创建表TestTable ( Bill_date DATE, Phone_no NUMBER(10), Planlvl1 VARCHAR2(20), Planlvl2 VARCHAR2(20) 收入NUMBER
)
INSERT INTO TestTable 值 ('1/01/2014',64221,'Bundle','SpecialPack1','$ 23'), ('1/01/2014'',64221,'Bundle','PlanA','$ 32'), ('1/01/2014',65211,'Bundle','SpecialPack2','$ 3'), ('1/01/2014',65211,'Bundle','SpecialPack1','$ 23'), ('1/01/2014',66211,'Bundle','PlanB','$ 34'), ('1/01/2014',66211,'Bundle','SpecialPack2','$ 3'), ('1/01/2014',66222,'Bundle','SpecialPack1','$ 23'), ('1/01/2014',66222,'Bundle','SpecialPack2','$ 3'), ('1/01/2014',66222,'Bundle','PlanB','$ 65'), ('1/01/2014',32444,'Non_bundle','Casual1','$ 32'), ('1/01/2014',324441,'Non_bundle','Casual2','$ 76'), ('1/01/2014',65444,'Non_bundle','Casual1','$ 12'), ('1/01/2014',65444,'Bundle','PlanB','$ 98'), ('1/01/2014',54322,'Bundle','PlanA','$ 12'), ('1/01/2014',54322,'Non_bundle','休闲','12美元')
预期结果: Bill_date PlanLvl2 PhonenoCount '01 / 01 / 2014''FitialPack1'1
'01 / 01/2014''SpecialPack2'3
'01 / 01/2014''Casual1'1
'01 / 01/2014''Casual2'1
'01 / 01/2014''PlanA'1
'01 / 01/2014''PlanB'1
正如我所提到的,如果手机没有这两款产品,'SpecialPack2'将优先于特殊包装1。
希望它更清楚
基本上最昂贵的计划计数逻辑适用于手机没有超过1'特殊包'并且没有其他类型的计划的情况。 如果电话没有特殊包装和其他计划,那么我们不需要根据“非特殊”计划计算电话号码。
我有一个测试表如下
CREATE TABLE TestTable
(`Bill_date` datetime, `Phone_no` int, `Planlvl1` varchar(10), `PlanLvl2` varchar(12), `revenue` varchar(3))
;
INSERT INTO TestTable
(`Bill_date`, `Phone_no`, `Planlvl1`, `PlanLvl2`, `revenue`)
VALUES
('2014-01-01 13:00:00', 64221, 'Bundle', 'SpecialPack1', '$23'),
('2014-01-01 13:00:00', 64221, 'Bundle', 'PlanA', '$32'),
('2014-01-01 13:00:00', 65211, 'Bundle', 'SpecialPack2', '$3'),
('2014-01-01 13:00:00', 65211, 'Bundle', 'SpecialPack1', '$23'),
('2014-01-01 13:00:00', 66211, 'Bundle', 'PlanB', '$34'),
('2014-01-01 13:00:00', 66211, 'Bundle', 'SpecialPack2', '$3'),
('2014-01-01 13:00:00', 66222, 'Bundle', 'SpecialPack1', '$23'),
('2014-01-01 13:00:00', 66222, 'Bundle', 'SpecialPack2', '$3'),
('2014-01-01 13:00:00', 66222, 'Bundle', 'PlanB', '$65'),
('2014-01-01 13:00:00', 32444, 'Non_bundle', 'Casual1', '$32'),
('2014-01-01 13:00:00', 324441, 'Non_bundle', 'Casual2', '$76'),
('2014-01-01 13:00:00', 65444, 'Non_bundle', 'Casual1', '$12'),
('2014-01-01 13:00:00', 65444, 'Bundle', 'PlanB', '$98'),
('2014-01-01 13:00:00', 54322, 'Bundle', 'PlanA', '$12'),
('2014-01-01 13:00:00', 54322, 'Non_bundle', 'Casual', '$12')
;
基本上我必须以某种方式计算按计划分组的所有电话号码:
如果PlanLvl1 = Bundle,那么我必须查看planLvl2并查看该手机是否没有'SpecialPack%',还有另一个计划,他们'特殊包'获得优先权并且手机没有计入特殊包
如果PlanLvl1 = Bundle并且手机没有“特殊包装”作为他们的计划,那么手机号码将被计入“特别包”以及更高的收入。
如果PalnLvl是'Bundle'并且手机没有多个'Special Packs'且非特殊包,那么ph no只会在'Special Pack'下计算一次;与较低转速的特殊包装相比,转速更高。
现在还有PlanLvl1,它们是'Non_Bundles',这意味着它们没有任何'SpecialPacks',但是如果带有'NonBundle'计划的ph值在planLvl2下有2个不同的计划,我们需要计算eack planLvl2的ph值..
然后有一个场景,其中一个ph不能有捆绑和非捆绑,在这种情况下,我们只需要计算捆绑中的ph值,而不是非捆绑。
这是预期的结果:
Bill_date PlanLvl2 PhonenoCount
01/01/2014 SpecialPack1 3
01/01/2014 SpecialPack2 1
01/01/2014 Casual1 0
01/01/2014 Casual2 1
01/01/2014 PlanA 1
01/01/2014 PlanB 1
答案 0 :(得分:0)
试试这个fiddle,注意没有“SpecialPack2”,因为所有数字都有SpecialPack1和聚合值忽略空值,所以不返回零。
注意问题不是聚合,而是“不计算此”逻辑。 另外我注意到大多数这个逻辑只计算最昂贵的计划,在这种情况下逻辑可以简化很多。 顺便说一下,将这些值保持为字符串(并带有前导'$')是一种非常糟糕的做法。
select bill_date
, case
when planlvl1 = 'Bundle' and planlvl2 like 'SpecialPack%' then planlvl2
when planlvl1 = 'Bundle' then planlvl2
when planlvl1 = 'Non_bundle' then planlvl2
else planlvl1 end as PlanLvl2
, count(phone_no) as PhonenoCount
from
(
select Bill_date, Phone_no, Planlvl1, PlanLvl2, cast(substring(revenue, 2, 20) as float) as revenue
from testTable
where
(
planlvl1 = 'Bundle'
and
(
(planlvl2 like 'SpecialPack%'
and cast(substring(revenue, 2, 20) as float) = (select max(cast(substring(t1.revenue, 2, 20) as float)) from testTable t1 where t1.phone_no = phone_no and planlvl2 like 'SpecialPack%')
)
or
(planlvl2 not like 'SpecialPack%'
and phone_no not in (select phone_no from testTable where planlvl2 like 'SpecialPack%')
)
)
)
or (planlvl1 = 'Non_bundle' and phone_no not in (select phone_no from testTable where Planlvl1 = 'Bundle')
and cast(substring(revenue, 2, 20) as float) = (select max(cast(substring(t1.revenue, 2, 20) as float)) from testTable t1 where t1.phone_no = phone_no and planlvl1 = 'Non_bundle')
)
) as ignore_duplicates
group by bill_date
, case
when planlvl1 = 'Bundle' and planlvl2 like 'SpecialPack%' then planlvl2
when planlvl1 = 'Bundle' then planlvl2
when planlvl1 = 'Non_bundle' then planlvl2
else planlvl1 end