1

I have a table with the following columns:

ref_year, ref_no, inv_id, start_date, end_date

The first two columns (ref_year and ref_no) combine to form a primary key in other tables and I will refer to them as 'reference' from now on, but in this table they can appear multiple times. The third (inv_id) is a foreign key. The final two columns represent the date an inv_id became attached to the reference and, where appropriate, the date it ceased being attached to that reference.

I want to return exactly one row for each reference that will relfect the earliest inv_id attached to that reference where end_date is null. It's the end_date part that's causing me problems. Here's what I've got so far:

SELECT
    t1.*
FROM
    involvements t1
LEFT OUTER JOIN
    involvements t2
    ON
        (t1.ref_year = t2.ref_year
    AND
        t1.ref_no = t2.ref_no
    AND
        t1.start_date < t2.start_date)
WHERE
    t2.ref_year IS NULL
AND
    t2.ref_no IS NULL

This selects the inv_id with the earliest start_date perfectly, but I can't figure out how to account for those cases where the inv_id with the earliest start_date has an end_date that is not null, in which case I'd want the script to check the next-oldest inv_id for that reference instead, and so on until it returns one with a null end_date. I tried creating a temporary table with only null end_dates then inner joining to this as a sub-query but of course couldn't because the WHERE clause came before the sub-query. Is there an efficient way to get my desired behaviour?

4

2 に答える 2

3

I would use ROW_NUMBER() to pick the earliest record for each reference.

WITH
  sequenced_data
AS
(
  SELECT
    ROW_NUMBER() OVER (PARTITION BY ref_year, ref_no ORDER BY start_date ASC) AS sequence_id,
    *
  FROM
    involvements
  WHERE
    end_date IS NULL
)
SELECT
  *
FROM
  sequenced_data
WHERE
  sequence_id = 1

If a reference doesn't have any records where end_date IS NULL, then it won't return anything for that reference.

于 2012-06-19T14:21:56.440 に答える
0

次のようなものを試してください。

SELECT
    t2.*
FROM
(SELECT
    ref_year, 
    ref_no,
    min(start_date) start_date
FROM
    involvements t1
where
    end_date is null
GROUP BY
    ref_year,
    ref_no
) as subq
INNER JOIN involvements t2 on 
    t2.ref_year - subq.ref_year 
    and t2.ref_no = subq.ref_no 
    and subq.start_date = t2.start_date
于 2012-06-19T14:23:34.613 に答える