具有12个月表的SQL计数条件

时间:2018-01-24 06:31:25

标签: sql oracle pivot

我有下表名为:LISTON

| TYPE | MONTHS | New | Old |
+------+--------+-----+-----+
| A    | FEB    |  Y  |  N  |
| A    | MAY    |  Y  |  N  |
| A    | MAY    |  N  |  Y  |
| B    | MAY    |  Y  |  N  |
| A    | MAY    |  Y  |  N  |
| C    | MAY    |  Y  |  N  |
| D    | MAY    |  Y  |  N  |

我想将上面的数据安排成下面显示的格式:

| MONTHS |     A     |     B     |     C     |     D     |
|        | New | Old | New | Old | New | Old | New | Old |
+--------+-----+-----+-----+-----+-----+-----+-----+-----+
| JAN    |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |
| FEB    |  1  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |
| MAR    |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |
| APR    |  0  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |
| MAY    |  2  |  1  |  1  |  0  |  1  |  0  |  1  |  0  |

是否可以在SQL中执行此操作?通过计数或排序?或者任何其他方式都会有所帮助。

5 个答案:

答案 0 :(得分:1)

您可以使用 var allowedDrivers = (ObservableCollection<Person>)Car.AllowedDrivers; allowedDrivers.Add(person) 执行此操作,例如

pivot

这给出了输出:

with pvt as(select * from mtable
        pivot (
          sum(case new when 'Y' then 1 else 0 end) new,
          sum(case old when 'Y' then 1 else 0 end) old
          for atype in ('A' a, 'B' b, 'C' c, 'D' d)
        )
        order by to_char(to_date(months, 'MON'), 'mm')),
  mnt as (select level mid, to_char(to_date(to_char(level,'09'),'mm'),'MON') months from dual connect by level <= 12)
select months, nvl(a_new,0) a_new, nvl(a_old,0) a_old, 
   nvl(b_new,0) b_new, nvl(b_old,0) b_old, 
   nvl(c_new,0) c_new, nvl(c_old,0) c_old, 
   nvl(d_new,0) d_new, nvl(d_old,0) d_old
from mnt
left outer join pvt using (months)
order by mnt.mid;

答案 1 :(得分:1)

您可以尝试以下代码:

with
MyTable as 
  ( select 'A' as type, 'FEB' as months, 'Y' as new, 'N' as old from dual
    union all select 'A', 'MAY', 'Y', 'N' from dual
    union all select 'A', 'MAY', 'N', 'Y' from dual
    union all select 'B', 'MAY', 'Y', 'N' from dual
    union all select 'A', 'MAY', 'Y', 'N' from dual
    union all select 'C', 'MAY', 'Y', 'N' from dual
    union all select 'D', 'MAY', 'Y', 'N' from dual
  )
select *
  from MyTable
 pivot ( count(decode(new, 'Y', 1, null)) as new
       , count(decode(old, 'Y', 1, null)) as old
       for type in ('A' a, 'B' b, 'C' c, 'D' d)
       )
 Order by 1

答案 2 :(得分:0)

您可以使用下面给出的SUM CASE WHEN条件来执行此操作。

{{1}}

答案 3 :(得分:0)

您可以使用pivot子句来管理它:

with tab as 
(
 select mon, type||new||old type from months m1 right outer join 
 ( select to_char(to_date(lpad(level,2,'0'),'MM'),'MON') mon, level mon_nr from dual 
   connect by level <= 5 ) m2 on ( m1.month = m2.mon ) -- you can replace 5 with 12 for whole year
)
select * from tab
pivot 
(
   count(1) for (type) in ('AYN' as "A (New)",'ANY' as "A (Old)",'BYN' as "B (New)",'BNY' as "B (Old)",'CYN' as "C (New)",'CNY' as "C (Old)",'DYN' as "D (New)",'DNY' as "D (Old)")
)
order by to_date(mon,'MM');

表创建如下:

create table months(Type varchar2(1),Month varchar2(3),New varchar2(1),Old varchar2(1));

输出 是:

MON A (New) A (Old) B (New) B (Old) C (New) C (Old) D (New) D (Old)
JAN    0       0       0       0       0       0       0       0
FEB    1       0       0       0       0       0       0       0
MAR    0       0       0       0       0       0       0       0
APR    0       0       0       0       0       0       0       0
MAY    2       1       1       0       1       0       1       0

D e m o

答案 4 :(得分:-2)

由于您使用 plsql 标记了帖子,我假设您使用的是Oracle数据库。

根据您的描述,我认为您希望将行转换为列。这可以使用所谓的 pivot 在Oracle中完成。此Web page向您展示了如何编写数据透视查询。希望它有所帮助。

祝你好运,

阿维。