在保存父记录之前检查是否存在匹配的子记录

时间:2011-12-04 19:41:32

标签: sql sql-server-2008 tsql

我们基本上有一组子记录,我们将在其中创建新的父/子记录,但需要首先验证父记录是否已经存在,包含相同的子记录。以下是详细信息:

我们有3个表,一个基本上是父记录和子记录之间的链接表。

表A(父表)

Id
Name
Desc

表B(表A和表C之间的链接表)

Id
TableAId
TableCId

表C(子表)

Id
StartPosition
EndPosition
Percentage

所以使用那个结构,这里是一个完整记录的例子,父表与子表的一对多关系:

表A

(1, 'Sample', 'N/A')

表B

(1, 1, 1)
(2, 1, 2)
(3, 1, 3)

表C

(1, 1, 3, 0.50)
(2, 4, 5, 0.30)
(3, 6, 9, 0.20)

然后我们传入一个xml字符串,我们将其解析并放入临时表中。临时表的内容是表C的内容,没有特定的Id。

然后,在我们保存任何新记录之前,我们需要检查是否存在具有相同数量的子记录并且这些子记录与临时表中的3列匹配的现有表A记录(不能识别ID) )。

希望这个解释得很好,我做了很多搜索,找不到任何特定的问题。

1 个答案:

答案 0 :(得分:0)

您正在寻找的是关系部门。文章“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