商売力開発ブログ

非エンジニアがWebサービスの開発、運営によって商売力をつける記録、その他の雑記

【スポンサーリンク】

JavaScriptのDateオブジェクトを文字列で作成する場合について

今回はJavaScriptのDateオブジェクトのメモです。

時刻なしの日付文字列で指定する場合、ハイフンで行うとき注意する

Dateオブジェクトをnewするとき、指定する方法がいくつかありますが、日付文字列で指定する場合について調査します。
結果は Google Chrome で起動した場合の例になります。
まずはスラッシュで区切った日付文字列の場合です。

var date =new Date("2018/10/1");
console.log(date);

コンソールでは以下のようになります。想定通りです。

Mon Oct 01 2018 00:00:00 GMT+0900 (日本標準時)

次はハイフンで区切った場合です。

var date =new Date("2018-10-1");
console.log(date);

コンソールでは以下のようになります。こちらも結果は同じです。

Mon Oct 01 2018 00:00:00 GMT+0900 (日本標準時)

続いては少し日付を変更して、確かめます。

var date =new Date("2018/10/10");
console.log(date);

コンソールでは以下のようになります。想定通りです。

Wed Oct 10 2018 00:00:00 GMT+0900 (日本標準時)

次はハイフンで区切った場合です。

var date =new Date("2018-10-10");
console.log(date);

コンソールでは以下のようになります。

Wed Oct 10 2018 09:00:00 GMT+0900 (日本標準時)

この場合、時刻の部分に差異があり、「09:00:00」となっています。この時間は日本の時差の分と一致しています。この原因を調査すると、ハイフンで日付文字列にした場合、UTCとして扱われるためのようです。
developer.mozilla.org

注: ブラウザごとに動作が異なり一貫性がないため、Date コンストラクタ (または同等の Date.parse) で日付文字列を解釈しないように強くすすめます。RFC 2822 形式の文字列のサポートは、慣例にすぎません。 ISO 8601 フォーマットのサポートは、日付のみの文字列 (例: "1970-01-01") が地方時ではなくUTCとして扱われる点で異なります。

しかし、「2018-10-1」のときはUTCではありませんでした。これは ISO 8601 の年月日の形式が「YYYY-MM-DD」であり、日が2桁表示だからです。「2018-10-1」の場合、ISO 8601 の形式ではありませんが、ブラウザ側で日付として解釈してDateオブジェクトを作成しているようです。(例えばIE11で試すと、「Invalid data」としてエラーとなります。)
正しい形式で指定した場合、どうなるか確認してみます。

var date =new Date("2018-10-01");
console.log(date);

コンソールでは以下のようになります。

Mon Oct 01 2018 09:00:00 GMT+0900 (日本標準時)

この形式の場合、UTCとして扱われていることが確認できました。
ISO 8601 の年月日の形式が「YYYY-MM-DD」ですので、ハイフンを利用してDateオブジェクトをnewする場合、日にちだけでなく月の部分についても2桁になるようにしておかないと時刻まで扱うときに不具合の要因となるので注意しましょう。例えばgetTime()を利用して日付の大小比較をしているときなどです。それまで問題なかったものが、MM-DDとなる10月10日からおかしくなってしまうという問題が発生するかもしれません。

まとめ

今回はJavaScriptのDateオブジェクトを文字列で作成する場合についてでした。

以上

【更新情報】工数推移グラフの表示

※Project-Alphaは2019年12月をもって、サービスの提供を終了します。

今回は我々が開発しているプロジェクト管理ツールProject-Alpha(プロジェクトアルファ)を更新したので内容を説明します。

更新情報

更新内容

ガントチャートで登録した内容から工数の推移がわかるグラフを表示できるようになりました。ガントチャートの入力画面から「表・グラフ」を選択して、工数推移グラフを選択すると新しいウィンドウで表示されます。

工数推移グラフで開始から終了までの期間の工数推移が分かるようになります。予定については、開始日付と終了日付が入力されているものが反映されます。実績については、開始日付が入力されているものが反映されます。進捗率があっても、開始日付が入力されていない場合、グラフ上には反映されません。

またマイルストーンの設定を行っている場合、その日付についてラインで表示されます。表示するラインの日付は以下の優先順位で入力のある日付上に表示されます。
①実績の終了日付がある場合、その終了日付
②実績の開始日付がある場合、その開始日付
③予定の終了日付がある場合、その終了日付

グラフの配色について

予定や実績の色については、進捗表の設定と同期しています。プロジェクト設定のコンテンツ設定から変更することが可能です。

例えば、進捗表の設定を以下のように変更します。

この場合の、工数推移グラフは以下のようになります。進捗表も同時に表示することができ、配色が同期するようになっていることがわかります。

※追記 以下の追加更新を行っています。

マイルストーンだけでなく基準日付もラインで表示されるようになり、タイトルだけでなく日付を表示するようにしました。

更に日次推移以外にもグラフを表示できるようになりました。

週次推移の場合は以下のようになります。

週次工数の場合は以下のようになります。各週ごとの予定と実績の工数を棒グラフで表示します。

 週次工数推移の場合は以下のようになります。累計工数と週ごとの工数を同時に表示されます。

各グラフの凡例の名称にマウスを乗せると、そのグラフ以外がうすくなります。またこの名称をクリックすると非表示となり、再度クリックすると非表示から表示に戻ります。

例えば予定工数をクリックして、非表示にした場合の表示は以下のようになります。

まとめ

今回は更新情報の内容の説明でした。
現在はこの表示のみですが、グラフについては今後複数のパターンで表示できるようになる予定です。

以上

【関連するリンク】

www.prj-alpha.biz

www.prj-alpha.biz

home.prj-alpha.biz

Laravelのクエリビルダを構築するメソッドの検討 - Select文を作成する②複数の結合条件の対応など

今回はPHPフレームワークの一つのLaravelの中から、データベースのクエリビルダを自動構築する設定を検討してみたいと思います。具体的には取得条件のテーブルなどの定義情報を渡して、クエリビルダを構築するメソッドを検討します。今回利用するDBはMySQLです。SQLの基本が理解できていることが前提となります。
これまでの内容は以下を参照してください。

Laravelのクエリビルダを構築するメソッドの検討 - Select文を作成する① - 商売力開発ブログ

Select文の構成

前回までの説明で結合条件と取得するカラムについて対応しました。以下のようなクエリ定義情報を渡すことでクエリビルダを構築するようにしました。

$queryDef=[
   'table' => [],
   'join' => [],
   'select' => [],
];

$queryDef['table']=['table1','joinTable2','leftTable3'];

$queryDef['join']=[
    [
        'tblNo' => 1,
        'type' => 'join',
        'cond'=>[
            ['leftTblNo' => 0,'leftCol'=>'col1','ope'=>'=','rightTblNo' => 1,'rightCol'=>'col1']
        ]
    ],
    [
        'tblNo' => 2,
        'type' => 'leftJoin',
        'cond'=>[
            ['leftTblNo' => 0,'leftCol'=>'col1','ope'=>'=','rightTblNo' => 2,'rightCol'=>'col1']
        ]
    ],
];

$queryDef['select']=[
    [
        'tblNo' => 0,
        'column' => 'col1',
        'alias' => NULL,
    ],
    [
        'tblNo' => 1,
        'column' => 'col2',
        'alias' => 'ColName',
    ],
];

ただこのままだと、使いにくい部分があるので、変更を加えていきます。

取得する部分の設定

取得するカラムの設定については、テーブルのNoと列名を指定することで取得してます。このままだと計算式などができないので、DB::rawメソッドで対応できるようにします。例えば以下のようなrawフラグをクエリ定義情報に追加してみます。'column'にDB::rawメソッドで使用する文字列を設定しています。注意が必要なのは、テーブル名のプレフィックスとして設定する文字列(この場合、「tbl」)を含めた形式で記述する必要があります。プレフィックスを変更する場合、こちらの設定も変更する必要が出てきます。

$queryDef['select']=[
    [
        'tblNo' => 0,
        'column' => 'col1',
        'alias' => NULL,
        'flgRaw' => FALSE,
    ],
    [
        'tblNo' => 1,
        'column' => 'col2',
        'alias' => 'ColName',
        'flgRaw' => FALSE,
    ],
    [
        'tblNo' => NULL,
        'column' => 'tbl1.col3+tbl2.col3',
        'alias' => 'ColRaw',
        'flgRaw' => TRUE,
    ],
];

この追加したフラグを元に、addSelectの部分を変更します。

for ($i=0; $i < count($queryDef['select']); $i++) { 
    //flgRawの有無
    if($queryDef['select'][$i]['flgRaw']){
        //flgRawの場合、カラムからのみ設定する
        $addCol=$queryDef['select'][$i]['column'];
    }else{
        //テーブルとカラムの設定
        $addCol=$prefix.$queryDef['select'][$i]['tblNo'].'.'.$queryDef['select'][$i]['column'];
    }
    
    //別名の設定
    if(!empty($queryDef['select'][$i]['alias'])){
        //別名を設定する
        $addCol=$addCol.' as '.$queryDef['select'][$i]['alias'];
    }
    //flgRawの有無
    if($queryDef['select'][$i]['flgRaw']){
        //DB::rawとして設定する
        $addCol=DB::raw($addCol);
    }
    
    //カラムの設定
    $query->addSelect($addCol);
}

この状態でtoSqlメソッドで確認すると以下の結果が得られました。

select
  `tbl0`.`col1`
  , `tbl1`.`col2` as `ColName`
  , tbl1.col3 + tbl2.col3 as ColRaw 
from
  `table1` as `tbl0` 
  inner join `joinTable2` as `tbl1` 
    on `tbl0`.`col1` = `tbl1`.`col1` 
  left join `leftTable3` as `tbl2` 
    on `tbl0`.`col1` = `tbl2`.`col1`

問題なくDB::rawメソッドの部分も設定されました。

複数条件による結合

joinやleftJoinの結合条件について、その結合条件の数が一つの場合はメソッドの引数に指定しますが、複数ある場合は、第2引数にクロージャを指定して設定することになります。

//結合条件が一つの場合
$query->join('table2', 'table1.col1', '=', 'table2.col1');

//結合条件が複数の場合
$query->join('table2', function($join){
    $join->on('table1.col1','=','table1.col1');
    $join->on('table1.col2','=','table1.col2');
});

複数の結合条件を構築するには、クエリ定義情報から動的にクロージャを定義し、それを渡すことによって対応することができそうです。ですが動的にメソッドを定義することは、ちょっと調査しても簡単に対応できそうにないので、他の方法で対応します。
具体的にどのように対応していくかと言うと、結合条件が一つの場合の書き方とDB::rawメソッドを利用して、複数の条件を渡します。結合条件の左辺の部分をDB::rawメソッドで設定し複数の条件と最終条件の左辺まで記述して対応するイメージとなります。

//結合条件が一つの場合と同じ形式にして、DB::rawで対応する。
$query->join('table2', DB::raw('条件1' and '条件2' andand '最終条件の左辺'), '=', 'table2.col1');

クエリ定義情報の結合条件を複数持てるようにし追加してみます。

$queryDef['join']=[
    [
        'tblNo' => 1,
        'type' => 'join',
        'cond'=>[
            ['leftTblNo' => 0,'leftCol'=>'col1','ope'=>'=','rightTblNo' => 1,'rightCol'=>'col1'],
            ['leftTblNo' => 0,'leftCol'=>'col2','ope'=>'=','rightTblNo' => 1,'rightCol'=>'col2'],
        ]
    ],
    [
        'tblNo' => 2,
        'type' => 'leftJoin',
        'cond'=>[
            ['leftTblNo' => 0,'leftCol'=>'col1','ope'=>'=','rightTblNo' => 2,'rightCol'=>'col1'],
        ]
    ],
];

このクエリ定義情報から、結合条件が一つの場合と同じ形式にして、DB::rawメソッドで対応するように設定すると以下のようになります。

for ($i = 0; $i < count($queryDef['join']); $i++) {
    //左辺に設定する文字列
    $leftString='';
    //結合するテーブルと別名の設定
    $joinTable = $queryDef['table'][$queryDef['join'][$i]['tblNo']].' as '.$prefix.$queryDef['join'][$i]['tblNo'];
    
    for ($j = 0; $j < count($queryDef['join'][$i]['cond']); $j++) {
        //左結合カラム
        $leftCol = $prefix.$queryDef['join'][$i]['cond'][$j]['leftTblNo'].'.'.$queryDef['join'][$i]['cond'][$j]['leftCol'];
        //等号などの演算子
        $operator = $queryDef['join'][$i]['cond'][$j]['ope'];
        //右結合カラム
        $rightCol = $prefix.$queryDef['join'][$i]['cond'][$j]['rightTblNo'].'.'.$queryDef['join'][$i]['cond'][$j]['rightCol'];
        
        //左辺の文字列への設定
        $leftString = $leftString.$leftCol;
        
        if($j != count($queryDef['join'][$i]['cond'])-1){
            //最後の結合条件でない場合、左辺の文字列に、演算子と右結合カラムを追加し、and条件で設定する
            $leftString = $leftString.' '.$operator.' '.$rightCol.' and ';
        }else{
            //最後の結合条件、結合の種類ごとに設定する
            if($queryDef['join'][$i]['type'] == 'join'){
                //join
                $query->join($joinTable,DB::raw($leftString),$operator,$rightCol);
            }elseif($queryDef['join'][$i]['type'] == 'leftJoin'){
                //leftJoin
                $query->leftJoin($joinTable,DB::raw($leftString),$operator,$rightCol);
            }
        }
    }
}

この状態でtoSqlメソッドで確認すると以下の結果が得られました。

select
  `tbl0`.`col1`
  , `tbl1`.`col2` as `ColName`
  , tbl1.col3 + tbl2.col3 as ColRaw 
from
  `table1` as `tbl0` 
  inner join `joinTable2` as `tbl1` 
    on tbl0.col1 = tbl1.col1 
    and tbl0.col2 = `tbl1`.`col2` 
  left join `leftTable3` as `tbl2` 
    on tbl0.col1 = `tbl2`.`col1`

問題なく結合条件が設定されています。これにより複数の結合条件にも動的に対応できるようになっています。この対応によりクエリビルダを自動構築するメソッドの対応範囲が大きくなり、色々な場面で利用できるようになったと思います。

まとめ

今回はLaravelのデータベースのクエリビルダについて、定義情報から構築する方法を検討しました。
今回の検討により、Select項目や結合条件については、ある程度対応できる状態になりました。この他の設定については、また別の機会で紹介します。

以上

【関連するリンク】 www.prj-alpha.biz www.prj-alpha.biz

Laravelのクエリビルダを構築するメソッドの検討 - Select文を作成する①

今回はPHPフレームワークの一つのLaravelの中から、データベースのクエリビルダを自動構築する設定を検討してみたいと思います。具体的には取得条件のテーブルなどの定義情報を渡して、クエリビルダを構築するメソッドを検討します。今回利用するDBはMySQLです。SQLの基本が理解できていることが前提となります。
またこのメソッドに関連する他の記事については以下を参照して下さい。

Laravelのクエリビルダを構築するメソッドの検討 - Select文を作成する②複数の結合条件の対応など - 商売力開発ブログ

クエリビルダを活用する

Laravelではクエリビルダが用意されており、このメソッド使用することでクエリを作成してデータベースを操作することができることは、以前紹介しました。
www.prj-alpha.biz
クエリビルダを利用することで簡単にデータベースからデータを取得できますが、使用頻度が多い場合は毎回記述するとなると結構面倒です。そこでクエリビルダを構築するメソッドを検討したいと思います。今回は簡単なデータの取得の部分、要はSelect文を構築するクエリビルダについて考えていきたいと思います。

クエリビルダとSelect文の構成要素

Select文の構成は簡単なものだと以下のようになります。

SELECT select_list
FROM table_list
[ WHERE search_conditions ]
[ GROUP BY group_by_list ]
[ HAVING search_conditions ]
[ ORDER BY order_list [ ASC | DESC ] ]

今回はこの中で、SELECT、FROMについてクエリビルダを構築するメソッドを検討します。以下のようなSelect文を構成するためのクエリ定義情報を受け取ると、その定義に合わせたクエリビルダを構築するイメージです。

$queryDef=[
   'table' => [],
   'join' => [],
   'select' => [],
];

テーブルの設定と結合条件

まず始めにテーブルの設定に関して考えてみます。クエリビルダで記述する場合、DBファサードに基となるテーブルを設定し、結合を行う場合はjoinやleftJoinメソッドを利用し結合対象のテーブルを指定し、結合条件を記載します。

$query = DB::table('table1');
//内部結合
$query->join('joinTable2', 'table1.col1', '=', 'joinTable2.col1');
//左外部結合
$query->leftJoin('leftTable3', 'table1.col1', '=', 'leftTable3.col1');

ここで考えたいのがテーブル名についてです。結合条件にもテーブル名を持っていますが、これを別名で置き換えるようにします。別名を付けることで、同じテーブルとの結合が複数必要な場合にも対応することができます。例えば、クエリ定義情報のtable設定が以下のようになってるとします。

$queryDef['table']=['table1','joinTable2','leftTable3'];

結合条件にはテーブルのNoを指定して書き換えるようにします。わかりやすくするため、テーブルのプレフィックスも設定します。

//テーブル名のプレフィックス
$prefix = 'tbl';
$query = DB::table($queryDef['table'][0].' as '.$prefix.'0');
//内部結合
$query->join($queryDef['table'][1].' as '.$prefix.'1', $prefix.'0'.'.col1', '=', $prefix.'1'.'.col1');
//左外部結合
$query->leftJoin($queryDef['table'][2].' as '.$prefix.'2', $prefix.'0'.'.col1', '=', $prefix.'2'.'.col1');

この状態でどのようなSQLが発行されるか、確認してみます。以下のtoSqlメソッドで確認することができます。

logger($query->toSql());

この結果は以下のようになりました。

select
  * 
from
  `table1` as `tbl0` 
  inner join `joinTable2` as `tbl1` 
    on `tbl0`.`col1` = `tbl1`.`col1` 
  left join `leftTable3` as `tbl2` 
    on `tbl0`.`col1` = `tbl2`.`col1`

テーブルをクエリ定義情報から設定できるイメージができたので、続いては結合条件の部分です。結合条件には対象のテーブルと、結合するカラムの情報が必要になります。クエリ定義情報のjoin設定を以下のようにします。

$queryDef['join']=[
    [
        'tblNo' => 1,
        'type' => 'join',
        'cond'=>[
            ['leftTblNo' => 0,'leftCol'=>'col1','ope'=>'=','rightTblNo' => 1,'rightCol'=>'col1']
        ]
    ],
    [
        'tblNo' => 2,
        'type' => 'leftJoin',
        'cond'=>[
            ['leftTblNo' => 0,'leftCol'=>'col1','ope'=>'=','rightTblNo' => 2,'rightCol'=>'col1']
        ]
    ],
];

この定義情報から結合するようにしてみます。

//テーブル名のプレフィックス
$prefix = 'tbl';
$query = DB::table($queryDef['table'][0].' as '.$prefix.'0');

for ($i=0; $i < count($queryDef['join']); $i++) {
    //結合するテーブルと別名の設定
    $joinTable = $queryDef['table'][$queryDef['join'][$i]['tblNo']].' as '.$prefix.$queryDef['join'][$i]['tblNo'];
    //左結合カラム
    $leftCol = $prefix.$queryDef['join'][$i]['cond'][0]['leftTblNo'].'.'.$queryDef['join'][$i]['cond'][0]['leftCol'];
    //等号などの演算子
    $operator = $queryDef['join'][$i]['cond'][0]['ope'];
    //右結合カラム
    $rightCol = $prefix.$queryDef['join'][$i]['cond'][0]['rightTblNo'].'.'.$queryDef['join'][$i]['cond'][0]['rightCol'];
    //結合するタイプごとに設定するメソッドを変更する
    if($queryDef['join'][$i]['type']=='join'){
        //join
        $query->join($joinTable,$leftCol,$operator,$rightCol);
    }elseif($queryDef['join'][$i]['type']=='leftJoin'){
        //leftJoin
        $query->leftJoin($joinTable,$leftCol,$operator,$rightCol);
    }
}

この状態でtoSqlメソッドで確認すると同じ結果が得られました。

取得するカラムの設定

取得対象のテーブルの準備ができましたので、続いては取得するカラムの設定です。取得対象となるカラムの情報にはテーブルとカラムの情報が必要です。テーブルはNoを指定するようにします。クエリ定義情報のselect設定を以下のようにします。

$queryDef['select']=[
    [
        'tblNo' => 0,
        'column' => 'col1',
        'alias' => NULL,
    ],
    [
        'tblNo' => 1,
        'column' => 'col2',
        'alias' => 'ColName',
    ],
];

この定義情報からカラムを追加するようにしてみます。

//テーブル名のプレフィックス
$prefix = 'tbl';
$query = DB::table($queryDef['table'][0].' as '.$prefix.'0');

for ($i=0; $i < count($queryDef['join']); $i++) {
    //結合するテーブルと別名の設定
    $joinTable = $queryDef['table'][$queryDef['join'][$i]['tblNo']].' as '.$prefix.$queryDef['join'][$i]['tblNo'];
    //左結合カラム
    $leftCol = $prefix.$queryDef['join'][$i]['cond'][0]['leftTblNo'].'.'.$queryDef['join'][$i]['cond'][0]['leftCol'];
    //等号などの演算子
    $operator = $queryDef['join'][$i]['cond'][0]['ope'];
    //右結合カラム
    $rightCol = $prefix.$queryDef['join'][$i]['cond'][0]['rightTblNo'].'.'.$queryDef['join'][$i]['cond'][0]['rightCol'];
    //結合するタイプごとに設定するメソッドを変更する
    if($queryDef['join'][$i]['type']=='join'){
        //join
        $query->join($joinTable,$leftCol,$operator,$rightCol);
    }elseif($queryDef['join'][$i]['type']=='leftJoin'){
        //leftJoin
        $query->leftJoin($joinTable,$leftCol,$operator,$rightCol);
    }
}

for ($i=0; $i < count($queryDef['select']); $i++) { 
    //テーブルとカラムの設定
    $addCol=$prefix.$queryDef['select'][$i]['tblNo'].'.'.$queryDef['select'][$i]['column'];
    //別名の設定
    if(!empty($queryDef['select'][$i]['alias'])){
        //別名を設定する
        $addCol=$addCol.' as '.$queryDef['select'][$i]['alias'];
    }
    //カラムの設定
    $query->addSelect($addCol);
}

この状態でtoSqlメソッドで確認すると以下の結果が得られました。

select
  `tbl0`.`col1`
  , `tbl1`.`col2` as `ColName` 
from
  `table1` as `tbl0` 
  inner join `joinTable2` as `tbl1` 
    on `tbl0`.`col1` = `tbl1`.`col1` 
  left join `leftTable3` as `tbl2` 
    on `tbl0`.`col1` = `tbl2`.`col1`

問題なく別名も設定されました。

まとめ

今回はLaravelのデータベースのクエリビルダについて、定義情報から構築する方法を検討しました。
ここまではSelectを行うのに最低限の設定となります。この他の設定については、また別の機会で紹介します。

以上

【関連するリンク】 www.prj-alpha.biz www.prj-alpha.biz

Laravelのクエリビルダの基本機能を確認する

今回はPHPフレームワークの一つのLaravelの中から、データベースのクエリビルダの基本機能について確認します。今回利用するDBはMySQLです。

クエリビルダの基本

Laravelではクエリビルダが用意されており、このメソッド使用することでクエリを作成してデータベースを操作することができます。
クエリビルダを使用するにはDBファサードをuseしておく必要があります。

use DB;

まずDBファサードのtableメソッドを使用して取得したテーブル名を指定します。以下ではusersテーブルを指定してます。

$users = DB::table('users');

指定したテーブルのレコードを取得するには、getメソッドを使用します。getメソッドによりSelectされることになります。上記のクエリビルダインスタンスを使用する場合、以下のようにして取得できます。

$records = $users->get();

この場合、usersテーブルが全件取得されます。取得されたレコードは、StdClassオブジェクトのインスタンスを結果として含むCollectionオブジェクトとして返ってきます。以下では取得した結果の最初のデータのname(usersテーブルのnameカラム)を表示します。

echo $records[0]->name;

その他の基本構文

ここまでSelectを行うのに必要最低限のコードを確認しました。ここからSelectを行う際に良く使うメソッドを確認していきます。共通で以下のテーブルを使用するものとします。

$query = DB::table('table1');

取得するカラムを指定する

Selectする際に必要なカラムを指定する場合、selectメソッドやaddSelectメソッドで対応することができます。取得したいカラム名を渡すことが指定されます。両方のメソッドとも複数のカラム名を指定できます。

$query->select('col1','col2');
//ここでgetを行うと、2列取得されます

$query->addSelect('col3');
//ここでgetを行うと、3列取得されます

$query->select('col1','col2')->select('col1');
//ここでgetを行うと、1列取得されます

$query->select('col1');
$query->addSelect('col2','col3');
//ここでgetを行うと、3列取得されます

ちなみにカラム名に別名をつけたい場合は以下のようになります。

$query->select('col1','col2 as name2');
$query->addSelect('col3 as name3');

SQL文をそのまま使用する

selectメソッドでカラム名を指定して取得しましたが、関数や算出を行いたいなどSQLを直接使用したい場面もあります。そのようなときにはDB::rawメソッドを使用することで対応することができます。

$query->select(DB::raw('col1, CONCAT(col2,col3) as col23'));
//以下は上と同じとなります
$query->select('col1',DB::raw('CONCAT(col2,col3) as col23'));

DB::rawメソッドを使用して書きましたが、クエリのそれぞれに対応したrawメソッドが用意されています。
selectの部分についてはselectRawメソッドが用意されています。selectRawはaddSelect(DB::raw(...))と同じです。

$query->select(DB::raw('col1, CONCAT(col2,col3) as col23'));
//以下は上と同じとなります
$query->select('col1'));
$query->selectRaw('CONCAT(col2,col3) as col23'));
//以下も上と同じとなります
$query->select('col1'));
$query->addSelect(DB::raw('CONCAT(col2,col3) as col23'));

rawメソッドはそのままクエリとして実行されるので、SQLインジェクションが発生しないように気を付けましょう。

JOINを設定する

テーブルを結合する場合、内部結合がjoinメソッド、左外部結合がleftJoinメソッドが用意されています。テーブル名と結合条件を指定することができます。

//内部結合
$query->join('table2', 'table1.col1', '=', 'table2.col1')
    ->join('table3', 'table1.col2', '=', 'table3.col2');
//左外部結合
$query->leftJoin('table4', 'table1.col1', '=', 'table4.col1')
    ->leftJoin('table5', 'table1.col2', '=', 'table5.col3');

テーブルの結合条件が複数ある場合は、第2引数にクロージャを指定して設定することができます。

$query->join('table2', function($join){
    $join->on('table1.col1','=','table1.col1');
    $join->on('table1.col2','=','table1.col2');
});

ちなみにLaravel5.6ではサブクエリのJOINにも対応できるようになったようです。

WHEREを設定する

WHERE句についてはいくつものメソッドが用意されています。一番基本はwhereメソッドです。

$query->where('col1','=',0);
$query->where('col2','>',0);
$query->where('col3','<>',0);
$query->where('col4','like','%1');

この書き方やチェーンでつなげるとANDでのWHERE句になります。ORで対応したい場合はorWhereメソッドを使います。
この他にwhereBetween、whereIn、whereNotIn、whereNull、whereNotNull、whereRaw、orWhereRawなどがあります。

クエリビルダをどのように活用するか

クエリビルダを利用して簡単なSelectを行う方法は確認できました。SQLがわかっている人であれば、特に難しいことなく取得するコードを記述できると思います。
ただデータベースからSelectを行なおうとする度にこれらの構文を記述するのは結構面倒です。なので我々は、取得したいテーブル、結合条件、取得対象カラム、抽出条件などの定義情報を引数として渡すと、Select結果が返ってくるような関数やメソッドを定義して取得するようにしています。このあたりの設定例については、機会があれば別途紹介したいと思います。
※以下の記事で紹介しています。

Laravelのクエリビルダを構築するメソッドの検討 - Select文を作成する① - 商売力開発ブログ
Laravelのクエリビルダを構築するメソッドの検討 - Select文を作成する②複数の結合条件の対応など - 商売力開発ブログ

まとめ

今回はLaravelのデータベースのクエリビルダの基本機能のうち主にSelectの方法について確認しました。

以上
【関連するリンク】
www.prj-alpha.biz
www.prj-alpha.biz

はてなブログをHTTPS化した後の、Search Console の状態を確認する

今回は、はてなブログをHTTPS化した後のグーグルの Search Console の状態を紹介します。

HTTPS化した後の状態

はてなブログをHTTPS化しても、その直後はグーグル検索の結果はHTTPのURLが表示されますが、それが徐々にHTTPSに置き換わっていきます。その状況がグーグルの Search Console のインデックスの状態として確認できます。
以前に書いた以下のブログではHTTPS化した場合、 Search Console のアドレス変更で対応できるような記載をしていましたが、HTTPS化のみの場合はできませんでした。

www.prj-alpha.biz

Search Console のアドレス変更はできませんので、基本的にはインデックスが移行されるのをただ待つということになります。
ちなみにグーグル検索の結果がHTTPのURLの状態でも、はてなブログが自動で301リダイレクトしてHTTPSのURLへアクセスすることになります。301リダイレクトが分からない人は以下を参考にして下さい。

www.prj-alpha.biz

Search Console での確認

6月中旬にHTTPS化してからの状態を示します。ベータ版ですが新しい Search Console での表示結果を加工したもので示します。上がHTTPで下がHTTPSの表示結果となります。棒グラフがインデックスに登録されたページ数で、折れ線グラフは表示回数です。HTTP化を変更してから少しずつインデックスが移行されているのが分かります。

こちらも上がHTTPで下がHTTPSの表示結果となります。クリック回数の状況で、青がクリック回数で、ターコイズブルーが表示回数です。インデックスが移行されるにつれて、上のHTTPの表示回数とクリック回数が減っていき、HTTPSの方が増えていってます。注目したいのがクリック数と表示回数の目盛りの値です。HTTPSの方がどちらも3倍以上になっています。変更日以降に記事の数は多少増えてはいえますが、それ以上の伸び率です。HTTPSになってから、グーグル検索からのアクセスが大幅に伸びました。

ちなみにインデックスカバレッジでその「有効」と「除外」の内容のページがわかります。以下はHTTPSの方ですが、重複している部分が0となっていれば、移行がほぼ完了したものと思われます。

こちらはHTTPの方です。リダイレクトや重複しているページが増加してます。こちらをクリックすると移行されたページの情報が分かります。

HTTPS化してから約2か月かかってますね。早いのか遅いのか・・・URL変更の時はアドレス変更依頼をすることで一週間程度で移行できてたので、それと比べると大分時間がかかってますね。

Fetch as Google でリクエストすることもできる

Fetch as Google を利用して、インデックス登録をリクエストすることもできます。
移行に時間がかかっていたので試しにリクエストしてました。これにより大きな効果があるという感触はあまり得られませんでした。リクエストしたページは数日経つと移行されるものもあれば、なかなか移行されないものもありました。以下はHTTPSでのリクエストの画面です。

こちらはHTTPでの画面です。ステータスは「リダイレクトされました」となっており、インデックス登録を依頼するとリダイレクトページとして認識されるようです。

まとめ

今回ははてなブログをHTTPS化した後のグーグルの Search Console の状態の紹介でした。

以上

【関連するリンク】

www.prj-alpha.biz

www.prj-alpha.biz

www.prj-alpha.biz

はてなブログの Search Console がエラーとなってたので対処する

今回ははてなブログの Google Search Console の状態がエラーとなっていたので、それの対処方法を説明します。

Google Search Console が突然エラーとなる

Google Search Console をホーム画面を確認すると、HTTPS化したはてなブログに「未確認」というマークが付いていて、Google Search Console が機能していない状態となっていました。

この一覧を見ると分かる通り、HTTPS化した方だけが「未確認」となっており、HTTPの方はエラーとはなっていません。はてなブログ側も Google Search Console も特に設定を変更していないのに、この状態になっていました。
とりあえずクリックして状態を確認してみると、内部エラーが発生しているとのことでした。ちなみに確認方法ははてなブログでは一般的なメタタグによるものです。

履歴を見ると、5日前から内部エラーが発生しています。ちなみにこの内部エラーが出ていた期間も Google Search Console は問題なく利用できていました。約5日間など一定期間で解決しないと、最終的に使用できない状態になるようです。
また Analytics の Search Console の部分を見ると、2日前からクリック数が取れなくなっていました。このあたりで関連付けの設定が切れたのかもしれません。

メタタグを使用しての確認を再度行ってみます。ちなみにこの確認に際して、はてなブログと Google Search Console については何の設定変更もしていません。

問題なく確認がされました。

一覧画面でも「未確認」が消えてます。

※追記 更に Google Analytics と Google Search Console の関連付けが消えている場合があります。

Google Analytics を利用していて関連付けを行っていた場合、今回の事象により関連付けが消えていることがあります。この場合は Google Search Console で再度関連付けを行って下さい。

突然エラーとなった理由は不明

今回設定を何も変更してないのにエラーとなった理由はわかりませんでした。対処方法自体は簡単ですが、気がかりなのはエラーとなってもGoogleからは何の通知もなかったことです。 Google Search Console の画面を起動して、「未確認」となっている状態を見て、初めて気が付きました。そこまで頻繁に確認しないので、気付くのがかなり遅くなるかもしれません。

まとめ

今回は Google Search Console の状態がエラーとなっていたので、それの対処方法を説明しました。

以上

【スポンサーリンク】