[英]Select closest maximal numeric value in Firebird
假設有 2 個表,我們稱它們為“Master”和“Detail”:
Master
--------------------------------
| ID | field_1 | ... | field_n |
--------------------------------
Detail
--------------------------------------------
| ID | master_id | f_value | ... | field_n |
--------------------------------------------
| 1 | 1 | 0.03 | ... | ... |
--------------------------------------------
| 2 | 1 | 0.95 | ... | ... |
--------------------------------------------
| 3 | 1 | 1.22 | ... | ... |
--------------------------------------------
| 4 | 2 | 0.91 | ... | ... |
--------------------------------------------
| 5 | 2 | 0.93 | ... | ... |
--------------------------------------------
| 6 | 2 | 2.07 | ... | ... |
--------------------------------------------
有 2 個輸入參數:主 ID 列表( master_id_list
)和數值( num_value
)。
對於master_id_list
每個ID
,我應該得到一個 Detail 記錄:
num_value < MIN( f_value )
,它應該是MIN( f_value )
的記錄num_value > MAX( f_value )
,它應該是MAX( f_value )
的記錄f_value
的記錄例一。 master_id_list = [ 1, 2 ]
, num_value = 0
。 結果:
--------------------------------------------
| 1 | 1 | 0.03 | ... | ... |
--------------------------------------------
| 4 | 2 | 0.91 | ... | ... |
--------------------------------------------
例2。 master_id_list = [ 1, 2 ]
, num_value = 50
。 結果:
--------------------------------------------
| 3 | 1 | 1.22 | ... | ... |
--------------------------------------------
| 6 | 2 | 2.07 | ... | ... |
--------------------------------------------
例3。 master_id_list = [ 1, 2 ]
, num_value = 0.94
。 結果:
--------------------------------------------
| 2 | 1 | 0.95 | ... | ... |
--------------------------------------------
| 6 | 2 | 2.07 | ... | ... |
--------------------------------------------
您應該能夠使用相關子查詢。 假設num_value
在主表中, f
值在num_value
中:
select m.*,
(select first 1 d.f_value
from detail d
where d.master_id = m.master_id
order by abs(m.num_value - d.f_value)
)
from master m;
編輯:
如果您想要更大的值的偏好 - 如果它存在 - 只需將order by
更改為:
order by (case when d.f_value >= m.num_value then 1 else 2 end),
abs(d.f_value - m.num_value)
讓我們將num_value
稱為您正在尋找的針(如“大海撈針”)。
首先,我們將對針進行標准化,使其不低於MIN(f_value)
且不高於每個master_id
的MAX(f_value)
。
然后,我們將查找每個Detail
行,其最近的f_value
大於或等於我們的歸一化針,按master_id
分組。 (這只是一個最大的每組 sql問題)。
WITH normalized AS ( -- First normalize the needle for each master_id
SELECT hilo.master_id,
MAXVALUE(hilo.lo, MINVALUE(hilo.hi, d.needle)) AS needle
FROM (SELECT ? FROM rdb$database) d (needle) -- <- change this ? to your needle
CROSS JOIN
(SELECT master_id, MAX(f_value), MIN(f_value)
FROM detail GROUP BY master_id) hilo (master_id, hi, lo)
),
ranked AS ( -- Next order f_value >= needle by master_id
SELECT detail.*,
ROW_NUMBER() OVER (PARTITION BY detail.master_id ORDER BY f_value ASC)
AS rk
FROM detail
LEFT JOIN
normalized ON detail.master_id = normalized.master_id
WHERE detail.f_value >= normalized.needle
)
-- Strip off the rank ordering and SELECT what you want
SELECT id, master_id, f_value, ...
FROM ranked
WHERE rk = 1;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.