代码之家  ›  专栏  ›  技术社区  ›  Organiccat

选择一列非重复SQL

  •  14
  • Organiccat  · 技术社区  · 16 年前

    添加:使用SQL Server 2000和2005,因此必须同时使用两者。此外,值“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工作,所以如果有一个简单的解决方法,我也愿意接受。我正试图限制或“按”第一列“值分组”。价值是我的大问题,因为每个价值都是独一无二的,但我只需要一个。

    注:数值“rk”不是数字,因此不起作用。

    更新:我有一个工作版本,可能比纯SQL版本慢得多,但老实说,在这一点上工作的任何东西都比什么都没有要好。它从第一个查询中获取结果,执行第二个查询,只将结果限制为一个,并为匹配的值获取匹配值。像这样:

    <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 回复  |  直到 11 年前
        1
  •  11
  •   walming    16 年前

    这可能有效:

    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
    

    …未测试。

        2
  •  8
  •   Bill Karwin    16 年前
    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 存在于相同的 value 还有一个更大的 value_rk .

        3
  •  8
  •   Patryk Kordylewski    16 年前

    这应该对PostgreSQL有效,我不知道您使用哪种DBMS。

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

    PostgreSQL Docs

        4
  •  2
  •   gfrizzle    16 年前

    这就是你要找的吗?

    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
    

    如果值是唯一的,这应该是有效的。

        5
  •  2
  •   John Fiala    16 年前

    好吧,我的假设是:

    标准SQL Server

    值“rk”不是数值,而是值和属性“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)
    

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

        6
  •  2
  •   Dane    16 年前

    如果您愿意使用表变量,可以将其全部保存在单个数据库调用中,如下所示:

    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中工作正常。

        7
  •  1
  •   Chris Cudmore    16 年前
    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
    

    没有测试过!

        8
  •  1
  •   Adam    16 年前

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

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

    再说一次,我不确定你想限制哪一列,或者你想如何限制它。

        9
  •  0
  •   matt.mercieca    16 年前

    没有我想要的那么优雅——这本质上就是你所做的,仅仅是在纯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和其他。

        10
  •  0
  •   David M    13 年前

    我想

    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
    

    工作

        11
  •  0
  •   Corwin Joy    12 年前

    正如John Fiala所指出的,SQL Server中的规范化答案是,当您希望对列的子集执行“distinct”操作时,使用group by子句。为什么这是正确的规范答案?好吧,您希望拉入不属于“distinct”组的列。您要为这些辅助列拉入哪些行?使用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
    

    另外,值得注意的是,最小值和最大值用于文本和其他一些非数值数据类型。