【问题标题】:Subtracting or Adding data based on logtime of another table根据另一个表的 logtime 减去或添加数据
【发布时间】:2021-10-14 05:40:10
【问题描述】:

所以目前我有 2 个表,称为列表和日志表。列表表包含产品参考号及其当前状态。所以假设如果它的状态是当前发布并且它已售出,则状态更新为已售出。这里是参考号。此表中的内容是唯一的,因为 1 个产品的状态可以更改。

现在我有另一个名为 Logs 的表,该表记录了特定产品(由 refno 引用)在特定时间范围内发生的所有状态更改。假设 Product 带有 refno。 5 是在 10 月 1 日发布并在 10 月 2 日售出,日志表将显示为:

Refno status_from status_to logtime
5 Stock Publish 2021-10-01
5 Publish Sold 2021-10-02

这是我的表格目前的样子:

列表表格:('D'=>'Draft','N'=>'Action','Y'=>'Publish')

我使用以下语句获取的日志表:

SELECT refno, logtime, status_from, status_to FROM ( 
SELECT refno, logtime, status_from, status_to, ROW_NUMBER() OVER(PARTITION BY refno ORDER BY logtime DESC)
AS RN FROM crm_logs WHERE logtime < '2021-10-12 00:00:00' ) r 
WHERE r.RN = 1 UNION SELECT refno, logtime, status_from, status_to
FROM crm_logs WHERE logtime <= '2021-10-12 00:00:00' AND logtime >= '2015-10-02 00:00:00'
ORDER BY `refno` ASC

日志表会在每次状态更改时创建一条新记录,并将当前时间戳作为日志时间传递,而列表表会更改/更新状态并更新其 update_date。现在要获取截至今天的总房源,我使用以下语句:

SELECT SUM(status_to = 'D') AS draft, SUM(status_to = 'N') AS action, SUM(status_to = 'Y') AS publish FROM `crm_listings`

这将返回截至当天状态的所有计数数据。

现在这让我感到困惑。所以假设今天的计数是 10,明天是 15,我想检索昨天存在的总数(10)。因此,为此我要做的是取今天的总数(15)并减去昨天和今天之间产品更改为草稿的所有地方(清单表中今天的总数 - count(*) where status_to='来自日志表的操作)。反之亦然,如果昨天是 10,今天是 5,它应该添加日志表中 status_from 列中的值

注意:Refno 在我的日志表中不是唯一的,因为具有相同 refno 的产品可以标记为发布 1 天并取消发布另一个,但它在我的列表表中是唯一的。

到 dbfiddle 的链接:https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=01cb3ccfda09f6ddbbbaf02ec92ca894

【问题讨论】:

  • 提供一些示例数据作为 CREATE TABLE + INSERT INTO 和该数据的所需输出。
  • @Akina 我提供了一个 dbfiddle
  • 您想要的输出绝对不清楚。请参阅edited fiddle,第 3 块,其中我将两个表中的数据按事件时间排序 - 我无法理解它与所需输出之间的关系以及解释...... PS。在 MySQL 中,标有-- 的注释需要在这两个破折号之后的空格中。
  • @JayModi 想要的输出是什么,您是否想找到在指定日期有多少项目?比如 01.10.2021 那天的情况如何?

标签: mysql sum


【解决方案1】:

我相信它可以被简化或更好。但这是我的查询和逻辑:

  1. 我找到了每个 refno 的 status_changes 并计算了从所需日期到现在的总变化:

select status_logs, sum(cnt_status) to_add from (
SELECT 
status_to as status_logs, -1*count(*) cnt_status
FROM logs lm
where
id = (select max(id) from logs l where l.refno = lm.refno) and 
logtime >= '2021-10-01 00:00:00'
group by status_to
union all 
SELECT 
status_from, count(*) cnt_status_from
FROM logs lm
where
id = (select max(id) from logs l where l.refno = lm.refno) and
logtime >= '2021-10-01 00:00:00'
group by status_from ) total_changes
group by status_logs

  1. 我通过转换列表表键匹配列表表和日志表之间的键:

select
case status
when 'D' THEN 'Draft'
when 'A' THEN 'Action'
when 'Y' THEN 'Publish'
when 'S' THEN 'Sold'
when 'N' THEN 'Let'
END status_l ,COUNT(*) c
from listings
group by status

  1. 我加入了他们并将计算结果添加到当前数据的总和中。

  1. 我必须使用完全外连接,所以我有一个左连接和一个右连接,具有相同的子查询。

最后我使用 distinct ,因为它会为每个连接查询生成相同的结果,并使用 ifnull 将其他表的状态带到另一列。

select distinct IFNULL(status_l, status_logs) status, counts_at_2021_10_01
  from (select l.*,
               logs.*,
               l.c + ifnull(logs.to_add, 0) counts_at_2021_10_01
          from (select case status
                         when 'D' THEN
                          'Draft'
                         when 'A' THEN
                          'Action'
                         when 'Y' THEN
                          'Publish'
                         when 'S' THEN
                          'Sold'
                         when 'N' THEN
                          'Let'
                       END status_l,
                       COUNT(*) c
                  from listings
                 group by status) l
          left join (
                    
                    select status_logs, sum(cnt_status) to_add
                      from (SELECT status_to as status_logs,
                                    -1 * count(*) cnt_status
                               FROM logs lm
                              where id = (select max(id)
                                            from logs l
                                           where l.refno = lm.refno)
                                and logtime >= '2021-10-01 00:00:00'
                              group by status_to
                             union all
                             SELECT status_from, count(*) cnt_status_from
                               FROM logs lm
                              where id = (select max(id)
                                            from logs l
                                           where l.refno = lm.refno)
                                and logtime >= '2021-10-01 00:00:00'
                              group by status_from) total_changes
                     group by status_logs) logs
            on logs.status_logs = l.status_l
        union all
        select l.*,
               logs.*,
               l.c + ifnull(logs.to_add, 0) counts_at_2021_05_01
          from (select case status
                         when 'D' THEN
                          'Draft'
                         when 'A' THEN
                          'Action'
                         when 'Y' THEN
                          'Publish'
                         when 'S' THEN
                          'Sold'
                         when 'N' THEN
                          'Let'
                       END status_l,
                       COUNT(*) c
                  from listings
                 group by status) l
         right join (
                    
                    select status_logs, sum(cnt_status) to_add
                      from (SELECT status_to as status_logs,
                                    -1 * count(*) cnt_status
                               FROM logs lm
                              where id = (select max(id)
                                            from logs l
                                           where l.refno = lm.refno)
                                and logtime >= '2021-10-01 00:00:00'
                              group by status_to
                             union all
                             SELECT status_from, count(*) cnt_status_from
                               FROM logs lm
                              where id = (select max(id)
                                            from logs l
                                           where l.refno = lm.refno)
                                and logtime >= '2021-10-01 00:00:00'
                              group by status_from) total_changes
                     group by status_logs) logs
            on logs.status_logs = l.status_l) l

【讨论】:

    猜你喜欢
    • 2013-05-21
    • 2019-04-12
    • 2021-12-13
    • 2019-08-19
    • 1970-01-01
    • 1970-01-01
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多