2

我正在做这样的工会

select name, price from products where project = 10  // prio 1
union
select name, price from products where customer = 5  // prio 2
union
select name, price from products where standard = 9  // prio 3

编辑:更改 where-clause 使其更复杂一些

这通常会给我回来

+-----+------+-----------+--------------+
|(NO) | name |  price    |  (prio)      |
+-----+------+-----------+--------------+
|  1  |  a   |    10     |  (1)         |
|  2  |  b   |     5     |  (1)         |

|  3  |  a   |    13     |  (2)         |
|  4  |  b   |     2     |  (2)         |

|  5  |  a   |     1     |  (3)         |
|  6  |  b   |     5     |  (3)         |
|  7  |  c   |     3     |  (3)         |
+-----+------+-----------+--------------+

我了解例如第 1 行和第 3 行不是重复的,不会被 union 语句删除。然而,这正是我想要做的。也就是说,如果第一个 select 语句(prio 1)返回了一个名称(例如“a”),我不希望任何其他“a”:s 从更高优先级的 select 语句中进入结果集。

即,我想要这个:

+-----+------+-----------+--------------+
|(NO) | name |  price    |  (prio) |
+-----+------+-----------+--------------+
|  1  |  a   |    10     |  (1)         |
|  2  |  b   |     5     |  (1)         |

|  7  |  c   |     3     |  (3)         |
+-----+------+-----------+--------------+

这可能吗?

我尝试使用group by,但这要求我在我不想做的价格上使用 MIN、MAX、AVG 等,即:

select name, avg(price) from (...original query...) group by name
// this is not ok since I donnot want the avg price, I want the "first" price

我正在使用 MS SQL 2000。我可以使用类似的东西first(..)作为聚合函数group by吗?尝试此操作时,出现错误:

select name, first(price) from (...original query...) group by name
// error: 'first' is not a recognized built-in function name.

谢谢!

4

3 回答 3

2

对于 SQL Server 2005+:

WITH records
AS
(
    SELECT  name, price, prio,
            ROW_NUMBER() OVER (PARTITION BY name
                                ORDER BY prio ASC) rn
    FROM    products
)
SELECT  Name, Price
FROM    records
WHERE   rn = 1

试试这个SQL Server 2000

SELECT  a.*
FROM    products a
        INNER JOIN
        (
            SELECT  name, MIN(prio) min_prio
            FROM    products 
            WHERE   prio IN (1,2,3)
            GROUP   BY  name
        ) b ON a.name = b.name AND
                a.prio = b.min_prio

为了获得更好的性能,请在 column 上添加一个复合索引(name, prio)

于 2013-03-04T09:37:03.317 回答
1
select name, price from products where prio = 1
union
select name, price from products where prio = 2 and name not in (select name from products where prio = 1)

union
select name, price from products where prio = 3 and name not in 
(select name from products where prio = 1
union
select name from products where prio = 2 and name not in (select name from products where prio = 1))
于 2013-03-04T09:36:33.923 回答
1

不确定这是否有效,但想法是这样的:

select name,
    min(case when prio=min_prio then price else NULL end) as price,
    min(prio) as min_prio
from products
group by name
order by min_prio
于 2013-03-04T09:55:58.393 回答