• 締切済み

SQL,値の大きい順に値を取得

質問させて頂きます。 DB:PostgresSQL 言語:PHP 現在仕事情報の入ったテーブルから、金額の高い順にデータを10件取り出したいと考えています。 金額の入ったカラムが1つであれば、order by句で取り出すのですが、今回、時給[hour]、月給[month]、年収[year]と3つのカラムが存在しています。 ※下記のid4のように2つ以上の金額情報カラムを持っているデータも存在します。 ※データの中にはnullでなく0が入っているデータも存在します。 [id][hour][month][year] 1 ,1000 ,null ,null 2 ,1200 ,0 ,0 3 ,null ,300000 ,null 4 ,1500 ,200000 ,null 5 ,null ,null ,3200000 ... 100,null ,250000 ,null 質問の内容なのですが、下記のルールに従いデータを取得する際、どのような方法を行えば一番効率的でしょうか。 「ルール」 1. 金額比較の際、 月給はそのまま、 年収は12で割った金額、 時給に関しては、時給×8(1日の平均的労働時間)×20(1月の平均的な労働日数)の金額とします。 2. 2つ以上のカラムに金額を持っていた際は(id4のようなデータ)、金額の大きさに関わらず、年収>月給>時給の順で取得する。 id4のデータならば、時給の方が月給より高いですが、月給のデータを使用します。年収があれば年収優先。 id2の場合、0はnullと同じ扱いと考え、時給のデータを使用します。 このルールをふまえたうえでデータを取得する際、SQLで全データを取得して、PHPで高い順を判定するべきか、SQLで取得する時点である程度絞って取得した方が良いのか・・・。 SQLに関しての知識が乏しいため、効率的な方法をご存知の方はアドバイス頂けると大変助かります。 よろしくお願いします。

みんなの回答

回答No.2

未テストですが、以下のような感じはどうでしょう? select case when year >= month then year else (case when month >= hour then month else hour end ) end as money from (select COALESCE(year,0) / 12 as year , COALESCE(month,0) as month , COALESCE(hour,0) * 8 * 20 as hour from table ) order by money desc

回答No.1

ムリ。というか、NULLと0の扱いが一緒なら NULLがなければいいと思うんですが。 NULLがあるせいで凄いごりごりしないと いけないですね。 結論的に、どうしてもNULLが必要ならNULLは 見直さなくてもいいけど、DB設計を見直すのが 早いでしょう。 データが登録されるタイミングで、ソート用の 列があれば楽です。 算数、NULLを0に置換済みの列を設けて、それを インデックスにしてソートすればいいです。 考えるのがめんどいので、今の設計上での 実現方法は他の方におまかせです。

関連するQ&A

  • SQL

    テーブル情報 id start_dt end_dt --+----------+---------- 1 2014-01-07 2014-01-20 2 2014-01-08 Null 3 2014-01-09 Null 4 2014-01-10 Null 5 2014-01-11 Null を以下のSQL文の場合 select * from infomation where start_dt <= '2014/01/10' order by start_dt desc limit 3 id start_dt end_dt --+----------+---------- 4 2014-01-10 Null 3 2014-01-09 Null 2 2014-01-08 Null が取得されます。 id start_dt end_dt --+----------+---------- 4 2014-01-10 Null 3 2014-01-09 Null 1 2014-01-07 2014-01-20 の結果のように「id:2」よりも「end_dt」を優先して取得するSQL文をつくることは可能でしょうか? 何がしたいかというと ・start_dtが'2014/01/10'より新しい順に3件取得したい。 ・end_dtが'2014/01/10'より未来で該当する場合にNullのレコードより優先したい。 どうかお助けください。

    • ベストアンサー
    • MySQL
  • SQL

    テーブル情報 id start_dt end_dt --+----------+---------- 1 2014-01-07 2014-01-20 2 2014-01-08 Null 3 2014-01-09 Null 4 2014-01-10 Null 5 2014-01-11 Null を以下のSQL文の場合 select * from infomation where start_dt <= '2014/01/10' and (end_dt >= '2014/01/10' or end_dt is null) order by start_dt desc limit 3 id start_dt end_dt --+----------+---------- 4 2014-01-10 Null 3 2014-01-09 Null 2 2014-01-08 Null が取得されます。 id start_dt end_dt --+----------+---------- 4 2014-01-10 Null 3 2014-01-09 Null 1 2014-01-07 2014-01-20 の結果のように取得するSQL文をつくることは可能でしょうか? 何がしたいかというと ・start_dtが新しい順に並べる。 ・3件のレコードを取得する。 ・start_dtが'2014/01/10'より古いレコードを取得する。 ・end_dtが'2014/01/10'より新しいレコードがある場合は、Nullのレコードより優先する。 どうかお助けください。

    • ベストアンサー
    • MySQL
  • ■一番最初に値が入っている(Nullでない)カラム名を取得するには?

    ■一番最初に値が入っている(Nullでない)カラム名を取得するには? 会社の上司が、上記の条件をSQL文一つで出来るというのですが、 postgres SQLの書き方が思いつかず、大変困っています。 状況を説明します。 主に以下のようなカラムを持つテーブルがあります。 ID, 年, 月, タイプ, price_1d, price_2d, price_3d, ..., price_31d price_?d には null or 数字が入ります。 上記のような状況で、 price_1d ~ price_31d の順で最初に値が入っているカラム名を取得し、 最初に値があるのは何年何月何日と判定したいというわけです。 おまけに、タイプには 0 or 1 が入り、 その値によっては、price_?dではなく、別カラム price2_?d を見ないといけないという条件付きです。 このような条件をSQL一つで抽出することははたして本当に可能なのでしょうか? 何かしら解決の糸口となるヒントだけでも構いませんので、 何か情報を頂けると大変ありがたいです。 また、そんなの出来ません、 という情報でもいただけると嬉しいです。 宜しくお願い致します。

  • カラム情報取得方法

    テーブル内のカラム情報を取得するにはどのようなSQLを作ればよいのでしょうか? 欲しい情報は「カラム名・主キーかどうか・データ型・桁数・NULLを許容かどうか」の5つとなります。 SQL Server は2005と2008を使用していて、どちらでも扱えるSQLがあると助かります。 どうぞ宜しくお願いいたします。

  • ソート順の一番若い者を取得する

    お世話になります。 Oracle SQL文で質問があります 以下のようなテーブルから【結果】のような レコードを取得したいのです id id2 が同じものでsort順が一番若いものを 取り出すSQLです。 おわかりの方よろしくお願いします。 id id2 sort 1 1 1 1 1 2 1 2 1 1 2 2 1 2 3 1 3 1 【結果】 id id2 sort 1 1 1 1 2 1 1 3 1

  • 動的にSQLを作成し、値を取得する方法について

    Pro*Cでテーブル名を動的に与え、カラムの1つであるシーケンス番号の最大値を取得しようとしています。 ネットで調べたところ、 EXEC SQL DECLARE S1 STATEMENT; sprintf(buf1, "実行するSQL文", ); EXEC SQL PREPARE S1 FROM :buf1; EXEC SQL EXECUTE S1 INTO :取得結果格納領域; という構文で出来るということがわかったのですが、最後のところで、取得結果格納領域に値が入りません(正確には初期値「0」が入ります)。 取得したいデータを直接SQL*PLUSで実行すると0ではない値となるのですが、どのようにすれば値が取得できるかをご教授いただければと思います。 実行するSQL文の中には「%s」を含んでおり、sprintfの第3引数でテーブル名を渡しているので、buf1の中身はそのままSQL*PLUSで実行できる内容となっています。 それぞれのEXEC SQLの後にSQL終了コード(sqlca.sqlcode)を取得しましたが、どれも0(正常終了)で終わっていました。 どうかご教授のほど、よろしくお願いします。

  • SQLで取得したフィールドをSQL文として利用

    お世話になっております。 MYSQLで sql_id (int PK) sql_data (text) のようなテーブル(sql_db)を持ち select sql_id from where (sql_data をsqlとして実行した結果 ) > 200 のように、フィールドから取得した値をSQLとして実行したりする方法はございますでしょうか。 ご教授よろしくお願いいたします。

  • 複数のテーブルから値を合計出力するSQLについて

    複数のテーブルから値を合計出力するSQLについて 以下の様な3つのテーブルがあり、それぞれのテーブルから値を合計した結果を取得したいと思っております。 この場合のSQL文をご教授いただけないでしょうか? 拙い説明でお分かりに難いかと思いますが、何卒、宜しくお願いします。 ●テーブル t1(テーブル1) id, 会員ID, 日付, 金額 t2(テーブル2) id, 会員ID, 日付, 金額 t3(テーブル3) id, 会員ID, 日付, 金額 ●期待する結果 上記、テーブル内の会員ID、日付が同じものの金額を合計して取得。(1行で出力) いずれかのテーブルに「会員ID」が一つしか存在しない場合も、「日付」、「金額」を取得して「合計金額」に反映。 もし、各テーブル、レコードの「金額」が「0」または「null」の場合は「0」として処理する。 ●期待出力結果イメージ 会員ID | 日付 | 合計金額 | -------------------------------- m001 | 2011/07/20 | 1500 | -------------------------------- m001 | 2011/06/10 | 2000 | -------------------------------- m002 | 2011/06/05 | 1000 | -------------------------------- m003 | 2011/05/25 | 0 | -------------------------------- m001 | 2011/03/05 | 3000 | ※「合計金額」は、「t1(テーブル1)」~「t3(テーブル3)」の中に含まれていた金額の合計。

    • ベストアンサー
    • MySQL
  • 指定した年月までのデータを取得するSQL文

    いつもお世話になっております。 今、指定した年月までのデータを取得するSQL文を考えています。 例:NENGETSU_DATEカラムがDATE型で、 データとして、2008/11/12と、2008/11/18と、2008/12/12が入っているとして、11月だけのデータを取得したい。(今回は、2008/11/12と、2008/11/18を取得) どのようなSQL文を書けばよろしいでしょうか。 よろしくお願いいたします。

  • MySQLでのランキングを作成するSQL

    ランキングを作成する、効率の良いSQLを教えて下さい。 MySQLで、以下の状態です。 テーブル名: hoge カラム: id,kbn,name,score,flg,date id…自動 kbn…1~4 name…string score…int flg…bool date…年月日 (1)dateが1週間以内のデータのみ (2)flgがtrueのデータのみ (3)kbn毎に、5レコード取得 (4)順位は、点数が重複している場合は同一の順位をつけSQLで生成しn位のフォーマット (5)6レコード以降に同一スコアのデータがある場合は日付が古い順 (6)scoreは、n点のフォーマット (7)該当データが5レコード存在しなかった場合は、順位だけをセットし他をnull 欲しい結果は、以下の状態です。 kbn,順位,name,score 1 ,1位 ,ホゲ,100点 1 ,2位 ,あい, 85点 1 ,2位 ,かき, 85点 1 ,4位 ,くけ, 70点 1 ,5位 ,さし, 65点 2 ,1位 ,すせ, 99点 2 ,1位 ,たち, 99点 2 ,3位 ,つて, 80点   ・   ・   ・ 4 ,4位 ,らり, 10点 null ,5位 ,null, null 以上、よろしくお願い致します。

    • ベストアンサー
    • MySQL