お探しの商品は、という関係部門と呼ばれています。記事「Divided We Stand: The SQL of Relational Division」には、SQLを使用してリレーショナル部門を実行するためのさまざまな手法の概要が紹介されています。
CREATE TABLE tableA (
Id int PRIMARY KEY,
Name varchar(25),
[Desc] varchar(255)
);
INSERT INTO tableA
(Id, Name, [Desc])
VALUES
(1, 'Sample 1', 'Should match the XML'),
(2, 'Sample 2', 'Partial match (should be excluded)'),
(3, 'Sample 3', 'Has extra matches (should be excluded)');
GO
CREATE TABLE tableB (
Id int PRIMARY KEY,
TableAId int,
TableCId int
);
INSERT INTO tableB
(Id, TableAId, TableCId)
VALUES
(1, 1, 1),
(2, 1, 2),
(3, 1, 3),
(4, 2, 1),
(5, 2, 2),
(6, 3, 1),
(7, 3, 2),
(8, 3, 3),
(9, 3, 4);
GO
CREATE TABLE tableC (
Id int PRIMARY KEY,
StartPosition int,
EndPosition int,
Percentage decimal(3,2)
);
INSERT INTO tableC
(Id, StartPosition, EndPosition, Percentage)
VALUES
(1, 1, 3, 0.50),
(2, 4, 5, 0.30),
(3, 6, 9, 0.20),
(4, 10, 12, 0.10);
GO
-- this represents the temp table holding the XML data
-- we want to match Sample 1
CREATE TABLE xmlData (
StartPosition int,
EndPosition int,
Percentage decimal(3,2)
);
INSERT INTO xmlData
(StartPosition, EndPosition, Percentage)
VALUES
(1, 3, 0.50),
(4, 5, 0.30),
(6, 9, 0.20);
GO
SELECT
b.TableAId
FROM
tableB AS b
INNER JOIN
tableC AS c
ON
b.TableCId = c.Id
LEFT OUTER JOIN
xmlData AS x
ON
c.StartPosition = x.StartPosition AND
c.EndPosition = x.EndPosition AND
c.Percentage = x.Percentage
GROUP BY
b.TableAId
HAVING
COUNT(c.Id) = (SELECT COUNT(*) FROM xmlData) AND
COUNT(x.StartPosition) = (SELECT COUNT(*) FROM xmlData);
GO
DROP TABLE xmlData;
DROP TABLE tableC;
DROP TABLE tableB;
DROP TABLE tableA;
GO
なぜSQL Server 2008では、[テーブル値パラメータ]を導入し、使用するXML(http://msdn.microsoft.com/en-us/library:あなたのケースのために、あなたは「正確な課」の下にリストされている技術が欲しいです/bb510489.aspx)? – Oded
3つ目のテーブルと「1対多数の関係」があるのはなぜですか? – danihp
@Oded - 2000年からXmlを使用していて、2008年にアップグレードしてからコードを更新していないため、一貫した解決策をとっています。 – kruegerste