2010-04-20 74 views
4
SELECT AVG(`col5`) 
    FROM `table1` 
    WHERE `id` NOT IN (
     SELECT `id` FROM `table2` 
     WHERE `col4` = 5 
    ) 
    group by `col2` having sum(`col3`) > 0 
UNION 
    SELECT MAX(`col5`) 
    FROM `table1` 
    WHERE `id` NOT IN (
     SELECT `id` FROM `table2` 
     WHERE `col4` = 5 
    ) 
    group by `col2` having sum(`col3`) = 0 

出於可讀性和性能的原因,我認爲這個代碼可以重構。但是如何?如何重構這個MySQL代碼?

EDITIONS

  1. 除去外選擇

  2. 作出的第一選擇返回的總和,而第二個返回另一個值

  3. 取代SUM通過AVG

+0

我很困惑,因爲你有'GROUP BY',但沒有'SELECT'中的聚合列。你回來什麼專欄? – 2010-04-20 19:43:34

+0

@馬庫斯我糾正了這個例子,以反映爲什麼有一個工會的真正原因 – 2010-04-20 20:26:13

+0

你不需要'UNION'。考慮使用「IF」功能。看到我的答案在下面更新。 – codeholic 2010-04-21 22:03:17

回答

4
SELECT * 
FROM table1 t1 
left outer join table2 t2 on t1.id = t2.id and t2.col4 = 5 
where t2.id is null 
group by t1.col2 
having sum(col3) >= 0 

外部選擇缺少FROM子句並且沒有添加任何內容,因此我將其刪除。與LEFT OUTER JOIN方法相比,NOT IN效率低下,因此我將其替換。通過使用>=,兩個UNION很容易組合成一個。

更新: 注意使用UNION ALL而非UNION。我不想認爲你想刪除重複項,並且它會以這種方式更快地執行。

SELECT AVG(t1.col5) 
FROM table1 t1 
left outer join table2 t2 on t1.id = t2.id and t2.col4 = 5 
where t2.id is null 
group by t1.col2 
having sum(t1.col3) > 0 
UNION ALL 
SELECT MAX(t1.col5) 
FROM table1 t1 
left outer join table2 t2 on t1.id = t2.id and t2.col4 = 5 
where t2.id is null 
group by t1.col2 
having sum(t1.col3) = 0 
+0

感謝您的建議:我刪除了外部選擇,我可以使用'left outer join'建議,但是我無法合併'UNION',因爲代碼與我先寫的代碼略有不同。我重寫了這個問題,以說明爲什麼很難將這兩個陳述結合起來。 – 2010-04-20 20:29:06

+0

好的,沒問題。我會稍後發佈解決方案。 – RedFilter 2010-04-20 20:30:09

+0

你是對的,SUM和MAX混合不好。我使用的實際操作是AVG和MAX。我編輯了這個問題來反映這一點。 – 2010-04-20 20:40:58

1
SELECT t1.* FROM table1 t1 LEFT OUTER JOIN table2 t2 ON t1.id = t2.id 
WHERE t2.col4 <> 5 AND SUM(t1.col3) > 0 GROUP BY t1.col2 
+0

真實代碼與我最初寫的代碼略有不同。我重寫了這個問題,以說明爲什麼很難將這兩個陳述結合起來。 – 2010-04-20 20:33:53

0

我猜,你想這樣的:

SELECT * FROM `table` 
WHERE col2 IN 
(SELECT col2 
    FROM `table1` 
    WHERE `id` NOT IN ( 
     SELECT `id` FROM `table2` 
     WHERE `col4` = 5 
    ) 
    group by `col2` having sum(`col3`) >= 0 
) 

使用GROUP BY,你應該只返回屬於GROUP BY子句中指定或包括聚合函數列。因此,這裏的內部SELECT獲得col2值,其中總和大於或等於零,然後外部SELECT抓取這些值的整個行。

0
SELECT 
    IF(SUM(`table1`.`col3`) > 0, AVG(`table1`.`col5`), MAX(`table1`.`col5`)) 
FROM `table1` 
    LEFT JOIN `table2` ON `table2`.`id` = `table1`.`id` AND `table2`.`col4` = 5 
WHERE `table2`.`id` IS NULL 
GROUP BY `table1`.`col2` 
HAVING SUM(`table1`.`col3`) >= 0 

另外*被認爲是有害的。如果您想使查詢向前兼容未來對數據庫模型的可能更改,請按名稱指定列。

+0

真實的代碼與我最初寫的代碼略有不同。我重寫了這個問題,以說明爲什麼很難將這兩個陳述結合起來 – 2010-04-20 20:37:40