sql - 仅选择一行,按值字段,排序
问题描述
此问题从Oracle SQL Where 条件权重扩展而来,但更笼统(没有产品限制,但按产品值给出)。
我有一张桌子
DROP TABLE mytable;
CREATE TABLE mytable
(
product_code VARCHAR2(20 BYTE) NOT NULL ENABLE,
priority NUMBER NOT NULL ENABLE,
date_act DATE,
date_dis DATE
);
填充表格
INSERT INTO mytable (product_code, priority, date_act, date_dis) VALUES ('bla', '0', TO_DATE('2019-01-01', 'YYYY-MM-DD'), TO_DATE('2019-01-31', 'YYYY-MM-DD'));
INSERT INTO mytable (product_code, priority, date_act, date_dis) VALUES ('bla', '1', TO_DATE('2019-02-01', 'YYYY-MM-DD'), TO_DATE('2019-02-28', 'YYYY-MM-DD'));
INSERT INTO mytable (product_code, priority, date_act) VALUES ('bla', '2', TO_DATE('2019-01-01', 'YYYY-MM-DD'));
INSERT INTO mytable (product_code, priority, date_act) VALUES ('bla', '3', TO_DATE('2019-02-01', 'YYYY-MM-DD'));
INSERT INTO mytable (product_code, priority, date_dis) VALUES ('bla', '4', TO_DATE('2019-01-31', 'YYYY-MM-DD'));
INSERT INTO mytable (product_code, priority, date_dis) VALUES ('bla', '5', TO_DATE('2019-02-28', 'YYYY-MM-DD'));
INSERT INTO mytable (product_code, priority) VALUES ('bla', '6');
INSERT INTO mytable (product_code, priority) VALUES ('bla', '7');
INSERT INTO mytable (product_code, priority, date_act, date_dis) VALUES ('foo', '0', TO_DATE('2019-01-01', 'YYYY-MM-DD'), TO_DATE('2019-01-31', 'YYYY-MM-DD'));
INSERT INTO mytable (product_code, priority, date_act) VALUES ('foo', '1', TO_DATE('2019-02-01', 'YYYY-MM-DD'));
INSERT INTO mytable (product_code, priority, date_dis) VALUES ('foo', '2', TO_DATE('2019-01-31', 'YYYY-MM-DD'));
INSERT INTO mytable (product_code, priority) VALUES ('foo', '3');
INSERT INTO mytable (product_code, priority, date_act, date_dis) VALUES ('tmp', '0', TO_DATE('2019-01-01', 'YYYY-MM-DD'), TO_DATE('2019-01-31', 'YYYY-MM-DD'));
INSERT INTO mytable (product_code, priority, date_act) VALUES ('tmp', '1', TO_DATE('2019-01-01', 'YYYY-MM-DD'));
INSERT INTO mytable (product_code, priority, date_dis) VALUES ('tmp', '2', TO_DATE('2019-02-28', 'YYYY-MM-DD'));
INSERT INTO mytable (product_code, priority) VALUES ('tmp', '3');
内容
SELECT * FROM mytable;
和输出
PRODUCT_CODE PRIORITY DATE_ACT DATE_DIS
-------------------- ---------- --------- ---------
bla 0 01-JAN-19 31-JAN-19
bla 1 01-FEB-19 28-FEB-19
bla 2 01-JAN-19
bla 3 01-FEB-19
bla 4 31-JAN-19
bla 5 28-FEB-19
bla 6
bla 7
foo 0 01-JAN-19 31-JAN-19
foo 1 01-FEB-19
foo 2 31-JAN-19
foo 3
tmp 0 01-JAN-19 31-JAN-19
tmp 1 01-JAN-19
tmp 2 28-FEB-19
tmp 3
条件定义
- condition_weight 4:当行已经定义
date_act
时。date_dis
- condition_weight 3:当行已
date_dis
定义但未定义时date_act
。 - condition_weight 2:当行已
date_act
定义但未定义时date_dis
。 - condition_weight 1:当行已定义
date_act
且未date_dis
定义时。
如果 condition_weight 4 为真,则左侧(3、2 和 1)将被忽略。
如果 condition_weight 4 为 false 且 condition_weight 3 为 true ,则 condition_weight 2 和 condition_weight 1 将被忽略。
如果 condition_weight 4 和 3 为 false 而 condition_weight 2 为 true,condition_weight 1 将被忽略。
如果 condition_weight 4、3 和 2 为假,则只会评估 condition_weight 1。
问题:product_code
如何使用具有条件权重定义的输入参数 date_submit获取每个优先级最高的一行?
所需输出示例 注意:下表结果是手动创建的(我需要类似的结果,但我没有查询)。
DATE_SUBMIT :='2019/01/15'
CONDITION_WEIGHT PRIO PRODUCT_CODE PRIORITY DATE_ACT DATE_DIS :DATE_SUBMIT
---------------- ---------- -------------------- ---------- --------- --------- --------------------------------------------------------------------------------------------------------------------------------
4 0 bla 0 01-JAN-19 31-JAN-19 2019/01/15
4 0 foo 0 01-JAN-19 31-JAN-19 2019/01/15
4 0 tmp 0 01-JAN-19 31-JAN-19 2019/01/15
DATE_SUBMIT :='2019/02/15'
CONDITION_WEIGHT PRIO PRODUCT_CODE PRIORITY DATE_ACT DATE_DIS :DATE_SUBMIT
---------------- ---------- -------------------- ---------- --------- --------- --------------------------------------------------------------------------------------------------------------------------------
4 1 bla 1 01-FEB-19 28-FEB-19 2019/02/15
2 1 foo 1 01-FEB-19 2019/02/15
3 2 tmp 2 28-FEB-19 2019/02/15
DATE_SUBMIT :='2018/12/31'
CONDITION_WEIGHT PRIO PRODUCT_CODE PRIORITY DATE_ACT DATE_DIS :DATE_SUBMIT
---------------- ---------- -------------------- ---------- --------- --------- --------------------------------------------------------------------------------------------------------------------------------
3 5 bla 5 28-FEB-19 2018/12/31
3 2 foo 2 31-JAN-19 2018/12/31
3 2 tmp 2 28-FEB-19 2018/12/31
DATE_SUBMIT :='2019/12/31'
CONDITION_WEIGHT PRIO PRODUCT_CODE PRIORITY DATE_ACT DATE_DIS :DATE_SUBMIT
---------------- ---------- -------------------- ---------- --------- --------- --------------------------------------------------------------------------------------------------------------------------------
2 3 bla 3 01-FEB-19 2019/12/31
2 1 foo 1 01-FEB-19 2019/12/31
2 1 tmp 1 01-JAN-19 2019/12/31
检查答案https://stackoverflow.com/a/59779653/1410223结果,但是否有可能更简单的查询。
编辑只有priority
最高priority
必须是。
解决方案
使用 分配条件权重case when
。然后为每种产品选择最佳行,使用rank()
:
with
d as (select date '2019-02-15' date_submit from dual),
t as (
select m.*, case
when date_act is not null and date_dis is not null then 4
when date_act is null and date_dis is not null then 3
when date_act is not null and date_dis is null then 2
else 1 end condition
from mytable m)
select product_code, priority, date_act, date_dis, condition, date_submit
from (
select t.*, d.*,
rank() over ( partition by product_code order by condition desc ) rnk
from t join d
on date_submit between nvl(date_act, date_submit) and nvl(date_dis, date_submit))
where rnk = 1
推荐阅读
- r - 如何在分组列中按行添加值
- html - 为什么内容会从容器中挤出来?
- android - 如何在android studio中创建一个新项目?
- java - 为什么 JavaFX 画布有时无法绘制并破坏我的程序?
- ionic-framework - 尝试使用离子登录,但输入密码字段被完全跳过离子 3
- python - 如何使函数在函数外部使用变量,但在类的方法中
- c# - 如何保护 App.Config 窗体应用程序?
- c# - 如何在 C# 中获取包含表情符号的字符串的正确长度
- javascript - Javascript if else循环?
- javascript - Postman 脚本在 Postman 中完美执行,在 Newman 中失败