Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/82.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
Python 需要在不使用相关子查询的情况下重写此查询_Python_Mysql - Fatal编程技术网

Python 需要在不使用相关子查询的情况下重写此查询

Python 需要在不使用相关子查询的情况下重写此查询,python,mysql,Python,Mysql,我知道相关子查询是如何工作的,通常会避开它们。。但对于我试图做的事情,我找不到另一种方法来编写这个查询。我可以使用它,因为我使用的表中没有一堆记录。。但是现在我需要在一些记录超过100000条的表上做同样的事情,这将使这个查询花费很长时间。所以我需要一些帮助来重写这个查询 初始查询: 如果您注意到它正在按每天的计数递增计数 这个查询本身只需要0.036秒就可以运行,这不是什么大问题 但是在一些更大的桌子上,它已经需要12秒,而且它们只会变得更大 注意:这可以在不使用相关子查询的情况下完成吗?假设

我知道相关子查询是如何工作的,通常会避开它们。。但对于我试图做的事情,我找不到另一种方法来编写这个查询。我可以使用它,因为我使用的表中没有一堆记录。。但是现在我需要在一些记录超过100000条的表上做同样的事情,这将使这个查询花费很长时间。所以我需要一些帮助来重写这个查询

初始查询:

如果您注意到它正在按每天的计数递增计数

这个查询本身只需要0.036秒就可以运行,这不是什么大问题

但是在一些更大的桌子上,它已经需要12秒,而且它们只会变得更大

注意:这可以在不使用相关子查询的情况下完成吗?假设您不能使用用户定义的变量

如果在mysql中不能做到这一点,我可以在python中访问数据库两次,但我希望在mysql中找到解决方案,而不是多次访问数据库


谢谢你的指点/帮助

编辑:修复查询中的错误

EDIT2:python方式的建议

你可以用一个显式的自动连接重写它,但我不认为它会更快

SELECT
DATE(m.Created_At) AS m_date,
COUNT(m.id) AS daily_count,
COUNT(m1.id) AS member_totals
FROM members_joined AS m
JOIN members_joined m1 ON m1.has_verified = 1 and DATE(m1.Created_At) <= DATE(m.Created_At) 
WHERE m.has_verified = 1 and m.Created_At BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE()
GROUP BY m_date;
获取过去30天内每个日期的每日_计数,以及

SELECT
CURDATE() - INTERVAL 30 DAY AS m_date,
COUNT(m.id) AS member_totals,
FROM members_joined AS m
WHERE m.has_verified = 1 and m.Created_At < CURDATE() - INTERVAL 30 DAY;

使用纯SQL很难有效地做到这一点,但您可以使用MySQL特定的用户定义变量。您只需要计算每天的计数,并累积每行的计数

主要技巧是强制MySQL以正确的顺序更新变量

查询应如下所示,但不确定是否100%正确:

SELECT m_date, daily_count, @count:=(daily_count + @count) as member_totals
FROM
(SELECT DATE(Created_At) as m_date, COUNT(*) as daily_count
 FROM members_joined
 WHERE DATE(Created_At) >= CURDATE() - INTERVAL 30 DAY AND has_verified = 1
 GROUP BY m_date
) as days,
(SELECT @count:=COUNT(*) as cnt0
 FROM members_joined
 WHERE DATE(Created_At) < CURDATE() - INTERVAL 30 DAY 
   AND has_verified = 1) as init
ORDER BY m_date;

使用存储过程怎么样?在第一步中,将起始值存储在变量中。这是对您的内部查询的一个单独查询,并且应该是快速的,假设在上创建了一个索引。然后将外部查询与此变量结合使用,甚至使用光标,当前外部查询只有30行。。我在这里使用标量来回答这个问题,因为它返回多行。我不知道是否可以使用此方法调用存储过程。。。如果是这样的话,用python本身进行计算可能会更快。。对不起,我确实错过了关于UDV的便条。然后,您可以只获取每天的数据和init计数,然后用python计算第三列。您将需要一个查询。@newtover将您的答案放回原处lolI已将我的答案放回原处,但仍与您的问题不匹配=您以前尝试过这个吗?它返回一个错误,因为它不知道m_date列是什么。。未知栏目“m_date”在…我让它工作了。。。选择了m_date和daily_count,然后在外部选择上加入,以便将m_date作为列。。。再多花2秒钟。。因为这个问题是关于性能的,这与我想要的正好相反:@JohnRuddell对这个错误表示抱歉。不,没有桌子我无法测试。。。后编辑井。。。我做了改变。。。不知道这有什么不同,但是现在不是14秒而是83秒lol…我不知道你是否注意到了,但是使用用户定义的变量是我说我做不到的。。。它们不适用于我们的系统。请看注释:在我的问题中,除此之外,如果我可以使用它们,这将非常快地工作。我已经这样做了:。。。不幸的是我不能。。。我必须对数据库进行两次点击,然后用Pythoni进行计算guess@John,但是为什么你需要两次点击呢?为了让事情有一个正确的角度,我在发布问题之前写了这个精确的查询,它确实加快了速度。。从14.347秒到0.877秒运行。。。我将在python中执行此操作,并在不使用UDV的情况下运行此查询。。接受你的答案,因为它符合我的要求,即使我不能使用它:如果我在一个查询中选择两个选项,那么计数会减少很多,我还不知道为什么,但当我这样做时,我将使用一个点击。。。不过,这有多个层次。。我必须做10次这种类型的查询,然后每一次都做一次,并建立一个过去30天的交互主列表。。通过计算使事情每天都累积起来。。写入excel并在excel中绘制图表。。。所以我确切地知道输出应该是什么,但不确定为什么计数大约为100。无论如何,谢谢你的努力!
SELECT
DATE(m.Created_At) AS m_date,
COUNT(m.id) AS daily_count,
FROM members_joined AS m
WHERE m.has_verified = 1 and m.Created_At BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE()
GROUP BY m_date;
SELECT
CURDATE() - INTERVAL 30 DAY AS m_date,
COUNT(m.id) AS member_totals,
FROM members_joined AS m
WHERE m.has_verified = 1 and m.Created_At < CURDATE() - INTERVAL 30 DAY;
for row in rows:
    dat, daily_count = row
    member_totals += daily_count
    # use dat, daily_count, member_totals
SELECT m_date, daily_count, @count:=(daily_count + @count) as member_totals
FROM
(SELECT DATE(Created_At) as m_date, COUNT(*) as daily_count
 FROM members_joined
 WHERE DATE(Created_At) >= CURDATE() - INTERVAL 30 DAY AND has_verified = 1
 GROUP BY m_date
) as days,
(SELECT @count:=COUNT(*) as cnt0
 FROM members_joined
 WHERE DATE(Created_At) < CURDATE() - INTERVAL 30 DAY 
   AND has_verified = 1) as init
ORDER BY m_date;