はてなブックマーク - PostgreSQLでCase式とGroup化
    このエントリーをはてなブックマークに追加

    まさか3度目は無いだろうと完全に油断していた。。。。
    Advent Calendar3度目の登場の安元です。
    年末ジャンボを買うなら今だ!と無責任にけしかける社員がいっぱいる楽しい会社です。

    さて、前回、前々回とSQLについて書いております。今回も趣向も変えずにSQLです。
    PHPでもRubyでもフレームワークを利用されることがほとんどで
    「SQLなんて書かねーよ!!」というかたも多いのではないでしょうか?

    弊社でもフレームワーク導入の前後ではSQLに携わる機会は激減しているのが現状です。
    しかし業務系のシステムでは、集計や統計を必要とすることがよくありますので、
    「SQLでデータまとめる」という選択肢を持っておくと、プログラムがぐっとシンプルになることもあります。

    というわけで、今回はGroup ByとCase式を絡めて利用してみましょう。

    年齢ごとの集計

    今回利用するのは以下のようなテーブルです
    性別と誕生日が格納されているシンプルなテーブル構成です。
    実務ではユーザーテーブルなんかでよくある構成ですね。
    レコード数は全部で3525件準備しました。

    
     id | sex |  birthday
    ----+-----+------------
      1 | f   | 1920-08-08
      2 | f   | 1927-07-28
      3 | f   | 1920-03-28
      4 | f   | 1921-03-21
      5 | f   | 1913-12-23
    (10 rows)
    

    まずはシンプルに年齢ごとの集計をとってみましょう
    (12月1日時点での年齢をもとに集計します)

    これで「年齢」ごとの集計はできました。
    しかし実務では、「年齢」ごとの集計では情報の粒度が細かすぎることが多いです。

    年代ごとの集計

    では、10代・20代のように年代ごとの集計をしてみましょう。
    使うのは、Case式です。
    まずはSQLを見てみましょう

    特徴的なのは、
    SELECT句の最初のCase式で条件分けをしていることと
    COUNT関数の中でのCase式の利用いる部分ですね

    SELECT句のCase式はGROUP BYにも書くことができますが、
    SELECT句に先に記述し「AS」で別名を付けることで、
    GROUP BY、ORDERともに別名を利用でき、SQLを短くすることができます。

    Case式の中でやっていることは年齢を年代に置き換える作業です

    date_part('year', age('2010-12-1',birthday)) between 1 and 19 then 10

    分解してみましょう
    1:age関数を利用して、誕生日からの経過年・月・日が取得できます

    age('2010-12-1',birthday)

    2:取得した年月日から、年だけを取得します。これが年齢になりますね

    date_part('year', age('2010-12-1',birthday))

    3:最後にbetweenを利用して、「年代」に置き換えています

    case
    when date_part('year', age('2010-12-1',birthday)) between 1 and 19 then 10
    end

    このようにCase式を使うと、「条件に一致する複数のデータを一つのデータにまとめ直す」ことができるのが大きな利点です。

    性別・年代ごとの集計

    それでは最後に、先ほどの年代別の集計を性別ごとに分けてみましょう。
    問い合わせ結果が横に伸びるということは、SELECT句の項目が増えることになります。
    今回はシンプルにCase式の各条件に性別条件を付加しました

    結果はこのようになります

    age_group | men | women
    -----------+-----+-------
    20 | 0 | 1
    30 | 14 | 192
    40 | 45 | 663
    50 | 56 | 905
    60 | 47 | 743
    70 | 9 | 367
    80 | 21 | 278
    90 | 4 | 141
    100 | 1 | 36
    (9 rows)

    とてもシンプルな結果が返ってきました。
    Case式は応用の幅が広いです。
    思いもつかなかった活用法がWEB紹介されていることもありますから、
    集計に行き詰ったら、Case式の活用を検討してみるといいことがあるかもしれません。

      はてなブックマーク - Titanium Mobile 社内勉強会の裏側 ~Ustream配信で使った機器
      このエントリーをはてなブックマークに追加

      Advent Calendarの途中ですが、ここでブレイクを。

      すみません、山本です。
      個人的に、年内15エントリーを目標に掲げておるものですから、割り込み失礼します。

      技術ネタが多いなか、今日はコラム的なものを。

      皆さん、Ustreamはご存知かと思いますが、見るのではなく配信をされたことはあるでしょうか。
      カメラとマイクとネット環境さえあれば、年中いつでもどこでも全世界に映像を配信できるサービスですが、実際に配信された方は少ないかと思います。
      そもそも配信するコンテンツがないから、というケースが多いかもしれませんが、いざ配信しようとしたときに、何を用意すればいいのかわからないという方もいらっしゃると思います。

      そこで今回は、11/25にZENPRE上でTitaniumMobile勉強会を配信した際に使用した機器などをご紹介します。

      カメラ


      Logicool QVP-30SV
      (発売当初のオンラインストア価格は2,480円)

      Logicool製の、お手頃価格なカメラですね。
      2007年発売というのもありまして、動画の画素数は30万画素と低めです。
      これを使って撮った映像が以下です。

      多少の粗さが目立ちますね。
      それでも、人の表情は認識できるレベルです。

      ちなみに、不測の事態に備えて、この模様はMacBookProのカメラでも撮っていました。
      その映像が以下です。

      MBPに搭載されているiSight130万画素で、Logicoolのカメラよりも多いですが、あまり変わりないですね。

      マイク

      このコンテンツを配信するにあたって重要なのは、映像よりも音声でした。
      資料はZENPREのスライド上に表示されるので見える必要はないのですが、音声に関しては発表者が何を言っているのかはっきりと認識できるレベルが必要でした。

      単一指向性か無指向性か

      まず、無指向性を試しました。
      これは会議によく使われるタイプで、より大勢の音声が拾えるよう設計されたマイクですね。
      これでテストしたところ、やはり発表者の声が小さくなってしまいました。
      そのコンテンツが発表者重視なのか、会場の雰囲気重視なのかで選択肢は変わると思いますが、今回は発表者メインですので、単一指向性にしました。


      audio-technica AT9904
      メーカー価格4,410円

      テレビでよく見かけるピンマイクですね。
      発表者の音声がちゃんと拾えてます。

      ちなみにMacBookProで撮った方も、音声の聞き取り度は高いですね。

      まとめ

      何か書いていて、「MacBookProさえあればUstreamを簡単に配信できる」というタイトルに変更しようかと思うくらい、
      MBPは便利ですね。
      でも、持っていない方でも、1万円以内で機材を揃えることができますし、今ならHD対応のウェブカメラも安価で購入できます。
      もっと探せば、同程度の機材であれば5,000円以内に収まると思います。

      今日もどこかで勉強会やセミナーが行われていることでしょうが、
      多くの人に見てもらうため、認知度向上のためにも、オンラインで配信される機会が増えればと思います。
      いち地方都市で開催されるような東京に比べたら集客数は減る勉強会でも、オンライン配信すれば擬似的な参加者は格段に上がるはずですから。
      また、逆に東京でしか行われない勉強会も、物理的に行けない人のために積極的にオンライン配信が行われればと思います。
      配信すること自体は、特別難しいことではないですから。

      で、画面が粗いので資料の識字ができないって時に、ZENPREを使っていただけたらと思います。

        はてなブックマーク - PHPExcelとReviserの比較(後編)
        このエントリーをはてなブックマークに追加

        まさかの1日明けでアドベントカレンダーの順番が回ってきました。
        生まれ変わって元素になるなら、アルミニウムになりたい
        ・・・という設定らしい1年目の新人、萩原です。

        さて、前回はPHPExcelとReviserの機能について比較を行いました。
        機能としてReviserも十分な機能を持ち合わせていますが、PHPExcelの方が優れているという結論でした。

        スピードの比較

        さて、実際に運用していく上でスピードは重要なポイントだと思います。
        ファイルダウンロードに時間がかかってしまってはストレスもたまりますしね。
        というわけで、今日は、スピードについて検証していくことにします。

        今回、クリックしてからダウンロードを開始する直前までの時間を測定しています。
        ソースにmicrotime(‘now’)を埋め込んでいる&virtualBox上のCentOSなので時間自体は正確ではない(というか倍くらい時間がかかっている)ですが、相対的な値としては問題ないです。

        20回ずつ測定をして平均を取っているので比較としては十分かと思われます。

        まずは、何も書きこまれていないテンプレートに何も入力せずそのまま出力した結果です。
        参考までにPHPExcelでのExcel5形式出力も一緒に載せています。

        Reviser
        平均値:0.033(s)
        標準偏差:0.016

        PHPExcel(.xlsx)
        平均値:0.123(s)
        標準偏差:0.011

        PHPExcel(.xls)
        平均値:0.223(s)
        標準偏差:0.039

        かなり差がでましたね。
        ただ、Reviserと比べてPHPExcelの方が標準偏差が小さく安定はしているのかなという印象です。

        続いてテンプレートに横15、縦600すべてのセルに’test’と入力した状態で何も入力せずにそのまま出力した結果です。

        Reviser
        平均値:0.911(s)
        標準偏差:0.113

        PHPExcel(.xlsx)
        平均値:2.508(s)
        標準偏差:0.080

        PHPExcel(.xls)
        平均値:2.483(s)
        標準偏差:0.027

        こちらも差がでましたね。

        次に何も入力されていない空のテンプレートに横10、縦1000すべてのセルに’test’と入力して出力した結果です。
        ここからはPHPExcelのExcel5形式での出力は行っていません。

        Reviser
        平均値:0.871(s)
        標準偏差:0.026

        PHPExcel(.xlsx)
        平均値:2.798(s)
        標準偏差:0.034

        こちらも時間はPHPExcelの方が時間がかかっています。
        この辺りで20回測定するのが面倒になってきてちょっと後悔を始めました・・・。

        最後に上の条件にさらに該当セル全てに色と左右上下の罫線を引いてみました。

        Reviser
        平均値:0.873(s)
        標準偏差:0.049

        PHPExcel
        平均値:73.269(s)

        ・・・タイプミスじゃないですよ。。。100倍くらい差が出ましたよ。
        CentOS内部で73秒平均なのですが、多分3,4分くらいかかってる気がしないでもない・・・
        因みにPHPExcelは20回やる気力が流石になかったので(無駄だし)5回しか測定してません。

        罫線と色のどちらに時間がかかっているかと思って色をつけずに出力させてみたところ40.981(s)かかりました。

        どっちもどっちといったところですかね。

        まとめ

        というわけで2回にわたってReviserとPHPExcelの比較を行ってきました。
        ReviserとPHPExcel、どちらも長所短所あると思います。

        色や罫線がある場合ちょっと使用に耐えられないレベルだという結果に見えますが、そうではないと思います。
        例えば色をつけることについても全てのセルに色や罫線をつけるわけではないし、PHPExcelは個別に指定できますが、Reviserはテンプレートを準備しないといけません。
        極端な話セルのパターンが100パターンあればReviserならあらかじめ100パターンのテンプレートセルを準備する必要があるという問題点があります。
        また、xlsx形式はPHPExcelしか使えません。

        機能的な面で見ればやはり、PHPExcelの方が優れていると思います。

        まぁ一方で流石に何分もダウンロードに時間がかかってしまっては困るという面もあります。
        Excelの出力はPHPExcelにしてもReviserにしてもかなりメモリを食いますので他の作業を並行して行うことが難しいです。
        (両者ともini_set(“memory_limit” , -1);をつけている理由ですね。これを記述していないとまともに動かせません。)

        現に私がPHPExcelで作ったもの(社内システムですが)は長いものは出力に5分ほどかかりますし、使いどころが難しいですね。

        個人的には基本的にはReviserだと思いますが、xlsx形式を使いたい場合、Excel2007関数をどうしても使いたい場合など、PHPExcelでないと機能が実現できない場合も出てくると思います。

        最後に役に立たない化学豆知識を

        空気中に2番目に多く存在している、酸素
        実は常磁性、つまり磁石に引っ付くってこと、ご存知でしたか?
        実際、液体酸素を流しているところに磁石を近づけると流れの向きが変わります。

        それでは。