0

我有一个关于我在SQL Server 2008数据库中编写的特定查询的问题。这是(更大)查询的一部分,但我会简化它,以便更容易隔离我正在尝试做的事情。

我有一张桌子TableX,两列:

  • IDX (int) identity
  • VarX (varchar(20))

我有两个辅助表,TableY并且TableZ. 两者都有两列,

TableY
  • IDY (int) identity

  • VarY (varchar(20))

    TableZ

  • IDZ (int) identity

  • VarZ (varchar(20))

我正在插入第四个表,我们称之为TableA. TableA有三列:

  • IDA (int) identity
  • IDY (int)
  • IDZ (int)

此表中的 IDY 和 IDZ 字段是表 Y 和表 Z 中标识列的外键。

听起来很复杂,但它是一个非常简单的连接。不过,这就是有趣的地方。

所以里面的数据TableX可能是这样的:

IDX | VarX
--------------
1   | ABC
2   | ABC-LMN

中的数据TableY

IDY | VarY
----------------
1   |ABC
2   | HIJ

中的数据TableZ

IDZ | VarZ
----------------
1   | LMN
2   | OPQ

基本上,VarX(第二列)要么是单个 varchar 字符串,要么是两个由连字符连接的字符串,没有空格。在没有连字符的单个字符串的情况下,它始终是表 Y 中的匹配项。匹配项将在VarYinTableY = VarXTableX。我会获取相关的 ID ( IDY),并在插入时使用它TableA

在第 1 行的示例中,插入TableA将是(null, 1, null)

现在在第 2 行的情况下,它有两个由连字符分隔的字符串。所以插入TableA最终会是(null, 1, 1).

所以我的问题是......我如何制定插入及其相应的连接来处理这种类型的逻辑?我确信它必须是一个案例陈述......只是在可视化完整查询时遇到了很多麻烦,因为我不是 DBA.... 任何帮助表示赞赏。

4

2 回答 2

2

没有必要制作这个动态 SQL,除非作为它的一部分的 proc 需要它。

INSERT INTO TableA (IDY,IDZ)
SELECT ty.IDY, tz.IDZ
FROM TableX tx
LEFT JOIN TableY ty ON ty.VarY =
   (CASE WHEN CHARINDEX('-', tx.VarX) = 0 THEN tx.VarX
   ELSE LEFT(tx.VarX, CHARINDEX('-', tx.VarX) - 1) END)
LEFT JOIN TableZ tz ON tz.VarZ =
   CASE WHEN CHARINDEX('-', tx.VarX) = 0 THEN NULL
   ELSE RIGHT(tx.VarX, LEN(tx.VarX) - CHARINDEX('-', tx.VarX)) END

我故意省略了将 NULL 插入到 中TableA.IDA,因为我不知道您为什么要尝试将 NULL 插入到标识列中,或者这是否可能。我还假设中的数据VarX不会有退化的情况,例如'-', 'ZXC-','ASD-BNM '等。

于 2012-07-06T19:58:35.617 回答
1

我改了,好像可以简化成这样:

DECLARE @x TABLE (IDX INT, VarX VARCHAR(20))
INSERT @x VALUES (1, 'ABC'), (2, 'ABC-LMN')

DECLARE @y TABLE (IDY INT, VarY VARCHAR(20))
INSERT @y VALUES (1, 'ABC'), (2, 'HIJ')

DECLARE @z TABLE (IDZ INT, VarZ VARCHAR(20))
INSERT @z VALUES (1, 'LMN'), (2, 'OPQ') 

DECLARE @a TABLE (IDA INT IDENTITY(1, 1), IDY INT, IDZ INT)

INSERT      @a
SELECT      y.IDY,
            z.IDZ
FROM        @x x
LEFT JOIN   @y y ON y.VarY = LEFT(x.VarX, LEN(y.VarY))
LEFT JOIN   @z z ON z.VarZ = RIGHT(x.VarX, LEN(z.VarZ)) AND CHARINDEX('-', x.VarX) <> 0

 SELECT  *
 FROM    @a
于 2012-07-06T19:52:40.267 回答