-
20-08-2019 - |
题
我要查询这个数据库得到的每一行,而且结果的列值的一个总和。我可以使用PHP来获得的总价值,但后来我需要运行两个循环,一个得到总的(这在结果上方的顶部行)。所以,我宁愿查询抓住它,只是做一个“总”行,但我得到了它的工作的唯一方法是使用一个子查询基本上是原始查询的重复。有没有更好的办法?
SELECT
CONCAT(u.firstname, ' ', u.lastname ) name, u.id, s.description, s.shiftstart, s.shiftend,
(SELECT
SUM( TIME_TO_SEC( TIMEDIFF( shiftend, shiftstart ) ) ) /3600
FROM shifts
WHERE id = '$user'
AND DATE( shiftstart )
BETWEEN '$start'
AND '$end') total
FROM shifts s
INNER JOIN users u ON ( s.id = u.id )
WHERE s.id = '$user'
AND DATE( shiftstart )
BETWEEN '$start'
AND '$end'
ORDER BY shiftstart
在上述工程和输出:
name id description shiftstart shiftend total
Joe User joeuser Stuff 2009-01-05 07:45:00 2009-01-05 12:15:00 39.5000
Joe User joeuser Stuff 2009-01-05 13:00:00 2009-01-05 17:00:00 39.5000
Joe User joeuser Stuff 2009-01-06 07:45:00 2009-01-06 10:45:00 39.5000
Joe User joeuser Stuff 2009-01-06 10:45:00 2009-01-06 12:45:00 39.5000
Joe User joeuser Stuff 2009-01-06 13:30:00 2009-01-06 14:30:00 39.5000
Joe User joeuser Stuff 2009-01-06 14:30:00 2009-01-06 17:00:00 39.5000
Joe User joeuser Stuff 2009-01-07 09:45:00 2009-01-07 14:00:00 39.5000
Joe User joeuser Stuff 2009-01-07 15:00:00 2009-01-07 17:00:00 39.5000
Joe User joeuser Stuff 2009-01-08 08:00:00 2009-01-08 12:15:00 39.5000
Joe User joeuser Stuff 2009-01-08 13:15:00 2009-01-08 17:00:00 39.5000
Joe User joeuser Stuff 2009-01-09 07:45:00 2009-01-09 10:45:00 39.5000
Joe User joeuser Stuff 2009-01-09 11:45:00 2009-01-09 15:15:00 39.5000
Joe User joeuser Stuff 2009-01-09 15:15:00 2009-01-09 17:00:00 39.5000
这就是我需要的,但可能不会得到它的最好方式。
解决方案
MySQL支持一个特殊的基团的改性剂由称为 ROLLUP 。
SELECT CONCAT(u.firstname, ' ', u.lastname ) name, u.id,
s.description, s.shiftstart, s.shiftend,
SUM( TIME_TO_SEC( TIMEDIFF( shiftend, shiftstart ) ) ) /3600 total
FROM shifts s INNER JOIN users u ON ( s.id = u.id )
WHERE s.id = ? AND DATE( shiftstart ) BETWEEN ? AND ?
GROUP BY u.id, s.shiftstart WITH ROLLUP
ORDER BY shiftstart;
其他提示
在更好的方法是用代码来做到这一点。人们一直坚持使用SQL,这是一个关系代数,做程序的职责。试图鞋拔子程序岬到SQL是总是一个坏主意,在复杂性和性能方面。从专业DBA借此建议。
运行在您的代码两个查询。输出设定较大的第一,然后在你想要的任何格式的总线。您的查询会更小,更简单,你的表现就会提高,你会得到你想要的输出。
其他的一些建议 - 磁盘空间很便宜,大多数数据库表中读取的次数远远多于他们写的。设置插入/更新触发器(如果可能的话在MySQL)来填充一个单独的列中包含“CONCAT(u.firstname,' ',u.lastname)
”计算字段,并用这些查询。每排功能不可扩展,并且当它变得更大会杀了你的DBMS的性能。
什么都可以通过比较好;问题是比较什么,对吧?
您指出问题的关键是,你在结果顶部总想; Crystal Reports和其他应用程序,通过成为2通发动机管理这种魔力。第一遍得到的总数。
有权衡与任何溶液。如果你得到一个单独的“总”行,则接收应用程序将需要或者剥离出来的结果,或者玩一些其他技巧来隐藏它。
一种可能性,如果你不写了1万重击/小时网站,这可能是一种选择,是简单地让2个电话 - 一个用于开销信息,如名称,总时间等,那么对于细节......它似乎从你选择一个人的结果的查询。
我们都是为节省开销和带宽,但有时候,越简单越好...
编辑:大同打我的 “保存” 按钮...笑...
使用用于此目的的确切提供的MySQL扩展,如在比尔Karwin的响应描述(我已经upvoted自己)。
如果这是不可用,选择2将是另一个SQL语句:SELECT SUM ...)SQL确实进行了优化,对这样的事情非常有效的,比起任何程序代码循环,你很可能会写。