SQL - 将行转换为列,分组数据和计数行

时间:2014-08-04 05:02:02

标签: sql oracle

当前情景:

我有以下源数据表(TABLE1):

SOURCEDATE      FILENAME  UNIQUE_ROW
--------------  --------  ----------
20140704232250  FILE1     ABCDEF10
20140704232250  FILE2     ABCDEF11
20140704232250  FILE3     ABCDEF12
20140704232250  FILE4     ABCDEF13
20140704232250  FILE1     ABCDEF10
20140704232250  FILE2     ABCDEF11
20140704232250  FILE3     ABCDEF12
20140704232250  FILE4     ABCDEF13
20140703232250  FILE1     ABCDEF14
20140703232250  FILE3     ABCDEF15
20140703232250  FILE1     ABCDEF14
20140703232250  FILE3     ABCDEF15
20140702232250  FILE2     ABCDEF16
20140702232250  FILE3     ABCDEF17
20140702232250  FILE4     ABCDEF18
20140701232250  FILE1     ABCDEF19
20140701232250  FILE5     ABCDEF20
20140630232250  FILE2     ABCDEF21
20140630232250  FILE3     ABCDEF22
20140629232250  FILE1     ABCDEF23
20140629232250  FILE4     ABCDEF24
20140629232250  FILE5     ABCDEF25
20140629232250  FILE6     ABCDEF26
20140629232250  FILE1     ABCDEF23
20140629232250  FILE4     ABCDEF24
20140629232250  FILE5     ABCDEF25
20140629232250  FILE6     ABCDEF26

目前日期为YYYYMMDDHH24MISS格式。我希望将上面的行和列转换为以下格式并插入TABLE2:

SOURCEDATE  FILE1  FILE2  FILE3  FILE4  FILE5  FILE6
----------  -----  -----  -----  -----  -----  -----
04-07-2014    2      2      2      2      0      0
03-07-2014    2      0      2      0      0      0
02-07-2014    0      1      1      1      0      0
01-07-2014    1      0      0      0      1      0
30-06-2014    0      1      1      0      0      0
29-06-2014    2      0      0      2      2      2

换句话说,我希望源数据按日期和文件名分组并完成计数。如果特定文件记录不存在,则向Table2插入0值。

我有基本的SQL知识,但目前这超出了我的专业知识。我已经能够创建一个表,可以按日期计算文件数,但不能根据上述要求格式化表。我当前的SQL代码如下:

CREATE TABLE TABLE2 AS
   select
      to_char(TO_DATE(SOURCEDATE, 'YYYYMMDDHH24MISS'), 'DD-MM-YYYY') AS S_DATE,
      filename,
      count(*) as RECORD_COUNT 
   from TABLE1
   group by SOURCEDATE, filename
   order by SOURCEDATE DESC;

这给了我下表:

S_DATE      FILENAME  RECORD_COUNT
----------  --------  ------------
04-07-2014  FILE1           2
04-07-2014  FILE2           2
04-07-2014  FILE3           2
04-07-2014  FILE4           2
03-07-2014  FILE1           2
03-07-2014  FILE3           2
02-07-2014  FILE2           1
02-07-2014  FILE3           1
02-07-2014  FILE4           1
01-07-2014  FILE1           1
01-07-2014  FILE5           1
30-06-2014  FILE2           1
30-06-2014  FILE3           1
29-06-2014  FILE1           2
29-06-2014  FILE4           2
29-06-2014  FILE5           2
29-06-2014  FILE6           2

2 个答案:

答案 0 :(得分:1)

对于旧版本的oracles(10g),您可以使用:

CREATE TABLE TABLE2 AS
  SELECT
     TO_CHAR(TO_DATE(sourcedate, 'YYYYMMDDHH24MISS'), 'DD-MM-YYYY') AS s_date,
     SUM(CASE WHEN filename='FILE1' THEN 1 ELSE 0 END) AS file1,
     SUM(CASE WHEN filename='FILE2' THEN 1 ELSE 0 END) AS file2,
     SUM(CASE WHEN filename='FILE3' THEN 1 ELSE 0 END) AS file3,
     SUM(CASE WHEN filename='FILE4' THEN 1 ELSE 0 END) AS file4,
     SUM(CASE WHEN filename='FILE5' THEN 1 ELSE 0 END) AS file5,
     SUM(CASE WHEN filename='FILE6' THEN 1 ELSE 0 END) AS file6
  FROM TABLE1
  or GROUP BY TO_CHAR(TO_DATE(sourcedate, 'YYYYMMDDHH24MISS'), 'DD-MM-YYYY');

对于oracle 11G,您可以使用PIVOT功能:

CREATE TABLE TABLE2 AS
WITH MY_TAB AS
(SELECT TO_CHAR(TO_DATE(sourcedate, 'YYYYMMDDHH24MISS'), 'DD-MM-YYYY') AS s_date,
FILENAME FROM TABLE1
)
select *
from MY_TAB
pivot
(
  COUNT(FILENAME)
  for FILENAME in ('FILE1', 'FILE2', 'FILE3','FILE4','FILE5','FILE6')
) piv;

<强> FIDDLE HERE for 11G

<强> FIDDLE HERE FOR 10G and 11G

答案 1 :(得分:0)

你应该使用这样的东西:

CREATE TABLE TABLE2 AS
  SELECT
     TO_CHAR(TO_DATE(sourcedate, 'YYYYMMDDHH24MISS'), 'DD-MM-YYYY') AS s_date,
     SUM(CASE WHEN filename='FILE1' THEN 1 ELSE 0 END) AS file1,
     SUM(CASE WHEN filename='FILE2' THEN 1 ELSE 0 END) AS file2,
     SUM(CASE WHEN filename='FILE3' THEN 1 ELSE 0 END) AS file3,
     SUM(CASE WHEN filename='FILE4' THEN 1 ELSE 0 END) AS file4,
     SUM(CASE WHEN filename='FILE5' THEN 1 ELSE 0 END) AS file5,
     SUM(CASE WHEN filename='FILE6' THEN 1 ELSE 0 END) AS file6
  FROM table1
  GROUP BY SOURCEDATE;

由于您正在创建表格,因此我非常确信已知并修复了不同文件名值的数量,因此无需进行交叉连接。

如果要将数据插入表中,也不需要对数据进行排序。不要依赖数据的物理顺序。明确地获取它时订购它。