HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2017
0824
イナウサsqlについて12解決


イナウサ

リンク

2017/8/24(Thu) 00:30:02|NO.81080

一度、解決としたのですが、詰まづいてしまいもう一度新規として質問させていだきました。
前回の質問でstrongestさんが提示していただきました、スクリプトにあった変数Aにもっとも近い
カラムBを検索するところ↓

sql_q "SELECT B,C FROM data_bace ORDER BY abs(B-"+A+") ASC LIMIT 1"
これの変数Aが負の数だった場合でも対応できるようにするにはどうしたらいいですか?
負の数のまま実行(変数A=-10)すると B--10となりおそらく"-"が二重なることがエラーの元凶かと思います。



この記事に返信する


tds12

リンク

2017/8/24(Thu) 01:09:04|NO.81083

よくわかりませんがこのようではだめなのです?
「"abs(B" + (-A) + ")"」



strongest

リンク

2017/8/24(Thu) 07:39:36|NO.81086

Aがマイナス値も取りうるのであれば、

abs(B-("+A+"))

と括弧で囲んでやりましょう。



さか

リンク

2017/8/24(Thu) 22:02:27|NO.81093

「ORDER BY 」は並び替えを行う命令なので通常はカラム名を記述するのですが
「ORDER BY abs(B-10)」はどういう意味なのでしょうか。

カラムの代わりに数字Nとすれば、N番目のカラムということにはなるので上記
の場合だとテーブル内の0より大きいカラム数以下なら動くとは思いますが。



イナウサ

リンク

2017/8/25(Fri) 00:10:45|NO.81095

ちなみにこれで、変数Aが負の数であっても同じように変数Aに最も近いカラムBが摘出されますか?



イナウサ

リンク

2017/8/25(Fri) 13:25:42|NO.81100

わかりにくくてすみません。質問の仕方を変えます。

#include "sqlele.hsp" //sqleleモジュール ; データベースファイル「sample.db」を開く (ファイルが無ければ作成されます) sql_open "data_bace.db" ;「data_base」テーブルを作成 (すでにテーブルがあれば作成されません) sql_q "drop table if exists data_bace" ; [カラムB,C] カラムを作成 (すでにカラムがあれば作成されません) sql_q "CREATE TABLE IF NOT EXISTS data_bace (ID INTEGER PRIMARY KEY AUTOINCREMENT, B)" repeat A=rnd(100) sql_q "INSERT INTO data_bace(B) VALUES("+A+")" sql_q "SELECT B FROM data_bace ORDER BY abs("+B+"-("+A+")) ASC LIMIT 1" B =int(sql_v("B")) title ""+B+":"+A+"" await 20 loop
これを実行すると必ずBとAの値は同じになるはずですよね?それとも違う値になりますか?



strongest

リンク

2017/8/25(Fri) 18:03:50|NO.81102

ORDER BY句には、カラム名以外にも式を記述できます。
tksqliteなどで実際に生成されたテーブルを開き、問題のSQL文をLIMIT句なしで実行すると、
正しく動作していることがわかります。

詳しくは、SQLiteの公式サイトのドキュメントを参照ください。
https://www.sqlite.org/lang_select.html



strongest

リンク

2017/8/25(Fri) 18:29:18|NO.81103

それと、イナウサさんの新しいソースは、何を意図しての質問なのかが判りかねます。
前回のソースを引用・改修しますが、

#include "sqlele.hsp" ; データベースファイル「sample.db」を開く (ファイルが無ければ作成されます) sql_open "data_bace.db" ;「MemoTable」テーブルを作成 (すでにテーブルがあれば作成されません) sql_q "drop table if exists data_bace" sql_q "CREATE TABLE IF NOT EXISTS data_bace (ID INTEGER PRIMARY KEY AUTOINCREMENT, B, C)" sql_q "begin" repeat 1000 sql_q "insert into data_bace(B,C) values("+str(rnd(256)-128)+","+str(rnd(256)-128)+")" loop sql_q "commit" A=-100 sql_q "SELECT B,C FROM data_bace ORDER BY abs(B-("+A+")) ASC LIMIT 1" cls 4:pos 0,0:color 255,255,255:mes "B = " + sql_v("B") + " / C = " + sql_v("C")+""

マイナス値も含んだテーブルを作成し、上で述べたように括弧で囲ったものです。
このソースを実行後、生成されたデータファイルを tksqlite で開き、中にあるdata_baceに
対し上記ソース中のSQL文である

SELECT B,C FROM data_bace ORDER BY abs(B-(-15)) ASC

を実行すれば、Aがマイナス値の場合でもテーブルが正しくソートされ、
LIMIT句を用いればその先頭の1行が取得できることがわかると思います。

HSPのスクリプトエディタだけでは、SQLを理解するのは大変です。
tksqlite などのSQLite向けエディタを利用されることをお勧めいたします。



strongest

リンク

2017/8/25(Fri) 18:31:20|NO.81104

上記内容を一部訂正。

Aが-100ですので、tksqliteで実行すべきコードは

SELECT B,C FROM data_bace ORDER BY abs(B-(-100)) ASC
ですね。失礼いたしました。



strongest

リンク

2017/8/25(Fri) 18:35:01|NO.81105

もうひとつ追記。

ORDER句に式が書けるというのがいまいちわからないのであれば、
上記ソースで生成されたテーブルに tksqlite などで以下のSQL文を実行してみてください。

SELECT *, abs(B-(-100)) FROM data_bace ORDER BY abs(B-(-100)) ASC



イナウサ

リンク

2017/8/25(Fri) 23:47:38|NO.81106

たくさんの回答有難うございました。解決とさせていただきます。今後ともお願いします。



さか

リンク

2017/8/26(Sat) 02:38:58|NO.81109

解決済ということですが前の投稿の以下のSQLをみてstrongestさんのやりたいことがわかりました。
sql_q "SELECT [C] , [B] FROM [data_bace] WHERE abs([B] - " + A + ")= (SELECT min(abs([B] - " + A + ")) FROM [data_baceX]) ORDER BY [B] ;"

動作としては以下と同じということですね。
SELECT A, abs(B-(-100)) AS ABS FROM data_bace ORDER BY ABS
または
SELECT A, abs(B-(-100)) FROM data_bace ORDER BY 2

しかし元々のイナウサさんの質問である,data_baceテーブルとdata_baceXテーブルを使用
してますのでdata_baceXを無視して単純にdata_baceのみにはならないのではないでしょうか。
とは言えなにをしたいのかわからないSQLなのでそれぞれのテーブルのデータをEXCEL等に表と
して整理しどういう場合のC,Bを抽出するのかまずは整理した方が良いと思います。



strongest

リンク

2017/8/26(Sat) 15:46:10|NO.81114

元々のソースでは、data_baceX はソース中のどこにも生成の記述がないので、
サブクエリのつもりで記述したのだろうかと考えましたがそうでもなさそうだと。
ですので、純粋にSQL構文の勉強不足だと判断し、大元の質問文の

 data_baceとういテーブルにID,B,Cというカラムがあります。
 そこから変数Aに最も近い数[カラムB]の値とそれの[カラムC]の値を抽出し「B= / C= 」
 のような感じで表示したい。

に絞って解釈しました。

ORDER BY句の構文についてですが、ちょっと気になったので。
以下の´△SQL文は、動作が異なります。

  SELECT * FROM temp ORDER BY 3  ◆SELECT * FROM temp ORDER BY 6-3

先に紹介したSQLiteの解説ページにもありますが、ORDER BY句の指定が定数の場合は、
カラムの順番に従い指定されたカラムを基準にソート。上の例だと、tempテーブル中の
3番目のカラムを基準にソートします。

式の場合は、それを解釈した新カラムを基準にソートします。AS句でエイリアスを
つけない場合は、式そのものがカラム名だと解釈されます。
ただし上の例だと、「6-3」というカラムが作られますが計算結果は常に3ですから
全ての行の評価が3になるだけ、実際にはtempテーブルにinsertした順そのままが
出力されることになります。

この式に、行ごとに値が異なる状態のカラム名を加えることで、各行の結果が変化し、
それを元にソートが行われるというわけです。

くどくなりますので、わたしもここまで。



ONION software Copyright 1997-2021(c) All rights reserved.