2016-05-31 5 views
2

私は候補とcandidate_locationの2つのテーブルを持っています。 candidate_locationテーブルは、typeフィールドに応じて、他の3つのテーブルのいずれかからマップ座標を取得します。その結果、エイリアスはlatlngです。これは、距離のあるIF文の後にクエリーの部分で使用する必要があります。距離計算にエイリアスを使用する

距離計算の部分に「lat」や「lng」の列が見つからないというエラーが表示されています。エイリアスであるためです。どのように私は計算で認識されるようにこれを再構成することができますか?あなたがそれらを使っている同じクエリで別名を定義している

SELECT candidate.CandID, 
    IF (candidate_location.type = 1, p.latitude, IF (candidate_location.type = 2, a.latitude, pr.latitude)) AS lat, 
    IF (candidate_location.type = 1, p.longitude, IF (candidate_location.type = 2, a.longitude, pr.longitude)) AS lng, 
    IF (candidate_location.type = 2, a.standard_deviation,null) as standard_deviation, 
    (3959 * acos(cos(radians(51.41019)) * cos(radians(lat)) 
    * cos(radians(lng) - radians(0.07222)) + sin(radians(51.41019)) 
    * sin(radians(lat)))) AS distance 

    FROM candidate_location 

    LEFT JOIN geo_postcodes AS p ON (candidate_location.type = 1 AND candidate_location.postal_id = p.id) 
    LEFT JOIN geo_area_averages AS a ON (candidate_location.type = 2 AND candidate_location.postal_id = a.id) 
    LEFT JOIN geo_probability AS pr ON (candidate_location.type = 3 AND candidate_location.postal_id = pr.id) 
LEFT JOIN candidate ON candidate_location.candid=candidate.CandID 

答えて

3

、あなたは計算にフィールドとして直接結果列名を使用することはできません。代わりにMySql変数を使用しない限り、再度書き直す必要があります。彼らはインラインプログラミングのように動作します。変数値を設定し、それを使用しますが、問題の列名としてその値を保持することはできます。

SELECT 
     candidate.CandID, 
     @varLat := COALESCE(p.latitude, a.latitude, pr.latitude) AS lat, 
     @varLong := COALESCE(p.longitude, a.longitude, pr.longitude) AS lng, 
     COALESCE(a.standard_deviation, null) as standard_deviation, 
     (3959 * acos(cos(radians(51.41019)) * cos(radians(@varLat)) 
     * cos(radians(@varLat) - radians(0.07222)) + sin(radians(51.41019)) 
     * sin(radians(@varLong)))) AS distance 
    FROM 
     (select @varLat := 0.00, @varLong := 0.00) sqlvars, 
     candidate_location CanLoc 
     LEFT JOIN geo_postcodes AS p 
      ON (CanLoc.type = 1 AND CanLoc.postal_id = p.id) 
     LEFT JOIN geo_area_averages AS a 
      ON (CanLoc.type = 2 AND CanLoc.postal_id = a.id) 
     LEFT JOIN geo_probability AS pr 
      ON (CanLoc.type = 3 AND CanLoc.postal_id = pr.id) 
     LEFT JOIN candidate 
      ON CanLoc.candid=candidate.CandID 

また、ネストされたIF()ブロックの代わりにCOALESCE()を使用しています。最初のNULL以外の値が返されるため、ジョインはタイプ1,2または3に基づいているため、その行のみが修飾する値を持ちます。

+0

@dlofrodloh、私はLat参照の1つを見逃しました...リビジョンを確認してください。 – DRapp

+0

この回答をお寄せいただきありがとうございます。私はこれまでにこの方法を使用していませんでした。それは非常に有用であることが証明されました。また、他の有効なソリューション – dlofrodloh

2

は、ここでのクエリです。次のようにサブクエリから緯度とLNGを使用できるようにメインクエリの外距離句を取って試してみてください:

のAshwinが述べたように
Select tTable.*, (3959 * acos(cos(radians(51.41019)) * cos(radians(lat)) 
* cos(radians(lng) - radians(0.07222)) + sin(radians(51.41019)) 
* sin(radians(lat)))) AS distance 
from (
SELECT candidate.CandID, 
IF (candidate_location.type = 1, p.latitude, IF (candidate_location.type = 2, a.latitude, pr.latitude)) AS lat, 
IF (candidate_location.type = 1, p.longitude, IF (candidate_location.type = 2, a.longitude, pr.longitude)) AS lng 
IF (candidate_location.type = 2, a.standard_deviation,null) as standard_deviation 

FROM candidate_location 

LEFT JOIN geo_postcodes AS p ON (candidate_location.type = 1 AND candidate_location.postal_id = p.id) 
LEFT JOIN geo_area_averages AS a ON (candidate_location.type = 2 AND candidate_location.postal_id = a.id) 
LEFT JOIN geo_probability AS pr ON (candidate_location.type = 3 AND candidate_location.postal_id = pr.id) 
LEFT JOIN candidate ON candidate_location.candid=candidate.CandID) tTable 
+0

ありがとう、この方法もうまくいきますが、他の答えは実行時間がずっと速いので、私はその1つを選択しました – dlofrodloh

+0

それは本当です。それはより良い解決策です。 – Ash