2014-07-24 71 views
0

我想使用UNION來連接兩個SQL SELECT查詢。我需要最後的數據來使用HAVING子句來過濾整個查詢。這裏是我的發言:SQL UNION不能使用2 HAVING子句

SELECT CLIENT, 
     BIZNAME, 
     BIZSTREET, 
     BIZCITY, 
     BIZSTATE, 
     BIZZIP, 
     BIZPHONE, 
     URL, 
     LAT, 
     LNG, 
     CONSOLIDATED, 
     (3959 * ACOS(COS(RADIANS('%s')) * COS(RADIANS(LAT)) * COS( 
        RADIANS(LNG) - RADIANS('%s')) 
           + SIN 
           (RADIANS('%s')) * SIN(RADIANS(LAT)))) AS distance 
FROM BizInfo 
     INNER JOIN WebSites 
       ON WebSites.CUSTOMER = BizInfo.CUSTOMER 
WHERE BizInfo.CLIENT = 'GCB' 
     AND WebSites.STATUS <> 'Cancel' 
     AND WebSites.STATUS <> 'In Progress' 
     AND WebSites.STATUS <> 'Review' 
     AND WebSites.STATUS <> 'Testing' 
UNION 
SELECT CLIENT, 
     BIZNAME, 
     BIZSTREET, 
     BIZCITY, 
     BIZSTATE, 
     BIZZIP, 
     BIZPHONE, 
     'http://www.abc-site.com', 
     LAT, 
     LNG, 
     '0', 
     (3959 * ACOS(COS(RADIANS('%s')) * COS(RADIANS(LAT)) * COS( 
        RADIANS(LNG) - RADIANS('%s')) 
           + SIN 
           (RADIANS('%s')) * SIN(RADIANS(LAT)))) AS distance 
FROM BizInfo 
WHERE CLIENT = 'GCB' 
     AND BIZNAME = 'Acme' 
HAVING DISTANCE < '%s' 
ORDER BY DISTANCE 
LIMIT 0, 200 

我在這個網站閱讀http://www.really-fine.com/SQL_union.html(GROUP BY和HAVING子句只能在各個查詢中使用,不能用於影響最終結果集),但我不明白如何實現這個或者它是否正確。

如何正確編寫此SQL查詢?

+0

我結束了剛剛使用左外部連接而不是聯合,現在它的工作。雖然,我擔心它只是一個創可貼而不是乾淨的解決方案...... – Doran

回答

0

HAVING只能在具有GROUP BY子句的聚合查詢中使用。您的查詢不。改爲使用WHERE。

0
  1. 這些是標量函數,而不是聚合函數。因此,要篩選結果,請使用WHERE子句,而不是HAVING子句。您正在水平過濾,而不是垂直過濾。

  2. 您不能在WHERE子句中使用列別名,因此您必須重新聲明SELECT列表中使用的函數(我在下面的查詢中已經這樣做了)。

請嘗試以下操作。有兩個問題在發揮。

SELECT Client, 
     BizName, 
     BizStreet, 
     BizCity, 
     BizState, 
     BizZip, 
     BizPhone, 
     url, 
     lat, 
     lng, 
     Consolidated, 
     (3959 * acos(cos(radians('%s')) * cos(radians(lat)) * 
        cos(radians(lng) - radians('%s')) + 
        sin(radians('%s')) * sin(radians(lat)))) AS distance 
    FROM BizInfo 
INNER JOIN WebSites 
    ON WebSites.Customer = BizInfo.Customer 
WHERE BizInfo.Client = 'GCB' 
    AND WebSites.Status <> 'Cancel' 
    AND WebSites.Status <> 'In Progress' 
    AND WebSites.Status <> 'Review' 
    AND WebSites.Status <> 'Testing' 
UNION 
SELECT Client, 
     BizName, 
     BizStreet, 
     BizCity, 
     BizState, 
     BizZip, 
     BizPhone, 
     'http://www.abc-site.com', 
     lat, 
     lng, 
     '0', 
     (3959 * acos(cos(radians('%s')) * cos(radians(lat)) * 
        cos(radians(lng) - radians('%s')) + 
        sin(radians('%s')) * sin(radians(lat)))) AS distance 
    FROM BizInfo 
WHERE Client = 'GCB' 
    AND BizName = 'Acme' 
    and (3959 * acos(cos(radians('%s')) * cos(radians(lat)) * 
        cos(radians(lng) - radians('%s')) + 
        sin(radians('%s')) * sin(radians(lat)))) < '%s' 
ORDER BY distance LIMIT 0, 200 
0

你可以很容易地通過將所有東西包裝到子查詢中來解決這個問題。例如:

SELECT 
    * 
FROM 
    (
     SELECT Client, BizName, BizStreet, BizCity, BizState, BizZip, BizPhone, url, lat, lng, Consolidated, 
     (3959 * acos(cos(radians('%s')) * cos(radians(lat)) * cos(radians(lng) - radians('%s')) + sin(radians('%s')) * sin(radians(lat)))) 
     AS distance FROM BizInfo 
     INNER JOIN WebSites ON WebSites.Customer = BizInfo.Customer 
     WHERE BizInfo.Client = 'GCB' 
     AND WebSites.Status <> 'Cancel' AND WebSites.Status <> 'In Progress' AND WebSites.Status <> 'Review' AND WebSites.Status <> 'Testing' 
     UNION SELECT Client, BizName, BizStreet, BizCity, BizState, BizZip, BizPhone, 'http://www.abc-site.com', lat, lng, '0', 
     (3959 * acos(cos(radians('%s')) * cos(radians(lat)) * cos(radians(lng) - radians('%s')) + sin(radians('%s')) * sin(radians(lat)))) 
     AS distance FROM BizInfo WHERE Client = 'GCB' AND BizName = 'Acme' 
) AS ClientInfo 
WHERE 
    distance < '%s' 
ORDER BY 
    distance 
LIMIT 0 , 200 

這是你想要的最快的路徑,但它不是很乾淨。

也請告訴我,所有這些參數不容易SQL injection ......?