我正在尝试编写一个查询,该查询将在我的数据库中找到最连续的内容。这导致我尝试了以前从未真正使用过的变量。
我遇到的问题是我的查询正确地给出了我认为应该的结果,但是当我在另一个查询中使用它作为子查询时,当我按照子句的顺序添加组时,它似乎都会转到底池
这是正常的,如果是这样的话,解决方案往往是什么?或者我犯了一个简单的错误?
我的子查询的结果是完美的,我在外部查询中尝试做的就是选择我创建的“连续”列的最大值。此列采用
的形式@r := IF(nFound=nThis,@r + 1,0)
即。对于符合我的位置/顺序排列的每一行,它只会计数1,如果找不到匹配,则重置为0。
我希望子查询结果将“设置”并在用于主查询之前简单地用作值。
我把它比作优秀;有时你想“粘贴为值”,而不是复制所有的公式,如果你明白我的意思。在MySQL中有一种简单的方法吗?我想知道创建一个视图是否可以“巩固”数据集,但后来发现视图中不允许变量!
修改 好的,这是查询。它不漂亮,但我一直在乱砍并尝试很多东西。如果你删除最后两行和“MAX”函数它可以正常工作,它们只返回一行,而不是10行。
我今天之前从未使用过交叉联接;我通常所做的一切似乎只是“加入”或“左加入”,但今天似乎是必要的。
基本上,这个想法是检索每个人所在的最大数量的按时间顺序排列的连续事件。您可以随意修改!
“P.person< 10”只是一个考验。实际上有成千上万的人,但是如果我试着立即对所有人这样做,那么多年来他们坐着什么都不做 - 交叉连接变得太大了,我想?
SET @r=0;
SELECT person,MAX(nConsec) FROM (
SELECT @r := IF(nFound=person,@r + 1,0) AS nConsec
test.*
FROM (SELECT P.person, event, tDate, MAX(C.person) AS nFound
FROM PEOPLE P
CROSS JOIN EVENTS E
LEFT JOIN COMPETITORS C ON C.event=E.event AND C.person = P.person
WHERE P.person < 10
AND tDate < NOW()
GROUP BY P.person, event, tDate
ORDER BY P.person ASC, tDate ASC
) test
) test2
GROUP BY person
ORDER BY MAX(nConsec) DESC
编辑2 好吧我不知道是什么,但在改变一些东西以保持一点匿名时,我似乎无意中修复了我自己的代码...一个惊喜,但令人讨厌的是没有任何数量的ctrl-Z和ctrl-shift- Zing似乎首先向我展示了我做错了什么!
关于这个烂摊子的任何意见/建议我仍然感激不尽。我确信我可以做一些不使用交叉连接的聪明人。 “人”中有30,000行,“事件”中有1000行,每个事件大约有500个竞争者,所以我可以看到为什么交叉连接会给我带来问题(我做了150亿行......)。对于我挑选出的10个ID,查询需要0.6秒,如果我将其提升到1000个ID,则需要34秒。
答案 0 :(得分:0)
这对你有什么作用:
SELECT person, MAX(nConsec) AS numConsecutive FROM (
SELECT person, COUNT(*) AS nConsec FROM (
SELECT @r := @r + (COALESCE(@person, P.person) <> P.person) as consecutive, @person := P.person AS person FROM (
SELECT @r := 0, @person := NULL
) vars
JOIN PEOPLE P
JOIN EVENTS E
LEFT JOIN COMPETITORS C
ON C.person = P.person
AND C.event = E.event
ORDER BY tDate
)
GROUP BY consecutive
)
从http://www.dancewithgrenades.com/blog/mysql-consecutive-row-streaks找到的代码修改。
请注意,如果您计算多个人,则需要跟踪您要计算的人(@person
变量)。我认为这应该更快,但主要是由于最内层子查询中缺少GROUP
,这可能对性能产生很大影响。如果性能仍然不够好,那么我建议在PEOPLE
中创建一个列以保持此连续出勤值,将查询修改为一次只能处理一个人,并针对不同的集运行查询用户在不同时间更新PEOPLE
中的值。
哦,就CROSS JOIN
而言 - 在MySQL中,CROSS JOIN
相当于INNER JOIN
相当于JOIN
。你之前使用过交叉连接,你只是没有意识到它。 ;)