根据另一个 table 的日志时间减去或添加数据
Subtracting or Adding data based on logtime of another table
所以目前我有 2 个 table 称为列表和日志 table。列表 table 包含产品参考编号及其当前状态。因此,假设如果它的状态是当前发布并且已售出,则状态更新为已售出。这里是 refno。其中 table 是唯一的,因为 1 个产品的状态可以更改。
现在我有另一个 table 称为日志 table,这个 table 记录了特定产品(由 refno 引用)在特定时间范围内发生的所有状态更改。假设带有 refno 的产品。 5 于 10 月 1 日发布并于 10 月 2 日售出,日志 table 将显示为:
Refno
status_from
status_to
logtime
5
Stock
Publish
2021-10-01
5
Publish
Sold
2021-10-02
这是我的 table 目前的样子:
列表table:('D'=>'Draft','N'=>'Action','Y'=>'Publish')
Logs Table 我正在使用以下语句:
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
日志 table 对每个状态更改进行新记录,并将当前时间戳作为日志时间传递,列表 table changes/updates 状态并更新其 update_date.现在要获取截至今天的总列表,我使用以下语句:
SELECT SUM(status_to = 'D') AS draft, SUM(status_to = 'N') AS action, SUM(status_to = 'Y') AS publish FROM `crm_listings`
这 returns 截至当天状态的所有计数数据。
这就是让我感到困惑的地方。因此,假设今天正在执行的计数是 10,明天将是 15,我想检索昨天出现的总数 (10)。因此,为此我要做的是取今天的总数 (15) 并减去昨天和今天之间产品更改为草稿的所有地方(今天列表中的总计数 table - count(*)其中 status_to='Action' 来自日志 table)。反之亦然,如果昨天它是 10,今天它是 5,它应该添加日志 table
中 status_from 列的值
注意:Refno 在我的日志中不是唯一的 table 因为具有相同 refno 的产品可以标记为发布 1 天并取消发布另一天,但它在我的列表中是独一无二的 table.
Link 到 dbfiddle:https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=01cb3ccfda09f6ddbbbaf02ec92ca894
我相信它可以被简化或变得更好。但这是我的查询和逻辑:
- 我发现每个 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
- 我通过转换列表 table 键来匹配列表 table 和日志 table 之间的键:
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
- 我加入了他们并将计算添加到当前数据的总和中。
- 我不得不使用完全外连接,所以我有一个左连接和一个右连接与相同的子查询。
最后我使用了 distinct ,因为它会为每个连接的查询生成相同的结果,并使用 ifnull 将其他 tables 状态带到另一列。
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
所以目前我有 2 个 table 称为列表和日志 table。列表 table 包含产品参考编号及其当前状态。因此,假设如果它的状态是当前发布并且已售出,则状态更新为已售出。这里是 refno。其中 table 是唯一的,因为 1 个产品的状态可以更改。
现在我有另一个 table 称为日志 table,这个 table 记录了特定产品(由 refno 引用)在特定时间范围内发生的所有状态更改。假设带有 refno 的产品。 5 于 10 月 1 日发布并于 10 月 2 日售出,日志 table 将显示为:
Refno | status_from | status_to | logtime |
---|---|---|---|
5 | Stock | Publish | 2021-10-01 |
5 | Publish | Sold | 2021-10-02 |
这是我的 table 目前的样子:
列表table:('D'=>'Draft','N'=>'Action','Y'=>'Publish')
Logs Table 我正在使用以下语句:
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
日志 table 对每个状态更改进行新记录,并将当前时间戳作为日志时间传递,列表 table changes/updates 状态并更新其 update_date.现在要获取截至今天的总列表,我使用以下语句:
SELECT SUM(status_to = 'D') AS draft, SUM(status_to = 'N') AS action, SUM(status_to = 'Y') AS publish FROM `crm_listings`
这 returns 截至当天状态的所有计数数据。
这就是让我感到困惑的地方。因此,假设今天正在执行的计数是 10,明天将是 15,我想检索昨天出现的总数 (10)。因此,为此我要做的是取今天的总数 (15) 并减去昨天和今天之间产品更改为草稿的所有地方(今天列表中的总计数 table - count(*)其中 status_to='Action' 来自日志 table)。反之亦然,如果昨天它是 10,今天它是 5,它应该添加日志 table
中 status_from 列的值注意:Refno 在我的日志中不是唯一的 table 因为具有相同 refno 的产品可以标记为发布 1 天并取消发布另一天,但它在我的列表中是独一无二的 table.
Link 到 dbfiddle:https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=01cb3ccfda09f6ddbbbaf02ec92ca894
我相信它可以被简化或变得更好。但这是我的查询和逻辑:
- 我发现每个 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
- 我通过转换列表 table 键来匹配列表 table 和日志 table 之间的键:
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
- 我加入了他们并将计算添加到当前数据的总和中。
- 我不得不使用完全外连接,所以我有一个左连接和一个右连接与相同的子查询。
最后我使用了 distinct ,因为它会为每个连接的查询生成相同的结果,并使用 ifnull 将其他 tables 状态带到另一列。
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