8

テーブルを「左結合」して、値が一致する行だけでなく、次の一致する行まで、後続の一致しない行にも結合されるようにします。別の言い方をすれば、以前の非 null 値で null を埋めたいのです。

サンプルデータと望ましい結果:

x:

 id 
----
  1
  2
  3
  4
  5

y:

 id | val 
----+-----
  1 | a
  4 | b

の結果select x.id, y.val from x left join y on x.id=y.id order by x.id;:

 id | val 
----+-----
  1 | a
  2 | 
  3 | 
  4 | b
  5 | 

望ましい結果:

 id | val 
----+-----
  1 | a
  2 | a
  3 | a
  4 | b
  5 | b
4

7 に答える 7

4
select id,
       first_value(t.val) over (partition by group_flag order by t.id) as val
from (
  select x.id, 
         y.val, 
         sum(case
            when y.val is null then 0
            else 1
          end) over (order by x.id) as group_flag
  from x 
    left join y on x.id=y.id
) t    
order by id;

SQLFiddle の例: http://sqlfiddle.com/#!12/38903/1

于 2013-04-07T11:05:17.177 に答える
4

SQL フィドル

select
    id, 
    first_value(val) over(partition by g order by id) val
from (
    select
        x.id, val, count(val) over(order by x.id) g
    from
        x
        left join
        y on x.id=y.id
) s
order by id
于 2013-04-07T11:08:15.780 に答える
2

私は集約関数 MIN()、MAX()、またはcloser_to()(NOT) EXISTS で表現するのが好きです。

SELECT x.id, y.val
FROM   x
JOIN   y ON y.id <= x.id
WHERE NOT EXISTS (SELECT *
        FROM y y2
        WHERE y2.id <= x.id -- same condition AS main query
        AND y2.id > y.id    -- but closer to x.id
        )
        ;

私の直感では、これにより Erwin の回答とまったく同じクエリ プランが生成されるということです。

于 2013-04-07T14:27:23.197 に答える
2
SELECT
  m.id,
  y.val
FROM (
  SELECT
    x.id,
    MAX(y.id) id_y
  FROM
    x INNER JOIN y ON x.id >= y.id
  GROUP BY
    x.id
  ) m INNER JOIN y ON m.id_y = y.id
ORDER BY
  m.id

ここでフィドルを参照してください。

于 2013-04-07T11:12:34.210 に答える
1

ロジックにはCOALESCEと Subquery を使用します。

サブクエリは、最後の val 値を取得します。

これを試して:

SELECT x1.id,
       coalesce(y1.val, (SELECT val
                       FROM   y
                       WHERE  id = (SELECT Max(x2.id)
                                    FROM   x AS x2
                                           JOIN y AS y2
                                             ON x2.id = y2.id
                                    WHERE  x2.id < x1.id)))
FROM   x AS x1
       LEFT JOIN y AS y1
              ON x1.id = y1.id
ORDER  BY x1.id;  

sqlfiddle : http://www.sqlfiddle.com/#!12/42526/1

于 2013-04-07T11:03:30.490 に答える