最初の部分は次のとおりです。ユーザーごとに重複する車...
2番目の部分-同時に1台の車に複数のユーザーがいる:SQLFiddle-相関クエリと結合クエリ 。以下のクエリ...
相関クエリを使用します:
useridと'car'のインデックスが必要になる可能性があります。ただし、「explain plan」をチェックして、mysqlがデータにどのようにアクセスしているかを確認してください。そして試してみてください:)
ユーザーごとに重複する車
クエリ:
SELECT `allCars`.`userid` AS `allCars_userid`,
`allCars`.`car` AS `allCars_car`,
`allCars`.`From` AS `allCars_From`,
`allCars`.`To` AS `allCars_To`,
`allCars`.`tableid` AS `allCars_id`
FROM
`cars` AS `allCars`
WHERE
EXISTS
(SELECT 1
FROM `cars` AS `overlapCar`
WHERE
`allCars`.`userid` = `overlapCar`.`userid`
AND `allCars`.`tableid` <> `overlapCar`.`tableid`
AND NOT ( `allCars`.`From` >= `overlapCar`.`To` /* starts after outer ends */
OR `allCars`.`To` <= `overlapCar`.`From`)) /* ends before outer starts */
ORDER BY
`allCars`.`userid`,
`allCars`.`From`,
`allCars`.`car`;
結果:
allCars_userid allCars_car allCars_From allCars_To allCars_id
-------------- ----------- ------------ ---------- ------------
1 Navara 2015-03-01 2015-03-31 3
1 GTR 2015-03-28 2015-04-30 4
1 Skyline 2015-04-29 2015-05-31 9
2 Aygo 2015-03-01 2015-03-31 7
2 206 2015-03-29 2015-04-30 8
2 Skyline 2015-04-29 2015-05-31 10
なぜそれが機能するのですか?または私がそれについてどう思うか:
私は相関クエリを使用しているので、重複を処理する必要はありません。おそらく、私にとって最も理解しやすいでしょう。クエリを表現する方法は他にもあります。それぞれに長所と短所があります。わかりやすいものが欲しい。
要件:ユーザーごとに、同時に2台以上の車を持っていないことを確認してください。
したがって、各ユーザーレコード(AllCars)について、完全なテーブル(overlapCar)をチェックして、異なるを見つけることができるかどうかを確認します。 現在のレコードの時間と重複するレコード。見つかった場合は、チェックしている現在のレコードを(allCarsで)選択します。
したがって、重複 チェックは:
-
allCars
userid
およびoverLap
userid
同じでなければなりません -
allCars
車の記録とoverlap
車の記録異なる必要があります -
allCars
時間範囲とoverLap
時間範囲は重複している必要があります。時間範囲チェック:
重複する時間をチェックする代わりに、ポジティブテストを使用します。最も簡単な方法は、重複していないことを確認し、
NOT
を適用することです。 それに。
同時に複数のユーザーがいる1台の車...
クエリ:
SELECT `allCars`.`car` AS `allCars_car`,
`allCars`.`userid` AS `allCars_userid`,
`allCars`.`From` AS `allCars_From`,
`allCars`.`To` AS `allCars_To`,
`allCars`.`tableid` AS `allCars_id`
FROM
`cars` AS `allCars`
WHERE
EXISTS
(SELECT 1
FROM `cars` AS `overlapUser`
WHERE
`allCars`.`car` = `overlapUser`.`car`
AND `allCars`.`tableid` <> `overlapUser`.`tableid`
AND NOT ( `allCars`.`From` >= `overlapUser`.`To` /* starts after outer ends */
OR `allCars`.`To` <= `overlapUser`.`From`)) /* ends before outer starts */
ORDER BY
`allCars`.`car`,
`allCars`.`userid`,
`allCars`.`From`;
結果:
allCars_car allCars_userid allCars_From allCars_To allCars_id
----------- -------------- ------------ ---------- ------------
Skyline 1 2015-04-29 2015-05-31 9
Skyline 2 2015-04-29 2015-05-31 10
編集:
@philipxyによるコメントを考慮して、「以上」のチェックが必要な時間範囲について、ここでコードを更新しました。 SQLFiddles
を変更していません 。