如何拉出oracle sql中出售的独特商品数量

时间:2017-10-25 22:04:14

标签: sql oracle

我有过去一年在我店里销售的所有商品的订单数据。该表如下所示:

order_date    item_id    item_name    order_quantity    unit_price
--------------------------------------------------------------------
01-01-2017    a123       a234         2                 10
04-02-2017    b123       b234         3                 12
04-09-2017    c123       c234         1                 15
04-10-2017    b123       b234         2                 12

我需要提取按周,月和季度销售的唯一商品数量的数据。查询输出应如下所示:

timeline number    unique_item_count
week      1         1
week      14        1
week      15        2
month     1         1
month     4         2
quarter   2         2

我尝试过以下方法:

 SELECT 
  TO_CHAR(c.ORDER_DAY, 'Q') AS QTR,
  TO_CHAR(c.ORDER_DAY, 'MM') AS MNTH,
  TO_CHAR(c.ORDER_DAY, 'WW') AS WK,
  COUNT(DISTINCT CASE WHEN (c.QUANTITY*c.OUR_PRICE) > 0 THEN ITEM_ID ELSE NULL END) AS SALES_CNT
FROM TABLE c
GROUP BY TO_CHAR(c.ORDER_DAY, 'Q'), TO_CHAR(c.ORDER_DAY, 'MM'), TO_CHAR(c.ORDER_DAY, 'WW');

这适用于每周数据,但是,每月和每季度只是每周数字的总和,在这种情况下是不正确的,因为相同的项目可能会在两个不同的周内订购,因此每月数量应该更低。

有没有办法拉出每周,每月,每季度购买的独特商品数量?

谢谢!

3 个答案:

答案 0 :(得分:0)

您可以使用union all

执行此操作
SELECT 'Q' as timeline, TO_CHAR(c.ORDER_DAY, 'Q') AS number,
       COUNT(DISTINCT CASE WHEN (c.QUANTITY*c.OUR_PRICE) > 0 THEN ITEM_ID  END) AS SALES_CNT  
FROM TABLE c
GROUP BY TO_CHAR(c.ORDER_DAY, 'Q')
UNION ALL
SELECT 'MM' as timeline, TO_CHAR(c.ORDER_DAY, 'MM') AS number,
       COUNT(DISTINCT CASE WHEN (c.QUANTITY*c.OUR_PRICE) > 0 THEN ITEM_ID  END) AS SALES_CNT  
FROM TABLE c
GROUP BY TO_CHAR(c.ORDER_DAY, 'MM')
UNION ALL
SELECT 'WW' as timeline, TO_CHAR(c.ORDER_DAY, 'WW') AS number,
       COUNT(DISTINCT CASE WHEN (c.QUANTITY*c.OUR_PRICE) > 0 THEN ITEM_ID  END) AS SALES_CNT  
FROM TABLE c
GROUP BY TO_CHAR(c.ORDER_DAY, 'WW');

答案 1 :(得分:0)

您可以使用createdById

在不使用多个语句的并集的情况下执行此操作

SQL Fiddle

Oracle 11g R2架构设置

UNPIVOT

查询1

CREATE TABLE table_c (
  order_date,
  item_id,
  item_name,
  order_quantity,
  order_price
) AS
SELECT DATE '2017-09-01' + LEVEL * 3 - 3, 1, 'aaa', 1, 1 FROM DUAL CONNECT BY LEVEL <= 10
UNION ALL
SELECT DATE '2017-09-01' + LEVEL * 4 - 4, 2, 'bbb', 1, 1 FROM DUAL CONNECT BY LEVEL <= 10
UNION ALL
SELECT DATE '2017-09-01' + LEVEL * 5 - 5, 3, 'ccc', 1, 1 FROM DUAL CONNECT BY LEVEL <= 10

<强> Results

SELECT year,
       timeline,
       "number",
       COUNT( DISTINCT item_id )
FROM   (
  SELECT TO_CHAR( order_date, 'WW' ) AS week,
         TO_CHAR( order_date, 'MM' ) AS month,
         TO_CHAR( order_date, 'Q' ) AS quarter,
         EXTRACT( YEAR from order_date ) AS year,
         item_id
  FROM   table_c
  WHERE  order_quantity > 0
  AND    order_price > 0
)
UNPIVOT ( "number" FOR timeline IN ( week AS 'week', month AS 'month', quarter AS 'quarter' ) )
GROUP BY year, timeline, "number"
ORDER BY year, timeline, "number"

答案 2 :(得分:0)

您可以使用GROUPING SETS在单个查询中以不同级别进行汇总。像这样:

SELECT CASE
         WHEN GROUPING (TO_CHAR (c.order_day, 'Q')) = 0 THEN 'Quarter'
         WHEN GROUPING (TO_CHAR (c.order_day, 'MM')) = 0 THEN 'Month'
         WHEN GROUPING (TO_CHAR (c.order_day, 'WW')) = 0 THEN 'Week'
         ELSE '??'
       END
         timeline,
       CASE
         WHEN GROUPING (TO_CHAR (c.order_day, 'Q')) = 0 THEN TO_CHAR (c.order_day, 'Q')
         WHEN GROUPING (TO_CHAR (c.order_day, 'MM')) = 0 THEN TO_CHAR (c.order_day, 'MM')
         WHEN GROUPING (TO_CHAR (c.order_day, 'WW')) = 0 THEN TO_CHAR (c.order_day, 'WW')
         ELSE '??'
       END
         "NUMBER",
       COUNT (DISTINCT CASE WHEN (c.quantity * c.our_price) > 0 THEN item_id ELSE NULL END) unique_item_count
FROM   c
GROUP BY GROUPING SETS ( 
    (TO_CHAR (c.order_day, 'Q')), 
    (TO_CHAR (c.order_day, 'MM')), 
    (TO_CHAR (c.order_day, 'WW')))