Select 只有一行,按值字段,排序
Select Only One Row, by Value Field, Ordering
这个问题从 延伸而来,但更笼统(没有产品限制,但按产品价值给出一个)。
我有一个table
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
);
填充 table
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 为假且 condition_weight 3 为真,则 condition_weight 2 和 condition_weight 1 将被忽略。
如果condition_weight4和3为假而condition_weight2为真condition_weight1将被忽略。
如果 condition_weight 4, 3 和 2 只为假 condition_weight 1 将被评估。
问题:每个product_code
如何只获得一行,其优先级最高,输入参数 date_submit with condition weight definitions?
EXAMPLE of OUTPUT Required 注意:以下table结果是手动创建的(我需要类似的结果,但我没有查询)。
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
检查答案 结果,但如果有可能更简单的查询。
编辑 只有 priority
最高 priority
必须是 .
我认为这应该可以满足您的要求。
select *
from (
SELECT mytable.*,
case when date_act is not null and date_dis is not null then 4
when date_dis is not null then 3
when date_act is not null then 2
else 1 end as weight,
max(case when date_act is not null and date_dis is not null then 4
when date_dis is not null then 3
when date_act is not null then 2
else 1 end) over (partition by product_code) as max_weight
FROM mytable
where TO_DATE(:date_submit, 'yyyy/mm/dd') between coalesce(date_act, TO_DATE(:date_submit, 'yyyy/mm/dd'))
and coalesce(date_dis, TO_DATE(:date_submit, 'yyyy/mm/dd'))
) iv
where weight = max_weight
;
如果您还想按 :product_code
参数进行过滤,就像在您的其他问题中那样,会简单一些。
使用 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
这个问题从
我有一个table
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
);
填充 table
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 为假且 condition_weight 3 为真,则 condition_weight 2 和 condition_weight 1 将被忽略。
如果condition_weight4和3为假而condition_weight2为真condition_weight1将被忽略。
如果 condition_weight 4, 3 和 2 只为假 condition_weight 1 将被评估。
问题:每个product_code
如何只获得一行,其优先级最高,输入参数 date_submit with condition weight definitions?
EXAMPLE of OUTPUT Required 注意:以下table结果是手动创建的(我需要类似的结果,但我没有查询)。
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
检查答案
编辑 只有 priority
最高 priority
必须是 .
我认为这应该可以满足您的要求。
select *
from (
SELECT mytable.*,
case when date_act is not null and date_dis is not null then 4
when date_dis is not null then 3
when date_act is not null then 2
else 1 end as weight,
max(case when date_act is not null and date_dis is not null then 4
when date_dis is not null then 3
when date_act is not null then 2
else 1 end) over (partition by product_code) as max_weight
FROM mytable
where TO_DATE(:date_submit, 'yyyy/mm/dd') between coalesce(date_act, TO_DATE(:date_submit, 'yyyy/mm/dd'))
and coalesce(date_dis, TO_DATE(:date_submit, 'yyyy/mm/dd'))
) iv
where weight = max_weight
;
如果您还想按 :product_code
参数进行过滤,就像在您的其他问题中那样,会简单一些。
使用 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