0

我有两个表,Document定义DocumentField如下。

文档(相关栏目仅为简洁起见):

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

文档字段

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

DocumentKeyDocTypeKey值是标准的 GUID。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你必须在子选择中使用+FieldId条件FieldValue的数量。

这是包含您的数据的 ideone 示例:http: //ideone.com/uURwu。ideone 使用 SQLite,我在 H2 中开发了它,但 SQL Server 语法应该相同。

于 2012-07-22T21:41:02.003 回答
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 回答
1

正如其他答案所述,您不能有 FieldId = '1' AND FieldId = '2' 的行。

但是,我不同意使用 OR 的其他答案 - 您似乎希望找到 FieldId 为 1 和 2 且具有适当 FieldValues 的单个 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 回答
0

谢谢大家的建议。我最终得到的结果与Brian S 和millimoose 的答案大致相同,对每个附加条件都使用了子选择。

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 回答