我遇到了特定查询的问题 - 首先分别创建查询
列可以缩减为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))
,id
和seconds
。
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>
有没有办法做到这一点(甚至可能有效)?
答案 0 :(得分:3)
以下是union all
和exists
的一个选项:
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 Condition1 = True或Condition2 = True AND Condition3 = True
应该是
WHERE Condition1 = 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