0

2 つのテーブルがDocumentあり、以下のようにDocumentField定義されています。

ドキュメント(簡潔にするために関連する列のみ):

DocumentKey - char(36)
DocTypeKey - char(36)

ドキュメントフィールド:

DocumentKey - char(36)
FieldId - varchar(10)
FieldValue - varchar(255)

DocumentKey値は標準のDocTypeKeyGUID です。FieldId主に 1 から 30 までの数値の文字列値です (他にも数値以外の値がいくつかあるため、varchar列になっています)。FieldValueは単なる文字列値であり、何でもかまいません。

のサンプル データは次のDocumentようになります。

DocKey | DocTypeKey  
A      | X  
B      | Y  
C      | Z  

のサンプル データは次のようにDocumentFieldなります。

DocKey | FieldId | FieldValue  
A      | 1       | PO1234  
A      | 2       | INV1234  
B      | 1       | PO5678  
B      | 2       | INV5678 
C      | 1       | PO1234
C      | 2       | INV2345 

私が実行しようとしているクエリは次のとおりです。

SELECT * 
FROM Document 
INNER JOIN DocumentField ON Document.DocumentKey = DocumentField.DocumentKey 
WHERE  (DocTypeKey IS NOT NULL) AND (FieldId = '1' AND FieldValue LIKE 'PO1%') AND (FieldId = '2' AND FieldValue LIKE 'INV1%') 

AND (FieldId = '2' AND FieldValue LIKE 'INV%')しかし、その部分を追加しても結果が得られません。WHERE (DocTypeKey IS NOT NULL) AND (FieldId = '1' AND FieldValue LIKE 'PO%')最初の部分だけでうまく機能します。上記のサンプルデータを考えると、私はそれを返したいと思います:

DocKey | DocTypeKey
A      | X

探している結果を簡単に得る方法はありますか?

4

5 に答える 5

3

サブクエリで各ドキュメントをチェックする必要があります。私が思いつくことができる最高のものはこれです:

select d.* from Document d
where d.DocTypeKey is not null
and (
    select count(*) = 2 from DocumentField df
    where df.DocKey = d.DocKey
    and (
        (df.FieldId = '1' and df.FieldValue like 'PO1%')
        or (df.FieldId = '2' and df.FieldValue like 'INV1%')));

サブセレクトで+条件count(*) = 2の数を使用する必要がある場所。FieldIdFieldValue

ここにあなたのデータを含む ideone サンプルがあります: http://ideone.com/uURwu . ideone は SQLite を使用し、私はこれを H2 で開発しましたが、SQL Server の構文は同じである必要があります。

于 2012-07-22T21:41:02.003 に答える
1

他の回答が述べているように、FieldId = '1' AND FieldId = '2' の行を持つことはできません。

ただし、代わりに OR を使用する他の回答には同意しません。適切な FieldValues を持つ 1 と 2 の両方の FieldId を持つ単一の Document 行を見つけたいようです。そのため、OR では必要なものが得られません。サブセレクトを使用する必要があります。

SELECT Document.DocKey, Document.DocTypeKey
FROM Document 
INNER JOIN DocumentField ON Document.DocKey = DocumentField.DocKey 
WHERE  Document.DocTypeKey IS NOT NULL 
  AND DocumentField.FieldId = '1' AND DocumentField.FieldValue LIKE 'PO1%'
  AND  Document.DocKey = (SELECT DocumentField.DocKey FROM DocumentField WHERE DocumentField.FieldId = '2' AND DocumentField.FieldValue LIKE 'INV1%')
于 2012-07-22T21:53:12.317 に答える
1

おそらく、OR (FieldId = '2' AND FieldValue LIKE 'INV1%') が必要です。

FieldId = '1' AND FieldId = '2' を持つことはできません

于 2012-07-22T21:41:07.167 に答える
1

私はあなたがこれを望んでいると思います:

WHERE  (DocTypeKey IS NOT NULL) 
AND ((FieldId = '1' AND FieldValue LIKE 'PO1%') OR (FieldId = '2' AND FieldValue LIKE 'INV1%'))
于 2012-07-22T21:41:42.277 に答える
0

皆さんの提案に感謝します。私が最終的に得たのは、追加の基準ごとにサブセレクトを使用して、ブライアンSとミリムースの回答と同じようなものでした。

SELECT Document.* 
FROM Document 
INNER JOIN DocumentField ON Document.DocumentKey = DocumentField.DocumentKey 
WHERE  (DocTypeKey IS NOT NULL) 
AND Document.DocumentKey IN (
    SELECT DocumentKey FROM DocumentField WHERE FieldId = '1' AND FieldValue  LIKE 'PO1%' 
    INTERSECT 
    SELECT DocumentKey FROM DocumentField WHERE FieldId = '2' AND FieldValue  LIKE 'INV1%'
) 
于 2012-07-23T14:31:21.523 に答える