基于varchar列中的连字符的动态SQL查询

时间:2012-07-06 19:29:22

标签: sql sql-server sql-server-2008 tsql

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

我有一个表TableX,两列:

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

我有两个辅助表,TableYTableZ。两者都有两列,

TableY
  • IDY (int) identity
  • VarY (varchar(20))

    TableZ

  • IDZ (int) identity

  • VarZ (varchar(20))

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

  • 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中始终匹配。匹配将位于VarY TableY = VarX中的TableX上。我会抓取相关的ID(IDY),然后在TableA的插页中使用它。

在第1行的示例中,TableA中的插入内容为(null, 1, null)

现在在第2行的情况下,它有两个用连字符分隔的字符串。因此,TableA中的插入最终会为(null, 1, 1)

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

2 个答案:

答案 0 :(得分: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

我故意忽略在TableA.IDA中插入NULL,因为我不知道你为什么要尝试在身份列中插入NULL,或者甚至可能。我还假设VarX中的数据不会出现退化情况,例如'-''ZXC-''ASD-BNM '等。

答案 1 :(得分: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