SNSの個人設定で、以下のような日記の公開範囲設定があります。 ※「○月○日の日記を公開するかどうか」ではなく、そのユーザーの日記全体の設定です。 5.インターネット全体に公開 4.SNSユーザー全員に公開 3.友達の友達にまで公開 2.友達にだけ公開 1.非公開 ここで、特定のサイト訪問者が閲覧できる日記だけを、記事単位で最新10件分取得したい場合、 どのようなSQLを書くのがスマートでしょうか。 いまは、最初に上記の公開範囲テーブルから「閲覧できるユーザーID」を全取得して、 日記を select するときに where user_id in(1,2,3,5,6,8,9,10,11,13,...) などとやってて、 パフォーマンスがだいぶ悪いです。 そこで、手段を変えて、次のようにひとつのクエリで取得しようとしたら、もっと悪化しました。 where (private.diary = 5) or (private.diary = 4 and ログインしてるかどうか) or (private.diary = 3 and 友達の友達かどうかのサブクエリ) or (private.diary = 2 and 友達かどうか) or (private.diary = 1 and 自分かどうか)
予約語がカラム名に使われてるデータベースがあります。 以下のようにすると、参照できることはわかりました。 select * from table_name where 'show' like 'hoge'; ですが、これだと予約語ではないカラム名の場合検索できません。 select * from table_name where column_name like 'hoge'; で帰ってくる結果が select * from table_name where 'column_name' like 'hoge'; では帰ってこなくなります。 どういうsql文ならカラム名が予約語、予約語ではない場合の両方で使えるでしょうか? sql文はphpから発行しています。
皆様ありがとうございます。 まとめると、採番テーブルでDBサーバの時刻を使ったほうが問題が 少ないということで、こんな感じですよね? create table seq ( id int not null, dt datetime ); update seq set id=if(dt<now(),0,id+1),dt=(dt<now(),now(),dt);
57 :
create table seq ( id int not null, dt datetime ) engine=MyISAM; update seq set id = last_insert_id( if(dt<now(),0,id+1) ), dt = if(dt<now(),now(),dt); select last_insert_id(), dt from seq;
58 :
それだとupdateとselectの間にdtが変わってるかもしれないからロック必要じゃね?
59 :
phpで $query = mysql_query("SELECT * FROM question_tb WHERE purchase_date >='$sdate' AND purchase_date <='$edate' AND star>=4 ORDER BY purchase_date"); これでpurchase_dateが$sdate以上、purchase_dateが$edate以下、star>=4 の3つの条件でmysqlで問い合わせできますが、 別の書き方、 $sql = 'SELECT question_id,purchase_date,purchase_price,star, lang_php,lang_perl,lang_java,lang_cs,lang_cpp,lang_basic, job,entry_date FROM question_tb WHERE purchase_date >= "' . $sdate . '" AND purchase_date <= "' . $edate . '"'; ではどのようにstarが4以上を書くのですか?
60 :
>>59 phpで質問したほうがいいっす >AND purchase_date <= "' . $edate . '"'; AND purchase_date <= "' . $edate . '" AND star >= 4 ORDER BY purchase_date' ヒアドキュメントにするとわかりやすい・・かも BETWEENにするとわかりやすい・・かも $sql = <<<EOT SELECT question_id,purchase_date,purchase_price,star, lang_php,lang_perl,lang_java,lang_cs,lang_cpp,lang_basic, job,entry_date FROM question_tb WHERE purchase_date BETWEEN '{$sdate}' AND '{$edate}' AND star >= 4 ORDER BY purchase_date EOT;
61 :
すまぬセミコロン抜け AND purchase_date <= "' . $edate . '" AND star >= 4 ORDER BY purchase_date' ↓ AND purchase_date <= "' . $edate . '" AND star >= 4 ORDER BY purchase_date';
62 :
mysqlを使っていて、AとBというカラムがあって、基本的にはAでソートするのですが、 AがnullのときにBでソートするようにしたいのですが、どうしたらいいのでしょうか? obder by A,Bにすると、Aがnullのものが先に出るようになります。 AがnullならBの値を使って、AとBを合わせたようなソートを行いたいです。
log name buy inputdate 1.yamamoto 20 2011-12-8 2.takahashi 10 2011-12-7 3.yamamoto 10 2011-12-3 4.hayashi 5 2011-12-1 このようなテーブルがあった場合。 select from log where name ='yamamoto' group by DATE_FORMAT(inputdate,"%Y%M"); このとき最新のもの(1行目)を選んだり最古のもの(3行目)を選んだりできるようにしたいです。 要はgroupby で抽出される行を選択するということなのですが、 having byですと、group by抽出後のものに対する文みたいですし、 なにかいい方法はありますでしょうか?
>>75 Oracleの場合rank()関数を使ってやる内容。 MySQLの場合はユーザ変数を使ったrank()の再現をする。 かなりめんどくさいけどこんな感じ。 set @r := 0; select * from (select @r := @r + 1 rank, e2.* from (select job, count(*) from emp group by job order by count(*) ) e2 ) e3 where rank = 2;
77 :
基礎からのMySQLという本を読んで、学習中です。 302ページのファイルエクスポートのところなのですが、 SELECT * INTO OUTFILE 'C:/data/out.csv' FIELDS TERMINATED BY ',' FROM tb1; とすると 「Can't create/write to file 'C:\data\out.csv'(Errcode:2)」というエラーがでます。 これはパーミッションの問題ですか? Windows XPを使っています。
78 :
>>77 perrorというコマンドでエラーの詳細が取れる。 > perror 2 OS error code 2: No such file or directory Win32 error code 2: 指定されたファイルが見つかりません。