PostgreSQLでDATE型のフィールドにnow()でSELECTする時の注意

データベースのデータを抽出する際、今現在有効なデータを取得するというケースは多々あるかとっ。
そこで、now()を用いて取得すると、思ってたのと少し違う挙動をしちゃいます。

続きを読む

PostgreSQLでnullをソートする

明日からシルバーウィークですねっ。
バーベキュー行ったり、仕事したりしながら、基本的にダラダラ過ごしていると思われます。


それはさておき、SQLでデータを抽出する際、ORDER BY句でソートするカラムにNULLが入っていることもあります。
例えば、

SELECT price, name FROM fruit ORDER BY price;
とした時に、
price name
100 みかん
200 りんご
400 ぶどう
いちご
と返ってくるテーブルがあるとします。
この時、いちごは値段をつけていないけど、一番先頭に表示するには、以下のSQL文で抽出できます。
SELECT price, name FROM fruit ORDER BY (price IS NULL) DESC, price;
price name
いちご
100 みかん
200 りんご
400 ぶどう
trueはfalseより大きいとなるので、price IS NULLをDESCとすることでいちごが先頭に来たのち、priceの昇順で抽出されます。

CakePHPで論理削除するSoft Deletable Behavior2

最近朝方は冷え込んできました。
私も朝はミノムシのように毛布にくるまっております。


さて、昨日の記事で紹介したSoft Deletable Behaviorですが、[CakePHP] SoftDeletable Behavior で論理削除 – Sun Limited Mt.を参考にそのままやると、特にPostgreSQLの場合にいくつか問題があります。

TINYINTという型がPostgreSQLは対応していないです。
削除フラグなのでINT型にするというのも変なので、BOOL型に変更しようかと思います。
soft_deletable.phpを開き、

$attributes['field'] => 1
 ↓
$attributes['field'] => true
$purged = $Model->deleteAll(array($this->__settings[$Model->alias]['field'] => '1'), $cascade);
 ↓
$purged = $Model->deleteAll(array($this->__settings[$Model->alias]['field'] => true), $cascade);
$this->__settings[$Model->alias]['field'] => '0'
 ↓
$this->__settings[$Model->alias]['field'] => false
$queryData['conditions'] = $Db->name($Model->alias) . '.' . $Db->name($this->__settings[$Model->alias]['field']) . '!= 1 AND ' . $queryData['conditions'];
 ↓
$queryData['conditions'] = $Db->name($Model->alias) . '.' . $Db->name($this->__settings[$Model->alias]['field']) . '= false AND ' . $queryData['conditions'];
$queryData['conditions'][$Model->alias . '.' . $this->__settings[$Model->alias]['field']] = '!= 1';
 ↓
$queryData['conditions'][$Model->alias . '.' . $this->__settings[$Model->alias]['field']] = false;

と変更。
これでBOOL型で動作すると思います。

とはいえ、ではMySQLだったらそのままでいいってわけでもなく・・・
CakePHPはTINYINT型をBOOLEARN型として扱うようで、これはこれで常にデータが全削除扱いになってしまうので、結局TINYINT型は使えないようです。
CakePHPトtinyintトboolean – [k]zi.bz


それ以外にもSoft Deletable Behaviorの挙動にちょっとした難点があり、[CakePHP] SoftDeletable Behavior で論理削除 – Sun Limited Mt.によると

「SoftDeletable Behavior を使用すると Model::del は必ず false が返ります。
これは Behavior が beforeDelete で削除フラグを立てて、モデルの del メソッドを実行させないために false を返すためです。
この点だけ注意が必要です。」

とのことなので、削除に成功したか失敗したかは別過程で取得しないといけないというネックがあります。

CakePHPで論理削除するSoft Deletable Behavior1

CakePHPはデフォルトで物理削除です。
データがあったら、そのまま削除してしまうっていう方法ですね。
WindowsでShift+Deleteを押すような感じです。

削除の仕方にはもう1つあって、もう一つが論理削除と言われるもの。
代表的なのだと、『削除フラグ』を用いたものですね。
イメージ的には、ゴミ箱にデータをいれるような感じです。


その論理削除を楽に実現するのがSoft Deletable Behaviorというビヘイビア。
導入する際は[CakePHP] SoftDeletable Behavior で論理削除 – Sun Limited Mt.を参考にするんですが、CakePHPに導入する場合、特にPostgreSQLを用いている場合は調整が必要です。
その調整にかんしてはまた明日にでも。