まだ出ていない方法として、ORDER BY
句による指定でもご希望の結果になりそうですね。
SQL
1CREATE TABLE ZZZ
2(
3 ID varchar(10) not null
4 , 計測日 date not null
5 , 身長 float
6 , 体重 float
7 , BMI float
8);
9
10INSERT INTO ZZZ
11 ( ID, 計測日, 身長, 体重, BMI )
12VALUES
13 ( '001', '2021-09-01', 160, 55, 21.48 )
14 , ( '001', '2021-09-09', Null, 56, Null )
15 , ( '001', '2021-09-15', 161, 55, 21.22 )
16 , ( '002', '2021-07-18', 188, 88, 24.90 )
17 , ( '002', '2021-09-15', 189, Null, Null )
18 , ( '003', '2021-08-08', Null, Null, Null )
19 , ( '003', '2021-09-15', 155, Null, Null )
20 , ( '004', '2021-09-01', 157, 45, 18.26 )
21 , ( '004', '2021-09-15', 156, 43, 17.67 )
22 , ( '005', '2021-09-01', Null, 88, Null )
23 , ( '005', '2021-09-15', 171, Null, Null )
24;
SQL
1SELECT * FROM ZZZ
2WHERE 計測日 <= '2021-09-15'::date
3ORDER BY rank()
4 over( partition by ID
5 order by ( 身長 is not null )::int
6 +
7 ( 体重 is not null )::int desc
8 , 計測日 desc
9 )
10 , ID
11 LIMIT (
12 SELECT count( distinct( ID ) )
13 FROM ZZZ
14 WHERE 計測日 <= '2021-09-15'::date
15 )
16;
result
1 id | 計測日 | 身長 | 体重 | bmi
2-----+------------+------+------+-------
3 001 | 2021-09-15 | 161 | 55 | 21.22
4 002 | 2021-07-18 | 188 | 88 | 24.9
5 003 | 2021-09-15 | 155 | |
6 004 | 2021-09-15 | 156 | 43 | 17.67
7 005 | 2021-09-15 | 171 | |
( 以下、仕様としては考えにくいですが参考までに )
もし、身長・体重どちらかの数値しか入力されていないレコードに
計測日より上位の優先度を設定する場合は、優先したい項目の入力に重みを付与します。仮に
( 体重 is not null )::int * 2
という記述にすると
データ例 ID:005 の表示対象は 2021-09-01 のレコードに変更されます。