2010-09-29 63 views
3

我有一個簡單的發送報告的框架,基本上做以下的事情: 它執行SELECT查詢,它使基於結果的一些文本格式的表格它發送一封電子郵件,並執行UPDATE查詢。MySQL的:包括SELECT查詢的盤點結果爲一列(不分組)

該系統是一個較舊的一個,所有的行動是硬編碼的推廣。然而,在將所有我想要做的邏輯推入SELECT查詢中時,我遇到了一個問題。

之前,我可以說得到大部分的信息爲我的文字表:

SELECT Name, Address FROM Databas.Tabl WHERE Status='URGENT'; 

然後,當我需要的電子郵件額外的數量,也這樣做:

SELECT COUNT(*) FROM Databas.Tabl WHERE Status='URGENT' AND TimeLogged='Noon'; 

現在,我不再擁有多個SELECT查詢的好處了。我想要做的是一樣的東西:

SELECT Tabl.Name, Tabl.Address, COUNT(Results.UID) AS Totals 
FROM Databas.Tabl 
LEFT JOIN Databas.Tabl Results 
    ON Tabl.UID = Results.UID 
    AND Results.TimeLogged='Noon' 
WHERE Status='URGENT'; 

這一點,至少在我的頭上,說要拿到選擇,也有一些條件的所有行的總數。

在現實中,雖然,這給我的「1140 - 混合組列沒有GROUP列非法的,如果沒有GROUP BY」的錯誤。問題是,我不想GROUP BY。我希望COUNT冗餘地重複發現其TimeLogged ='Noon'的SELECT結果的數量。或者我想刪除AND子句並在SELECT語句的結果中包含該SELECT語句找到的結果的數量。

GROUP BY不是辦法,因爲這會導致它得到的只有誰在一些列的值相同的行數。而COUNT甚至可能不是這樣的方式,儘管這是想到的。 FOUND_ROWS()不會執行這個技巧,因爲它需要是輔助查詢的一部分,我只能得到一個(加上沒有LIMIT參與),而且由於它是SELECT語句,因此ROW_COUNT()似乎不起作用。

我可以從錯誤的角度完全可以接近它。但是我想要做的是在單個查詢中獲取有關SELECT查詢結果的COUNT類型信息,以及SELECT查詢返回的所有其他信息。

===這就是我這麼遠===

SELECT Tabl.Name, Tabl.Address, Results.Totals 
FROM Databas.Tabl 
LEFT JOIN (SELECT COUNT(*) AS Totals, 0 AS Bonus 
      FROM Databas.Tabl 
      WHERE TimeLogged='Noon' 
      GROUP BY NULL) Results 
    ON 0 = Results.Bonus 
WHERE Status='URGENT'; 

這確實使用子查詢,這是我最初希望避免的,但現在認識到,希望可能是愚蠢的。另外,由於COUNT條件全部在一個表上,COUNTING SELECT子查詢似乎比主查詢更便宜,但我正在使用的真正SELECT必須連接到多個不同的表以獲取派生信息。

關鍵的實現是我可以GROUP BY NULL,它將返回一個單一的結果,以便COUNT(*)實際上會捕獲所有內容,並且我可以強制與該列關聯,只需使用0在兩張桌子上。

它看起來這是我將要使用的解決方案,但我不能真正接受它作爲一個答案,直到明天。感謝所有的幫助。

回答

10
SELECT Tabl.Name, Tabl.Address, Results.Totals 
FROM Databas.Tabl 
LEFT JOIN (SELECT COUNT(*) AS Totals, 0 AS Bonus 
      FROM Databas.Tabl 
      WHERE TimeLogged='Noon' 
      GROUP BY NULL) Results 
    ON 0 = Results.Bonus 
WHERE Status='URGENT'; 

我想到了這一點,這要歸功於由多個答案產生的想法,儘管它實際上並不是任何一個的直接結果。爲什麼這樣做需要我在原文的編輯中解釋過,但我希望能夠通過正確的答案解決問題,以防其他人想要執行這種愚蠢的操作。感謝所有的幫助。

1

這是否做你所需要的?

SELECT Tabl.Name     , 
     Tabl.Address    , 
     COUNT(Results.UID) AS GrandTotal, 
     COUNT(CASE WHEN Results.TimeLogged='Noon' THEN 1 END) AS NoonTotal 
FROM  Databas.Tabl 
     LEFT JOIN Databas.Tabl Results 
     ON  Tabl.UID = Results.UID 
WHERE Status   ='URGENT' 
GROUP BY Tabl.Name, 
     Tabl.Address 
WITH ROLLUP; 
+0

不完全。我甚至沒有100%理解它的邏輯,但我跑它進行了一個快速測試,並計算出兩個截然不同的有用值。但是我基於SELECT查詢的結果進行計數。如果我將LIMIT 10添加到最後(並且忽略TimeLogged位),那麼我希望每行都包含一個10的GrandTotal。我想要的數字不是基於表中的某些內容,而是基於什麼我選擇了它,我不想做一個子查詢,因爲我可能需要多個不同的計數,而且會變得很難看。 – 2010-09-29 23:36:45

+0

@Hammer - 如果添加WITH WITH ROLLUP?會怎樣? – 2010-09-29 23:38:17

+0

將它添加到示例中似乎沒有改變我的結果,但WITH ROLLUP實際上可能是關鍵。如果我得到所有我想要的結果和一列僅計1(結果由唯一標識符分組),並且WITH ROLLUP可以讓他們計算結果的數量,那麼我的框架允許(實際上是強制)我得到最後一行的列值,當我想要一個單一的值,而不是他們的列表。給我幾個嘗試去適應 - 我對GROUPING和ROLLUP都有點新鮮感。 – 2010-09-29 23:54:18

0

您使用的是訪問數據庫的API應該能夠向您報告是如何返回多行 - 比方說,如果你正在運行的Perl,你可以做這樣的事情:

my $sth = $dbh->prepare("SELECT Name, Address FROM Databas.Tabl WHERE Status='URGENT'"); 
my $rv = $sth->execute(); 
my $rows = $sth->rows; 
+0

我不認爲這是他的問題。他需要運行兩個查詢並將它們返回到一個結果集中。 – 2010-09-29 23:25:33

+0

我實際上並沒有使用API​​ - 只是定期掃描目錄中的.properties文件,這些文件指定了SELECT查詢,表格格式信息,電子郵件格式信息和UPDATE查詢。如果我想要一個包含所有名稱的表,我可以在該行上放置$ {Name},並從ResultSet中選擇「Name」。但是,這隻能從一個SELECT查詢中獲得信息,所以我試圖找到一種方法來處理這個不尋常的COUNT信息到單個SELECT語句,因此我可以爲電子郵件主題獲取$ {ResultCount}。 – 2010-09-29 23:45:11

2

你或許可以做一個聯合。您必須將一列添加到原始查詢中,然後在其中選擇0,然後使用您的第二個查詢返回單個列的UNION。要做到這一點,第二個查詢也必須選擇空字段來匹配第一個。

SELECT Cnt = 0, Name, Address FROM Databas.Tabl WHERE Status='URGENT' 
UNION ALL 
SELECT COUNT(*) as Cnt, Name='', Address='' FROM Databas.Tabl WHERE Status='URGENT' AND TimeLogged='Noon'; 

這是一個黑客位,但你正在試圖做的是不理想......

+1

他試圖做的事很可怕,錯誤,但UNION是做錯事的非常好的工具。它可以將任何數據粘貼在一起,只要它是正確的形狀;它並不關心語義。 – 2010-09-30 00:01:05

+0

這似乎並不奏效(它給出了一個有關在'字段列表'中找不到'Cnt'的錯誤),但它看起來像第二個SELECT也會給出關於具有GROUP BY函數(COUNT)的錯誤與非GROUP列一起。在輸入回覆時,我意識到我可以使用GROUP BY NULL,這對我的事業確實非常有幫助。我想我可以通過嵌套SELECT中的LEFT JOIN得到一些結果,這些結果會爲每個計數重複一次查詢,但這可能是必要的,並且回顧我必須計算的事情從不像主查詢那麼複雜。 – 2010-09-30 00:53:37

+1

@Hammer Bro:嘗試在Phil的查詢中將'Cnt = 0'更改爲'0 Cnt'。 – 2010-09-30 13:20:47

0

分組由Tabl.id我不相信會弄亂結果。嘗試一下,看看你是否想要什麼。

+0

這就是我第一次嘗試,但是這將返回一個結果行與單個Tabl行相匹配的計數,給我一堆1。我想要的是每個Tabl行都具有所有不同結果行的全部計數,試圖讓SQL通過使用自聯接來計算SELECT查詢返回的行數。我懷疑這是獲取這些信息的最好方法,但這是我能想到的最好的方法,單SELECT查詢限制有點不同尋常。 – 2010-09-29 23:48:22