web-dev-qa-db-ja.com

WHERE条件付きの行の挿入

構造

1つのテーブル名:scan

名前付きの2つの列:id、およびdate

問題

SELECTとINSERTの2つの機能するクエリがあり、それらをマージして、条件が0に等しいINSERTを作成します。

クエリ1

データベースのlatestID行に今日のスキャン日付がある場合は「1」を表示します。それ以外の場合は、今日の日付が存在しないときに「0」を表示します。

SELECT
  COUNT(scan.date) AS datecheck
FROM scan
WHERE scan.id = (SELECT
    MAX(scan.id) AS datecheck
  FROM scan
  WHERE scan.date = CURDATE())

クエリ2

今日のエントリがない場合、つまり結果が「0」の場合、ID + 1と現在の日付で新しい行を作成します。

INSERT INTO `scan`(`id`, `date`) SELECT (MAX(id)+1), CURDATE() FROM scan;

私は今何時間も運が悪い状態で試してきましたが、どこが間違っているのかを教えて、正しいクエリを教えていただければ幸いです。ありがとうございました。

3
rwcommand

クエリを言い換えると、今日の日付の行がないかどうかを確認したいだけのようです。条件付き挿入にするには少し注意が必要です。

INSERT INTO scan (id, date)
SELECT (MAX(id)+1), CURDATE()
FROM scan
HAVING COUNT(CASE WHEN scan.date = CURDATE() THEN 1 end) = 0;

空のテーブルでも機能するようにするには、(COALESCE(MAX(id),0)+1)に変更します。

4
dnoeth

クエリ1

データベースのlatestID行に今日のスキャン日付がある場合は_1_を表示し、それ以外の場合は_0_を表示します。

より簡単に(そしてより効率的に)書くことができます:

_SELECT CASE WHEN scan.date = CURDATE() THEN 1 ELSE 0 END AS datecheck
FROM scan
ORDER BY scan.id DESC
LIMIT 1 ;
_

(難読化が好きな場合):

_SELECT (scan.date = CURDATE()) AS datecheck
FROM scan
ORDER BY scan.id DESC
LIMIT 1 ;
_

クエリ2

前のクエリの結果が_0_の場合、_ID + 1_と現在の日付を含む新しい行を挿入します。

_INSERT INTO scan 
    (id, date) 
SELECT latest.id + 1, CURDATE() 
FROM 
  ( SELECT scan.id, scan.date
    FROM scan
    ORDER BY scan.id DESC
    LIMIT 1 
  ) AS latest
WHERE latest.date <> CURDATE() ;
_

注:上記のすべてのクエリは、最新(最高)id値を持つ行のみをチェックします。あなたの言い回しがあいまいです。 idが低い行ほど、現在の日付がdate値として含まれる場合があります。その場合に何をしたいのか明確ではありません!

テーブルの最も高い日付を確認する場合は、_ORDER BY scan.id DESC_を_ORDER BY scan.date DESC_に置き換える必要があります。これにより、最も高い日付(および現在の日付)。

現在の日付の行があるかどうかすべてのテーブルをチェックする場合は、現在の日付のある行がないかテーブル全体をチェックするWHERE scan.date <= CURDATE() ORDER BY scan.date DESCに置き換える必要があります。

2
ypercubeᵀᴹ