选择一列DISTINCT SQL

时间:2008-10-30 18:42:31

标签: sql sql-server coldfusion cfml

补充:使用SQL Server 2000和2005,因此必须同时使用它们。另外,value_rk不是数字/整数(错误:操作数数据类型uniqueidentifier对于min运算符无效)

当我不关心返回的其他列时,有没有办法做单列“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版本慢一点,但老实说,在这一点上工作的东西总比没有好。它从第一个查询获取结果,执行第二个查询,但将结果限制为一个,并获取匹配值的匹配value_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建议仍然非常受欢迎:)

11 个答案:

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

换句话说,找到行a1,其中没有行a2,但valuevalue_rk更高。

答案 2 :(得分:8)

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

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

PostgreSQL Docs

答案 3 :(得分: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是唯一的,这应该可行。

答案 4 :(得分:2)

好的,这是我的假设:

标准SQL Server

value_rk不是数值,但value和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)

如果其中一个字段不是数字,则需要更多考虑 - 请告诉我们。

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

基本上,您正在创建一个有限的记录集,其中表填充了“value”的唯一值,并让SQL Server仅使用主表中的一个匹配来填补空白。

编辑添加:这个语法在cfquery中运行得很好。

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

没有测试!

答案 7 :(得分:1)

我不确定我是否完全理解你的设置,但这样的工作会是这样的:

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

同样,我不确定你试图限制哪一列,或者你想如何限制它。

答案 8 :(得分: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 VALUE=@keyVal 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和其他人。

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

工作

答案 10 :(得分:0)

如John Fiala所述,SQL服务器中的规范答案是,当您要对列的子集执行“不同”操作时,请使用group 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处理文本和其他几种非数值的数据类型。