如何使用多个查询选择最高价格

时间:2017-12-04 16:58:51

标签: sql oracle oracle11g

我创建了两个表,表和数据插入值如下:

create table product (
pid number(10) primary key,
pname varchar2(30)
);

INSERT INTO product values(100,'Apple');
INSERT INTO product values(101,'Banana');
INSERT INTO product values(102,'Pinaple');
INSERT INTO product values(103,'Orange');

create table purchase(
invid  number(10) primary key,
pid number(10),
pprice number(10)
);
alter table purchase add(constraint pid_fk FOREIGN KEY (pid) references  product(pid));

INSERT INTO  purchase values(10,101,30);
INSERT INTO  purchase values(11,103,35);
INSERT INTO  purchase values(12,103,9);
INSERT INTO  purchase values(13,103,22);
INSERT INTO  purchase values(14,101,12);

现在我已经选择了表购买节目给出数据

invid    pid  pprice
10       101   30
11       103   35
12       103    9
13       103   22
14       101   12

现在我想成为最后一次插入价格pid = 103 现在需要显示pprice = 22 我已经准备好使用两个查询完成任务,例如:

  

select max(invid) from purchase where pid=103;

结果是22并运行下一个语句

  

select max(pprice) from purchase where invid=13;

显示结果= 22  我想使用运行一个语句来显示结果22,

2 个答案:

答案 0 :(得分:2)

可能最直接的方法是使用子查询:

SELECT MAX(pprice)
FROM purchase
WHERE invid = (SELECT MAX(invid) FROM purchase WHERE pid = 103)

旁注,根据您的示例数据,您不需要MAX() pprice,但我保留了这种方式,以防您需要真实数据集。

答案 1 :(得分:0)

聚合FIRST/LAST功能完全适用于此类任务。不幸的是,似乎绝大多数开发人员都没有使用它 - 要么是因为他们不知道它的存在,要么是因为他们不了解它是如何工作的,或者是谁知道其他原因。

https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions056.htm

该函数允许max(invid)(在您的模型中)不唯一的情况;在这种情况下,您必须决定要选择的pprice。您可以从max和最大值min的所有用户中选择ppricesum或平均pid = 103(或invidmax(invid)列中的值。当然,如果pprice是唯一的(就像你的问题一样),那么所有这些函数都只返回与invid相关联的min;但是您仍然必须使用这些聚合函数之一,因为在解析时不知道该唯一性,它只在执行时才知道。 select min(pprice) keep (dense_rank last order by invid) as pprice from ........ where pid = 103 ; 通常以这种方式使用。所以:

HashSet<PropertyInfo> visitedProperties = new HashSet<PropertyInfo>();
Stack<PropertyInfo> remainingProperties = new Stack<PropertyInfo>(type.GetProperties());
List<PropertyInfo> foundProperties = new List<PropertyInfo>();

while (remainingProperties.Count > 0)
{
    var currentProperty = remainingProperties.Pop();

    // Process this property if we haven't visited it yet
    // Add returns true if the element is not yet in the set
    if (visitedProperties.Add(currentProperty))
    {

        // Add sub-properties to the remaining property list if we haven't visited them
        var nestedProperties = currentProperty.PropertyType.GetProperties();
        foreach (var nestedProperty in nestedProperties)
        {
            if (!visitedProperties.Contains(nestedProperty))
            {
                remainingProperties.Push(nestedProperty);
            }
        }

        // Check the current property for attributes
        var singleNestedPropertyIndex = nestedProperty.GetCustomAttribute<SingleIndexAttribute>();
        var groupNestedIndex = nestedProperty.GetCustomAttribute<GroupIndexAttribute>();
        var ttlIndex = property.GetCustomAttribute<TTLIndexAttribute>();

        if (singleNestedPropertyIndex != null || groupNestedIndex != null || ttlIndex != null)
        {
            foundProperties.Add(nestedProperty);
        }
    }
}