2012-07-06 57 views
0

我对SQL Server 2008数据库中的特定查询有疑问。这是一个(很多)更大的查询的一部分,但我会简化它,让它更容易隔离我想要做的事情。基于varchar列中连字符的动态SQL查询

我有一个表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中匹配。匹配将在TableY = VarX,TableXVarY中进行。我将获取关联的ID(IDY),并在TableA的插入中使用该ID。

在行1的例子中,插入件成TableA(null, 1, null)

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

所以我的问题是这样的...我如何用相应的连接来处理这种类型的逻辑?我相信它必须是一个案例声明......只是有很多的问题可视化的完整查询,因为我不是DBA ....任何帮助表示赞赏。

回答

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,或者如果这甚至有可能。我也认为在VarX数据不会有变质的情况下,如'-''ZXC-''ASD-BNM '

+0

对不起,插入null的东西只是想象第一列是一个身份的事实。我也从实际插入中省略了它。想不到如何写出来,所以它是有道理的:) – optionsix 2012-07-06 20:02:18

+0

你也是正确的......它总是或者是一个字符串匹配的东西,或两个连字符总是匹配的东西。 – optionsix 2012-07-06 20:03:18

+0

@optionsix - 听起来不错,只是想涵盖未来遇到问题的人的基础。 – 2012-07-06 20:04:09

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 
+0

我希望你注意到VARx前提和变化都是类型为varchar(20)。我不确定3个角色的假设是否有效! – Akhil 2012-07-06 19:54:13

+0

Akhil是正确的,我的例子是3 char - 3 char,但这只是一个例子。可以在连字符的每一边最多8个 – optionsix 2012-07-06 19:56:10

+0

对不起,我有点仓促,现在正在工作。 – 2012-07-06 20:26:14