尝试根据特定日期*之前*的最新时间戳连接 2 个表
Trying to join 2 tables based on the most recent timestamp *before* a specific date
这是我的 SQL 语句,在我们创建新数据库之前它似乎运行良好。这种方法似乎适用于另一对结构相似的 tables.
SELECT *
FROM tele2_details AS d
INNER JOIN
tele2_usage AS u
ON
d.iccid = u.iccid
AND
u.timestamp = (
SELECT MAX(u.timestamp)
FROM tele2_usage
WHERE u.timestamp <= DATE_FORMAT('2022-01-08 09:30:00','%Y-%m-%d %H:%i:%s')
)
WHERE
accountCustom1='Horizon'
我在这里尝试做的是将详细信息 table 与用法 table 结合起来,用法行仅包含 sim 卡的 iccid、时间戳和它们当前的用法以字节为单位。这应该做的是在指定日期 (2022-01-08 09:30:00) 之前找到最近的使用记录。这应该给我一组模拟人生,每个模拟人生都在指定时间之前加入了它的最新使用记录,但是我通常在这个 tables.
的特定组合上得到零结果
但具体来说,它 确实 匹配日期与查询中指定的日期完全相同的任何记录,但不匹配指定日期之前或等于指定日期的日期。谁能帮我解决我哪里出错了。此查询在以前的数据库中运行良好,我们正在重建我们的系统,现在这已成为一个问题。
在此先感谢您的帮助。
编辑
这里有一些更多的信息,我希望能让这个问题更有意义。所以这里是详细信息的概述 table,我删除了一些列,但这至少是对 table.
的说明
CREATE TABLE `tele2_details` (
`iccid` VARCHAR(255) NOT NULL,
`msisdn` VARCHAR(255) NOT NULL,
`status` VARCHAR(255) NOT NULL,
`ratePlan` VARCHAR(255) NOT NULL,
`communicationPlan` VARCHAR(255) NOT NULL,
PRIMARY KEY (`iccid`)
)
COLLATE='utf8mb4_0900_ai_ci'
ENGINE=InnoDB
;
然后我们还有一个 usages table,它存储 sim 卡的数据使用示例,以及时间戳...
CREATE TABLE `tele2_usage` (
`id` INT NOT NULL AUTO_INCREMENT,
`iccid` VARCHAR(255) NOT NULL COLLATE 'latin1_swedish_ci',
`msisdn` VARCHAR(255) NOT NULL COLLATE 'latin1_swedish_ci',
`timestamp` DATETIME NOT NULL,
`ctd_data_usage` BIGINT NOT NULL,
`ctd_sms_usage` BIGINT NOT NULL,
`ctd_voice_usage` BIGINT NOT NULL,
`session_count` INT NOT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8mb4_hr_0900_ai_ci'
ENGINE=InnoDB
AUTO_INCREMENT=10116319
;
我正在尝试创建的查询应该return 一组 sim 详细信息,并与最接近特定时间但不晚于特定时间的使用记录结合在一起。
因此,如果您查看顶部的原始查询,我会尝试将详细信息加入最接近但不是在 2022-01-08 之后的使用记录 09:30:00 * *
我希望这是有道理的。
让我们来看看特定的 sim
SELECT iccid, msisdn, status, ratePlan, communicationPlan FROM tele2_details WHERE iccid='xxxx203605100034xxxx'
1 场比赛结果
"xxxx203605100034xxxx" "xxxx9120012xxxx" "ACTIVATED" "Pay as use - Existing Business" "Data LTE"
如果我查看同一个 sim 的用法 table,我可以看到许多满足我的条件的记录
SELECT id, iccid, TIMESTAMP, ctd_data_usage FROM tele2_usage WHERE iccid='xxxx203605100034xxxx' AND TIMESTAMP <= '2022-01-08 09:30:00'
结果
"10096279" "xxxx203605100034xxxx" "2022-01-08 09:01:00" "77517560"
"10092271" "xxxx203605100034xxxx" "2022-01-08 08:01:03" "77002733"
"10088263" "xxxx203605100034xxxx" "2022-01-08 07:01:11" "76270445"
"10084255" "xxxx203605100034xxxx" "2022-01-08 06:01:05" "76270445"
其中我想 select 第一条记录(带有 09:01 时间戳)以加入详细记录。我可以通过以下查询获得该时间戳
SELECT MAX(timestamp)
FROM tele2_usage
WHERE TIMESTAMP <= DATE_FORMAT('2022-01-08 09:30:00','%Y-%m-%d %H:%i:%s') AND iccid='xxxx203605100034xxxx'
结果为“2022-01-08 09:01:00”,这正是我想要的。所以现在我把它们放在一起...
SELECT *
FROM tele2_details AS d
INNER JOIN
tele2_usage AS u
ON
d.iccid = u.iccid
AND
u.timestamp = (
SELECT MAX(timestamp)
FROM tele2_usage
WHERE timestamp <= DATE_FORMAT('2022-01-08 09:30:00','%Y-%m-%d %H:%i:%s')
)
WHERE
accountCustom1='Horizon' AND iccid='xxxx203605100034xxxx'
我什么也没得到!我希望取回与该特定 sim 连接的详细记录,但实际上我得到的结果为零,我不明白为什么。
理想情况下,我会删除 iccid 的最终 AND,并且我希望收到该客户的所有模拟人生的集合,使用时间从最接近但不在指定日期之后。
所以有了这个解释,有人知道为什么我没有收到任何记录吗?我有一个类似的 table 用于另一个结构完全相同的 sim 提供商,具有详细信息 table 和用法 table 并且此查询在 table 上工作得很好。我简直无法理解为什么这不起作用。
编辑 2
@Serg 建议尝试为子查询设置别名(我想这就是它的名字),这导致了以下代码...
SELECT *
FROM tele2_details AS d
INNER JOIN
tele2_usage AS u
ON
d.iccid = u.iccid
AND
u.timestamp = (
SELECT MAX(u2.timestamp)
FROM tele2_usage AS u2
WHERE u2.timestamp <= DATE_FORMAT('2022-01-08 09:30:00','%Y-%m-%d %H:%i:%s')
)
WHERE
accountCustom1='Horizon'
不幸的是,这仍然导致结果为零。
您应该关联子查询:
SELECT *
FROM tele2_details AS d INNER JOIN tele2_usage AS u
ON d.iccid = u.iccid
AND u.timestamp = (
SELECT MAX(u2.timestamp)
FROM tele2_usage u2
WHERE d.iccid = u2.iccid AND u2.timestamp <= DATE_FORMAT('2022-01-08 09:30:00','%Y-%m-%d %H:%i:%s')
)
WHERE d.accountCustom1='Horizon';
或者,连接到聚合查询:
SELECT *
FROM tele2_details AS d
INNER JOIN tele2_usage AS u ON d.iccid = u.iccid
INNER JOIN (
SELECT iccid, MAX(timestamp) timestamp
FROM tele2_usage
WHERE timestamp <= DATE_FORMAT('2022-01-08 09:30:00','%Y-%m-%d %H:%i:%s')
GROUP BY iccid
) m ON m.iccid = u.iccid AND m.timestamp = u.timestamp
WHERE d.accountCustom1='Horizon';
这是我的 SQL 语句,在我们创建新数据库之前它似乎运行良好。这种方法似乎适用于另一对结构相似的 tables.
SELECT *
FROM tele2_details AS d
INNER JOIN
tele2_usage AS u
ON
d.iccid = u.iccid
AND
u.timestamp = (
SELECT MAX(u.timestamp)
FROM tele2_usage
WHERE u.timestamp <= DATE_FORMAT('2022-01-08 09:30:00','%Y-%m-%d %H:%i:%s')
)
WHERE
accountCustom1='Horizon'
我在这里尝试做的是将详细信息 table 与用法 table 结合起来,用法行仅包含 sim 卡的 iccid、时间戳和它们当前的用法以字节为单位。这应该做的是在指定日期 (2022-01-08 09:30:00) 之前找到最近的使用记录。这应该给我一组模拟人生,每个模拟人生都在指定时间之前加入了它的最新使用记录,但是我通常在这个 tables.
的特定组合上得到零结果但具体来说,它 确实 匹配日期与查询中指定的日期完全相同的任何记录,但不匹配指定日期之前或等于指定日期的日期。谁能帮我解决我哪里出错了。此查询在以前的数据库中运行良好,我们正在重建我们的系统,现在这已成为一个问题。
在此先感谢您的帮助。
编辑 这里有一些更多的信息,我希望能让这个问题更有意义。所以这里是详细信息的概述 table,我删除了一些列,但这至少是对 table.
的说明CREATE TABLE `tele2_details` (
`iccid` VARCHAR(255) NOT NULL,
`msisdn` VARCHAR(255) NOT NULL,
`status` VARCHAR(255) NOT NULL,
`ratePlan` VARCHAR(255) NOT NULL,
`communicationPlan` VARCHAR(255) NOT NULL,
PRIMARY KEY (`iccid`)
)
COLLATE='utf8mb4_0900_ai_ci'
ENGINE=InnoDB
;
然后我们还有一个 usages table,它存储 sim 卡的数据使用示例,以及时间戳...
CREATE TABLE `tele2_usage` (
`id` INT NOT NULL AUTO_INCREMENT,
`iccid` VARCHAR(255) NOT NULL COLLATE 'latin1_swedish_ci',
`msisdn` VARCHAR(255) NOT NULL COLLATE 'latin1_swedish_ci',
`timestamp` DATETIME NOT NULL,
`ctd_data_usage` BIGINT NOT NULL,
`ctd_sms_usage` BIGINT NOT NULL,
`ctd_voice_usage` BIGINT NOT NULL,
`session_count` INT NOT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8mb4_hr_0900_ai_ci'
ENGINE=InnoDB
AUTO_INCREMENT=10116319
;
我正在尝试创建的查询应该return 一组 sim 详细信息,并与最接近特定时间但不晚于特定时间的使用记录结合在一起。
因此,如果您查看顶部的原始查询,我会尝试将详细信息加入最接近但不是在 2022-01-08 之后的使用记录 09:30:00 * *
我希望这是有道理的。
让我们来看看特定的 sim
SELECT iccid, msisdn, status, ratePlan, communicationPlan FROM tele2_details WHERE iccid='xxxx203605100034xxxx'
1 场比赛结果
"xxxx203605100034xxxx" "xxxx9120012xxxx" "ACTIVATED" "Pay as use - Existing Business" "Data LTE"
如果我查看同一个 sim 的用法 table,我可以看到许多满足我的条件的记录
SELECT id, iccid, TIMESTAMP, ctd_data_usage FROM tele2_usage WHERE iccid='xxxx203605100034xxxx' AND TIMESTAMP <= '2022-01-08 09:30:00'
结果
"10096279" "xxxx203605100034xxxx" "2022-01-08 09:01:00" "77517560"
"10092271" "xxxx203605100034xxxx" "2022-01-08 08:01:03" "77002733"
"10088263" "xxxx203605100034xxxx" "2022-01-08 07:01:11" "76270445"
"10084255" "xxxx203605100034xxxx" "2022-01-08 06:01:05" "76270445"
其中我想 select 第一条记录(带有 09:01 时间戳)以加入详细记录。我可以通过以下查询获得该时间戳
SELECT MAX(timestamp)
FROM tele2_usage
WHERE TIMESTAMP <= DATE_FORMAT('2022-01-08 09:30:00','%Y-%m-%d %H:%i:%s') AND iccid='xxxx203605100034xxxx'
结果为“2022-01-08 09:01:00”,这正是我想要的。所以现在我把它们放在一起...
SELECT *
FROM tele2_details AS d
INNER JOIN
tele2_usage AS u
ON
d.iccid = u.iccid
AND
u.timestamp = (
SELECT MAX(timestamp)
FROM tele2_usage
WHERE timestamp <= DATE_FORMAT('2022-01-08 09:30:00','%Y-%m-%d %H:%i:%s')
)
WHERE
accountCustom1='Horizon' AND iccid='xxxx203605100034xxxx'
我什么也没得到!我希望取回与该特定 sim 连接的详细记录,但实际上我得到的结果为零,我不明白为什么。
理想情况下,我会删除 iccid 的最终 AND,并且我希望收到该客户的所有模拟人生的集合,使用时间从最接近但不在指定日期之后。
所以有了这个解释,有人知道为什么我没有收到任何记录吗?我有一个类似的 table 用于另一个结构完全相同的 sim 提供商,具有详细信息 table 和用法 table 并且此查询在 table 上工作得很好。我简直无法理解为什么这不起作用。
编辑 2 @Serg 建议尝试为子查询设置别名(我想这就是它的名字),这导致了以下代码...
SELECT *
FROM tele2_details AS d
INNER JOIN
tele2_usage AS u
ON
d.iccid = u.iccid
AND
u.timestamp = (
SELECT MAX(u2.timestamp)
FROM tele2_usage AS u2
WHERE u2.timestamp <= DATE_FORMAT('2022-01-08 09:30:00','%Y-%m-%d %H:%i:%s')
)
WHERE
accountCustom1='Horizon'
不幸的是,这仍然导致结果为零。
您应该关联子查询:
SELECT *
FROM tele2_details AS d INNER JOIN tele2_usage AS u
ON d.iccid = u.iccid
AND u.timestamp = (
SELECT MAX(u2.timestamp)
FROM tele2_usage u2
WHERE d.iccid = u2.iccid AND u2.timestamp <= DATE_FORMAT('2022-01-08 09:30:00','%Y-%m-%d %H:%i:%s')
)
WHERE d.accountCustom1='Horizon';
或者,连接到聚合查询:
SELECT *
FROM tele2_details AS d
INNER JOIN tele2_usage AS u ON d.iccid = u.iccid
INNER JOIN (
SELECT iccid, MAX(timestamp) timestamp
FROM tele2_usage
WHERE timestamp <= DATE_FORMAT('2022-01-08 09:30:00','%Y-%m-%d %H:%i:%s')
GROUP BY iccid
) m ON m.iccid = u.iccid AND m.timestamp = u.timestamp
WHERE d.accountCustom1='Horizon';