質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

3270閲覧

PHPの中でSQL文を書いて緯度経度から指定半径内の住所の一覧を得る方法

igaiga

総合スコア144

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2017/03/30 08:55

編集2017/03/31 04:22

###前提・実現したいこと
PHPの中でSQL文を書いて緯度経度から指定半径内の住所の一覧を得たいと思います。
ベースのSQL文では正常に値を取得できましたが、
下記を参考に指定半径内の住所で絞り込もうとするとうまくできませんでした。
恐れ入りますが、アドバイス頂ければ幸いです。
https://www.firstlogic.co.jp/blog/lab/raku/71

WordPressを使用していますが、今回はあまり関係ないかと思いますので端折ります。

###ベースのSQL文

$result = $wpdb->get_results(" SELECT post_title, id, m1.meta_value AS '_lat', m2.meta_value AS '_lnt', m3.meta_value AS 'googlemap' FROM $wpdb->posts INNER JOIN $wpdb->postmeta AS m1 ON m1.post_id = $wpdb->posts.ID /* テーブルを結合-カスタムフィールド */ INNER JOIN $wpdb->postmeta AS m2 ON m2.post_id = $wpdb->posts.ID /* テーブルを結合-カスタムフィールド */ INNER JOIN $wpdb->postmeta AS m3 ON m3.post_id = $wpdb->posts.ID /* テーブルを結合-カスタムフィールド */ WHERE post_type = 'areainfo' AND post_status = 'publish' /* かつ公開済の記事 */ AND m1.meta_key = '_lat' AND m2.meta_key = '_lnt' AND m3.meta_key = 'googlemap' ORDER BY post_date DESC LIMIT 5 ");

上記の出力結果はこんな感じです。

Array ( [0] => stdClass Object ( [post_title] => ソフィアタワー勝どき [id] => 562 [_lat] => 35.6584463 [_lnt] => 139.7735894 [googlemap] => a:3:{s:7:"address";s:41:"東京都中央区勝どき3丁目12-12";s:3:"lat";s:10:"35.6584463";s:3:"lng";s:11:"139.7735894";} ) [1] => stdClass Object ( [post_title] => クレストレジデンス [id] => 561 [_lat] => 35.6571881 [_lnt] => 139.7719590 [googlemap] => a:3:{s:7:"address";s:41:"東京都中央区勝どき5丁目5-14 ";s:3:"lat";s:10:"35.6571881";s:3:"lng";s:18:"139.77195900000004";} ) )

###試したSQL文:追記版

$areainfo_lat = "35.6746700"; $areainfo_lnt = "139.7885380"; $result = $wpdb->get_results(" SELECT post_title, id, m1.meta_value AS '_lat', m2.meta_value AS '_lnt', m3.meta_value AS 'googlemap' ,(6371 * ACOS( COS(RADIANS($areainfo_lat)) * COS(RADIANS(m1.meta_value)) * COS(RADIANS(m2.meta_value) - RADIANS($areainfo_lnt)) + SIN(RADIANS($areainfo_lat)) * SIN(RADIANS(m1.meta_value)) )) AS distance FROM $wpdb->posts INNER JOIN $wpdb->postmeta AS m1 ON m1.post_id = $wpdb->posts.ID /* テーブルを結合-カスタムフィールド */ INNER JOIN $wpdb->postmeta AS m2 ON m2.post_id = $wpdb->posts.ID /* テーブルを結合-カスタムフィールド */ INNER JOIN $wpdb->postmeta AS m3 ON m3.post_id = $wpdb->posts.ID /* テーブルを結合-カスタムフィールド */ WHERE post_type = 'areainfo' AND post_status = 'publish' /* かつ公開済の記事 */ AND m1.meta_key = '_lat' AND m2.meta_key = '_lnt' AND m3.meta_key = 'googlemap' HAVING distance ORDER BY distance LIMIT 5 ");

上記の出力結果はこんな感じです。
Array ( [0] => stdClass Object ( [post_title] => ソフィアタワー勝どき [id] => 562 [_lat] => 35.6584463 [_lnt] => 139.7735894 [googlemap] => a:3:{s:7:"address";s:41:"東京都中央区勝どき3丁目12-12";s:3:"lat";s:10:"35.6584463";s:3:"lng";s:11:"139.7735894";} [distance] => 2.2534462617295463 ) [1] => stdClass Object ( [post_title] => クレストレジデンス [id] => 561 [_lat] => 35.6571881 [_lnt] => 139.7719590 [googlemap] => a:3:{s:7:"address";s:41:"東京都中央区勝どき5丁目5-14 ";s:3:"lat";s:10:"35.6571881";s:3:"lng";s:18:"139.77195900000004";} [distance] => 2.453954933727737 ) )

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/03/30 10:53

MySQLには空間関数群があるので、緯度経度を元にした距離での絞込に使えそうな気がしますが、ダメなんでしょうか。参考例→ http://qiita.com/mitani/items/6909406ac4fe0db2d35c
igaiga

2017/03/30 12:08

ありがとうございます!拝見しましたが、データ登録はWordPressを使用するので「POINT」というデータ形式で保存できなそうに思ったのですがどうでしょうか?
CHERRY

2017/03/31 00:54 編集

distance の計算かなとも思いますが、HAVING distance <= 5.0 を外したら、結果は返ってくるのでしょうか? 返ってきた結果を追記してもらえないでしょうか。
igaiga

2017/03/31 03:21

CHERRYさんありがとうございます。値は帰ってきませんでした;;
igaiga

2017/03/31 03:38

すみません。 * COS(RADIANS(_lat)) を* COS(RADIANS(m1.meta_value))、* COS(RADIANS(_lnt)を* COS(RADIANS(m2.meta_value)に直したら値が取れましたので追記しました。
igaiga

2017/03/31 03:40

距離的には200~300mあたりのはずですが、2km以上あることになってますね。。。やっぱり計算がおかしいのかな。
ikedas

2017/03/31 05:02

HAVING句を元に戻してもだめですか?
igaiga

2017/03/31 06:24

できました。ありがとうございました!$areainfo_latと$areainfo_lntの座標が違うだけでした^^;
guest

回答1

0

自己解決

皆さんにアドバイスいただきながら完成させることができました。ありがとうございました!

$areainfo_lat = "35.6746700"; $areainfo_lnt = "139.7885380"; $result = $wpdb->get_results(" SELECT post_title, id, m1.meta_value AS '_lat', m2.meta_value AS '_lnt', m3.meta_value AS 'googlemap' ,(6371 * ACOS( COS(RADIANS($areainfo_lat)) * COS(RADIANS(m1.meta_value)) * COS(RADIANS(m2.meta_value) - RADIANS($areainfo_lnt)) + SIN(RADIANS($areainfo_lat)) * SIN(RADIANS(m1.meta_value)) )) AS distance FROM $wpdb->posts INNER JOIN $wpdb->postmeta AS m1 ON m1.post_id = $wpdb->posts.ID /* テーブルを結合-カスタムフィールド */ INNER JOIN $wpdb->postmeta AS m2 ON m2.post_id = $wpdb->posts.ID /* テーブルを結合-カスタムフィールド */ INNER JOIN $wpdb->postmeta AS m3 ON m3.post_id = $wpdb->posts.ID /* テーブルを結合-カスタムフィールド */ WHERE post_type = 'areainfo' AND post_status = 'publish' /* かつ公開済の記事 */ AND m1.meta_key = '_lat' AND m2.meta_key = '_lnt' AND m3.meta_key = 'googlemap' HAVING distance <= 0.5 ORDER BY distance LIMIT 5 "); print_r($result);

投稿2017/03/31 06:27

igaiga

総合スコア144

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問