20190310のSQLに関する記事は3件です。

3/9 

やったこと

vagrant
 起動
 停止
 破棄
 ファイル共有の確認

Linux
基礎操作
 webサーバー構築
 PHPサーバー構築(https://learning.courage.engineer/contents/?p=608)

 SQLインストール

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

個人または家族で使える自宅用のWebポータルシステム「MyHome Portal」

PHPで作成した個人または家族で使える自宅用のWebポータルシステム「MyHome Portal」をオープンソース/フリーソフトとして公開しています。
2008年から2016年にかけて、こつこつとバージョンアップを繰り返して作成したものです。
中級プログラマの作品ですので、ソースコードはあまりきれいとは言えません。バージョンアップを繰り返したことでコードがきたなくなってしまっている部分もあります。モジュールの構造を複雑にしすぎたかもしれません。
2016/08/02以降、バージョンアップしていません。Webサービスを利用している機能など一部は、Webサービスの停止等の理由により動作しなくなっています。

公開ページ

https://ok2nd.github.io/myportal/

ブログ

最近、更新はほとんどありません。
中級プログラマの自宅でPHP ブログ

コンセプト

  • 自宅でポータルとして使えるシステム。(家庭内グループウェア)
  • データはインターネット上ではなく、ローカルPCまたはローカルサーバに保管。
  • 初級、中級プログラマにも理解可能なシステム。
  • PHP、SQL、JavaScript、HTML、CSSの知識だけで理解可能なシステム。
  • PHPの良さを生かしたHTMLインラインコーディング。(なるべくprint文を使わない。)
  • ブラックボックスの少ないシステム。
  • オブジェクト指向型プログラミングを使わない。手続き型(関数型)プログラミングを採用。
  • MVCを使わない。
  • フレームワークに頼らないシステム。
  • テキストエディタ以外の開発ツールを必要としない。

対象者

  • 自分または家族専用のWebポータルサイトが作りたい。
  • Webポータルサイトをインターネット上ではなく、ローカルPCまたは自宅サーバーで立ち上げたい。
  • 日常的に良く使う機能が、個々のアプリケーションを起動せずに、ブラウザの中で出来たらうれしい。
  • スケジュールその他自分の個人情報をインターネット上に置きたくない。
  • パスワードなどのID情報をインターネット上に置きたくない。
  • Webプログラム開発初心者。
  • プログラミングを仕事でなく、趣味でやりたい。
    • オブジェクト指向が苦手。
    • MVCは面倒。
    • システム全体を把握したい。(ブラックボックスは少ない方が良い。)
    • フレームワークを使いたくない。(PHP、SQL、JavaScriptだけで開発したい。)

機能一覧

  • ホームページインデックス(ブックマーク)&検索
    • ブログパーツ貼り付け
  • 付箋
  • カレンダー(スケジューラ)
    • 天気出現率表示
  • 旅行記
  • ToDo
  • 掲示板
  • RSSリーダー
  • メモ
  • フォトアルバム
    • スライドショー
    • 動画サムネイル
    • FLV,MP4,WMV,MPG,MOV,M2TS(AVCHD)動画再生
  • 学習
  • 住所録
    • PDF葉書宛名書き
  • メール(一括受信)
  • SVGお絵かき
  • ペン画
  • チャット(Chat)
  • ID・パスワード管理
  • GPSログ(GPX)ビューワ
  • 預貯金管理
  • 縦計だけの表計算
  • HTML URL抽出&ファイルダウンロード
  • テキスト縦書き表示
  • Excel to グラフ
  • ソースコード表示&編集+ファイルマネージャー
  • MySQL管理ツール
  • ファイル暗号化/復号化
  • タイマーアラート

特徴・補足

  • 自宅で個人や家族で使えるシステムを目指して作りました。家庭内LANでの利用を想定しています。
  • 少人数の会社のイントラでの利用も可能かもしれません。 セキュリティは万全ではないので、スケジュール共有など機能を限定して利用願います。
  • ユーザー登録など、インターネット上での利用を想定した機能も付けています。ただし、セキュリティ等保障はできませんので、インターネット上での実利用は、自己責任にてお願いいたします。あくまで、LAN内またはPC単体での利用を想定しています。
  • 簡単なユーザー管理機能もあります。
  • 認証機能もあります。
  • ユーザー単位で他のユーザーに対して参照・書込の権限設定ができます。
  • レコード単位での非公開の設定もできます。
  • ただし、システム管理者はデータベースを直接見ることで全ての情報を参照ができてしまいますので、悪用しないように。
  • ID管理では、二重の認証が必要なしくみにしています。
  • ID管理では、パスワードを独自の方式で暗号化しています。ID情報は、2つのテーブルに分割して保存します。 暗号化のキーと2つのテーブルを別々にバックアップすれば、ID情報の復元はしづらい(?)と思います。
  • 簡単なログ機能も付けています。
  • 簡単なシステム管理者機能も付けています。
  • コンテンツを追加しやすい構造にしています。
  • ページ分割有りの一覧形式のページを簡単に作れる共有ライブラリを用意しています。一覧形式での編集もできます。 /myhome/common_/include-common-mp-list.php 各コンテンツのlist.php、category.phpを参考にしてください。
  • 一覧形式の表示部分のみを、独自のphpソースに置き換えられます。($mp_list_arg['template_view'])

開発環境

  • (Ver.3.27以降)XAMPP 1.7.1 (Windows)

    • Apache 2.2.11
    • MySQL 5.1.33 (Community Server)
    • PHP 5.2.9 + PEA
  • (Ver.3.26以前)XAMPP 1.6.6a (Windows)

    • Apache 2.2.8
    • MySQL 5.0.51a
    • PHP 5.2.5
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

window関数の説明

window関数の説明

概要

  • 機械学習の前処理やデータ分析において便利なwindow関数の使用方法を説明する。

準備

  • 使用するテーブル

    • book(購買対象物テーブル)
      • データ
book_id book_name price
1 1000のバグを持つ男 600
2 あなたもなれるスーパーエンジニア 1100
3 顧客をダマス極意 1200
4 バグか仕様か 1150
5 今こそ学ぶC++ 900
6 スーパーエンジニアを育てる方法 1100
7 上司に好かれる77の戦術 700
8 コードを書かないエンジニア 600
9 javaとjavascriptの違いを説明するには 900
10 僕は帰宅してからコーディングする 600
  • テーブル作成

    CREATE TABLE book
    (
      book_id SERIAL PRIMARY KEY,
      book_name varchar(255) not null,
      price DECIMAL (11, 2) not null
    );
    
  • データインポート

    INSERT INTO book (book_name, price)VALUES
      ('1000のバグを持つ男',600),
      ('あなたもなれるスーパーエンジニア',1100),
      ('顧客をダマス極意',1200),
      ('バグか仕様か',1150),
      ('今こそ学ぶC++',900),
      ('スーパーエンジニアを育てる方法',1100),
      ('上司に好かれる77の戦術',700),
      ('コードを書かないエンジニア',600),
      ('javaとjavascriptの違いを説明するには',900),
      ('帰宅後やっとコードを書き始める',600);
    
    • purchase(購買履歴テーブル)
      • データ
purchase_id user_id book_id
1 1 1
2 1 4
3 1 8
4 1 9
5 2 1
6 2 2
7 2 6
8 3 1
9 3 7
10 3 8
11 3 3
12 3 5
13 3 10
  • テーブル作成

    CREATE TABLE purchase
    (
      purchase_id SERIAL PRIMARY KEY,
      user_id INT NOT NULL,
      book_id INT NOT NULL,
      FOREIGN KEY (book_id) REFERENCES book (book_id)
    );
    
  • データ挿入

    INSERT INTO purchase (user_id, book_id)VALUES
    (1,1),
    (1,4),
    (1,8),
    (1,9),
    (2,1),
    (2,2),
    (2,6),
    (3,1),
    (3,7),
    (3,8),
    (3,3),
    (3,5),
    (3,10);
    

window関数の概要

  • 概要

    • window関数は集約関数と似ているが、集約関数と異なりレコードを削除しない。
    • 以下では、集約関数と比較しながらwindow関数の説明をする。
  • 集約関数を用いた平均額の算出

    • 集約関数を用いて、購入額の平均を算出する処理は以下になる。
    • AVG関数の引数にpriceを指定するだけ。
    • sql
      SELECT
        AVG(price)
      FROM
        purchase
      INNER JOIN book USING (book_id);
    
    • 結果
avg
819.2307692307692308
  • 集約関数を用いたユーザーごとの平均額の算出

    • 集約関数を用いて、ユーザー毎の購入額の平均を算出する処理は以下になる。
    • group byを用いて、ユーザーごとにグループ化した上で平均を計算するだけ。
    • sql
      SELECT
        user_id,
        AVG(price)
      FROM
        purchase
      INNER JOIN book USING (book_id)
      GROUP BY
        user_id;
    
    • 結果
user_id avg
3 766.6666666666666667
2 933.3333333333333333
1 812.5000000000000000
  • window関数を用いたユーザーごとの平均額の算出

    • window関数を用いると以下のようになる。
    • 集約関数と同様にユーザーごとにグループ化した上で平均が算出されるが、集約関数とは異なり、レコードが削除されない。
    • sql
      SELECT
        user_id,
        price,
        AVG (price) OVER (PARTITION BY user_id)
      FROM
        purchase
      INNER JOIN book USING (book_id);
    
    • 結果
user_id price avg
1 600.00 812.5000000000000000
1 1150.00 812.5000000000000000
1 600.00 812.5000000000000000
1 900.00 812.5000000000000000
2 600.00 933.3333333333333333
2 1100.00 933.3333333333333333
2 1100.00 933.3333333333333333
3 600.00 766.6666666666666667
3 700.00 766.6666666666666667
3 600.00 766.6666666666666667
3 1200.00 766.6666666666666667
3 900.00 766.6666666666666667
3 600.00 766.6666666666666667
  • 動作順序
    • window関数は、JOIN, WHERE, GROUP BY と HAVING 句のあとに動作する。
    • 加えて、ORDER BY句の前に動作する。

window関数の書き方

  • 基本構文
   window関数 (引数1, 引数2) OVER (PARTITION BY expression ORDER BY expression)
  • window関数

    • 集約関数をwindow関数として使用できる。
    • 加えて、以下のようなビルトインのwindow関数を使用できる。
      • row_number(), rank(), dense_rank()
  • PARTITION BY

    • 指定したものでパーティーションの設定(グループ化)を行う。
  • ORDER BY

    • パーティーション内での並び方を指定する。

window関数の使用例

  • レコードの番号

    • パーティーション内でのレコードの番号を取得する処理を以下のように書ける。
    • ROW_NUMBER

      • ユーザーごとに購入額の高い順にレコードに番号を振る。
      • ROW_NUMBER関数は、同一の値でも別の番号が振られる。
      • sql
       SELECT
         user_id,
         price,
         ROW_NUMBER() OVER ( PARTITION BY user_id ORDER BY price)
       FROM
         purchase
       INNER JOIN book USING (book_id);
      
      • 結果
user_id price row_number
1 600.00 1
1 600.00 2
1 900.00 3
1 1150.00 4
2 600.00 1
2 1100.00 2
2 1100.00 3
3 600.00 1
3 600.00 2
3 600.00 3
3 700.00 4
3 900.00 5
3 1200.00 6
  • RANK

    • ROW_NUMBER関数の例と同様に、ユーザーごとに購入額の高い順にレコードに番号を振る。
    • ただし同じ値があるときは同じ番号を振り、次の値はその分スキップする。
    • sql

       SELECT
         user_id,
         price,
         RANK() OVER ( PARTITION BY user_id ORDER BY price)
       FROM
         purchase
       INNER JOIN book USING (book_id);
      
    • 結果

user_id price rank
1 600.00 1
1 600.00 1
1 900.00 3
1 1150.00 4
2 600.00 1
2 1100.00 2
2 1100.00 2
3 600.00 1
3 600.00 1
3 600.00 1
3 700.00 4
3 900.00 5
3 1200.00 6
  • DENSE_RANK

    • RANK関数と似ているが、同じ値があるときに次の値をスキップしない。
    • sql

       SELECT
         user_id,
         price,
         DENSE_RANK() OVER ( PARTITION BY user_id ORDER BY price)
       FROM
         purchase
       INNER JOIN book USING (book_id);
      
    • 結果

user_id price dense_rank
1 600.00 1
1 600.00 1
1 900.00 2
1 1150.00 3
2 600.00 1
2 1100.00 2
2 1100.00 2
3 600.00 1
3 600.00 1
3 600.00 1
3 700.00 2
3 900.00 3
3 1200.00 4
  • パーティーション内での最初と最後の値

    • FIRST_VALUE

      • ユーザー毎の購入額の最小値をレコードに追加する。
      • sql
       SELECT
         user_id,
         price,
         FIRST_VALUE (price) OVER ( PARTITION BY user_id ORDER BY price) as user_lowest_price
       FROM
         purchase
       INNER JOIN book USING (book_id);
      
      • 結果
user_id price user_lowest_price
1 600.00 600.00
1 600.00 600.00
1 900.00 600.00
1 1150.00 600.00
2 600.00 600.00
2 1100.00 600.00
2 1100.00 600.00
3 600.00 600.00
3 600.00 600.00
3 600.00 600.00
3 700.00 600.00
3 900.00 600.00
3 1200.00 600.00
  • LAST_VALUE

    • ユーザー毎の購入額の最大値をレコードに追加する。
    • sql

       SELECT
         user_id,
         price,
         LAST_VALUE (price) OVER ( PARTITION BY user_id ORDER BY price RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as user_highest_price
       FROM
         purchase
       INNER JOIN book USING (book_id);
      
    • PARTITION BY user_id ORDER BY price RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

      • パーティション全体に渡る集約処理を行うための設定
      • デフォルト設定は(RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)で、これはパーティションの先頭から現在の行を集約処理の対象とする。(そのため最小値を出すときは、この指定がなくても正しく動作した)
    • 結果

user_id price user_highest_price
1 600.00 1150.00
1 600.00 1150.00
1 900.00 1150.00
1 1150.00 1150.00
2 600.00 1100.00
2 1100.00 1100.00
2 1100.00 1100.00
3 600.00 1200.00
3 600.00 1200.00
3 600.00 1200.00
3 700.00 1200.00
3 900.00 1200.00
3 1200.00 1200.00
  • 前後のレコード

    • LAG関数やLEAD関数を使用すると、レコードの前後にあるレコードの値を取得できる。
    • LAG関数やLEAD関数の書き方
      LAG  (expression [,offset] [,default])
      LEAD (expression [,offset] [,default])
    
    • offset
      • 何行ずらした位置のレコードを取得するか
      • デフォルト値: 1
    • default
      • ずらした位置にレコードが存在しない場合、設定する値
      • デフォルト値: NULL
        • LAG
    • ユーザーごとに、対象のレコードの価格よりも、1つ低い価格を取得する。
    • sql

       SELECT
         user_id,
         price,
         LAG(price, 1) OVER(PARTITION BY user_id ORDER BY price) AS prev_price
       FROM
         purchase
       INNER JOIN book USING (book_id)
       GROUP BY user_id, price;
      
    • 結果

user_id price prev_price
1 600.00
1 900.00 600.00
1 1150.00 900.00
2 600.00
2 1100.00 600.00
3 600.00
3 700.00 600.00
3 900.00 700.00
3 1200.00 900.00
  • LEAD

    • ユーザーごとに、対象のレコードの価格よりも、1つ高い価格を取得する。
    • sql

       SELECT
         user_id,
         price,
         LEAD(price, 1) OVER(PARTITION BY user_id ORDER BY price) AS next_price
       FROM
         purchase
       INNER JOIN book USING (book_id)
       GROUP BY user_id, price;
      
    • 結果

user_id price next_price
1 600.00 900.00
1 900.00 1150.00
1 1150.00
2 600.00 1100.00
2 1100.00
3 600.00 700.00
3 700.00 900.00
3 900.00 1200.00
3 1200.00

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む