• 締切済み
  • すぐに回答を!

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に関しての知識が乏しいため、効率的な方法をご存知の方はアドバイス頂けると大変助かります。 よろしくお願いします。

共感・応援の気持ちを伝えよう!

  • 回答数2
  • 閲覧数1122
  • ありがとう数0

みんなの回答

  • 回答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

共感・感謝の気持ちを伝えよう!

関連するQ&A

  • SQLがうまくいかない!

    SQLがうまくいかない! SQLについて、調べたんですが、わからないので教えてください! last_year(日付データ)関数 と round(日付データ,'書式')関数についてのご質問です。 select last_year('2007-01-01') from 表名; とやるとうまくいくのに 、 select round('2007-01-01','month') from 表名; とやるとエラーになってしまいます。 last_year関数では、'2007-01-01'は日付データとして扱われるのに、round関数では日付データとして扱われないのはなんででしょう? ちなみに、 select round(to_date('2007-01-01','yy-mm-dd'),'month') from 表名; とやるとうまくいきます・・・SQLの仕様ですか!? どなたか教えてください!宜しくお願い致します。

  • ある値以上の空き番の最小値を取得するSQL

    テーブル TB の項目 CDがNUMBER型でユニークキーだとします。 このCDで ・ある値以上の空いている最小の番号を取得したい。 としたら1つのSQLで実現できますか? 例) CDの値が 6・・・・80 150・・・ (81から149は存在しない) という具合に存在していた場合に、101以上で空いている最小の番号 を取得したいのです。 この場合は101です。1が取得されても駄目、81が取得されても駄目です。 また、同じ条件でデータが 6・・・・150 200・・・ (151から199は存在しない) の場合には151が取得したいのです。 このような値を検出するSQLってわかりますか? 以上よろしくお願い致します。

  • 日付を計算して件数を取得

    お世話になります。 よろしくお願いします。 MySQL5を使っています。 現在 year month day days の4つのフィールドがあり、それぞれに 2008 03 01 10 2008 03 02 20 というデータが入っているとします。 daysは数値です。 year,month,dayを日付に直して days-5の値を引いた日が本日と同じデータの件数を取得したいのですが SQLだけで可能でしょうか? たとえば、今日が2008-03-17だとすると 2008-03-01に(10-5)を足すと2008-03-05なので偽 2008-03-02に(20-5)を足すと2008-03-17なので真 なので1件 みたいな感じです。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • 回答No.1
  • naktak
  • ベストアンサー率36% (784/2137)

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

共感・感謝の気持ちを伝えよう!

関連するQ&A

  • 動的に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(正常終了)で終わっていました。 どうかご教授のほど、よろしくお願いします。

  • 日付取得

    ある変数に$year='2003', $month='1', $day='5' となっている場合 配列$dateに '2003/1/5' '2003/1/4' '2003/1/3' '2003/1/2' '2003/1/1' '2002/12/31' '2002/12/30'とデータを取得したいです。 また $year='2003', $month='1', $day='' の場合は '2003/1' '2002/12' '2002/11' '2002/10' '2002/9' '2002/8' '2002/7' と取得したいのですが どのようにすればよろしいのでしょうか? すみませんが宜しくお願いいたします。

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

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

  • SQL 特定のカラムが最大値のレコード取得

    初心者です。SQL文で困っています。 どなたかご教授頂けたらと思います。 環境は、SQL SERVER 2000です。 特定のカラムが最大値のレコードのみ取得したいです。 たとえば、以下のようなデータがあるとします。 コード、履歴番号で主キーとします。 コード|履歴番号 |金額 0001 | 1 | 12000 0001 | 2 | 12001 0001 | 3 | 12002 0002 | 1 | 12000 0002 | 2 | 12001 0002 | 3 | 12002 0003 | 1 | 12000 0003 | 2 | 12001 この場合に、コード毎に履歴番号が最大のレコードのみを取得したいです。 理想の結果は以下になります。 コード|履歴番号 |金額 0001 | 3 | 12002 0002 | 3 | 12002 0003 | 2 | 12001 以上です。よろしくお願いいたします。

  • MySQLで日毎の最高点を取得するSQLについて

    何時もお世話になっております。 日付ごとの最高ポイントを取得する 効率の良いMySQLでのSQLをご教授下さい。 T_DATA flg kbn point biko date ------------------------------ true 3 90 NNN 20141231 true 1 80 XXX 20150101 true 2 60 YYY 20150101 true 3 70 XXX 20150101 true 1 40 xxx 20150201 true 2 60 yyy 20150201 true 1 60 AAA 20150301 true 2 90 BBB 20150301 true 3 40 CCC 20150301 true 1 60 aaa 20150401 true 2 70 bbb 20150401 true 3 30 ccc 20150401 false 4 90 ddd 20150401 ■欲しい状態 kbn point biko date ----------------------- 2 70 bbb 20150401 2 90 BBB 20150301 2 60 yyy 20150201 1 80 XXX 20150101 (1)dateカラム毎にpointカラムが最大のデータを取得したいです。 (2)flgカラムがtrueのデータのみ取得したいです。 (3)dateカラムが降順になるよう取得したいです。 (4)dateカラムは、直近4日分取得したいです。 以上の条件で取得したく思います。 どうぞ、よろしくお願い致します。

    • ベストアンサー
    • MySQL
  • 1回のSQL文で取得できますか

    Postgresでテーブルが2つある場合、 その2つに登録されているデータを全て取得したいのです。 例えば Aテーブル       Bテーブル Key1 key2 A     Key1 key2 B ---------- --------- 01 01 A1     01 02 A2   01 02 B2 01 03 A3   01 03 B3             01 04 B4 とある場合、 1度のSQLで下のような結果を取得できますか? Key1 key2 A   B ------------ 01 01 A1   NULL 01 02 A2   B2 01 03 A3   B3 01 04 NULL  B4 お願いいたします。

  • SELECT/別テーブルのレコード数も取得したい

    ■環境 ・MySQL ■前提 ・テーブルA … idカラム ・テーブルB … A_idカラム ■やりたいこと ・テーブルAデータを取得する際、テーブルAレコードに応じて、テーブルB「A_idカラム」の数(レコード数)も取得したい ■取得イメージ例 ・テーブルA「全カラム」、「count」カラム ※「count」カラム … テーブルBにある「A_idカラム」の数 ■知りたいこと ・どこにも存在しないこの「count」カラムはどうやって作成したら良いでしょうか? ・全体のSQL文

    • ベストアンサー
    • MySQL
  • oracleのsqlで日付判断

    テーブルに以下の以下の様に日付が登録されています。、 cal_year cal_month cal_day item1 item2 item3 ・・・・・・ : 2019 6 29 2019 6 30 2019 7 1 2019 7 2 ; 2019 7 10 2019 7 11 ; 2019 7 20 2019 7 21 : 2019 7 31 2019 8 1 2019 8 2 : 見ての通り、テーブルに登録されている日付が、年、月、日と各々で 登録されており、また、月と日には、ゼロ埋めされてない値となって います。 因みに、cal_year、cal_month、cal_dayの属性は、varchar2です。 以下のsqlで、日付指定で、システム日付より以降の日付のデータを 取得しようとしているのですが、上手く行きません。 select * from tableA where cal_year||cal_month||cal_day>to_char(sysdate,'FMYYYYMMDD') order by cal_year,to_number(cal_month),to_number(cal_day) ; 今日、2019/7/22でやると、「2019 7 3」以降が出力されます。 また、日付を直接指定するとエラーとなります。 select * from tableA where cal_year||cal_month||cal_day>to_char('2019722','FMYYYYMMDD') order by cal_year,to_number(cal_month),to_number(cal_day) ; 「SQL : ORA-01481: 数値書式モデルが無効です」となります。 何がいけないのでしょうか。 このような使い方はダメなのでしょうか。 それとも、使わない使い方をしているのでしょうか。 お願いいたします。

  • 以下の場合のSQL文の書き方教えてください。

    2つのテーブルÅ、Bに同じ項目名(NYUSYA_DATE)が存在していて、 通常はAからデータを取得し、取得した値がNULLの場合は、Bから取得します。 これを1つのSQLで出来ますか? 今は、両方取得しておいて、IF文で判定しようとしています。 テーブルA SYAIN_ID (NOT NULL) NYUSYA_DATE テーブルB GROUP_ID (NOT NULL) SYAIN_ID NYUSYA_DATE

  • SQL文の作成

    こんにちわ。 JAVAプログラム上でデータベースを使用して データを取得したいのですが、 SQL文が複雑でわかりません。 一度データを取得して、その値を基に次に参照するカラムが変わるというものなのですが、一度にできるものでしょうか? どなたかお力添えよろしくお願いします。

    • ベストアンサー
    • Java