2

2つのテーブル間に1対1の列の関係がitemあり、log

アイテムごとに、アイテムが処理されたかどうかを保存するログがあります。log.itemIdこれは、に等しいことによって識別されitem.idます。log.status処理が進行中か終了したかを示します(-1は保留中、1は終了中)。

処理が開始される前は、logテーブル内の対応するアイテムの行はテーブルにありませんitem

ログに対応する行がない(処理が開始されていないことを意味する)か、ステータスが1ではない(保留中であることを意味する)アイテムから行を取得しようとしています。

私はこれを理解しようと夢中になっています、これは私の質問です:

SELECT 
    item.id
FROM item, log
WHERE log.itemId != item.id
OR (log.itemId = item.id AND log.status !='1')
ORDER BY item.id ASC LIMIT 1

ただし、これは空の結果を返します。

私は何が間違っているのですか?

4

4 に答える 4

4

これを試して:

SELECT 
  item.id
FROM
  item left join log on (log.itemId = item.id)
WHERE
  log.itemId is null
  OR log.status !='1'
ORDER BY item.id LIMIT 1
于 2012-12-30T17:05:18.053 に答える
2

提供されている他の回答は機能し、非常に一般的ですが(外部結合と外部テーブルのNULLのチェック)、SQLにはより直接的に適用される別のアプローチがあります。

SELECT
item.id
FROM item
WHERE
not exists
    (SELECT itemID from log where log.itemID = item.id and log.status = '1')

両方を試して、どちらがより高速に動作するかを判断することをお勧めします。NULLと「存在しない」構文の外部結合チェックです。ほとんどのデータベースは2つのクエリを同じように最適化しないため(結果が同じであっても)、どちらが優れているかは必ずしも明らかではありませんが、一方が他方よりも優れている可能性があります。

最後の行で!=を=に変更したことに注意してください。ただし、ロジックを誤解している可能性はありますが、それは正しいと思います。

于 2012-12-30T17:18:42.613 に答える
1

決定の1つは、EXISTS(http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html)を使用することです。この例は、以下にあります。または、LEFTJOINを使用できます。 。

SELECT *
FROM item AS i
WHERE NOT EXISTS(
    SELECT *
    FROM log AS l
    WHERE l.itemId = i.id
        AND l.status != 1
)
LIMIT 0, 1;
于 2012-12-30T17:09:00.813 に答える
0

これを行う別の方法は次のとおりです。

SELECT item.id FROM item WHERE item.id NOT IN (SELECT itemid FROM log where log.status != '1')
于 2012-12-30T17:10:37.393 に答える