sql union删除“半重复”

时间:2013-03-04 09:32:06

标签: sql sql-server sql-server-2000

我正在做一个像这样的工会

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子句以使其更复杂

这通常会让我回来

+-----+------+-----------+--------------+
|(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语句进入结果集。 / p>

即我想要这个:

+-----+------+-----------+--------------+
|(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.

谢谢!

3 个答案:

答案 0 :(得分: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

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

答案 1 :(得分: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))

答案 2 :(得分: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