SQL-Group By中两个值的总和



我正在尝试添加两个值或获取两个值的和,并将其显示在一个Exchange名称下。以下数据:

Table
--------------------------------------------------
EXCHANGE NAME       CODE        TURNOVER    TRADEDATE
PARIS               PA            12        14-NOV-2019
SWISS               SW            14        14-NOV-2019
NULL                SA             2        14-NOV-2019
NULL                MI             2        14-NOV-2019
MILAN               MI_1           3        14-NOV-2019
My Query
----------------------------------------------------
SELECT CE.EXCHANGE_NAME, sum(CE.TURNOVER)  
FROM CE
WHERE CE.tradedate = '14-NOV-2019'
GROUP BY CE.EXCHANGE_NAME
Result
-----------------------------------------------------
EXCHANGE NAME       SUM
PARIS               12
SWISS               14
MILAN               3

我想实现的是瑞士队的总人数是16人,米兰队是5人,因为MI也属于米兰。交易所名称有空值,但它们属于某个交易所(在这种情况下是瑞士和米兰(,即代码SA属于瑞士,MI属于米兰。

在我查询瑞士和米兰这样的情况时,如果我知道哪个代码属于EXCHANGE_NAME,我该如何处理这一问题?

非常感谢

您可以使用COALESCE():

SELECT COALESCE(CE.EXCHANGE_NAME, 'SWISS') as EXCHANGE_NAME, SUM(CE.TURNOVER)  
FROM CE
WHERE CE.tradedate = '14-NOV-2019'
GROUP BY COALESCE(CE.EXCHANGE_NAME, 'SWISS');

注意:我喜欢使用DATE作为日期常数:

WHERE CE.tradedate = DATE '2019-11-14'

这允许使用ISO标准日期格式。

编辑:

使用CASE表达式:

SELECT (CASE WHEN CE.CODE = 'SA' THEN 'SWISS'
WHEN CE.CODE = 'MI_1' THEN 'MILAN'
ELSE CE.EXCHANGE_NAME
END) as EXCHANGE_NAME,
SUM(CE.TURNOVER)  
FROM CE
WHERE CE.tradedate = DATE '2019-11-14'
GROUP BY (CASE WHEN CE.CODE = 'SA' THEN 'SWISS'
WHEN CE.CODE = 'MI_1' THEN 'MILAN'
ELSE CE.EXCHANGE_NAME
END);

对我来说,似乎必须创建一个映射表,该表将代码映射到交换名称:

SQL> create table exmap
2    (exchange_name varchar2(20),
3     code          varchar2(10));
Table created.
SQL> insert into exmap
2    select 'PARIS', 'PA'   from dual union all
3    select 'SWISS', 'SW'   from dual union all
4    select 'SWISS', 'SA'   from dual union all
5    select 'MILAN', 'MI'   from dual union all
6    select 'MILAN', 'MI_1' from dual;
5 rows created.
SQL>

现在,有了CE表中的日期(您发布的那个(,您就可以加入这两个表:

SQL> select e.exchange_name,
2         sum(c.turnover) sum_turnover
3  from ce c join exmap e on e.code = c.code
4  group by e.exchange_name;
EXCHANGE_NAME        SUM_TURNOVER
-------------------- ------------
PARIS                          12
MILAN                           5
SWISS                          16
SQL>

为什么要这样做?因为你迟早会在CE表中添加这样的内容(所以巴黎现在是20(:

SQL> insert into ce values ('PARIS', 'PR', 8);
1 row created.

现在,如果您选择在代码中维护映射,则必须在所有存储过程、报表、表单中的任何位置修复它。。。使用该表的任何内容,并添加另一个CASE,例如

case when code in ('PA', 'PR') then 'PARIS'
...                 ^^^^
this

这可能会让你发疯。但是,如果您简单地将其添加到映射表中:

SQL> insert into exmap values ('PARIS', 'PR');
1 row created.

"旧">加入查询将在没有任何进一步操作的情况下工作:

SQL> select e.exchange_name,
2         sum(c.turnover) sum_turnover
3  from ce c join exmap e on e.code = c.code
4  group by e.exchange_name;
EXCHANGE_NAME        SUM_TURNOVER
-------------------- ------------
PARIS                          20
MILAN                           5
SWISS                          16
SQL>

您可以使用COALESCE()EXCHANGE_NAMENULL值转换为'SWISS':

SELECT COALESCE(CE.EXCHANGE_NAME, 'SWISS'), sum(CE.TURNOVER)  
FROM CE
WHERE CE.tradedate = '14-NOV-2019'
GROUP BY COALESCE(CE.EXCHANGE_NAME, 'SWISS')

编辑:您可以使用方便的Oracle函数decode()code映射到默认的EXCHANGE_NAME:

SELECT 
COALESCE(
CE.EXCHANGE_NAME, 
DECODE(CE.CODE, 'SA', 'SWISS', 'MI_1', 'MILAN')
) EXCHANGE, 
SUM(CE.TURNOVER)  
FROM CE
WHERE CE.tradedate = '14-NOV-2019'
GROUP BY COALESCE(
CE.EXCHANGE_NAME, 
DECODE(CE.CODE, 'SA', 'SWISS', 'MI_1', 'MILAN')
)

您可以根据用例的需要扩展DECODE()参数。

最新更新