簡體   English   中英

MySQL添加總列

[英]MySQL add total column

我需要查詢此DB以獲取每一行,還要查詢結果的一個列值的SUM。 我可以使用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通道引擎來管理這種魔力。 第一遍獲得總數。

任何解決方案都需要權衡利弊。 如果你得到一個單獨的“總”行,那么接收應用程序將需要將其從結果中刪除或者播放其他技巧來隱藏它。

一種可能性,如果你不是為一個100萬次點擊/小時的網站寫作,可能是一個選項,就是簡單地進行2次調用 - 一次用於開銷信息,例如名稱,TOTAL Time等,然后用於詳細信息...從查詢中可以看出您正在選擇單個人的結果。

我們都是為了節省開銷和帶寬,但有時候,簡單就更好......

編輯:Pax打敗了我的“保存”按鈕......哈哈...

使用為此目的提供的mysql擴展,如Bill Karwin的回復(我自己贊成)中所述。

如果這不可用,則選項2將是另一個SQL語句:SELECT SUM ...)與您可能編寫的任何過程代碼循環相比,SQL確實被優化為對此類事物非常有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM