MySQL连接和分组方式在同一个表上
下表列出了多个日期、品牌和市场MySQL连接和分组方式在同一个表上,mysql,sql,Mysql,Sql,下表列出了多个日期、品牌和市场 Date | brand | Market | CONV | PgmGRPs | -----------|-------------|----------|---------|-------------| 2020-01-01 | ABC | MTL | conv. | 80 | 2020-01-01 | ABC | MTL | Spec.
Date | brand | Market | CONV | PgmGRPs |
-----------|-------------|----------|---------|-------------|
2020-01-01 | ABC | MTL | conv. | 80 |
2020-01-01 | ABC | MTL | Spec. | 20 |
2020-01-01 | ABC | TO | conv. | 70 |
2020-01-01 | ABC | TO | Spec. | 40 |
2020-01-02 | DEF | TO | conv. | 80 |
2020-01-02 | DEF | TO | Spec. | 20 |
...
我想得到的是
Date |brand | Market |Conv. PgmGRPs |Spec. PgmGRPs |Total PgmGRPs |Conv. Ratio | Spec. Ratio|
-----------|------|--------|--------------|--------------|--------------|------------|------------|
2020-01-01 | ABC | MTL | 80 | 20 | 100 | 0.80 | 0.20 |
2020-01-01 | ABC | TO | 70 | 40 | 110 | 0.64 | 0.36 |
2020-01-02 | DEF | TO | 80 | 20 | 100 | 0.80 | 0.20 |
...
我尝试了以下方法,但没有成功
SELECT
a.`Brand`,
a.`PgmGRPs` as 'Conv. PgmGRPs',
b.`PgmGRPs` as 'Spec. PgmGRPs',
a.`PgmGRPs` + b.`PgmGRPs` AS 'Total PgmGRPs',
ROUND(a.`PgmGRPs`/ (a.`PgmGRPs` + b.`PgmGRPs`),2) as 'Conv. Ratio',
ROUND(b.`PgmGRPs`/ (a.`PgmGRPs` + b.`PgmGRPs`),2) as 'Spec. Ratio'
FROM
(SELECT
`Brand`,
IF ( `CONV` = 'Conv.', SUM(`PgmGRPs`), 0)
AS 'PgmGRPs'
FROM transform_data_1
GROUP BY `Brand`, `CONV`
) a
LEFT JOIN
(SELECT
`Brand`,
`CONV`,
SUM(`PgmGRPs`) as 'PgmGRPs'
FROM transform_data_1
WHERE `CONV` = 'Spec.'
GROUP BY `Brand`, `CONV`
) b
ON a.`Brand` = b.`Brand`
这是我得到的,但我不知道如何获得日期、品牌、市场和删除第二行
|brand | Market |Conv. PgmGRPs |Spec. PgmGRPs |Total PgmGRPs |Conv. Ratio | Spec. Ratio|
|------|--------|--------------|--------------|--------------|------------|------------|
| ABC | MTL | 80 | 20 | 100 | 0.80 | 0.20 |
| ABC | MTL | 0 | 20 | 20 | 0 | 1.00 |
....
谢谢,您得到双线的原因是第一个查询
SELECT
`Brand`,
IF ( `CONV` = 'Conv.', SUM(`PgmGRPs`), 0)
AS 'PgmGRPs'
FROM transform_data_1
GROUP BY `Brand`, `CONV`
正在返回两行,并且您正在执行左外部联接,该联接将始终包含第一个查询中的每一行
相反,您应该像对第二个查询所做的那样,使用WHERE子句只获取第一个查询中的Conv
行。然后做一个内部连接
SELECT
a.`Brand`,
a.`PgmGRPs` as 'Conv. PgmGRPs',
b.`PgmGRPs` as 'Spec. PgmGRPs',
a.`PgmGRPs` + b.`PgmGRPs` AS 'Total PgmGRPs',
ROUND(a.`PgmGRPs`/ (a.`PgmGRPs` + b.`PgmGRPs`),2) as 'Conv. Ratio',
ROUND(b.`PgmGRPs`/ (a.`PgmGRPs` + b.`PgmGRPs`),2) as 'Spec. Ratio'
FROM
(SELECT
`Brand`,
SUM(`PgmGRPs`) AS 'PgmGRPs'
FROM transform_data_1
WHERE `CONV` = 'Conv.'
GROUP BY `Brand`
) a
INNER JOIN
(SELECT
`Brand`,
`CONV`,
SUM(`PgmGRPs`) as 'PgmGRPs'
FROM transform_data_1
WHERE `CONV` = 'Spec.'
GROUP BY `Brand`, `CONV`
) b
ON a.`Brand` = b.`Brand`
这还允许我们从group by中删除
CONV
字段,我们不需要在select中对其进行测试。只需使用条件聚合,无需子查询:
SELECT a.`Brand`,
SUM(`CONV` = 'Conv.') as ConvPgmGRPs,
SUM(`CONV` = 'Spec.') as as SpecPgmGRPs,
(SUM(`CONV` = 'Conv.') + SUM(`CONV` = 'Spec.')) AS 'Total PgmGRPs',
ROUND(SUM(`CONV` = 'Conv.')/ (SUM(`CONV` = 'Conv.') + SUM(`CONV` = 'Spec.')),2) as ConvRatio,
ROUND(SUM(`CONV` = 'Conv.')/ (SUM(`CONV` = 'Conv.') + SUM(`CONV` = 'Spec.')),2) as SpecRatio
FROM transform_data_1
GROUP BY `Brand`
我相信这就是你想要的:
select tab.`Date`
, tab.brand
, tab.market
, Conv_PgmGRPs
, Spec_PgmGRPs
, Total_PgmGRPs
, ROUND(Conv_PgmGRPs / (Conv_PgmGRPs + Spec_PgmGRPs),2) as 'Conv. Ratio'
, ROUND(Spec_PgmGRPs / (Conv_PgmGRPs + Spec_PgmGRPs),2) as 'Spec. Ratio'
from (select `Date`
, brand
, Market
, (select sum(PgmGRPs)
from transform_data_1 t1
where t.`Date` = t1.`Date`
and t.brand = t1.brand
and t.Market = t1.Market
and t1.CONV = 'conv.') Conv_PgmGRPs
, (select sum(PgmGRPs)
from transform_data_1 t1
where t.`Date` = t1.`Date`
and t.brand = t1.brand
and t.Market = t1.Market
and t1.CONV = 'Spec.') Spec_PgmGRPs
, sum(PgmGRPs) Total_PgmGRPs
from transform_data_1 t
group by `Date`
, brand
, Market) tab
结果是:
使用条件聚合:
select date, brand, market,
`Conv. PgmGRPs`, `Spec. PgmGRPs`,
`Conv. PgmGRPs` + `Spec. PgmGRPs` `Total PgmGRPs`,
round(`Conv. PgmGRPs` / (`Conv. PgmGRPs` + `Spec. PgmGRPs`), 2) `Conv. Ratio`,
round(`Spec. PgmGRPs` / (`Conv. PgmGRPs` + `Spec. PgmGRPs`), 2) `Spec. Ratio`
from (
select date, brand, market,
sum(case when conv = 'conv.' then PgmGRPS end) `Conv. PgmGRPs`,
sum(case when conv = 'Spec.' then PgmGRPS end) `Spec. PgmGRPs`
from transform_data_1
group by date, brand, market
) t
请参阅。结果:
当您试图开发的查询变得太复杂时,使用暂存表就更容易了。您应该使用交叉表/透视表函数来创建要创建的交叉表 第一步。创建一个无任何计算/比率的交叉表暂存表。 第二步。运行sql语句来计算总数和比率
上面的查询类似于@forpas在上面编写的查询。您应该缩进您的代码,这样更容易阅读hi@nicolas这是您请求的带有日期列的解决方案。希望没问题。干杯
| date | brand | market | Conv. PgmGRPs | Spec. PgmGRPs | Total PgmGRPs | Conv. Ratio | Spec. Ratio |
| -----------| ----- | ------ | ------------- | ------------- | ------------- | ----------- | ----------- |
| 2020-01-01 | ABC | MTL | 80 | 20 | 100 | 0.8 | 0.2 |
| 2020-01-01 | ABC | TO | 70 | 40 | 110 | 0.64 | 0.36 |
| 2020-01-02 | DEF | TO | 80 | 20 | 100 | 0.8 | 0.2 |