创建一个获取行及其相邻行的查询

时间:2016-06-10 17:37:38

标签: mysql sql select correlated-subquery

我遇到了特定查询的问题 - 首先分别创建查询 列可以缩减为SELECT SONG_ID, COUNT(*) FROM StationPlays WHERE StationPlays.DATE > '2016-06-01' GROUP BY SONG_ID, StationPlays.DATE HAVING COUNT(*) > (10 * (SELECT COUNT(*) FROM StationPlays SP2 WHERE SP2.DATE > '2016-06-01' AND SP2.SONG_ID = StationPlays.SONG_ID)) idseconds

status

我想拥有的内容:============================= | id | seconds | status | ----------------------------- | 0 | 0 | 0 | | 1 | 12 | 1 | | 2 | 25 | 0 | | 3 | 37 | 1 | | 4 | 42 | 0 | ============================= 所有条目加上距离这些条目不到10秒的所有条目。基本上,我想要获取所有可能的对(或者三元组等等要手动检查(稍后自动)它们是否需要配对(为此目的有一个列status = 1,但我们不需要查询)。我可以在代码中执行此操作(首先选择所有parent_id,然后循环),但我想知道是否可以在数据库中完全执行此操作。

因此,我想要的输出如下:

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个条目)。< / p>

有没有办法做到这一点(甚至可能有效)?

2 个答案:

答案 0 :(得分:3)

以下是union allexists的一个选项:

select * from entries where status = 1
union all
select * from entries e where status = 0 and 
  exists (select 1
          from entries e2 
          where e2.status = 1 and
                abs(e.seconds - e2.seconds) < 10
          )

或者,您可以outer join使用distinct代替exists

select distinct e.*
from entries e
  left join entries e2 on e2.status = 1 
where e.status = 1 or abs(e.seconds - e2.seconds) < 10

答案 1 :(得分:0)

我更喜欢在单个查询中执行此操作。但是,也有使用存在或子查询的方法。利用外部联接意味着您可以使用精心设计的where和join语句一次性获取所有内容,根据您的性能情况添加一个或不同的组将整理您的结果并使它们成为唯一的行。

我建议确保您的意图得到满足的声明是使用括号来确定您的预期优先顺序。这将使您的代码更清晰。

WHERE Con​​dition1 = True或Condition2 = True AND Condition3 = True

应该是

WHERE Con​​dition1 = True OR(Condition2 = True AND Condition3 = 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