Oracle pivot查询获取ora-00933

Oracle pivot查询获取ora-00933,oracle,pivot,rows,transpose,Oracle,Pivot,Rows,Transpose,我想转换我的结果 这是我的成绩表: CUMA 13:30 ORHAN SAVAS CUMA 14:00 FATMA ETA CUMA 14:30 ISMAHAN YALDIZ PAZARTESI 13:00 SEYHAN UNVER PAZARTESI 13:30 SELMA CALISKAN PAZARTESI 17:45 ESMA COMERT SALI

我想转换我的结果

这是我的成绩表:

CUMA        13:30   ORHAN SAVAS    
CUMA        14:00   FATMA ETA   
CUMA        14:30   ISMAHAN YALDIZ    
PAZARTESI   13:00   SEYHAN UNVER    
PAZARTESI   13:30   SELMA CALISKAN    
PAZARTESI   17:45   ESMA COMERT    
SALI        09:45   SEYMA DURLANIK    
SALI        10:00   HASAN GOC    
SALI        13:00   TURKAN BICAK    
SALI        14:30   ISMAHAN YALDIZ    
PERSEMBE    08:30   ZUHRE YEL    
PERSEMBE    08:48   AYSEL POLAT    
PERSEMBE    09:00   AHMET OZGUNGOR    
PERSEMBE    09:12   TELEFON RANDEVUSU
我可以这样转换我的结果表吗

CUMA                    PAZARTESI             SALI                  PERSEMBE
13:30 ORHAN SAVAS       13:00 SEYHAN UNVER    09:45 SEYMA DURLANIK  08:30 ZUHRE YEL
14:00 FATMA ETA         13:30 SELMA CALISKAN  10:00 HASAN GOC       08:48 AYSEL POLAT
14:30 ISMAHAN YALDIZ    17:45 ESMA COMERT     13:00 TURKAN BICAK    09:00 AHMET OZGUNGOR
                                              14:30 ISMAHAN YALDIZ  09:12 TELEFON RANDEVUSU
这是我的疑问:

WITH got_r_num  AS
(
    SELECT  TO_CHAR (t.r_tarihi, 'DY')      AS gun
    ,       TO_CHAR (t.baslama, 'HH24:MI')  AS saat
    ,       h.adi || ' ' || h.soyadi        AS hasta
    ,       ROW_NUMBER () OVER ( PARTITION BY  TO_CHAR (t.r_tarihi, 'DY')
                                 ORDER BY   t.baslama
                               )            AS r_num
    FROM             randevu_entegre_deneme  t
    LEFT OUTER JOIN  hasta_deneme            h  ON   h.id  = t.hasta_id
    WHERE   (r_tarihi   BETWEEN  TO_DATE ('20.5.2011', 'dd.mm.yyyy')
                        AND      TO_DATE ('20.5.2011', 'dd.mm.yyyy') + 9)
)
SELECT   *
FROM      got_r_num PIVOT ( MIN (SAAT) AS s , MIN (HASTA) AS h
          FOR  gun IN ( 'MON'  AS monday
                      , 'TUE'  AS tuesday
                      , 'WED'  AS wednesday
                      , 'THU'  AS thursday
                      , 'FRI'  AS friday
                      )
          )
ORDER BY  r_num;
这是我的CREATETABLE和INSERT语句

create table RANDEVU_ENTEGRE_DENEME
(
  hasta_id                     INTEGER,
  baslama                      DATE,
  R_TARIHI                        DATE
);

insert into RANDEVU_ENTEGRE_DENEME (hasta_id, baslama, r_tarihi)
values (39733, to_date('24-05-2011 13:00:00', 'dd-mm-yyyy hh24:mi:ss'), to_date('24-05-2011', 'dd-mm-yyyy'));
insert into RANDEVU_ENTEGRE_DENEME (hasta_id, baslama, r_tarihi)
values (367216, to_date('23-05-2011 13:30:00', 'dd-mm-yyyy hh24:mi:ss'), to_date('23-05-2011', 'dd-mm-yyyy'));
insert into RANDEVU_ENTEGRE_DENEME (hasta_id, baslama, r_tarihi)
values (522956, to_date('20-05-2011 13:30:00', 'dd-mm-yyyy hh24:mi:ss'), to_date('20-05-2011', 'dd-mm-yyyy'));
insert into RANDEVU_ENTEGRE_DENEME (hasta_id, baslama, r_tarihi)
values (801923, to_date('23-05-2011 17:45:00', 'dd-mm-yyyy hh24:mi:ss'), to_date('23-05-2011', 'dd-mm-yyyy'));
insert into RANDEVU_ENTEGRE_DENEME (hasta_id, baslama, r_tarihi)
values (815746, to_date('24-05-2011 09:45:00', 'dd-mm-yyyy hh24:mi:ss'), to_date('24-05-2011', 'dd-mm-yyyy'));
insert into RANDEVU_ENTEGRE_DENEME (hasta_id, baslama, r_tarihi)
values (815746, to_date('20-05-2011 08:54:00', 'dd-mm-yyyy hh24:mi:ss'), to_date('20-05-2011', 'dd-mm-yyyy'));
insert into RANDEVU_ENTEGRE_DENEME (hasta_id, baslama, r_tarihi)
values (842677, to_date('20-05-2011 14:00:00', 'dd-mm-yyyy hh24:mi:ss'), to_date('20-05-2011', 'dd-mm-yyyy'));
insert into RANDEVU_ENTEGRE_DENEME (hasta_id, baslama, r_tarihi)
values (842677, to_date('24-05-2011 14:00:00', 'dd-mm-yyyy hh24:mi:ss'), to_date('24-05-2011', 'dd-mm-yyyy'));
insert into RANDEVU_ENTEGRE_DENEME (hasta_id, baslama, r_tarihi)
values (854143, to_date('26-05-2011 08:48:00', 'dd-mm-yyyy hh24:mi:ss'), to_date('26-05-2011', 'dd-mm-yyyy'));
insert into RANDEVU_ENTEGRE_DENEME (hasta_id, baslama, r_tarihi)
values (854559, to_date('23-05-2011 13:00:00', 'dd-mm-yyyy hh24:mi:ss'), to_date('23-05-2011', 'dd-mm-yyyy'));
insert into RANDEVU_ENTEGRE_DENEME (hasta_id, baslama, r_tarihi)
values (861624, to_date('20-05-2011 10:00:00', 'dd-mm-yyyy hh24:mi:ss'), to_date('20-05-2011', 'dd-mm-yyyy'));
insert into RANDEVU_ENTEGRE_DENEME (hasta_id, baslama, r_tarihi)
values (868595, to_date('26-05-2011 08:30:00', 'dd-mm-yyyy hh24:mi:ss'), to_date('26-05-2011', 'dd-mm-yyyy'));
commit;

create table HASTA_DENEME
(
  id                  INTEGER,
  adi                 VARCHAR2(25),
  soyadi              VARCHAR2(25)
);

insert into HASTA_DENEME (id, adi, soyadi)
values (39733, 'TURKAN', 'BICAK');
insert into HASTA_DENEME (id, adi, soyadi)
values (367216, 'SELMA', 'CALISKAN');
insert into HASTA_DENEME (id, adi, soyadi)
values (522956, 'ORHAN', 'SAVAS');
insert into HASTA_DENEME (id, adi, soyadi)
values (801923, 'ESMA', 'COMERT');
insert into HASTA_DENEME (id, adi, soyadi)
values (815746, 'SEYMA', 'DURLANIK');
insert into HASTA_DENEME (id, adi, soyadi)
values (842677, 'FATMA', 'ETA');
insert into HASTA_DENEME (id, adi, soyadi)
values (854143, 'AYSEL', 'POLAT');
insert into HASTA_DENEME (id, adi, soyadi)
values (854559, 'SEYHAN', 'UNVER');
insert into HASTA_DENEME (id, adi, soyadi)
values (861624, 'SENGUL', 'AKBAS');
insert into HASTA_DENEME (id, adi, soyadi)
values (868595, 'ZUHRE', 'YEL');
commit;

我得到了ora-00933。如何修复..

PIVOT操作符被禁用。尝试在10gR2中运行代码时出现错误:

FROM      got_r_num PIVOT ( MIN (SAAT) AS s , MIN (HASTA) AS h
                          *
ERROR at line 15:
ORA-00933: SQL command not properly ended
在11g之前,您需要使用不同的机制

我想你想要这样的东西:

WITH got_r_num  AS
(
    SELECT  TO_CHAR (t.r_tarihi, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') AS gun
    ,       TO_CHAR (t.baslama, 'HH24:MI')  AS saat
    ,       h.adi || ' ' || h.soyadi        AS hasta
    ,       ROW_NUMBER () OVER ( PARTITION BY  TO_CHAR (t.r_tarihi, 'DY')
                                 ORDER BY   t.baslama
                               )            AS r_num
    FROM             randevu_entegre_deneme  t
    LEFT OUTER JOIN  hasta_deneme            h  ON   h.id  = t.hasta_id
    WHERE   (r_tarihi   BETWEEN  TO_DATE ('20.5.2011', 'dd.mm.yyyy')
                        AND      TO_DATE ('20.5.2011', 'dd.mm.yyyy') + 9)
)
SELECT    min(case when gun = 'MON' then SAAT ||' '|| HASTA end) as pazartesi
          , min(case when gun = 'TUE' then SAAT ||' '|| HASTA end) as sali
          , min(case when gun = 'WED' then SAAT ||' '|| HASTA end) as carsamba
          , min(case when gun = 'THU' then SAAT ||' '|| HASTA end) as persembe
          , min(case when gun = 'FRI' then SAAT ||' '|| HASTA end) as cuma
FROM      got_r_num
GROUP BY  r_num
ORDER BY  r_num;
您发布的表格和insert语句提供:

PAZARTESI            SALI                 CARSAMBA             PERSEMBE             CUMA
-------------------- -------------------- -------------------- -------------------- --------------------
13:00 SEYHAN UNVER   09:45 SEYMA DURLANIK                      08:30 ZUHRE YEL      08:54 SEYMA DURLANIK
13:30 SELMA CALISKAN 13:00 TURKAN BICAK                        08:48 AYSEL POLAT    10:00 SENGUL AKBAS
17:45 ESMA COMERT    14:00 FATMA ETA                                                13:30 ORHAN SAVAS
                                                                                    14:00 FATMA ETA
。。。这并不完全符合您所说的预期,但确实使用了
pivot
与数据和BlueFoot的SQl Fiddle保持一致

我使用了你似乎期待的土耳其日标签;正如realspirituals所指出的,在发布问题时更改代码中的内容并不是完全有帮助的。语言差异在这里很重要,因为您的日常比较是假设
DY
格式是某种语言-无论您实际使用的是英语缩写还是土耳其语缩写都无关紧要,关键是您假设客户机和代码使用的是同一种语言。您可以通过强制使用特定语言的
DY
来避免潜在的不匹配,这样您就知道您将对比什么;这就是它所做的,使用可选的第三个参数:

另外,我把它留作只报道五天,因为你似乎对周末不感兴趣。这似乎有点奇怪,虽然你有一个9天的日期跨度,因为这将包括其中的一些天多次,你将无法分辨出一个特定的时间是从哪个星期开始。你的
r\u num
应该保持它们的顺序,因此如果你两周都有它们,你可能会发现时间顺序不正确,尽管它们也将基于日期。也许这就是你想要的


用于后续查询列的排序;您可以使用
密集秩
分配另一个伪列,并将其用于
案例
,而不是

WITH got_r_num  AS
(
    SELECT  TO_CHAR (t.r_tarihi, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') AS gun
    ,       TO_CHAR (t.r_tarihi, 'DAY', 'NLS_DATE_LANGUAGE=TURKISH') AS d_name
    ,       DENSE_RANK () OVER ( ORDER BY TRUNC( t.r_tarihi) ) AS d_num
    ,       TO_CHAR (t.baslama, 'HH24:MI')  AS saat
    ,       h.adi || ' ' || h.soyadi        AS hasta
    ,       ROW_NUMBER () OVER ( PARTITION BY  TO_CHAR (t.r_tarihi, 'DY')
                                 ORDER BY   t.baslama
                               )            AS r_num
    FROM             randevu_entegre_deneme  t
    LEFT OUTER JOIN  hasta_deneme            h  ON   h.id  = t.hasta_id
    WHERE   (r_tarihi   BETWEEN  TO_DATE ('20.5.2011', 'dd.mm.yyyy')
                        AND      TO_DATE ('20.5.2011', 'dd.mm.yyyy') + 9)
)
SELECT    min(case when mod(d_num, 7) = 1 then SAAT ||' '|| HASTA end) as day1
          , min(case when mod(d_num, 7) = 2 then SAAT ||' '|| HASTA end) as day2
          , min(case when mod(d_num, 7) = 3 then SAAT ||' '|| HASTA end) as day3
          , min(case when mod(d_num, 7) = 4 then SAAT ||' '|| HASTA end) as day4
          , min(case when mod(d_num, 7) = 5 then SAAT ||' '|| HASTA end) as day5
          , min(case when mod(d_num, 7) = 6 then SAAT ||' '|| HASTA end) as day6
          , min(case when mod(d_num, 7) = 0 then SAAT ||' '|| HASTA end) as day7
FROM      got_r_num
GROUP BY  r_num
ORDER BY  r_num;

DAY1                 DAY2                 DAY3                 DAY4                 DAY5                 DAY6                 DAY7
-------------------- -------------------- -------------------- -------------------- -------------------- -------------------- --------------------
08:54 SEYMA DURLANIK 13:00 SEYHAN UNVER   09:45 SEYMA DURLANIK 08:30 ZUHRE YEL
10:00 SENGUL AKBAS   13:30 SELMA CALISKAN 13:00 TURKAN BICAK   08:48 AYSEL POLAT
13:30 ORHAN SAVAS    17:45 ESMA COMERT    14:00 FATMA ETA
14:00 FATMA ETA
实际上,我不再使用
gun
,但我保留了它,并添加了
d_name
作为全天名称,尽管目前两个名称都没有被选中。这完全跳过了
carsamba
列,因为它没有数据,这与您的问题所显示的内容相匹配。如果你知道哪一列是哪一列,这可能就是你想要的。不幸的是,您无法动态分配列别名,因此您不知道
day1
实际上是
cuma
。如果您想为
carsamba
留出间隙,则可以计算每个日期与开始日期的偏移量:

    ,       TRUNC( t.r_tarihi) - TO_DATE ('20.5.2011', 'dd.mm.yyyy') + 1 AS d_num
但您仍然不知道第1列代表哪一天。你可以假装,但这取决于你是如何运作的。如果要从应用程序中提取数据,则还可以查询
d_名称
,并使用该名称。从SQL*Plus中,如果重复查询并使用替换变量,则可以执行此操作,这可能会带来很大的开销,或者部分解决方案只是将它们作为单独的选择来选择,这也不理想:

column r_num noprint
set head off
WITH got_r_num  AS
(
  ...
)
SELECT    0 as r_num
         , min(case when mod(d_num, 7) = 1 then d_name end) as day1
         ,  min(case when mod(d_num, 7) = 2 then d_name end) as day2
         ,  min(case when mod(d_num, 7) = 3 then d_name end) as day3
         ,  min(case when mod(d_num, 7) = 4 then d_name end) as day4
         ,  min(case when mod(d_num, 7) = 5 then d_name end) as day5
         ,  min(case when mod(d_num, 7) = 6 then d_name end) as day6
         ,  min(case when mod(d_num, 7) = 0 then d_name end) as day7
FROM      got_r_num
UNION ALL
SELECT    r_num
          , min(case when mod(d_num, 7) = 1 then SAAT ||' '|| HASTA end) as day1
          , min(case when mod(d_num, 7) = 2 then SAAT ||' '|| HASTA end) as day2
          , min(case when mod(d_num, 7) = 3 then SAAT ||' '|| HASTA end) as day3
          , min(case when mod(d_num, 7) = 4 then SAAT ||' '|| HASTA end) as day4
          , min(case when mod(d_num, 7) = 5 then SAAT ||' '|| HASTA end) as day5
          , min(case when mod(d_num, 7) = 6 then SAAT ||' '|| HASTA end) as day6
          , min(case when mod(d_num, 7) = 0 then SAAT ||' '|| HASTA end) as day7
FROM      got_r_num
GROUP BY  r_num
ORDER BY  r_num;

CUMA                 PAZARTESI            SALI                 PER¿EMBE
08:54 SEYMA DURLANIK 13:00 SEYHAN UNVER   09:45 SEYMA DURLANIK 08:30 ZUHRE YEL
10:00 SENGUL AKBAS   13:30 SELMA CALISKAN 13:00 TURKAN BICAK   08:48 AYSEL POLAT
13:30 ORHAN SAVAS    17:45 ESMA COMERT    14:00 FATMA ETA
14:00 FATMA ETA

PIVOT
操作符被激活。尝试在10gR2中运行代码时出现错误:

FROM      got_r_num PIVOT ( MIN (SAAT) AS s , MIN (HASTA) AS h
                          *
ERROR at line 15:
ORA-00933: SQL command not properly ended
在11g之前,您需要使用不同的机制

我想你想要这样的东西:

WITH got_r_num  AS
(
    SELECT  TO_CHAR (t.r_tarihi, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') AS gun
    ,       TO_CHAR (t.baslama, 'HH24:MI')  AS saat
    ,       h.adi || ' ' || h.soyadi        AS hasta
    ,       ROW_NUMBER () OVER ( PARTITION BY  TO_CHAR (t.r_tarihi, 'DY')
                                 ORDER BY   t.baslama
                               )            AS r_num
    FROM             randevu_entegre_deneme  t
    LEFT OUTER JOIN  hasta_deneme            h  ON   h.id  = t.hasta_id
    WHERE   (r_tarihi   BETWEEN  TO_DATE ('20.5.2011', 'dd.mm.yyyy')
                        AND      TO_DATE ('20.5.2011', 'dd.mm.yyyy') + 9)
)
SELECT    min(case when gun = 'MON' then SAAT ||' '|| HASTA end) as pazartesi
          , min(case when gun = 'TUE' then SAAT ||' '|| HASTA end) as sali
          , min(case when gun = 'WED' then SAAT ||' '|| HASTA end) as carsamba
          , min(case when gun = 'THU' then SAAT ||' '|| HASTA end) as persembe
          , min(case when gun = 'FRI' then SAAT ||' '|| HASTA end) as cuma
FROM      got_r_num
GROUP BY  r_num
ORDER BY  r_num;
您发布的表格和insert语句提供:

PAZARTESI            SALI                 CARSAMBA             PERSEMBE             CUMA
-------------------- -------------------- -------------------- -------------------- --------------------
13:00 SEYHAN UNVER   09:45 SEYMA DURLANIK                      08:30 ZUHRE YEL      08:54 SEYMA DURLANIK
13:30 SELMA CALISKAN 13:00 TURKAN BICAK                        08:48 AYSEL POLAT    10:00 SENGUL AKBAS
17:45 ESMA COMERT    14:00 FATMA ETA                                                13:30 ORHAN SAVAS
                                                                                    14:00 FATMA ETA
。。。这并不完全符合您所说的预期,但确实使用了
pivot
与数据和BlueFoot的SQl Fiddle保持一致

我使用了你似乎期待的土耳其日标签;正如realspirituals所指出的,在发布问题时更改代码中的内容并不是完全有帮助的。语言差异在这里很重要,因为您的日常比较是假设
DY
格式是某种语言-无论您实际使用的是英语缩写还是土耳其语缩写都无关紧要,关键是您假设客户机和代码使用的是同一种语言。您可以通过强制使用特定语言的
DY
来避免潜在的不匹配,这样您就知道您将对比什么;这就是它所做的,使用可选的第三个参数:

另外,我把它留作只报道五天,因为你似乎对周末不感兴趣。这似乎有点奇怪,虽然你有一个9天的日期跨度,因为这将包括其中的一些天多次,你将无法分辨出一个特定的时间是从哪个星期开始。你的
r\u num
应该保持它们的顺序,因此如果你两周都有它们,你可能会发现时间顺序不正确,尽管它们也将基于日期。也许这就是你想要的


用于后续查询列的排序;您可以使用
密集秩
分配另一个伪列,并将其用于
案例
,而不是

WITH got_r_num  AS
(
    SELECT  TO_CHAR (t.r_tarihi, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') AS gun
    ,       TO_CHAR (t.r_tarihi, 'DAY', 'NLS_DATE_LANGUAGE=TURKISH') AS d_name
    ,       DENSE_RANK () OVER ( ORDER BY TRUNC( t.r_tarihi) ) AS d_num
    ,       TO_CHAR (t.baslama, 'HH24:MI')  AS saat
    ,       h.adi || ' ' || h.soyadi        AS hasta
    ,       ROW_NUMBER () OVER ( PARTITION BY  TO_CHAR (t.r_tarihi, 'DY')
                                 ORDER BY   t.baslama
                               )            AS r_num
    FROM             randevu_entegre_deneme  t
    LEFT OUTER JOIN  hasta_deneme            h  ON   h.id  = t.hasta_id
    WHERE   (r_tarihi   BETWEEN  TO_DATE ('20.5.2011', 'dd.mm.yyyy')
                        AND      TO_DATE ('20.5.2011', 'dd.mm.yyyy') + 9)
)
SELECT    min(case when mod(d_num, 7) = 1 then SAAT ||' '|| HASTA end) as day1
          , min(case when mod(d_num, 7) = 2 then SAAT ||' '|| HASTA end) as day2
          , min(case when mod(d_num, 7) = 3 then SAAT ||' '|| HASTA end) as day3
          , min(case when mod(d_num, 7) = 4 then SAAT ||' '|| HASTA end) as day4
          , min(case when mod(d_num, 7) = 5 then SAAT ||' '|| HASTA end) as day5
          , min(case when mod(d_num, 7) = 6 then SAAT ||' '|| HASTA end) as day6
          , min(case when mod(d_num, 7) = 0 then SAAT ||' '|| HASTA end) as day7
FROM      got_r_num
GROUP BY  r_num
ORDER BY  r_num;

DAY1                 DAY2                 DAY3                 DAY4                 DAY5                 DAY6                 DAY7
-------------------- -------------------- -------------------- -------------------- -------------------- -------------------- --------------------
08:54 SEYMA DURLANIK 13:00 SEYHAN UNVER   09:45 SEYMA DURLANIK 08:30 ZUHRE YEL
10:00 SENGUL AKBAS   13:30 SELMA CALISKAN 13:00 TURKAN BICAK   08:48 AYSEL POLAT
13:30 ORHAN SAVAS    17:45 ESMA COMERT    14:00 FATMA ETA
14:00 FATMA ETA
实际上,我不再使用
gun
,但我保留了它,并添加了
d_name
作为全天名称,尽管目前两个名称都没有被选中。这完全跳过了
carsamba
列,因为它没有数据,这与您的问题所显示的内容相匹配。如果你知道哪一列是哪一列,这可能就是你想要的。不幸的是,您无法动态分配列别名,因此您不知道
day1
实际上是
cuma
。如果您想为
carsamba
留出间隙,则可以计算每个日期与开始日期的偏移量:

    ,       TRUNC( t.r_tarihi) - TO_DATE ('20.5.2011', 'dd.mm.yyyy') + 1 AS d_num
但您仍然不知道第1列代表哪一天。你可以假装,但这取决于你是如何运作的。如果要从应用程序中提取数据,则还可以查询
d_名称
,并使用该名称。从SQL*Plus中,如果重复查询并使用替换变量,则可以执行此操作,这可能会带来很大的开销,或者