左连接使用来自同一个表的不同查询,其中标识符具有递增后缀

时间:2013-12-13 10:52:20

标签: sql sql-server

我有一个数据库,其中有三列对我来说很有意义;身份,反制和价值。 Id自然是标识符并且是唯一的。但是,数据库中有多个条目具有添加了额外后缀的初始序列。

这些条目中的每一个对应于具有不同值的不同计数器(最多可以有三个)。

数据可能是什么样子的一个例子;

|   id   |   counter   |  value   |
|--------|-------------|----------|
| 1234_1 |  counter_1  |   1.0    |
| 1234_2 |  counter_2  |   7.0    |
| 1234_3 |  counter_3  |   5.0    |
| 2341_1 |  counter_1  |   2.0    |
| 2341_2 |  counter_2  |   6.0    |
| 3412_1 |  counter_1  |   8.0    |

我想要实现的是获取与ID中前4位相关的每个计数器的值。因此,如果我得到'1234'和'2341'的值,我会得到以下结果;

|   id   |   value_1  |  value_2  |  value_3  |
|  1234  |     1.0    |    7.0    |    5.0    |
|  2341  |     5.0    |    2.0    |    NULL   |

我已经为每个计数器值构建了一个使用左连接的查询,这在从一个ID中检索值时工作正常,但在从两个不同的ID获取值时它不起作用。结果则超过(在这种情况下)2个结果。

当前查询;

select LEFT(t1.id,LEN(t1.id)-1)
     , t1.value
     , t2.value
     , t3.value
from (select * from table 
       where id LIKE '1234%'
         AND Counter = 'counter_1') t1
left join (Select * from table Where Counter = 'counter_2') t2 
  on LEFT(t2.id,LEN(t2.id)-1) = LEFT(t1.id,LEN(t1.id)-1)
left join (Select * from table Where Counter = 'counter_3') t3 
  on LEFT(t3.id,LEN(t3.id)-1) = LEFT(t1.id,LEN(t1.id)-1)

这很好用,会返回想要结果的第一行。但是,如果我将第一个更改为包含另一个ID;

from (select * from table where id LIKE '1234%' OR [Id] LIKE '2341%' ...

它将返回四个值,前三个值的标识为'1234'。

我无法以任何方式影响数据库的结构,选择左连接的原因是支持计数器的值不存在,它应该是NULL

我做错了什么?

3 个答案:

答案 0 :(得分:1)

你想要的是这个:

from (select * from [table] 
       where (id LIKE '1234%' OR [Id] LIKE '2341%')
         AND Counter = 'counter_1') t1

因为AND是在OR之前完成的,所以你得到的数据ID是1234%,而不是看着柜台。

答案 1 :(得分:0)

我认为总有一行与t1.Counter ='counter_1':

select LEFT(t1.id,LEN(t1.id)-2), t1.value, t2.value, t3.value
from MyTable t1 
left join MyTable t2 on t2.Counter = 'counter_2' and LEFT(t2.id,LEN(t2.id)-2) = LEFT(t1.id,LEN(t1.id)-2)
left join Mytable t3 on t3.Counter = 'counter_3' and LEFT(t3.id,LEN(t3.id)-2) = LEFT(t1.id,LEN(t1.id)-2)
where t1.Counter = 'counter_1'
and t1.[id] LIKE '1234%' OR t1.[Id] LIKE '2341%'

如果没有,你可以像这样欺骗查询:

select LEFT(t1.id,LEN(t1.id)-2), t1.value, t2.value, t3.value
from (select 1 as 'c') t
left join MyTable t1 on t1.Counter = 'counter_1' and t1.[id] LIKE '1234%' OR t1.[Id] LIKE '2341%'
left join MyTable t2 on t2.Counter = 'counter_2' and LEFT(t2.id,LEN(t2.id)-2) = LEFT(t1.id,LEN(t1.id)-2)
left join Mytable t3 on t3.Counter = 'counter_3' and LEFT(t3.id,LEN(t3.id)-2) = LEFT(t1.id,LEN(t1.id)-2)

答案 2 :(得分:0)

select LEFT(t1.id,LEN(t1.id)-1) id,
  max(case when id like '%_1' THEN value ELSE NULL END) as value_1,
  max(case when id like '%_2' THEN value ELSE NULL END) as value_2,
  max(case when id like '%_3' THEN value ELSE NULL END) as value_3
FROM table
GROUP BY LEFT(t1.id,LEN(t1.id)-1)
;