0

私は2つのテーブルを持っています:

ルート

ID 説明
1通り1
2 ストリート 2
3 通り 3
4 通り 4
5番街5

セグメント

ID RouteID、Progres、LabelStart、LabelEnd
1 1 5 1A 21B
2 1 10 2A 10
3 2 15 3 25
4 2 15 2 20
5 3 20 1 11
6 3 22 4 10
7 4 30 5 11
8 4 31 2 12

これらのルールを持つシーケンスが必要です:

  1. テーブルは Progress ASC で注文する必要があります
  2. 列の Type が定義され、LabelStart と LabelEnd が Odd の場合は O、Even の場合は E になります。
  3. 2 つのルートの進行状況が同じ場合、LabelStart が最小 (LabelStart Odd と LabelStart Even の間) で、LabelEnd が Max である行が 1 つにマージされます。この場合、Type は A (All) の値を取ります。

上記のデータの例によると、結果は次のようになります。

順序  
ID RouteID、Progres、LabelStart、LabelEnd タイプ
1 1 5 1 A 21 BO
2 1 10 2 あ 10 え
4 2 15 2 25A
5 3 20 1 11 ○
6 3 22 4 10 イー
7 4 30 5 11 ○
8 4 31 2 12 エ

Postgres 9.2用です

4

1 に答える 1

1

LabelStart フィールドと LabelEnd フィールドに文字が含まれていたため、これは興味深いクエリを作成するものでした。私はREGEX_REPLACEそれらを削除していました。次に、CTE を使用して、複数のルート ID と進行状況の行を持つレコードを取得しました。

私はこれがそれを行うべきだと思います:

WITH CTE AS (
  SELECT 
    RouteId, Progress
  FROM Sequence
  GROUP BY RouteId, Progress
  HAVING COUNT(DISTINCT Id) > 1
  )
SELECT MAX(S.ID) Id,
  T.RouteId,
  T.Progress,
  MIN(regexp_replace(LabelStart, '[^0-9]', '', 'g')) LabelStart,
  MAX(regexp_replace(LabelStart, '[^0-9]', '', 'g')) LabelEnd,
  'A' as Type
FROM Sequence S 
  INNER JOIN CTE T ON S.RouteId = T.RouteId AND S.Progress = T.Progress
GROUP BY T.RouteId, T.Progress
UNION 
SELECT S.Id,
  S.RouteId,
  S.Progress,
  S.LabelStart,
  S.LabelEnd,
  CASE 
    WHEN CAST(regexp_replace(LabelStart, '[^0-9]', '', 'g') as int) % 2 = 0 
    THEN 'E' 
    ELSE 'O' 
  END  
FROM Sequence S 
  LEFT JOIN  CTE T ON S.RouteId = T.RouteId AND S.Progress = T.Progress
WHERE T.RouteId IS NULL
ORDER BY Progress ASC

そしていくつかのサンプルFiddle

于 2013-02-18T02:24:22.180 に答える