2012-07-22 108 views
0

我有兩張表,DocumentDocumentField定義如下。SQL SELECT查詢幫助

文獻(相關的數據列僅出於簡潔):

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

DocumentField

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 

有一個簡單的方法可以讓我得到我在尋找的結果?

+0

我應該說明一下。我正在尋找所有具有'DocTypeKey'和BOTH(FieldId ='1'和FieldValue LIKE'PO1%')'AND'(FieldId ='2'和FieldValue LIKE'INV1%')'的文件'。 OR不符合搜索要求。 – Kettch19 2012-07-22 21:48:37

+0

你需要像子選擇一樣。看看下面的答案 - 它會給你你要求的結果。 – 2012-07-22 22:04:40

回答

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%' 
) 
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的語法應該是一樣的。

+0

事情是,我們不想要一個'OR'條件,我們希望'FieldId' /'FieldValue'條件都是真的,這是不幸的。 – Kettch19 2012-07-22 21:53:18

+0

@ Kettch19噢,你想要一個具有滿足兩個條件的行的DOCUMENT,而不僅僅是這些字段。 – millimoose 2012-07-22 21:59:25

+0

正確,我想我的描述不夠清楚。 – Kettch19 2012-07-22 22:00:57

1

你可能想OR(FieldId = '2' 和fieldValue方法LIKE '%INV1')

你不能有FieldId = '1' AND FieldId = '2'

+0

注意他正在尋找的結果,一個OR不會這樣做。 – 2012-07-22 22:02:16

1

我想你想這樣的:

WHERE (DocTypeKey IS NOT NULL) 
AND ((FieldId = '1' AND FieldValue LIKE 'PO1%') OR (FieldId = '2' AND FieldValue LIKE 'INV1%')) 
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%') 
+0

如果多個文檔具有匹配字段,最後一個條件可能會中斷 - 子選擇將返回一個「DocKey」元組。 – millimoose 2012-07-22 22:27:05

+0

你是對的@millimoose - 只是試圖給出一個例子,說明如何使用子選擇在給定問題中的數據集的情況下獲得期望的結果。 – 2012-07-22 22:38:53