2008-10-30 83 views
14

增加:使用SQL Server 2000和2005,因此必须同时使用两者。此外,value_rk不是一个数字/整数(错误:操作数数据类型uniqueidentifier无效最小运算符)选择一列DISTINCT SQL

有没有办法做单列“DISTINCT”匹配时,我不关心其他列返回?例如:

**Table** 
Value A, Value L, Value P 
Value A, Value Q, Value Z 

我需要基于第一个(值A)中的内容返回其中的一个行。我仍然需要第二栏和第三栏的结果(第二栏实际上应该与第一栏的全部匹配,但第三栏是唯一的键,至少我需要其中的一个)。

这里就是我这么远,虽然它没有明显的工作:

SELECT value, attribute_definition_id, value_rk 
FROM attribute_values 
WHERE value IN (
    SELECT value, max(value_rk) 
    FROM attribute_values 
) 
ORDER BY attribute_definition_id 

我在工作的ColdFusion所以,如果有一个简单的解决方法在我持开放的态度,以及。我试图限制或“分组”第一列“价值”。 value_rk是我的大问题,因为每个值都是唯一的,但我只需要一个值。

注:value_rk不是一个数字,所以这是行不通

更新:我有一个工作版本,它可能比纯粹的SQL版本慢了不少,但老实说,任何在这一点上工作总比没有好。它从第一个查询中得到结果,除第一个查询外,第二个查询将结果限制为1,并为匹配的值抓取匹配的值__rk。像这样:

<cfquery name="queryBaseValues" datasource="XXX" timeout="999"> 
    SELECT DISTINCT value, attribute_definition_id 
    FROM attribute_values 
    ORDER BY attribute_definition_id 
</cfquery> 

<cfoutput query="queryBaseValues"> 
    <cfquery name="queryRKValue" datasource="XXX"> 
     SELECT TOP 1 value_rk 
     FROM attribute_values 
     WHERE value = '#queryBaseValues.value#' 
    </cfquery> 
    <cfset resourceKey = queryRKValue.value_rk> 
    ... 

所以你有它,在ColdFusion中选择一个明显的列。任何纯粹的SQL Server 2000/2005建议仍然非常受欢迎:)

+0

你能说清楚你需要什么吗?任何行,但每个值只有一行?具有最大值value_rk的那一行?我不确定自己明白你要去哪里。 – tvanfosson 2008-10-30 18:49:10

+0

>注意:value_rk不是数字,因此这不起作用。 这与您的查询失败原因无关。您没有提到您正在使用的RDBMS,但在Oracle中,您可以在字符列上使用MAX。 – 2008-10-30 18:55:31

+0

MS SQL也可以在非数字列上使用MAX。 – BradC 2008-10-30 18:56:51

回答

11

这可能工作:

SELECT DISTINCT a.value, a.attribute_definition_id, 
    (SELECT TOP 1 value_rk FROM attribute_values WHERE value = a.value) as value_rk 
FROM attribute_values as a 
ORDER BY attribute_definition_id 

..未经测试。

1
SELECT value, attribute_definition_id, value_rk 
FROM attribute_values 
WHERE value, value_rk IN (
     SELECT value, max(value_rk) 
     FROM attribute_values 
     GROUP BY value 
) 
ORDER BY attribute_definition_id 

未测试!

2

这是你在找什么?

SELECT value, attribute_definition_id, value_rk 
FROM attribute_values av1 
WHERE value_rk IN (
     SELECT max(value_rk) 
     FROM attribute_values av2 
     WHERE av2.value = av1.value 
) 
ORDER BY attribute_definition_id 

如果value_rk是唯一的,这应该工作。

8
SELECT a1.value, a1.attribute_definition_id, a1.value_rk 
FROM attribute_values AS a1 
    LEFT OUTER JOIN attribute_values AS a2 
    ON (a1.value = a2.value AND a1.value_rk < a2.value_rk) 
WHERE a2.value IS NULL 
ORDER BY a1.attribute_definition_id; 

换句话说,找到其中没有行a2具有相同value和更大value_rk存在该行a1

1

我不知道如果我完全理解你的设置,但会是这样的工作:

SELECT value, attribute_definition_id, value_rk 
FROM attribute_values 
GROUP BY value 
ORDER BY attribute_definition_id; 

再次,我不是真正确定它是哪一列你想限制,或者你想限制它。

8

这应该适用于PostgreSQL,我不知道你使用哪个dbms。

SELECT DISTINCT ON (value) 
    value, 
    attribute_definition_id, 
    value_rk 
FROM 
    attribute_values 
ORDER BY 
    value, 
    attribute_definition_id 

PostgreSQL Docs

2

好了,这里是我的假设:

标准的SQL Server

value_rk不是一个数值,但价值和attribute_definition_id 数字。

SELECT value_rk, MIN(value) as value, MIN(attribute_definition_id) as attribute_definition_id 
FROM attribute_values 
GROUP BY value_rk 
ORDER BY MIN(attribute_definition_id) 

如果其中一个字段不是数字,那么需要更多的思考 - 请让我们知道。

0

比我想要的更不优雅----它基本上就是你在做什么,只是在纯SQL中---但它的工作原理可以在SQL中完成。

 
DECLARE @mytable TABLE(mykey NVARCHAR(512), myVal NVARCHAR(512)) 

DECLARE @keyVal NVARCHAR(512) 
DECLARE @depVal NVARCHAR(512) 
DECLARE myCursor CURSOR for 
    SELECT DISTINCT(value) FROM attribute_values 
OPEN myCursor 
FETCH NEXT FROM myCursor INTO @keyVal 
WHILE @@FETCH_STATUS=0 
    BEGIN 
    SET @depVal = (SELECT TOP 1 attribute_definition_id FROM attribute_values WHERE [email protected] ORDER BY attribute_definition_id) 
    INSERT INTO @mytable (mykey, myVal) VALUES (@keyVal, @depVal) 
    FETCH NEXT FROM myCursor INTO @keyVal 
    END 
DEALLOCATE myCursor 

SELECT * FROM @mytable 

您可以使用此方法添加depVal2和其他人。

2

如果你是开放的使用表变量,你可以把它所有的单个数据库调用这样的范围内:

DECLARE @attribute_values TABLE (value int, attribute_definition_id int, value_rk uniqueidentifier) 

INSERT INTO @attribute_values (value) 
SELECT DISTINCT value FROM attribute_values 

UPDATE @attribute_values 
SET attribute_definition_id = av2.attribute_definition_id, 
    value_rk = av2.value_rk 
FROM @attribute_values av1 
INNER JOIN attribute_values av2 ON av1.value = av2.value 

SELECT value, attribute_definition_id, value_rk FROM @attribute_values 

从本质上讲,你要创建一个拥有充满“价值的唯一值的表中的有限记录',并让SQL Server仅使用主表中的一个匹配填充空位。

编辑添加:此语法在cfquery中工作就好了。

0

我觉得

SELECT DISTINCT a.value, a.attribute_definition_id, 
(SELECT TOP 1 value_rk FROM attribute_values WHERE value = a.value) as value_rk 
FROM attribute_values as a 
ORDER BY attribute_definition_id 

工作

0

正如约翰·菲拉指出,在SQL服务器的典型回答是BY子句,当你想在一个子集进行“独特”的操作使用一组列。为什么这是正确的经典答案?那么,你想拉入不属于你的“独特”组的列。您想要为这些子列准备什么行?使用group by子句并为这些子列定义聚合函数可使您的查询行为良好,因为您现在知道如何获得这些子列。本文给出了更多的细节:

http://weblogs.sqlteam.com/jeffs/archive/2007/10/12/sql-distinct-group-by.aspx

SELECT value_rk, MIN(value) as value, 
MIN(attribute_definition_id) as attribute_definition_id 
FROM attribute_values 
GROUP BY value_rk 

此外,值得注意的是,在文本和不在数值的几个其他数据类型MIN和MAX工作。