简体   繁体   English

每月/每年计算不同但在查询结果中显示所有日期

[英]Count distinct per month/year but display all dates in the query result

DB-Fiddle DB-小提琴

CREATE TABLE sales (
    id int auto_increment primary key,
    orderID VARCHAR(255),
    sent_date DATE
);

INSERT INTO sales
(orderID, sent_date
)
VALUES 
("Order_01", "2019-03-15"),
("Order_01", "2019-03-16"),
("Order_02", "2020-06-16"),
("Order_03", "2020-07-27"),
("Order_03", "2020-08-05"),
("Order_03", "2020-08-10");

Expected Result:预期结果:

sent_date      COUNT(distinct orderID)
2019-03-15              1
2019-03-16              0
2020-06-16              1
2020-07-27              1
2020-08-05              1
2020-08-10              0

In the above table I have the same orders with multiple sent_dates .在上表中,我有多个sent_dates的相同orders

Now, I want to count the unique orderIDs per month/year on a daily-basis .现在,我想每天计算month/year唯一orderIDs
Therefore, I am looking for a query that checks for each orderID if it already exists at a previous sent_date and if so the value for the current sent_date should be 0 .因此,我正在寻找一个查询来检查每个orderID是否在之前的sent_date已经存在,如果是,则当前sent_date的值应该是0

I know the most simple way to the unique count per month/year would be this query:我知道每月/每年唯一计数的最简单方法是这个查询:

SELECT
YEAR(sent_date),
MONTH(sent_date),
COUNT(distinct orderID)
FROM sales
GROUP BY 1,2;

However, I need to have each sent_date displayed seperately in a list as you can see in the expected result.但是,我需要将每个sent_date显示在列表中,正如您在预期结果中看到的那样。
What query do I need to get the count unique although I need to query the data on a daily-basis ?尽管我需要每天查询数据,但我需要什么查询才能获得唯一的计数

If I understand correctly, you want to flag the first occurrence of each order in a month.如果我理解正确,您想标记每个订单在一个月内的第一次出现。 You can use window functions:您可以使用 window 函数:

select s.*,
       ( row_number() over (partition by extract(year_month from sent_date), orderid order by sent_date) = 1 ) as flag
from s;

Window functions are supported in MySQL 8+. MySQL 8+ 支持 Window 功能。

I think that you want to a histogram of the first monthly occurence of each orderid per date.我认为您想要每个日期每个 orderid 的第一个每月出现的直方图。

Here is an approach using window functions, available in MySQL 8.0:这是使用 MySQL 8.0 中可用的 window 函数的方法:

select sent_date, sum(rn = 1) cnt_distinct_orderid
from (
    select s.*, row_number() over(partition by year(sent_date), month(sent_date), orderid order by sent_date) rn
    from sales s
) t
group by sent_date
order by sent_date

In earlier versions, one option uses a self-join:在早期版本中,一个选项使用自联接:

select d.sent_date, count(s.orderid) cnt_distinct_orderid
from (select distinct sent_date from sales) d
left join (
    select orderid, min(sent_date) min_sent_date
    from sales 
    group by orderid, date_format(sent_date, '%Y-%m-01')
) s on d.sent_date = s.min_sent_date
group by d.sent_date

Demon on DB Fiddle : DB Fiddle上的恶魔

sent_date  | cnt_distinct_orderid
:--------- | -------------------:
2019-03-15 |                    1
2019-03-16 |                    0
2020-06-16 |                    1
2020-07-27 |                    1
2020-08-05 |                    1
2020-08-10 |                    0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM