情弱エンジニアのなかのblog

一人前のエンジニアになる為のブログです

MySQLで日付に関する処理

日付の処理の実装

MySQLでとある月から〇ヶ月後のデータを取得するなどを行ったので手順書等を記載いたします。

1.DATE_FORMAT

日付データから特定の数値だけ必要な時はDATE_FORMATを使います。 例えばフィールド[birthday]に[1994-05-23]という形式で誕生日のデータが入っていて 年と月の情報だけが欲しい場合以下のように記述することで 年と月のデータを取得できます。

(DATE_FORMAT(birthday,'%Y%m')

これで先ほどのデータが [1994-05]となります。

例えばこれを結合条件で利用するとなると以下のようになります。

(DATE_FORMAT(hoges.day,'%Y%m') = (DATE_FORMAT(customers.birthday,'%Y%m')

まあ誕生日を結合条件にすることがあるかは疑問ですが、、、

2.DATE_ADD

とある日付のデータがあり、その〇日後や〇ヶ月後のデータを取得したいときにDATE_ADDを使用します。 先ほどと同じように、フィールド[purchase_date]に[2017-06-01]という形式で購入日データが入っているとします 使い方は以下のようになります。

・3日後を取得したい。

DATE_ADD(purchase_date, INTERVAL 3 DAY)

DAYで日にち計算をします。 データは[2017-06-04]になります。

・5ヶ月前を取得したい

DATE_ADD(purchase_date, INTERVAL -5 MONTH)

MONTHで月計算をします。 データは[2017-01-01]になります

・来月を取得したい

DATE_ADD(LAST_DAY(CURDATE()),INTERVAL 1 DAY)

LAST_DAYで月末の日付を取得できます CURDATE()で現在の年月日を(0000-00-00)の形式で取得できます 1 DAYで次の日なので翌月のデータを取得できます。

.3 DATE_FORMAT と DATE_ADD の組合せ

さて続いては2ヶ月後のデータで月だけを取得したい時の処理を記載いたします。

 DATE_FORMAT(DATE_ADD(purchase_date , INTERVAL 2 MONTH),'%m')

DATE_ADDはデータが[0000-00-00]の形式である必要があるらしく、まず先に2ヶ月後のデータを取得してそのデータを DATE_FRMATで月のデータのみにいたします。

・来月の月のデータだけを取得するには以下のようになります。

 DATE_FORMAT( DATE_ADD(LAST_DAY(CURDATE()),INTERVAL 1 DAY) , '%m')

来月が誕生日の人のデータをとるときなどに使えます。

それでは

MySQLでデータの結合と月ごとのデータの出力

MySQLでサブクエリやDATE_FORMATを使用したので、 手順書等を記載いたします。

1.月毎にデータを出力する

データを月毎の結果で出力したい場合は DATE_FORMTというものを使います。

使い方としましては

SELECT
    DATE_FORMAT(fuga_time, '%Y-%m'),
    COUNT(*)
FROM
    hoges
GROUP BY
    DATE_FORMAT(fuga_time, '%Y%m');

といった形式で使用します。 例えば期間を指定すると、その期間で結果が表示されます。

SELECT
    DATE_FORMAT(fuga_time, '%Y-%m'),count(*)
FROM
    hoges
WHERE
    fuga_time between '2016-01-01' and '2016-12-31'
GROUP BY
    DATE_FORMAT(fuga_time, '%Y-%m')

こちらですと2016年1月から12月のデータが月毎で表示されます。

2.条件指定したテーブルを結合する

続いてはテーブルをWHEREで検索したものを他のテーブルに結合する手順を紹介いたします。 まずは単純にテーブルで検索を行います。

SELECT
    id
FROM
    customers
WHERE
    birthday between '1970-01-01' and '1999-12-31'

こちらの検索結果のテーブル情報を他のテーブルに結合したいときは サブクエリを使用します。

SELECT
    c.name , count(*) , sum(orders.price)
FROM
    orders
INNER JOIN
( SELECT
    id
FROM
    customers
WHERE
    birthday between '1970-01-01' and '1999-12-31') AS c
ON
    orders.customer_id = c.id

このようにすることでまとまったデータを他のテーブルに結合することが出来ます。

それでは

HTML5/CSS3を基礎から学ぶ

HTML5/CSS3の使い方等確認

現在HTML5やCSS3のコーディングの学習をしていまして そこで改めて学んだ知識等記載していきたいと思います。

ボックスモデル

CSSのボックスモデルについて記載致します。 HTML文書内に配置された要素は4つの領域をもち、階層があります。 一番内側から説明していきます。

まずはコンテンツエリアです。 単純にコンテンツ(内容)が表示されるエリアになります。

続いてパディングエリアです。 パディングエリアは要素の内側の余白までのことで、要素の外側とコンテンツとの間隔を調整できます。

続いてボーダーエリアです。 ボーダーエリアは要素の枠線までを含んだエリアです。 要素に背景色や背景画像を指定した場合、このボーダーエリアまで背景が適用されます。

最後にマージンエリアです。 マージンエリアは要素の外側の余白のことで、隣接するほかの要素との間隔を調整できます。

とても基本なところですが、最近のアプリ制作で意識していなかったので 自戒の念を込めて記載いたしました。

マージンの詳細

ボックスモデルの中でもmarginについて詳しく説明を記載いたします。

marginプロパティは、上下左右の余白をまとめて指定できます。 値を1つから4つまで指定出来て、値と個数の順番によって適用される位置が変わります。

//上下左右のmarginが10px
margin: 10px;

//上下のmarginが10px、左右のmarginが20px
margin: 10px 20px;

//上のmarginが10px、左右のmarginが20px、下のmarginが30px
margin: 10px 20px 30px;

//上のmarginが10px、右のmarginが20px、下のmarginが30px、左のmarginが40px
margin: 10px 20px 30px 40px;

こちらも基本的なことなのですが値が三つの場合はどうなるのかなど忘れていました。

このように基本の基本が抜けたままCakePHPでの制作などをしており UIの制作などで苦労していたので 初歩から学ぶことの大切さを実感致しました。

それでは

公開用アプリケーションのGit管理方法

サーバーのアプリをGitで管理する

サーバーでアプリを公開しているのですが、今後アプリをブラッシュアップをしていく予定なので リモートで制作したものをリポジトリに上げて、サーバーのアプリはpullするだけにしたいと思います。

1.サーバーのでGitHubの準備をする

サーバーでPuttyなどを使い、gitをインストールします。

$ git init

続いて公開鍵の作成を致します。

$ ssh-keygen -t rsa -C "[メールアドレス]"
Enter file in which to save the key (/c/fuga/hoge/.ssh/id_rsa): [左に出ているパスで良ければEnter]
Enter passphrase (empty for no passphrase):[任意のパスフレーズ入力]
Enter same passphrase again:[もう一度パスフレーズを入力]

鍵が出来ているか確認します。

$cd ~/.ssh
$ls ←.sshの中身を確認

中に「id_rsa.pub」というものが出来ていると思いますが、これが公開鍵です。 これの中身をコピーしてGitHubに登録します。

公開鍵の中身をコピーする方法としてほかのサイトでは

$ clip < ~/.ssh/id_rsa.pub

というコマンドが紹介されていたのですが、何故か私の環境では実行できなかったので

vim id_rsa.pub

で開いて内容を直接コピーしました。

2.GitHubで設定する

GitHubで右上のアイコンをクリックして「settings」を選択しましょう、続いて「SSH and GPG keys」を押します

右上の「new SSH key」で公開鍵の登録が出来るので Titleに任意のタイトルをつけて keyに先ほどの公開鍵の内容をペーストします「Add SSH key」で登録完了です。 f:id:nonaka-katuma-hal:20170725214658j:plain

3.サーバーでリポジトリからプロジェクトをCloneする

GitHubでサーバーにアップしたいプロジェクトのページで 「Clone or download」を押して表示されるテキストをコピーします。 f:id:nonaka-katuma-hal:20170725215438j:plain

続いてサーバーに戻りプロジェクトをCloneします。

$ git clone [テキストをペースト]

これでプロジェクトをサーバーに入れることが出来ますので 今後はリモートで制作したものをリポジトリにpushしてサーバーでpullしていきましょう。

それでは

CakePHPでComponentの実装

使いまわせて便利なComponent!

現在CakePHPでアプリを制作していまして、Componentを実装したので手順等を記載致します。

商品の紹介記事を投稿するアプリで記事データ(articles)には商品データ(products)がひもづいていて、その商品データには商品を売っている企業のデータ(companies)が紐づいています。 企業ごとの記事の数を企業の一覧表示画面で確認するという機能を制作致しました。

1.Componentの作成

まずはapp/Controller/ComponentにComponentファイルを作成します。

class CustomComponent extends Component {


public function get_article_count($table_name,$field_name,$this_list_count) {

    //記事データを取得できるようにする
    $article_data = ClassRegistry::init('Article');

    //検索用に文字列を繋げる
    $table_field = $table_name . "." . $field_name;

    //記事データと記事データに付随する記事数を取得したいフィールド情報を取得する
    $article_list = $article_data->find('all', array('fields' => array($table_field)));

    //記事ごとの目的のフィードの値を取得する
    for($i = 0; $i < count($article_list); $i++) {
        $field_id_list[$i] = $article_list[$i][$table_name][$field_name];
    }

    //記事数を代入する
    $article_count = count($field_id_list);

    //記事数を取得したいフィールドの数分配列を用意する
    for($i = 1; $i <= $this_list_count; $i++) {
        $field_each_article_count[$i] = 0;
    }

    //記事数を取得したいフィールドごとの記事の数を配列に代入する
    for($i = 0; $i < $article_count; $i++) {
        for($j = 1; $j <= $this_list_count; $j++) {

            if($field_id_list[$i] == $j) {
                //フィールドごとの検索をして記事データがあったら
                //記事の数を加算していく
                $field_each_article_count[$j]++;
                continue;
            }
        }
    }

    return $field_each_article_count;
}

}

これを作っていれば複数のControllerでフィールドごとの記事の数を取得できます。

2.Controllerでデータを渡す

Controllerからデータを渡して、記事の数を取得します。 今回はサイトごとの記事の数を取得します。

public function index() {
    
    $table_name = "Product";
    $field_name = "company_id";
    //サイトの数を取得する
    $site_count = count($this->Company->find('list'));
    //各サイトごとの記事数を取得する
    $company_each_article_count = $this->Custom->get_article_count($table_name,$field_name,$site_count);

    $this->set('company_each_article_count',$company_each_article_count);
    $this->set('companies', $this->Paginator->paginate());
}

この形式の処理をControllerに書くことで様々なフィールドごとの記事数を取得できます。

3.indexで表示する

最後にindexでサイト名の横に記事数を表示します。

<?php foreach ($companies as $id => $company): ?>
//サイト名を一覧する処理
<td>
    <?php
    $id++;
    echo $company_each_article_count[$id];
    ?>
</td>

これでComponentにフィールドごとに記事数を取得する処理を作ることが出来ました。

もっと効率的に実装する方法もあるかと思うのですがとりあえずはここまでで 出来たらまたアップします。

それでは

サーバーを借りてアップロードするまでの流れ(LOLIPOP編)

制作したアプリを公開しましょう!

現在制作中のアプリをサーバーを借りてアップしたのですが アップするまでに色々と苦労したので手順などを記載致します。

ちなみにアプリはCakePHPで制作していまして、DBの接続などでつまずくこともあったので 同じような状況の方がいたら参考にしていただければ幸いです。

1.サーバーを借りる

まずはサーバーを借りるところから始まります。 今回私はロリポップ!というサービスのレンタルサーバーを使いました。

ロリポップ!レンタルサーバー |今だけ初期費用無料キャンペーン中!

プランは エコノミー、ライト、スタンダード、エンタープライズ、の4種類があり 料金や使える機能、容量に差があります。 個人利用ならスタンダードまでで十分だと思います。

とりあえずお手軽なライトプランを申し込みました。 契約自体は時間がかからず、契約後10分とたたずにサーバーを使えるようになりました。

早速FTPPuttyを繋いで、利用しようと思ったらSSHで繋げることが出来ませんでした。

原因は単純でSSHを使うにはスタンダードプランにする必要があるとのことでした。 もう契約しちゃった後なのでどうしようかと思ったのですが、契約後のプランの変更が出来たので スタンダードプランに変更しました。

2.CakePHPをアップする

FTPを使ってアプリをまるまるサーバーにアップしました。 この状態でアプリのURLをおすと

f:id:nonaka-katuma-hal:20170718191314j:plain

CakePHP is NOT able to connect to the database.

Database connection "Mysql" is missing, or could not be created.
SQLSTATE[HY000] [2002] No such file or directory

などと「CakePHPはDBに接続していない」という意味のエラーが出ると思うので まずはDBの準備をしましょう。

ロリポップの管理画面からDBを製作する画面があるのでそちらからDBを作ります。 管理画面からサーバー名、アカウント名、パスワードなど必要な情報を確認できるので App/Config/database.phpの public $default の中身を編集してください。

これでDBをつなぐ事が出来たかと思います。 DB接続に関して以下のサイトを参考に致しました。

CakePHP のデータベースの作成と接続設定 - PHP入門 - Webkaru

3.Migrationsを使う

アプリにMigrationsを実装しておくとDBをいちいち作らなくて済むので便利です。 Migrationsを使うのでPuttyを開き、 「./Console/cake Migrations.migration status」を実行してMigrationsを使えるかどうか確認しようとすると

Error: Plugin Migrations could not be found.

と出てしまいました。

解決方法としましては、まずapp/Plugin に「Migration」と「Schema」フォルダが入っているか、中にDBのデータを記載したファイルがあるか確認します。

次にBootstrapを使っている場合はapp/Config/bootstrap.php

CakePlugin::load(array('TwitterBootstrap' , 'Migrations'));

を記入しているか確認します。 これらをしてもう一度./Console/cake Migrations.migration statusをするとMigrationsを使うことができると思います。

まずはこれでCakePHPのアプリを起動出来るかと思います。

またサーバー周りで何かあれば記載致します。 それでは

phpでランダムな処理があるアプリの注意点

乱数生成!

アプリでランダムな数値を扱う処理を作ったのですが、なにやら偏りがあるということが発覚したので その対処等を記載致します。

1.rand()は偏る?

アプリでランダムな処理をする時にshuffle()を使っていたのですが、 どうやらshuffle()では内部でrand()を使っているようです。

ただこのrand()が問題でして、多少の偏りがあるようです。

2.mt_rand()を使う!

mt_rand()はrand()よりも高速かつ乱数生成において優秀との情報を見つけたので こちらを使っていきます。 普通にmt_rand()を使うか、どうしてもshuffle()を使わなきゃいけない場合は 以下のコードを参考にしてください。

function mt_shuffle($array) {

        $cnt = count($array);

        //渡される配列の添え字は$cntより1少ない数値~0なので$cnt -1をする
        for($i = $cnt -1; $i > 0; $i--) {

            $j = mt_rand(0 , $i);
            if($i !== $j) {
                //配列の中身を入れ替える
                list($array[$i], $array[$j]) = [$array[$j], $array[$i]];
            }
        }
}

このような形でランダムな処理を実装できます。 が、これでも偏りが全く出ないわけではないのでそこは注意してください。

今回の記事を書くにあたり以下のサイトを参考に致しました。

PHP関数 - 乱数を生成 - mt_rand() - PHP入門のカルマ

それでは