MySQL CASE文でNULL判定

前回

MySQL SELECT時にCASE文で値をわかりやすく出力するサンプル 

でCASE文の話をしましたが、これでNULL判定するときは気を付けましょう。

サンプルは前回と同じく下記のようなデータですが、4番目の null だけ追加しています。下記のテーブルをcallsとします。

id | driver_id | created
1 | 13 | 2018-11-19 11:23:25
2 | 15 | 2018-11-19 11:25:30
3 | 16 | 2018-11-19 11:26:30
4 | null | 2018-11-19 11:26:30

このテーブルからnullでないドライバーIDの場合は、1、そうでない場合は0を返したい場合、いかにも、下記のように判定できそうですが

SELECT
   id, 
CASE
   driver_id WHEN NULL THEN 0 ELSE 1 
END
FROM
calls

なんとこれではダメです。全部、1が返ってきます。

NULL判定は、CASE文の中でしないといけないそうです。

SELECT 
    id, 
CASE 
    WHEN driver_id IS NULL THEN 0 ELSE 1 
END 
FROM 
calls 

これで、ちゃんと driver_id がNULLの時、0になります。

 

MySQL SELECT時にCASE文で値をわかりやすく出力するサンプル 

MySQLにCASE文やIF文があるのを知っていても、使うシチュエーションがわからない、なんだか使いづらい…と感じている方も多いのではないでしょうか。

ここでは、SELECTするときに、CASEを使う方法を書いておきます。
私、思うにフラグを立てるような処理とかに使うといいと思います。(๑•̀ㅂ•́)و✧

calls というテーブルの中に、下記のようなデータがあったとして

id | driver_id | created
1 | 13 | 2018-11-19 11:23:25
2 | 15 | 2018-11-19 11:25:30
3 | 16 | 2018-11-19 11:26:30

ドライバーIDが “15” の時だけフラグを立てる的にわかりやすく出力したい、という場合があったとするとCASE文を使って次のように書けます。

SELECT
   id, 
CASE
   driver_id WHEN 15 THEN 1 ELSE 0 
END
FROM
calls

 

結果は

id | CASE driver_id WHEN 15 THEN 1 ELSE 0 END 
1 | 0
2 | 1
3 | 0

となります。
フィールドの名前がいやなので、エイリアスつけておきます。

SELECT
   id, 
CASE
   driver_id WHEN 15 THEN 1 ELSE 0 
END
 as driver_himself
FROM
calls

結果は

id | driver_himself
1 | 0
2 | 1
3 | 0

となります。

PHPで来月末を取得

PHPで来月末を取得するときに苦戦しました。
調べるとほいほいでてくるんですがstrtotime関数の+1 monthが安定していないだのなんだので、結構不安だったからです。ちゃんと理屈で自分が納得行くものを利用したいので…。結論としては以下のコードで取得可能です。

これを少し解説したコードが以下

これは2018年12月6日に実行した場合です。最初はなんでこれで月末が帰ってくるのかわからなかったんですが、date(‘Y-m-t’)の’t’を見落としていました。日付フォーマットの’t’は

指定した月の日数。
http://php.net/manual/ja/function.date.php

とあるので、1月なら30が、2月なら28が帰ってきます(うるう年なども考慮されるかと)。
簡単に見えますが、落とし穴たくさんありそうなので、いろいろ試してみました。

This support library should not use a different vesion than the compileSdkVersion

Android supportライブラリなどで利用するべきバージョンについて(サンプル有)

Androidのgradleのdependenciesのimplementation(旧 compile)でよく出るこのWarning。

StackOverflowとかで見て、このエラーでビルドできないからこれ、と闇雲にライブラリのバージョンを指定していると、こうなりますよねw

ほっといてもビルドできる時もありますが、時にできなくなって、できない時は本当にカオスでわけわかめになります。

なので、ちゃんとやった方がいいです。

じゃあ、どのバージョンを指定したらいいのー??ってなりますが、その方法を書いておきます。

下記のようにアプリケーションのbuild.gradleファイルを作ったとすると

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'


android {
    compileSdkVersion 27
    buildToolsVersion '28.0.3'
    defaultConfig {
        applicationId "hogehoge"
        minSdkVersion 14
        targetSdkVersion 27
        javaCompileOptions {
            annotationProcessorOptions {
                includeCompileClasspath false
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
    useLibrary 'org.apache.http.legacy'
    productFlavors {
    }
}

dependencies {
    compile project(':rateThisApp')
    compile 'com.android.support:support-v4:27.1.1'
    compile 'com.google.android.gms:play-services-location:16.0.0'
    compile files('lib/osmbonuspack_v4.2.9.jar')
    compile files('lib/osmdroid-android-4.1.jar')
    compile files('lib/osmdroid-third-party-4.1.jar')
    compile files('lib/slf4j-android-1.6.1-RC1.jar')
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support:design:27.1.1'
    implementation 'com.google.firebase:firebase-messaging:17.3.4'
    implementation 'com.google.android.gms:play-services-maps:16.0.0'  // GoogleMapを使うために追加する

}

compileSdkVersion 27のこの数字にサポートライブラリのバージョンの最初の数字を合わせます。

サポートライブラリとは、

'com.android.support:support-v4:27.1.1'

いたいなやつのことです。上記の意味は、com.android.support:support-v4というライブラリのバージョン27.1.1ですよ!ってことです。

つまり、compileSdkVersion が27だから、ライブラリのバージョンの最初の数字は27です。

後のやつはどうやって決めるの?というと、下記のサイトで探します。

Recent Support Library Revisions

https://developer.android.com/topic/libraries/support-library/revisions?hl=ja

例えば、上記のサイトを見ると、バージョン27だと、現在(2018/12/04)で
Revision 27.1.1
が最新ということになります。

なので、

'com.android.support:support-v4:27.1.1'

として、27.1.1を指定します。

AndroidManifest.xmlのminSdkVersionを変更しても反映されずビルドできない

さて、ADTのプロジェクトをAndroid Studioへ移す過程ではまったエラー対策の続きです。Android Studioはバージョン3.2.1です。

前回のことがあり、ようやくエラーの原因がわかりました。

C:\Android\takuru\ASdriver1\hogehoge\src\main\AndroidManifest.xml:7:5-74 Error:
uses-sdk:minSdkVersion 11 cannot be smaller than version 14 declared in library [com.google.android.gms:play-services:12.0.1] C:\Users\hogehoge\.gradle\caches\transforms-1\files-1.1\play-services-12.0.1.aar\93010549a0eaa8ce0a656b526c4ad348\AndroidManifest.xml as the library might be using APIs not available in 11
Suggestion: use a compatible library with a minSdk of at most 11,
or increase this project's minSdk version to at least 14,
or use tools:overrideLibrary="com.google.android.gms.play_services" to force usage (may lead to runtime failures)
:takuruDriver:processDebugManifest

 

ご丁寧にもダメなAndroidManifest.xmlへのリンクもあります。

「ほうほう。AndroidManifest.xmlのminSdk指定が悪いのね~ 11じゃなくって14にすればいいんでしょー?!」

っとちゃかちゃか直して、Gradle Sync。

そしたら、Sync Failured.なんですよ。なんで。(´・ω・)

また、プロジェクトをBuild→cleanします。

すると、また下記の同じエラー出てるんですよ。

Error:uses-sdk:minSdkVersion 11 cannot be smaller than version 14.....

ファッ?!ってなって、もう一度、AndroidManifest.xmlを見直したり、キャッシュを消したり、.gradleを消したり。
してみても、結果は一緒でした。。。

なんでAndroidManifest.xmlのminSdkVersionを変更しても反映されないの??と思っていたら、偶然にもAndroidManifest.xmlの下記の部分にマウスオーバーしたら

The minSdkVersion value(14) is not used. it is always overridden by the value specified in the Gradle build script (14) ...

ってメッセージが出てるんですよ。

「…あっ…」

そうですね、プロジェクトのbuild.gradleにもminSdkVersionを書くところがあり、そのほうがAndroidManifest.xmlよりも優先されるのだった。

build.gradleにある下記のminSdkVersionを直して、

android {
    compileSdkVersion 26
    buildToolsVersion '28.0.3'

    defaultConfig {
        applicationId "hogehoge.driver"
        minSdkVersion 14 //これを11から変更
        targetSdkVersion 26
    }
//以下略

AndroidManifest.xmlにあるminSdkVersionは紛らわしいので消します。

すると、やっとBuildが通り、Gradle Syncも成功しました!!( ˊᵕˋ )