Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 创建一个查询,以获取行及其相邻行_Mysql_Sql_Select_Correlated Subquery - Fatal编程技术网

Mysql 创建一个查询,以获取行及其相邻行

Mysql 创建一个查询,以获取行及其相邻行,mysql,sql,select,correlated-subquery,Mysql,Sql,Select,Correlated Subquery,我对一个特定的查询有问题——首先分别创建查询。 列可以减少为id、秒和状态 我想要的是:状态为1的所有条目加上距离这些条目不到10秒的所有条目。基本上,我想获取所有可能的行对或三元组等,以便在以后自动手动检查它们是否需要配对。为此,有一个列parent_id,但我们不需要用于查询。我可以在代码中这样做,首先选择all status=1,然后循环,但我想知道是否可以纯粹在数据库中这样做 因此,我期望的输出如下: ============================= | id | seco

我对一个特定的查询有问题——首先分别创建查询。 列可以减少为id、秒和状态

我想要的是:状态为1的所有条目加上距离这些条目不到10秒的所有条目。基本上,我想获取所有可能的行对或三元组等,以便在以后自动手动检查它们是否需要配对。为此,有一个列parent_id,但我们不需要用于查询。我可以在代码中这样做,首先选择all status=1,然后循环,但我想知道是否可以纯粹在数据库中这样做

因此,我期望的输出如下:

=============================
|  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.secondse.seconds-10,因为这要快得多,但这是我在问题中的错误。然后我意识到你甚至不需要这个联合,只需一起删除第一个查询,并在剩余的外部查询中删除status=0。更确切地说,我刚刚检查了mysql.com,它的优先级高于OR,所以1或2和3等于1或2和3。您的查询的一个问题是,当在给定的10秒范围内有多行状态为1时,它将复制行。@wow我编辑了这篇文章。但你投的答案基本上就是你所写的某个问题。EXISTS的执行速度应快于0