2008-10-30 118 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工作。