【问题标题】:Oracle SQL How to Count Column Value Occurences and Group BY during joinsOracle SQL 如何在连接期间计算列值出现次数和 Group BY
【发布时间】:2019-05-17 10:05:28
【问题描述】:

我正在处理另一个 SQL 查询,尝试在进行计数和连接表的同时对一组记录进行分组。有关用于构建和填充表的目标、当前查询和附加脚本,请参见下文。

显示查看的书籍多于 DVD 的所有客户。展示 客户姓名、图书结账总数和 DVD 结账总数。种类 按客户名字和姓氏排列的结果。

SELECT C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME, COUNT(T.TRANSACTION_ID)
FROM customer C
INNER JOIN library_card LC ON C.CUSTOMER_ID = LC.CUSTOMER_ID
INNER JOIN transaction T ON LC.LIBRARY_CARD_ID = T.LIBRARY_CARD_ID
INNER JOIN physical_item P ON T.PHYSICAL_ITEM_ID = P.PHYSICAL_ITEM_ID
INNER JOIN catalog_item CT ON P.CATALOG_ITEM_ID = CT.CATALOG_ITEM_ID 
GROUP BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME
ORDER BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME;

先运行:https://drive.google.com/open?id=1PYAZV4KIfZtxP4eQn35zsczySsxDM7ls

第二次运行:https://drive.google.com/open?id=1pAzWmJqvD3o3n6YJqVUM6TtxDafKGd3f

编辑
在巴巴罗斯先生的帮助下,我提出了以下查询,该查询更接近。但是,这个查询没有返回任何 DVD 的结果,这让我相信这是一个连接问题。

SELECT C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME, COUNT(CT1.TYPE) AS BOOK_COUNT, COUNT(CT2.TYPE) AS DVD_COUNT
FROM customer C
INNER JOIN library_card LC ON C.CUSTOMER_ID = LC.CUSTOMER_ID
INNER JOIN transaction T ON LC.LIBRARY_CARD_ID = T.LIBRARY_CARD_ID
INNER JOIN physical_item P ON T.PHYSICAL_ITEM_ID = P.PHYSICAL_ITEM_ID
INNER JOIN catalog_item CT1 ON P.CATALOG_ITEM_ID = CT1.CATALOG_ITEM_ID AND CT1.TYPE = 'BOOK'
LEFT OUTER JOIN catalog_item CT2 ON P.CATALOG_ITEM_ID = CT2.CATALOG_ITEM_ID AND CT2.TYPE = 'DVD'
GROUP BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME, CT1.TYPE, CT2.TYPE
ORDER BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME;

【问题讨论】:

    标签: sql oracle join oracle11g group-by


    【解决方案1】:

    您可以使用 catalog_item 表两次(将书籍和 dvd 视为单独的表),并通过 HAVING 子句进行比较:

    SELECT C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME, 
           COUNT(CT1.CATALOG_ITEM_ID) as "Book Checkout", 
           COUNT(CT2.CATALOG_ITEM_ID) as "DVD Checkout"
      FROM customer C
     INNER JOIN library_card LC ON C.CUSTOMER_ID = LC.CUSTOMER_ID
     INNER JOIN transaction T ON LC.LIBRARY_CARD_ID = T.LIBRARY_CARD_ID
     INNER JOIN physical_item P ON T.PHYSICAL_ITEM_ID = P.PHYSICAL_ITEM_ID
      LEFT JOIN catalog_item CT1 ON P.CATALOG_ITEM_ID = CT1.CATALOG_ITEM_ID AND CT1.TYPE = 'BOOK'
      LEFT JOIN catalog_item CT2 ON P.CATALOG_ITEM_ID = CT2.CATALOG_ITEM_ID AND CT1.TYPE = 'DVD'
     GROUP BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME
    HAVING COUNT(CT1.CATALOG_ITEM_ID) > COUNT(CT2.CATALOG_ITEM_ID)
     ORDER BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME;
    
    CUSTOMER_FIRSTNAME  CUSTOMER_LASTNAME   Book Checkout  DVD Checkout
    ------------------  -----------------   -------------  -------------
    Deena               Pilgrim                   3              1
    Emile               Cross                     5              2
    

    【讨论】:

    • 这个查询没有返回任何记录:/
    • 我稍微修改了查询以获取一些记录,但是 CT1 和 CT2 表的连接以某种方式关闭。我无法同时返回 DVD 和书籍的准确记录。请参阅更新的问题。谢谢。
    • @RyanCohan 不客气。好的,我解决了问题,抱歉,问题是由于inner 加入了新添加的条件,这些条件应该是left
    【解决方案2】:

    请尝试删除您的 group by 子句中的 ,CT1.TYPE, CT2.TYPE

    【讨论】:

      【解决方案3】:

      使用“条件聚合”(在聚合函数中使用 case 表达式)

      SELECT
          C.CUSTOMER_FIRSTNAME
        , C.CUSTOMER_LASTNAME
        , COUNT( CASE WHEN CT.TYPE = 'BOOK' THEN T.TRANSACTION_ID END ) books
        , COUNT( CASE WHEN CT.TYPE = 'DVD' THEN T.TRANSACTION_ID END ) dvds
      FROM customer C
      INNER JOIN library_card LC ON C.CUSTOMER_ID = LC.CUSTOMER_ID
      INNER JOIN transaction T ON LC.LIBRARY_CARD_ID = T.LIBRARY_CARD_ID
      INNER JOIN physical_item P ON T.PHYSICAL_ITEM_ID = P.PHYSICAL_ITEM_ID
      INNER JOIN catalog_item CT ON P.CATALOG_ITEM_ID = CT.CATALOG_ITEM_ID
      GROUP BY
          C.CUSTOMER_FIRSTNAME
        , C.CUSTOMER_LASTNAME
      HAVING
           COUNT( CASE WHEN CT.TYPE = 'BOOK' THEN T.TRANSACTION_ID END ) 
         > COUNT( CASE WHEN CT.TYPE = 'DVD' THEN T.TRANSACTION_ID END )
      ORDER BY
          C.CUSTOMER_FIRSTNAME
        , C.CUSTOMER_LASTNAME
      ;
      

      【讨论】:

        猜你喜欢
        • 2011-01-11
        • 2020-10-12
        • 2018-10-26
        • 1970-01-01
        • 2011-06-11
        • 1970-01-01
        • 2021-10-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多