web-dev-qa-db-ja.com

1つの列を選択しますDISTINCTSQL

追加:SQL Server 2000および2005での作業なので、両方で作業する必要があります。また、value_rkは数値/整数ではありません(エラー:オペランドデータ型uniqueidentifierは最小演算子には無効です)

返される他の列を気にしないときに、単一の列「DISTINCT」を一致させる方法はありますか?例:

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

最初の行(値A)に基づいて、これらの行の1つだけを返す必要があります。 2番目と3番目の列の結果がまだ必要です(2番目は実際にはすべての列に一致するはずですが、3番目は一意のキーであり、少なくとも1つ必要です)。

明らかに機能しませんが、これまでに得たものは次のとおりです。

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は、すべての値が一意であるため、私の大きな問題ですが、必要なのは1つだけです。

注:value_rkは数値ではないため、これは機能しません

更新:動作するバージョンがあります。おそらく純粋なSQLバージョンよりもかなり遅いですが、正直なところ、この時点で動作しているものは何もないよりはましです。最初のクエリから結果を取得し、結果を1つに制限することを除いて、2番目のクエリを実行し、一致する値に対して一致する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で1つの列を明確に選択できました。純粋なSQLServer2000/2005の提案はまだ大歓迎です:)

14
Organiccat

これはうまくいくかもしれません:

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
walming
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;

言い換えると、同じvalue以上のa1を持つ行a2が存在しない行value_rkを見つけます。

8
Bill Karwin

これはPostgreSQLで機能するはずです。どのDBMSを使用しているかわかりません。

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

PostgreSQLドキュメント

8

これはあなたが探しているものですか?

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が一意の場合、これは機能するはずです。

2
gfrizzle

テーブル変数を使用することにオープンである場合は、次のようにすべてを1つのデータベース呼び出し内に保持できます。

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」の一意の値を入力して制限付きレコードセットを作成し、メインテーブルの一致の1つだけを使用してSQLServerにギャップを埋めさせます。

追加のために編集:この構文はcfquery内で問題なく機能します。

2
Dane

さて、これが私の仮定です:

標準SQLServer

value_rkは数値ではありませんが、valueとattribute_definition_id are数値です。

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)

これらのフィールドの1つが数値でない場合は、さらに検討する必要があります。お知らせください。

2
John Fiala
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

未検証!

1
Chris Cudmore

あなたの設定を完全に理解しているかどうかはわかりませんが、次のように作業します。

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

繰り返しますが、どの列を制限しようとしているのか、またはどのように制限したいのかはわかりません。

1
Adam

私が望むほどエレガントではありません----それは本質的にあなたがしていることであり、純粋な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などを追加できます。

0
matt.mercieca

John Fialaが指摘しているように、SQL Serverの標準的な答えは、列のサブセットに対して「個別の」操作を実行する場合にgroupby句を使用することです。なぜこれが正しい正規の答えなのですか?さて、あなたはあなたの「別個の」グループの一部ではない列を引き込みたいと思います。これらの補助列に正確にどの行をプルしますか? 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は、数値ではないテキストやその他のいくつかのデータ型で機能することに注意してください。

0
Corwin Joy

おもう

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
user1133937