回答編集履歴

4 コード修正

hirohiro

hirohiro score 1943

2015/08/12 08:43  投稿

1と2で条件がかなり異なるので、多少コードが長くなってもSQLを2つ作ってUNIONで繋げたほうが、メンテナンスがやりやすくなるかも知れませんね。
###2015/8/12追記
> 同じ名前の項目があると、取り出せないですよね?
縦につなげるだけなので、要素数や要素名は普通にSELECTした場合と同じだと思うのですが、
reservation_dateが2つになるというのはどんな時でしょう?
抽出条件に従うと
条件1(と3)を抽出するSQLはこんな感じ
```SQL
SELECT cos.*, res.*
FROM costomer cos
INNER JOIN costomer_reservation res ON cos.costomer_id = res.costomer_id
WHERE res.reservation_date >= CURRENT_DATE
ORDER BY res.reservation_date DESC
```
条件2(と3)を抽出するSQLはこんな感じ
```SQL
SELECT cos.*, res.*
FROM costomer cos
INNER JOIN (
 SELECT *
 FROM costomer_reservation r1
 WHERE NOT EXISTS (
   SELECT *
   FROM costomer_reservation r2
   WHERE r1.costomer_id = r2.costomer_id
   AND r1.reservation_date < CURRENT_DATE
   AND r1.res.reservation_date < r2.res.reservation_date
 ) res ON cos.costomer_id = res.costomer_id
 )
) res ON cos.costomer_id = res.costomer_id
ORDER BY res.reservation_date DESC
```
UNIONで繋ぐとこんな感じ
```SQL
(SELECT cos.*, res.*
 FROM costomer cos
 INNER JOIN costomer_reservation res ON cos.costomer_id = res.costomer_id
 WHERE res.reservation_date >= CURRENT_DATE
)
UNION
(SELECT cos.*, res.*
 FROM costomer cos
 INNER JOIN (
   SELECT *
   FROM costomer_reservation r1
   WHERE NOT EXISTS (
     SELECT *
     FROM costomer_reservation r2
     WHERE r1.costomer_id = r2.costomer_id
     AND r1.reservation_date < CURRENT_DATE
     AND r1.reservation_date < r2.reservation_date
   )
 ) res ON cos.costomer_id = res.costomer_id
)
ORDER BY res.reservation_date DESC
```
要素が同じなら抵抗無く連結できると思います。
※動作テストはしていないのでエラーがあるかも知れません。
※フラグやクリニックチェックは条件に無かったので省いています
※条件2の方は、costomer_idとreservation_dateの2つがまったく同じレコードは無い前提です。
※条件2の方は相関サブクエリを使っており、レコードが多い場合は別の方法にしないと異様に遅いかも知れません。
3 コード修正

hirohiro

hirohiro score 1943

2015/08/12 08:41  投稿

1と2で条件がかなり異なるので、多少コードが長くなってもSQLを2つ作ってUNIONで繋げたほうが、メンテナンスがやりやすくなるかも知れませんね。
###2015/8/12追記
> 同じ名前の項目があると、取り出せないですよね?
縦につなげるだけなので、要素数や要素名は普通にSELECTした場合と同じだと思うのですが、
reservation_dateが2つになるというのはどんな時でしょう?
抽出条件に従うと
条件1(と3)を抽出するSQLはこんな感じ
```SQL
SELECT cos.*, res.*
FROM costomer cos
INNER JOIN costomer_reservation res ON cos.costomer_id = res.costomer_id
WHERE res.reservation_date >= CURRENT_DATE
ORDER BY res.reservation_date DESC
```
条件2(と3)を抽出するSQLはこんな感じ
```SQL
SELECT cos.*, res.*
FROM costomer cos
INNER JOIN (
 SELECT *
 FROM costomer_reservation r1
 WHERE NOT EXISTS (
   SELECT *
   FROM costomer_reservation r2
   WHERE r1.costomer_id = r2.costomer_id
   AND r1.reservation_date < CURRENT_DATE
   AND r1.res.reservation_date < r2.res.reservation_date
 ) res ON cos.costomer_id = res.costomer_id
ORDER BY res.reservation_date DESC
```
UNIONで繋ぐとこんな感じ
```SQL
(SELECT cos.*, res.*
 FROM costomer cos
 INNER JOIN costomer_reservation res ON cos.costomer_id = res.costomer_id
 WHERE res.reservation_date >= CURRENT_DATE
)
UNION
(SELECT cos.*, res.*
 FROM costomer cos
 INNER JOIN (
   SELECT *
   FROM costomer_reservation r1
   WHERE NOT EXISTS (
     SELECT *
     FROM costomer_reservation r2
     WHERE r1.costomer_id = r2.costomer_id
     AND r1.reservation_date < CURRENT_DATE
     AND r1.reservation_date < r2.reservation_date
   ) res ON cos.costomer_id = res.costomer_id
   )
 ) res ON cos.costomer_id = res.costomer_id
)
ORDER BY res.reservation_date DESC
```
要素が同じなら抵抗無く連結できると思います。
※動作テストはしていないのでエラーがあるかも知れません。
※フラグやクリニックチェックは条件に無かったので省いています
※条件2の方は、costomer_idとreservation_dateの2つがまったく同じレコードは無い前提です。
※条件2の方は相関サブクエリを使っており、レコードが多い場合は別の方法にしないと異様に遅いかも知れません。
2 コード修正

hirohiro

hirohiro score 1943

2015/08/12 08:36  投稿

1と2で条件がかなり異なるので、多少コードが長くなってもSQLを2つ作ってUNIONで繋げたほうが、メンテナンスがやりやすくなるかも知れませんね。
###2015/8/12追記
> 同じ名前の項目があると、取り出せないですよね?
縦につなげるだけなので、要素数や要素名は普通にSELECTした場合と同じだと思うのですが、
reservation_dateが2つになるというのはどんな時でしょう?
抽出条件に従うと
条件1(と3)を抽出するSQLはこんな感じ
```SQL
SELECT cos.*, res.*
FROM costomer cos
INNER JOIN costomer_reservation res ON cos.costomer_id = res.costomer_id
WHERE res.reservation_date >= CURRENT_DATE
ORDER BY res.reservation_date DESC
```
条件2(と3)を抽出するSQLはこんな感じ
```SQL
SELECT cos.*, res.*
FROM costomer cos
INNER JOIN (
 SELECT *
 FROM costomer_reservation r1
 WHERE NOT EXISTS (
   SELECT *
   FROM costomer_reservation r2
   WHERE r1.costomer_id = r2.costomer_id
   AND r1.reservation_date < CURRENT_DATE
   AND r1.res.reservation_date < r2.res.reservation_date
 ) res ON cos.costomer_id = res.costomer_id
ORDER BY res.reservation_date DESC
```
UNIONで繋ぐとこんな感じ
```SQL
SELECT cos.*, res.*
FROM costomer cos
INNER JOIN costomer_reservation res ON cos.costomer_id = res.costomer_id
WHERE res.reservation_date >= CURRENT_DATE
(SELECT cos.*, res.*
 FROM costomer cos
 INNER JOIN costomer_reservation res ON cos.costomer_id = res.costomer_id
 WHERE res.reservation_date >= CURRENT_DATE
)
UNION
SELECT cos.*, res.*
FROM costomer cos
INNER JOIN (
 SELECT *
 FROM costomer_reservation r1
 WHERE NOT EXISTS (
   SELECT *
   FROM costomer_reservation r2
   WHERE r1.costomer_id = r2.costomer_id
   AND r1.reservation_date < CURRENT_DATE
   AND r1.reservation_date < r2.reservation_date
 ) res ON cos.costomer_id = res.costomer_id
(SELECT cos.*, res.*
 FROM costomer cos
 INNER JOIN (
   SELECT *
   FROM costomer_reservation r1
   WHERE NOT EXISTS (
     SELECT *
     FROM costomer_reservation r2
     WHERE r1.costomer_id = r2.costomer_id
     AND r1.reservation_date < CURRENT_DATE
     AND r1.reservation_date < r2.reservation_date
   ) res ON cos.costomer_id = res.costomer_id
)
ORDER BY res.reservation_date DESC
```
要素が同じなら抵抗無く連結できると思います。
※動作テストはしていないのでエラーがあるかも知れません。
※フラグやクリニックチェックは条件に無かったので省いています
※条件2の方は、costomer_idとreservation_dateの2つがまったく同じレコードは無い前提です。
※条件2の方は相関サブクエリを使っており、レコードが多い場合は別の方法にしないと異様に遅いかも知れません。
1 追記

hirohiro

hirohiro score 1943

2015/08/12 08:26  投稿

1と2で条件がかなり異なるので、多少コードが長くなってもSQLを2つ作ってUNIONで繋げたほうが、メンテナンスがやりやすくなるかも知れませんね。
1と2で条件がかなり異なるので、多少コードが長くなってもSQLを2つ作ってUNIONで繋げたほうが、メンテナンスがやりやすくなるかも知れませんね。
###2015/8/12追記
> 同じ名前の項目があると、取り出せないですよね?
縦につなげるだけなので、要素数や要素名は普通にSELECTした場合と同じだと思うのですが、
reservation_dateが2つになるというのはどんな時でしょう?
抽出条件に従うと
条件1(と3)を抽出するSQLはこんな感じ
```SQL
SELECT cos.*, res.*
FROM costomer cos
INNER JOIN costomer_reservation res ON cos.costomer_id = res.costomer_id
WHERE res.reservation_date >= CURRENT_DATE
ORDER BY res.reservation_date DESC
```
条件2(と3)を抽出するSQLはこんな感じ
```SQL
SELECT cos.*, res.*
FROM costomer cos
INNER JOIN (
 SELECT *
 FROM costomer_reservation r1
 WHERE NOT EXISTS (
   SELECT *
   FROM costomer_reservation r2
   WHERE r1.costomer_id = r2.costomer_id
   AND r1.reservation_date < CURRENT_DATE
   AND r1.res.reservation_date < r2.res.reservation_date
 ) res ON cos.costomer_id = res.costomer_id
ORDER BY res.reservation_date DESC
```
UNIONで繋ぐとこんな感じ
```SQL
SELECT cos.*, res.*
FROM costomer cos
INNER JOIN costomer_reservation res ON cos.costomer_id = res.costomer_id
WHERE res.reservation_date >= CURRENT_DATE
UNION
SELECT cos.*, res.*
FROM costomer cos
INNER JOIN (
 SELECT *
 FROM costomer_reservation r1
 WHERE NOT EXISTS (
   SELECT *
   FROM costomer_reservation r2
   WHERE r1.costomer_id = r2.costomer_id
   AND r1.reservation_date < CURRENT_DATE
   AND r1.reservation_date < r2.reservation_date
 ) res ON cos.costomer_id = res.costomer_id
ORDER BY res.reservation_date DESC
```
要素が同じなら抵抗無く連結できると思います。
※動作テストはしていないのでエラーがあるかも知れません。
※フラグやクリニックチェックは条件に無かったので省いています
※条件2の方は、costomer_idとreservation_dateの2つがまったく同じレコードは無い前提です。
※条件2の方は相関サブクエリを使っており、レコードが多い場合は別の方法にしないと異様に遅いかも知れません。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る