名前の競合が発生したり、出力列を混乱させたりする場合を除いて、クエリはすでに機能します。 ( CASE
式)ソース列 結果コード> 、内容が異なります。
...
GROUP BY model.name, attempt.type, attempt.result
...
GROUP BY
する必要があります あなたのCASE
ソース列の代わりに式:
...
GROUP BY model.name, attempt.type
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END
...
または、列エイリアスを指定します これは、 FROM
の列名とは異なります。 リスト-または、その列が優先されます:
SELECT ...
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END AS result1
...
GROUP BY model.name, attempt.type, result1
...
SQL標準は、この点でかなり独特です。ここでマニュアルを引用する:
出力列の名前を使用して、
ORDER BY
の列の値を参照できます。 およびGROUPBY
句はありますが、WHERE
にはありません またはHAVING
句;代わりに式を書き出す必要があります。
そして:
ORDER BY
の場合 式は、出力列名と入力列名の両方に一致する単純な名前、ORDER BY
これを出力列名として解釈します。 これは、GROUP BY
の選択の反対です。 作る 同じ状況で。この不整合は、SQL標準と互換性があるように作成されています。
太字 強調鉱山。
これらの競合は、位置参照を使用することで回避できます。 (序数) GROUP BY
およびORDERBY
、 SELECT
内のアイテムを参照する 左から右にリストします。以下の解決策を参照してください。
欠点は、これが読みにくく、 SELECT
での編集に対して脆弱である可能性があることです。 リスト(それに応じて位置参照を適応させるのを忘れるかもしれません)。
しかし、あなたはしません day
列を追加する必要があります GROUP BY
へ 定数値( CURRENT_DATE-1
を保持している限り) 。
適切なJOIN構文と位置参照を使用して書き直し、簡略化すると、次のようになります。
SELECT m.name
, a.type
, CASE WHEN a.result = 0 THEN 0 ELSE 1 END AS result
, CURRENT_DATE - 1 AS day
, count(*) AS ct
FROM attempt a
JOIN prod_hw_id p USING (hard_id)
JOIN model m USING (model_id)
WHERE ts >= '2013-11-06 00:00:00'
AND ts < '2013-11-07 00:00:00'
GROUP BY 1,2,3
ORDER BY 1,2,3;
また、列名 time
を避けていることにも注意してください。 。これは予約語であり、識別子として使用しないでください。その上、あなたの「時間」は明らかにタイムスタンプ
です またはdate
、それはかなり誤解を招く恐れがあります。