根据个人搜索条件获取通过特定摄像头的汽车
Get the cars that passed specific cameras based on individual search criteria
我的问题与 问题有关,但它有所不同,因为每个搜索过滤器的日期时间都不同。
MYSQL/MARIADB 架构和示例数据:
CREATE DATABASE IF NOT EXISTS `puzzle` DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci;
USE `puzzle`;
DROP TABLE IF EXISTS `event`;
CREATE TABLE `event` (
`eventId` bigint(20) NOT NULL AUTO_INCREMENT,
`sourceId` bigint(20) NOT NULL COMMENT 'think of source as camera',
`carCode` varchar(40) NOT NULL COMMENT 'ex: A',
`carNumber` varchar(40) NOT NULL COMMENT 'ex: 5849',
`createdOn` datetime DEFAULT NULL,
PRIMARY KEY (`eventId`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `event` (`eventId`, `sourceId`, `carCode`, `carNumber`, `createdOn`) VALUES
(1, 44,'A', '4456', '2016-09-20 20:24:05'),
(2, 26,'B', '26484', '2016-09-20 20:24:05'),
(3, 5,'A', '4456', '2016-09-20 20:24:06'),
(4, 3,'C', '72704', '2016-09-20 20:24:15'),
(5, 3,'D' ,'399606', '2016-09-20 20:26:15'),
(6, 5, 'A', '4456', '2016-09-20 20:27:25'),
(7, 44,'C', '72704', '2016-09-20 20:29:25'),
(8, 3,'A' ,'4456', '2016-09-20 20:30:55'),
(9, 44,'B' ,'26484', '2016-09-20 20:34:55'),
(10, 26,'B' ,'4456', '2016-09-20 20:35:15'),
(11, 3, 'C','72704', '2016-09-20 20:35:15'),
(12, 3,'D', '399606', '2016-09-20 20:44:35'),
(13, 26,'A' ,'4456', '2016-09-20 20:49:45');
要求:
用户有两个搜索过滤器。
在第一个搜索过滤器中,他说,为我提供特定日期和时间在 (44,3) 中具有 sourceId 的所有汽车。假设 ( e.createdOn > '2016-09-20 20:24:00' and e.createdOn < '2016-09-20 20:35:00' )
在第二个搜索过滤器中,他说,为我提供另一个日期和时间的所有 sourceId 在 (26,3,5) 中的汽车。假设 ( e.createdOn > '2016-09-20 20:36:00' and e.createdOn < '2016-09-20 20:49:00' )
现在我想获取两个搜索结果中可用的所有 (carNumbers, carCode)。
查询需要快速,因为真实 table 包含超过 3 亿条记录。
到目前为止,以下是我可以进行查询的最大值(它甚至没有产生有效结果)
select distinct e1.carNumber, e1.carCode from event e1
inner join (select e2.carNumber, e2.carCode from event e2 where e2.sourceId in (44,3) ) e3 on e1.carNumber= e3.carNumber
inner join (select e2.carNumber, e2.carCode from event e2 where e2.sourceId in (44,3) ) e4 on e1.carCode= e4.carCode
inner join (select e2.carNumber, e2.carCode from event e2 where e2.sourceId in (26,3,5) ) e5 on e1.carNumber= e5.carNumber
inner join (select e2.carNumber, e2.carCode from event e2 where e2.sourceId in (26,3,5) ) e6 on e1.carCode= e6.carCode
我想知道SQL是否可以解决这个问题,还是我应该使用后端编码?
MySQL/正在使用的 MariaDB 版本:
mariadb-5.5.50
mysql-5.5.51
这是我根据您的病情做出的猜测
select distinct e1.carNumber, e1.carCode from event e1
where e.sourceId in (44,3)
and e.createdOn = "certain date"
and exists (
select 'x' from event e2
where e2.sourceId in (26,3,5)
and e2.createdOn = "another date"
and e1.carCode = e2.carCode
and e1.carNumber = e2.carNumber
)
Return 来自第二个过滤器 select 的第一个过滤器中的所有汽车
一次读一个部分:
select distinct e1.carNumber, e1.carCode from event e1
where e.sourceId in (44,3)
and e.createdOn = "certain date"
将 return 来自第一个过滤器的所有汽车。由此,我们需要用第二个再次过滤。
select 'x' from event e2
where e2.sourceId in (26,3,5)
and e2.createdOn = "another date"
and e1.carCode = e2.carCode
and e1.carNumber = e2.carNumber
我使用 exists
子句来检查第一个结果中是否有汽车已经存在的结果。
编辑 2:最后一次编辑,因为您不断添加需求...
select distinct e1.carNumber, e1.carCode from event e1
inner join event e2 on e1.carCode = e2.carCode and e1.carNumber = e2.carNumber and e2.sourceId in (26,3,5) and e2.createdOn = "another date" --the second filter
-- inner join event e3 on e1.carCode = e3.carCode and e1.carNumber = e3.carNumber and e3.sourceId in (x,y,z) and e3.createdOn = "some crazy date" --the third filter ...
where e.sourceId in (44,3) and e.createdOn = "certain date" --the first filter
例如(可能不是您想要的)
SELECT carnumber
FROM event
WHERE (sourceid IN (44,3) AND createdon BETWEEN '2016-09-20 20:24:00' and '2016-09-20 20:35:00')
OR (sourceid IN (26,3,5) AND createdon BETWEEN '2016-09-20 20:36:00' and '2016-09-20 20:49:00')
GROUP
BY carnumber HAVING COUNT(*) > 1;
我使用以下查询来解决我的问题。希望对其他人有帮助。
SELECT e1.carCode, e1.carNumber from event e1
WHERE (sourceid IN (44,3) AND createdon BETWEEN '2016-09-20 20:24:00' and '2016-09-20 20:35:00')
OR (sourceid IN (26,3,5) AND createdon BETWEEN '2016-09-20 20:36:00' and '2016-09-20 20:49:00')
group by e1.carCode, e1.carNumber
having sum(e1.sourceId IN (44,3)) > 0 and
sum(e1.sourceId IN (26,3,5)) > 0;
我的问题与
MYSQL/MARIADB 架构和示例数据:
CREATE DATABASE IF NOT EXISTS `puzzle` DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci;
USE `puzzle`;
DROP TABLE IF EXISTS `event`;
CREATE TABLE `event` (
`eventId` bigint(20) NOT NULL AUTO_INCREMENT,
`sourceId` bigint(20) NOT NULL COMMENT 'think of source as camera',
`carCode` varchar(40) NOT NULL COMMENT 'ex: A',
`carNumber` varchar(40) NOT NULL COMMENT 'ex: 5849',
`createdOn` datetime DEFAULT NULL,
PRIMARY KEY (`eventId`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `event` (`eventId`, `sourceId`, `carCode`, `carNumber`, `createdOn`) VALUES
(1, 44,'A', '4456', '2016-09-20 20:24:05'),
(2, 26,'B', '26484', '2016-09-20 20:24:05'),
(3, 5,'A', '4456', '2016-09-20 20:24:06'),
(4, 3,'C', '72704', '2016-09-20 20:24:15'),
(5, 3,'D' ,'399606', '2016-09-20 20:26:15'),
(6, 5, 'A', '4456', '2016-09-20 20:27:25'),
(7, 44,'C', '72704', '2016-09-20 20:29:25'),
(8, 3,'A' ,'4456', '2016-09-20 20:30:55'),
(9, 44,'B' ,'26484', '2016-09-20 20:34:55'),
(10, 26,'B' ,'4456', '2016-09-20 20:35:15'),
(11, 3, 'C','72704', '2016-09-20 20:35:15'),
(12, 3,'D', '399606', '2016-09-20 20:44:35'),
(13, 26,'A' ,'4456', '2016-09-20 20:49:45');
要求:
用户有两个搜索过滤器。
在第一个搜索过滤器中,他说,为我提供特定日期和时间在 (44,3) 中具有 sourceId 的所有汽车。假设 ( e.createdOn > '2016-09-20 20:24:00' and e.createdOn < '2016-09-20 20:35:00' )
在第二个搜索过滤器中,他说,为我提供另一个日期和时间的所有 sourceId 在 (26,3,5) 中的汽车。假设 ( e.createdOn > '2016-09-20 20:36:00' and e.createdOn < '2016-09-20 20:49:00' )
现在我想获取两个搜索结果中可用的所有 (carNumbers, carCode)。
查询需要快速,因为真实 table 包含超过 3 亿条记录。
到目前为止,以下是我可以进行查询的最大值(它甚至没有产生有效结果)
select distinct e1.carNumber, e1.carCode from event e1
inner join (select e2.carNumber, e2.carCode from event e2 where e2.sourceId in (44,3) ) e3 on e1.carNumber= e3.carNumber
inner join (select e2.carNumber, e2.carCode from event e2 where e2.sourceId in (44,3) ) e4 on e1.carCode= e4.carCode
inner join (select e2.carNumber, e2.carCode from event e2 where e2.sourceId in (26,3,5) ) e5 on e1.carNumber= e5.carNumber
inner join (select e2.carNumber, e2.carCode from event e2 where e2.sourceId in (26,3,5) ) e6 on e1.carCode= e6.carCode
我想知道SQL是否可以解决这个问题,还是我应该使用后端编码?
MySQL/正在使用的 MariaDB 版本:
mariadb-5.5.50
mysql-5.5.51
这是我根据您的病情做出的猜测
select distinct e1.carNumber, e1.carCode from event e1
where e.sourceId in (44,3)
and e.createdOn = "certain date"
and exists (
select 'x' from event e2
where e2.sourceId in (26,3,5)
and e2.createdOn = "another date"
and e1.carCode = e2.carCode
and e1.carNumber = e2.carNumber
)
Return 来自第二个过滤器 select 的第一个过滤器中的所有汽车
一次读一个部分:
select distinct e1.carNumber, e1.carCode from event e1
where e.sourceId in (44,3)
and e.createdOn = "certain date"
将 return 来自第一个过滤器的所有汽车。由此,我们需要用第二个再次过滤。
select 'x' from event e2
where e2.sourceId in (26,3,5)
and e2.createdOn = "another date"
and e1.carCode = e2.carCode
and e1.carNumber = e2.carNumber
我使用 exists
子句来检查第一个结果中是否有汽车已经存在的结果。
编辑 2:最后一次编辑,因为您不断添加需求...
select distinct e1.carNumber, e1.carCode from event e1
inner join event e2 on e1.carCode = e2.carCode and e1.carNumber = e2.carNumber and e2.sourceId in (26,3,5) and e2.createdOn = "another date" --the second filter
-- inner join event e3 on e1.carCode = e3.carCode and e1.carNumber = e3.carNumber and e3.sourceId in (x,y,z) and e3.createdOn = "some crazy date" --the third filter ...
where e.sourceId in (44,3) and e.createdOn = "certain date" --the first filter
例如(可能不是您想要的)
SELECT carnumber
FROM event
WHERE (sourceid IN (44,3) AND createdon BETWEEN '2016-09-20 20:24:00' and '2016-09-20 20:35:00')
OR (sourceid IN (26,3,5) AND createdon BETWEEN '2016-09-20 20:36:00' and '2016-09-20 20:49:00')
GROUP
BY carnumber HAVING COUNT(*) > 1;
我使用以下查询来解决我的问题。希望对其他人有帮助。
SELECT e1.carCode, e1.carNumber from event e1
WHERE (sourceid IN (44,3) AND createdon BETWEEN '2016-09-20 20:24:00' and '2016-09-20 20:35:00')
OR (sourceid IN (26,3,5) AND createdon BETWEEN '2016-09-20 20:36:00' and '2016-09-20 20:49:00')
group by e1.carCode, e1.carNumber
having sum(e1.sourceId IN (44,3)) > 0 and
sum(e1.sourceId IN (26,3,5)) > 0;