Mam tabelę dokumentów i tabelę znaczników. Dokumenty są oznaczone różnymi wartościami.Wybieranie z Tabeli A, w której łączy się ze wszystkimi danymi w Tabeli B
Próbuję utworzyć wyszukiwanie tych znaczników, a większość z nich działa. Jednak otrzymuję dodatkowe wyniki zwracane, gdy pasuje do dowolnego tagu. Chcę tylko wyników, w których pasują do wszystkich tagów.
Stworzyłem to zilustrować problem http://sqlfiddle.com/#!3/8b98e/11
tabele i dane:
CREATE TABLE Documents
(
DocId INT,
DocText VARCHAR(500)
);
CREATE TABLE Tags
(
TagId INT,
TagName VARCHAR(50)
);
CREATE TABLE DocumentTags
(
DocTagId INT,
DocId INT,
TagId INT,
Value VARCHAR(50)
);
INSERT INTO Documents VALUES (1, 'Document 1 Text');
INSERT INTO Documents VALUES (2, 'Document 2 Text');
INSERT INTO Tags VALUES (1, 'Tag Name 1');
INSERT INTO Tags VALUES (2, 'Tag Name 2');
INSERT INTO DocumentTags VALUES (1, 1, 1, 'Value 1');
INSERT INTO DocumentTags VALUES (1, 1, 2, 'Value 2');
INSERT INTO DocumentTags VALUES (1, 2, 1, 'Value 1');
Kod:
-- Set up the parameters
DECLARE @TagXml VARCHAR(max)
SET @TagXml = '<tags>
<tag>
<description>Tag Name 1</description>
<value>Value 1</value>
</tag>
<tag>
<description>Tag Name 2</description>
<value>Value 2</value>
</tag>
</tags>'
-- Create a table to store the parsed xml in
DECLARE @XmlTagData TABLE
(
id varchar(20)
,[description] varchar(100)
,value varchar(250)
)
-- Populate our XML table
DECLARE @iTag int
EXEC sp_xml_preparedocument @iTag OUTPUT, @TagXml
-- Execute a SELECT statement that uses the OPENXML rowset provider
-- to produce a table from our xml structure and insert it into our temp table
INSERT INTO @XmlTagData (id, [description], value)
SELECT id, [description], value
FROM OPENXML (@iTag, '/tags/tag',1)
WITH (id varchar(20),
[description] varchar(100) 'description',
value varchar(250) 'value')
EXECUTE sp_xml_removedocument @iTag
-- Update the XML table Id's to match existsing Tag Id's
UPDATE @XmlTagData
SET X.Id = T.TagId
FROM @XmlTagData X
INNER JOIN Tags T ON X.[description] = T.TagName
-- Check it looks right
--SELECT *
--FROM @XmlTagData
-- This is where things do not quite work. I get both doc 1 & 2 back,
-- but what I want is just document 1.
-- i.e. documents that have both tags with matching values
SELECT DISTINCT D.*
FROM Documents D
INNER JOIN DocumentTags T ON T.DocId = D.DocId
INNER JOIN @XmlTagData X ON X.id = T.TagId AND X.value = T.Value
(Uwaga Nie jestem DBA, więc mogą być lepsze sposoby robienia rzeczy, mam nadzieję, że jestem na dobrej drodze, ale ja Jestem otwarty na inne sugestie, jeśli moja implementacja może zostać ulepszona.)
Czy każdy może zaproponować jak uzyskać tylko wyniki z wszystkimi tagami?
Wielkie dzięki.
Jeśli masz kod aplikacji, taki jak coldfusion, .net, php itp., Łatwiej będzie z niego skorzystać. –
Ten problem nazywany jest podziałem relacyjnym. –