

下記の条件に当てはまるようにsqlを書いたのですが、うまくいきません。どこが間違っているでしょうか？  
・created(DATETIME型)が2016-02または、2016-01(2016-01というところには$_GETの変数を埋め込んでいます。)  
・billの値が0であるか、またはmodified(datetime型）から15日以上経過している。

[code]

    select id
    from contents
    where
        DATE_FORMAT(created,'y-m') = 2016-02 OR
        DATE_FORMAT(created,'y-m') = adddate(2016-02, interval -1 month) AND
        bill = 0 OR
        now() > (`modified` + INTERVAL 15 DAY)
    
[/code]


CC BY-SA 3.0
2016-02-04T05:04:47.203
21688
2016-03-05T22:17:09.477
2016-02-04T16:35:42.763
2238
8619
question
php mysql sql
SQLのWhere句の書き方、AND・ORの評価順


ANDのほうがORより優先順位が高いので、ORの結果(2か所)を括弧でくくる必要があります。

[code]

    select id
      from contents
     where 
         -- 括弧でくくる
         (DATE_FORMAT(created,'y-m') = 2016-02 OR DATE_FORMAT(created,'y-m') = adddate(2016-02, interval -1 month))
       AND
         -- 括弧でくくる
         (bill=0 OR now() > (`modified` + INTERVAL 15 DAY))
    
[/code]


CC BY-SA 3.0
2016-02-04T05:11:21.610
21689
2016-02-04T05:11:21.610
5750
21688
answer


[演算子の優先順位の問題](https://ja.stackoverflow.com/a/21689/5793)の他にも、DATE_FORMATの書式指定が間違っています。`DATE_FORMAT(created,'y-m')`は`y-m`という文字列を出力しています。意図しているのは`DATE_FORMAT(created,
'%Y-%m')`ではないでしょうか。

また、`2016-02`と言う文字列ですが、sprintfや文字列連結でSQLを生成している場合、文字列リテラルになっていません。数値の式と解釈されるので、`2014`になります(その場合セキュリティ上の問題も考えられます)。パラメータの埋め込みにプレースホルダを使用しているのであれば問題ありません。

他にも質問に書かれている意図を反映していない点があるかもしれませんがすべては確認していません。

意図通りに動かない時は、いきなり複雑な事をやらずに、CLIなどで関数の出力や条件を分解するなどして少しずつ動きを確認してください。


CC BY-SA 3.0
2016-02-04T14:00:41.427
21710
2016-02-04T14:00:41.427
2017-04-13T12:52:39.113
-1
5793
21688
answer