我在表格中有这些行
ID Name Price Delivery
== ==== ===== ========
1 apple 1 1
2 apple 3 2
3 apple 6 3
4 apple 9 4
5 orange 4 6
6 orange 5 7
如果没有第三次交货,我希望第三次交货(交货= 3)或最后价格。
它会给我这个:
ID Name Price Delivery
== ==== ===== ========
3 apple 6 3
6 orange 5 7
我没有必要想要一个完整的解决方案,但我们将非常感谢您对寻找什么的想法。
答案 0 :(得分:4)
SQL> create table t (id,name,price,delivery)
2 as
3 select 1, 'apple', 1, 1 from dual union all
4 select 2, 'apple', 3, 2 from dual union all
5 select 3, 'apple', 6, 3 from dual union all
6 select 4, 'apple', 9, 4 from dual union all
7 select 5, 'orange', 4, 6 from dual union all
8 select 6, 'orange', 5, 7 from dual
9 /
Table created.
SQL> select max(id) keep (dense_rank last order by nullif(delivery,3) nulls last) id
2 , name
3 , max(price) keep (dense_rank last order by nullif(delivery,3) nulls last) price
4 , max(delivery) keep (dense_rank last order by nullif(delivery,3) nulls last) delivery
5 from t
6 group by name
7 /
ID NAME PRICE DELIVERY
---------- ------ ---------- ----------
3 apple 6 3
6 orange 5 7
2 rows selected.
编辑:由于您想要“了解要查找的内容”,以下是对我认为此解决方案最佳的原因的说明,此外还有最少行的查询。您的预期结果集表示您要按水果名称对数据进行分组(“按名称分组”)。并且,对于每个组,您希望保留记录的值为delivery = 3,或者当该数字不存在时,最后一个(“keep(dense_rank last order by nullif(delivery,3)nulls lasts”)。在我的看来,上面的查询就是这样的。它只使用一个表访问来获得结果,尽管我的查询并不是唯一的。
此致 罗布。
答案 1 :(得分:3)
使用ROW_NUMBER两次 - 一次过滤第三次传递之后的行,第二次查找剩余的最后一行(即每组查询的典型最大值)。
我使用CTE实现了这一点。我在SQL Server中测试过,但我相信Oracle支持相同的语法。
WITH T1 AS (
SELECT
ID, Name, Price, Delivery,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Delivery) AS rn
FROM Table1
), T2 AS (
SELECT
t1.*,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Delivery DESC) AS rn2
FROM T1
WHERE rn <= 3
)
SELECT ID, Name, Price, Delivery
FROM T2
WHERE rn2 = 1
结果:
ID Name Price Delivery
3 apple 6 3
6 orange 5 7
答案 2 :(得分:2)
select t3.ID, t3.Name, t3.Price, t3.Delivery
from (
select Name, max(Delivery) as MaxDelivery
from MyTable
group by Name
) t1
left outer join MyTable t2 on t1.Name = t2.Name and Delivery = 3
inner join MyTable t3 on t1.Name = t3.name
and t3.Delivery = coalesce(t2.Delivery, t1.MaxDelivery)
答案 3 :(得分:2)
如果您的意思是第三次交付,马克和APC的答案都有效,无论交货编号如何。这是一个使用分析函数的解决方案,专门搜索Delivery = 3的记录。
CREATE TABLE FRUITS (
ID NUMBER,
Name VARCHAR2(10),
Price INTEGER,
Delivery INTEGER);
INSERT INTO FRUITS VALUES (1, 'apple', 1, 1);
INSERT INTO FRUITS VALUES (2, 'apple', 3, 2);
INSERT INTO FRUITS VALUES (3, 'apple', 6, 3);
INSERT INTO FRUITS VALUES (4, 'apple', 9, 4);
INSERT INTO FRUITS VALUES (5, 'orange', 4, 6);
INSERT INTO FRUITS VALUES (6, 'orange', 5, 7);
INSERT INTO FRUITS VALUES (7, 'pear', 2, 5);
INSERT INTO FRUITS VALUES (8, 'pear', 4, 6);
INSERT INTO FRUITS VALUES (9, 'pear', 6, 7);
INSERT INTO FRUITS VALUES (10, 'pear', 8, 8);
SELECT ID,
Name,
Price,
Delivery
FROM (SELECT ID,
Name,
Price,
Delivery,
SUM(CASE WHEN Delivery = 3 THEN 1 ELSE 0 END)
OVER (PARTITION BY Name) AS ThreeCount,
ROW_NUMBER()
OVER (PARTITION BY Name ORDER BY Delivery DESC) AS rn
FROM FRUITS)
WHERE (ThreeCount <> 0 AND Delivery = 3) OR
(ThreeCount = 0 AND rn = 1)
ORDER BY ID;
DROP TABLE FRUITS;
Oracle XE 10g的结果:
ID Name Price Delivery
---- ---------- ------- ----------
3 apple 6 3
6 orange 5 7
10 pear 8 8
我在样本数据中加入了第三个水果,以说明对问题的不同解释的影响。其他解决方案将为梨选择ID = 9。