Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pivot-like排序-sqloracle_Sql_Oracle - Fatal编程技术网

Pivot-like排序-sqloracle

Pivot-like排序-sqloracle,sql,oracle,Sql,Oracle,我有一张这样的桌子(书): user_rent | book_rent | rent_from | rent_to ----------------------------------------------- Alan Doe | Macbeth | 01.07.2018 | 15.07.2018 Alan Doe | Hamlet | 16.07.2018 | 01.08.2018 Alan Doe | Othello | 02.08.2018 | 31.08.2018

我有一张这样的桌子(书):

user_rent | book_rent | rent_from  | rent_to
-----------------------------------------------
Alan Doe  | Macbeth   | 01.07.2018 | 15.07.2018
Alan Doe  | Hamlet    | 16.07.2018 | 01.08.2018
Alan Doe  | Othello   | 02.08.2018 | 31.08.2018
Alan Doe  | King Lear | 01.09.2018 |    
Alex Doe  | Dracula   | 01.07.2018 | 15.07.2018
Alex Doe  | Hamlet    | 16.07.2018 | 01.08.2018
Alex Doe  | Hobbit    | 02.08.2018 | 31.08.2018
Alex Doe  | Inferno   | 01.09.2018 |    
Anna Doe  | 1984      | 01.07.2018 | 15.07.2018
Anna Doe  | King Lear | 16.07.2018 | 01.08.2018
Anna Doe  | Hobbit    | 02.08.2018 | 31.08.2018
Anna Doe  | Dracula   | 01.09.2018 |    
Ella Doe  | Macbeth   | 01.07.2018 | 15.07.2018
Ella Doe  | Beowulf   | 16.07.2018 | 01.08.2018
Ella Doe  | King Lear | 02.08.2018 | 31.08.2018
Ella Doe  | Dracula   | 01.09.2018 |    
Emma Doe  | Beowulf   | 01.07.2018 | 15.07.2018
Emma Doe  | Inferno   | 16.07.2018 | 01.08.2018
Emma Doe  | Macbeth   | 02.08.2018 | 31.08.2018
Emma Doe  | Lolita    | 01.09.2018 |    
Jack Doe  | 1984      | 01.07.2018 | 15.07.2018
Jack Doe  | Inferno   | 16.07.2018 | 01.08.2018
Jack Doe  | Othello   | 02.08.2018 | 31.08.2018
Jack Doe  | Dracula   | 01.09.2018 |
Jade Doe  | Lolita    | 01.07.2018 | 15.07.2018
Jade Doe  | Hobbit    | 16.07.2018 | 01.08.2018
Jade Doe  | Hamlet    | 02.08.2018 | 31.08.2018
Jade Doe  | Beowulf   | 01.09.2018 |    
Jane Doe  | Dracula   | 01.07.2018 | 15.07.2018
Jane Doe  | Ulysses   | 16.07.2018 | 01.08.2018
Jane Doe  | Inferno   | 02.08.2018 | 31.08.2018
Jane Doe  | Pygmalion | 01.09.2018 |
John Doe  | Macbeth   | 01.07.2018 | 15.07.2018
John Doe  | Hobbit    | 16.07.2018 | 01.08.2018
John Doe  | Ulysses   | 02.08.2018 | 31.08.2018
John Doe  | Dracula   | 01.09.2018 |    
Noah Doe  | Pygmalion | 01.07.2018 | 15.07.2018
Noah Doe  | Othello   | 16.07.2018 | 01.08.2018
Noah Doe  | Beowulf   | 02.08.2018 | 31.08.2018
Noah Doe  | 1984      | 01.09.2018 |    
Nora Doe  | Dracula   | 01.07.2018 | 15.07.2018
Nora Doe  | Pygmalion | 16.07.2018 | 01.08.2018
Nora Doe  | Hamlet    | 02.08.2018 | 31.08.2018
Nora Doe  | Lolita    | 01.09.2018 |    
Sara Doe  | Beowulf   | 01.07.2018 | 15.07.2018
Sara Doe  | Dracula   | 16.07.2018 | 01.08.2018
Sara Doe  | Ulysses   | 02.08.2018 | 31.08.2018
Sara Doe  | Lolita    | 01.09.2018 |    
Seth Doe  | Macbeth   | 01.07.2018 | 15.07.2018
Seth Doe  | Hamlet    | 16.07.2018 | 01.08.2018
Seth Doe  | King Lear | 02.08.2018 | 31.08.2018
Seth Doe  | Othello   | 01.09.2018 |
我需要一些租用莎士比亚书籍的用户

使用此查询:

SELECT USER_RENT,
   COUNT(DISTINCT CASE WHEN BOOK_RENT = 'Hamlet' THEN USER_RENT END) HAMLET,
   COUNT(DISTINCT CASE WHEN BOOK_RENT = 'Othello' THEN USER_RENT END) OTHELLO,
   COUNT(DISTINCT CASE WHEN BOOK_RENT = 'Macbeth' THEN USER_RENT END) MACBETH,
   COUNT(DISTINCT CASE WHEN BOOK_RENT = 'King Lear' THEN USER_RENT END) KING_LEAR
FROM BOOKS
GROUP BY USER_RENT;
我得到了这张临时桌子:

user_rent | hamlet | othello | macbeth | king_lear
--------------------------------------------------
Alan Doe  |      1 |       1 |       1 |       1
Alex Doe  |      1 |       0 |       0 |       0
Anna Doe  |      0 |       0 |       0 |       1
Ella Doe  |      0 |       0 |       1 |       1
Emma Doe  |      0 |       0 |       1 |       0
Jack Doe  |      0 |       1 |       0 |       0
Jade Doe  |      1 |       0 |       0 |       0
Jane Doe  |      0 |       0 |       0 |       0
John Doe  |      0 |       0 |       1 |       0
Noah Doe  |      0 |       1 |       0 |       0
Nora Doe  |      1 |       0 |       0 |       0
Sara Doe  |      0 |       0 |       0 |       0
Seth Doe  |      1 |       1 |       1 |       1
我将其导出到excel,然后通过pivot和过滤器得到了我想要的最终结果(这就是我需要的结果)):


因为我有一个比这个例子中的表大得多的表,所以有没有一种更优雅、更简单的方法可以直接在SQL中实现这一点?

这是您想要的吗

SELECT books, COUNT(*)
FROM (SELECT USER_RENT, LISTAGG(BOOK_RENT, ';') WITHIN GROUP (ORDER BY BOOK_RENT) as books
      FROM BOOKS
      GROUP BY USER_RENT
     ) bu
GROUP BY books;
如果有人把同一本书租了两次,它就会出现多次。您可能需要:

SELECT books, COUNT(*)
FROM (SELECT USER_RENT, LISTAGG(BOOK_RENT, ';') WITHIN GROUP (ORDER BY BOOK_RENT) as books
      FROM (SELECT DISTINCT USER_RENT, BOOK_RENT FROM BOOKS) ub
      GROUP BY USER_RENT
     ) bu
GROUP BY books;

这是你想要的吗

SELECT books, COUNT(*)
FROM (SELECT USER_RENT, LISTAGG(BOOK_RENT, ';') WITHIN GROUP (ORDER BY BOOK_RENT) as books
      FROM BOOKS
      GROUP BY USER_RENT
     ) bu
GROUP BY books;
如果有人把同一本书租了两次,它就会出现多次。您可能需要:

SELECT books, COUNT(*)
FROM (SELECT USER_RENT, LISTAGG(BOOK_RENT, ';') WITHIN GROUP (ORDER BY BOOK_RENT) as books
      FROM (SELECT DISTINCT USER_RENT, BOOK_RENT FROM BOOKS) ub
      GROUP BY USER_RENT
     ) bu
GROUP BY books;
我的尝试:

/* -- sample data 
with titles(book) as (
  select 'Hamlet'    from dual union all
  select 'Othello'   from dual union all
  select 'Macbeth'   from dual union all
  select 'King Lear' from dual ),
books (usr, book) as (
  select 'Alan', 'Hamlet'    from dual union all
  select 'Alan', 'Othello'   from dual union all
  select 'Alan', 'Macbeth'   from dual union all
  select 'Alan', 'King Lear' from dual union all
  select 'Alan', 'Hamlet'    from dual union all
  select 'Alex', 'Hamlet'    from dual union all
  select 'Anna', 'King Lear' from dual union all
  select 'Ella', 'Macbeth'   from dual union all
  select 'Ella', 'King Lear' from dual union all
  select 'Emma', 'Macbeth'   from dual union all
  select 'Jack', 'Othello'   from dual union all
  select 'Jade', 'Hamlet'    from dual union all
  select 'John', 'Macbeth'   from dual union all
  select 'Noah', 'Othello'   from dual union all
  select 'Nora', 'Hamlet'    from dual union all
  select 'Seth', 'Hamlet'    from dual union all
  select 'Seth', 'Othello'   from dual union all
  select 'Seth', 'Macbeth'   from dual union all
  select 'Seth', 'King Lear' from dual ),
*/ -- end of sample data
with 
  tmp as (
    select grp, sys_connect_by_path(book, '#') path, level cnt
      from (select row_number() over (order by book) grp, book from titles) 
      connect by book > prior book),
  groups as (
    select grp, path, cnt, trim(column_value) book 
      from tmp, xmltable(('"'||replace(ltrim(path,'#'), '#', '","')||'"')))
select path, count(1) cnt, listagg(usr, ', ') within group (order by usr) users
  from (
    select usr, path, grp
      from groups g join (select distinct usr, book from books) b on b.book = g.book
      group by usr, path, cnt, grp
      having cnt = count(1))
  group by path
看起来你想要所有的书籍组合。我使用分层查询,然后将函数
sys\u connect\u by\u path()
的结果拆分为行来实现这一点

下一步是使用表
books
加入这些组,计算每个用户的图书数量,如果该数量低于组中的图书数量,则将其从结果中删除

最后,我只对用户进行分组,对他们进行计数,并以列表形式呈现。结果:

PATH                                      CNT USERS
---------------------------------- ---------- -------------------------------
#Hamlet                                     5 Alan, Alex, Jade, Nora, Seth
#Hamlet#King Lear                           2 Alan, Seth
#Hamlet#King Lear#Macbeth                   2 Alan, Seth
#Hamlet#King Lear#Macbeth#Othello           2 Alan, Seth
#Hamlet#King Lear#Othello                   2 Alan, Seth
#Hamlet#Macbeth                             2 Alan, Seth
#Hamlet#Macbeth#Othello                     2 Alan, Seth
#Hamlet#Othello                             2 Alan, Seth
#King Lear                                  4 Alan, Anna, Ella, Seth
#King Lear#Macbeth                          3 Alan, Ella, Seth
#King Lear#Macbeth#Othello                  2 Alan, Seth
#King Lear#Othello                          2 Alan, Seth
#Macbeth                                    5 Alan, Ella, Emma, John, Seth
#Macbeth#Othello                            2 Alan, Seth
#Othello                                    4 Alan, Jack, Noah, Seth
我的尝试:

/* -- sample data 
with titles(book) as (
  select 'Hamlet'    from dual union all
  select 'Othello'   from dual union all
  select 'Macbeth'   from dual union all
  select 'King Lear' from dual ),
books (usr, book) as (
  select 'Alan', 'Hamlet'    from dual union all
  select 'Alan', 'Othello'   from dual union all
  select 'Alan', 'Macbeth'   from dual union all
  select 'Alan', 'King Lear' from dual union all
  select 'Alan', 'Hamlet'    from dual union all
  select 'Alex', 'Hamlet'    from dual union all
  select 'Anna', 'King Lear' from dual union all
  select 'Ella', 'Macbeth'   from dual union all
  select 'Ella', 'King Lear' from dual union all
  select 'Emma', 'Macbeth'   from dual union all
  select 'Jack', 'Othello'   from dual union all
  select 'Jade', 'Hamlet'    from dual union all
  select 'John', 'Macbeth'   from dual union all
  select 'Noah', 'Othello'   from dual union all
  select 'Nora', 'Hamlet'    from dual union all
  select 'Seth', 'Hamlet'    from dual union all
  select 'Seth', 'Othello'   from dual union all
  select 'Seth', 'Macbeth'   from dual union all
  select 'Seth', 'King Lear' from dual ),
*/ -- end of sample data
with 
  tmp as (
    select grp, sys_connect_by_path(book, '#') path, level cnt
      from (select row_number() over (order by book) grp, book from titles) 
      connect by book > prior book),
  groups as (
    select grp, path, cnt, trim(column_value) book 
      from tmp, xmltable(('"'||replace(ltrim(path,'#'), '#', '","')||'"')))
select path, count(1) cnt, listagg(usr, ', ') within group (order by usr) users
  from (
    select usr, path, grp
      from groups g join (select distinct usr, book from books) b on b.book = g.book
      group by usr, path, cnt, grp
      having cnt = count(1))
  group by path
看起来你想要所有的书籍组合。我使用分层查询,然后将函数
sys\u connect\u by\u path()
的结果拆分为行来实现这一点

下一步是使用表
books
加入这些组,计算每个用户的图书数量,如果该数量低于组中的图书数量,则将其从结果中删除

最后,我只对用户进行分组,对他们进行计数,并以列表形式呈现。结果:

PATH                                      CNT USERS
---------------------------------- ---------- -------------------------------
#Hamlet                                     5 Alan, Alex, Jade, Nora, Seth
#Hamlet#King Lear                           2 Alan, Seth
#Hamlet#King Lear#Macbeth                   2 Alan, Seth
#Hamlet#King Lear#Macbeth#Othello           2 Alan, Seth
#Hamlet#King Lear#Othello                   2 Alan, Seth
#Hamlet#Macbeth                             2 Alan, Seth
#Hamlet#Macbeth#Othello                     2 Alan, Seth
#Hamlet#Othello                             2 Alan, Seth
#King Lear                                  4 Alan, Anna, Ella, Seth
#King Lear#Macbeth                          3 Alan, Ella, Seth
#King Lear#Macbeth#Othello                  2 Alan, Seth
#King Lear#Othello                          2 Alan, Seth
#Macbeth                                    5 Alan, Ella, Emma, John, Seth
#Macbeth#Othello                            2 Alan, Seth
#Othello                                    4 Alan, Jack, Noah, Seth

我包括了我的整个示例表,因为这不符合我的需要。我需要一张桌子放在问题的最下面。拥有各种变体的莎士比亚书籍(1本书、2本书、3本书、4本书)的用户数量。Listagg看起来很有用,我可能不得不使用它。@Tzereen。这就是这个查询的作用。这显示了每一组书籍以及使用这些组合的用户数量。我理解,但这不是我需要的。问题的最后一部分包含了我用excel手动获得的所需输出。我想用SQL查询得到它。@Tzereen。有什么区别?
的对比?您可能需要为这个问题设置一个rextester或dbfiddle。我包括了我的整个示例表,因为这不符合我的需要。我需要一张桌子放在问题的最下面。拥有各种变体的莎士比亚书籍(1本书、2本书、3本书、4本书)的用户数量。Listagg看起来很有用,我可能不得不使用它。@Tzereen。这就是这个查询的作用。这显示了每一组书籍以及使用这些组合的用户数量。我理解,但这不是我需要的。问题的最后一部分包含了我用excel手动获得的所需输出。我想用SQL查询得到它。@Tzereen。有什么区别?
的对比?您可能需要为该问题设置rextester或dbfiddle。