Mysql 创建一个查询,以获取行及其相邻行
我对一个特定的查询有问题——首先分别创建查询。 列可以减少为id、秒和状态 我想要的是:状态为1的所有条目加上距离这些条目不到10秒的所有条目。基本上,我想获取所有可能的行对或三元组等,以便在以后自动手动检查它们是否需要配对。为此,有一个列parent_id,但我们不需要用于查询。我可以在代码中这样做,首先选择all status=1,然后循环,但我想知道是否可以纯粹在数据库中这样做 因此,我期望的输出如下:Mysql 创建一个查询,以获取行及其相邻行,mysql,sql,select,correlated-subquery,Mysql,Sql,Select,Correlated Subquery,我对一个特定的查询有问题——首先分别创建查询。 列可以减少为id、秒和状态 我想要的是:状态为1的所有条目加上距离这些条目不到10秒的所有条目。基本上,我想获取所有可能的行对或三元组等,以便在以后自动手动检查它们是否需要配对。为此,有一个列parent_id,但我们不需要用于查询。我可以在代码中这样做,首先选择all status=1,然后循环,但我想知道是否可以纯粹在数据库中这样做 因此,我期望的输出如下: ============================= | id | seco
=============================
| id | seconds | status |
-----------------------------
| 1 | 12 | 1 | <- status = 1
| 3 | 37 | 1 | <- status = 1
| 4 | 42 | 0 | <- only 5 seconds after status = 1
=============================
我目前的最佳猜测是:
SELECT * FROM entries e0
WHERE
e0.status = 1 OR
e0.status = 0 AND
0 < (SELECT count(*)
FROM entries e1
WHERE e1.status = 1 AND abs(e1.seconds - e0.seconds) < 10)
但是这会获取整个表,我真的不知道为什么——这需要很长时间才能完成,因为在秒列上有一个索引,这个表有9000个条目
有没有一种方法可以更有效地做到这一点?这里有一个选项,可以使用union all和exists:
我更喜欢在一个查询中完成它。但是,也有使用exists或子查询的方法。利用外部联接意味着您可以使用精心编制的where和join语句立即获取所有内容,根据您的性能情况添加group by或distinct将整理结果并使其成为唯一的行 关于在何处陈述以确保满足您的意图,我的建议是使用括号来确定您的预期优先级。它将使您的代码更清楚地表达您的意图 其中条件1=True或条件2=True和条件3=True 应该是 其中条件1=True或条件2=True和条件3=True 奇怪的是,由于过去的经验,我没有想到它会以你提到的方式进行评估,但我总是使用括号来确定我的优先顺序,以使它更清楚,更容易制定更复杂的条件 你得到整张桌子的原因。是因为表中的数据。说真的,有时候我们会去寻找答案,让问题变得复杂,我更喜欢用我的方法来解决你的查询,但考虑到你的结果集示例,我的查询和你的查询得到相同的结果!试着把10秒改为1/2/3等,看看你的查询有什么效果。我的假设是,在您的完整数据集中,您的任何状态为0的记录与状态为1的记录之间的距离不超过10秒。。。。。。我本来会回复的,但这是我回答的第一个问题之一 下面是一些基于数据集和查询的示例代码
DECLARE @Entries AS TABLE (
Id INT
,Seconds INT
,[Status] BIT
)
INSERT INTO @Entries (Id, Seconds, [Status])
VALUES (0,0,0 )
,(1,12,1 )
,(2,25,0 )
,(3,37,1 )
,(4,42,0 )
SELECT *
FROM
@Entries e0
WHERE
e0.Status = 1
OR e0.Status = 0
AND 0 < (SELECT count(*)
FROM
@Entries e1
WHERE e1.Status = 1 AND ABS(e1.Seconds - e0.Seconds) < 10)
SELECT DISTINCT
e0.*
FROM
@Entries e0
LEFT JOIN @Entries e1
ON e1.[Status] = 1
AND ABS(e1.seconds - e0.seconds) < 10
WHERE
e0.[Status] = 1
OR e1.id IS NOT NULL
非常感谢。我使用了第一个,虽然我对它做了一些修改:abse.seconds-e2.seconds<10->e2.seconds