0

プロジェクト用に少し複雑なクエリを作成しています。以下に示すような 2 つのテーブル test, test_Av

テスト:

 CREATE table test(id int not null, title varchar(50), place
     varchar(20), postcode varchar(20), primary key(id));

          INSERT INTO test VALUES(1,'test','','91982'); 
          INSERT INTO test VALUES(2,'test','','91982'); 
          INSERT INTO test VALUES(3,'test','','91982'); 
          INSERT INTO test VALUES(4,'test','','91982'); 
          INSERT INTO test VALUES(5,'test','','91982');

Test_AV

    CREATE table test_AV(id int not null, testid int, name varchar(25),
     stringvalue varchar(25) ,primary key(id));

INSERT INTO test_AV VALUES(1,1,'latitude','16.15074'); 
INSERT INTO test_AV VALUES(2,1,'longitude', '-22.74426'); 
INSERT INTO test_AV VALUES(3,2,'latitude','16.13725'); 
INSERT INTO test_AV VALUES(4,2,'longitude', '-22.85822'); 
INSERT INTO test_AV VALUES(5,3,'latitude','14.85633'); 
INSERT INTO test_AV VALUES(6,3,'longitude', '-24.72379'); 
INSERT INTO test_AV VALUES(7,4,'latitude','14.86949'); 
INSERT INTO test_AV VALUES(8,4,'longitude', '-24.70150'); 
INSERT INTO test_AV VALUES(9,5,'latitude','15.03118'); 
INSERT INTO test_AV VALUES(10,5,'longitude', '-24.32523');

test_AV テーブルの testid は外部キーです

これを達成するには、指定された「緯度」と「経度」から半径 100 km の結果を見つける必要があります。クエリを次のように書きました。

select * from (   SELECT id, 
     title, 
     ((ACOS(
           SIN(16.15074 * 3.141592653 / 180) 
           * SIN((SELECT stringvalue from test_AV WHERE name='latitude')
           * 3.141592653 / 180) 
           + COS(16.15074 * 3.141592653 / 180) 
           * COS((SELECT stringvalue from test_AV WHERE name='latitude') 
           * 3.141592653 / 180)
           * COS((-22.74426 - (SELECT stringvalue from test_AV WHERE name='longitude'))
           * 3.141592653 /180))*6373))    AS distance   FROM
 test ) t where distance <= 100

サブクエリ内のサブクエリの代わりに、test_AV テーブルにあるすべての緯度と経度の値が必要です。これを書いたとき、サブクエリはサブクエリが複数の行を返すと言っています

これどうやってするの?

4

1 に答える 1

1

wildplasser が正しく述べたように、サブクエリをメイン クエリと関連付ける必要があります。以下で機能するクエリを参照してください。WHERE av.testid = ts.idサブクエリの節に注意してください。

select * from (   SELECT id,  
 title,  
 ((ACOS( 
       SIN(16.15074 * 3.141592653 / 180)  
       * SIN((SELECT stringvalue from test_AV av WHERE av.testid = ts.id and name='latitude')  
       * 3.141592653 / 180)  
       + COS(16.15074 * 3.141592653 / 180)  
       * COS((SELECT stringvalue from test_AV av WHERE av.testid = ts.id and name='latitude')  
       * 3.141592653 / 180)  
       * COS((-22.74426 - (SELECT stringvalue from test_AV av WHERE av.testid = ts.id and name='longitude'))  
       * 3.141592653 /180))*6373))    AS distance   FROM  
test ts ) t where distance <= 100

それはあなたのクエリを修正することでした。しかし、Oracle の行を列にピボットする手法があります。経度と緯度の行が 1 つの行で testid に関連付けられているデータセットを取得できます。

select testid,
max(decode(name, 'longitude', to_number(stringvalue), NULL)) longitude,  
max(decode(name, 'latitude', to_number(stringvalue), NULL)) latitude  
from test_AV  
group by testid

このテーブルを test で結合するだけです。

于 2012-10-09T06:38:28.300 に答える