2012-02-06 43 views
1

我有一个MySQL表,看起来像这样存在:获得价值,即使它不表从SQL SELECT语句

|---ID---|---COUNTER---| 
| 1 |  2  | 
| 2 |  6  | 
| 3 |  1  | 
| 5 |  9  | 
| 6 |  10  | 

我在寻找返回的ID和他们的COUNTER SELECT语句。该表只有ID,例如:1,2,3,5,6。是否有声明说:我想要ID为1到10,即使它们不存在于表格中,并且如果ID不存在,仍然返回ID与COUNTER值0.例如:

|---ID---|---COUNTER---| 
| 1 |  2  | 
| 2 |  6  | 
| 3 |  1  | 
| 4 |  0  | 
| 5 |  9  | 
| 6 |  10  | 
| 7 |  0  | 
| 8 |  0  | 
| 9 |  0  | 
| 10 |  0  | 

我是否必须创建一个包含NOT EXIST参数的SELECT语句?

在此先感谢,史蒂夫 - O

+1

数据库无法返回不存在的ID,因为它不知道它应该。你有另外一张表来定义什么是有效值? – 2012-02-06 09:59:32

+0

@Jan Hudec:不,我知道我没有一个很愚蠢。但是,有什么方法可以用LEFT JOIN完成我的目标? – ClydeFrog 2012-02-06 10:03:35

+0

“我想要ID的1到10” - 其中是1到10的范围吗?例如在桌子上?作为参数传入? – onedaywhen 2012-02-06 11:25:47

回答

2

,而无需创建一个临时表:

select t.num as id, coalesce(yt.counter, 0) 
from your_table yt 
right join (
    select 1 as num union select 2 union select 3 union select 4 union select 5 union 
    select 6 union select 7 union select 8 union select 9 union select 10 
) t on yt.id = t.num 
order by t.num 

和位更普遍的:

select t.num as id, coalesce(yt.counter, 0) 
from your_table yt 
right join (
    select t1.num + t2.num * 10 + t3.num * 100 as num 
    from (
     select 1 as num union select 2 union select 3 union select 4 union select 5 union 
     select 6 union select 7 union select 8 union select 9 union select 0 
    ) t1 
    cross join (
     select 1 as num union select 2 union select 3 union select 4 union select 5 union 
     select 6 union select 7 union select 8 union select 9 union select 0 
    ) t2 
    cross join (
     select 1 as num union select 2 union select 3 union select 4 union select 5 union 
     select 6 union select 7 union select 8 union select 9 union select 0 
    ) t3 
) t on yt.id = t.num 
where t.num between (select min(id) from your_table) and (select max(id) from your_table) 

你可以自己在这里定义限制我使用minyour_tableid价值max

+0

我应该用我的表名替换'y'和'yt'吗? – ClydeFrog 2012-02-06 10:08:17

+0

@ Steve-O'yt'只是一个别名,所以你可以保持原样(或者如果你不喜欢就更改)。只有'your_table'变成适当的表名,如果列是正确的,这应该没问题。 – 2012-02-06 10:14:53

+0

谢谢!那真的有诀窍。你救了我的一天! – ClydeFrog 2012-02-06 10:22:32

2

您可以使用left join解决您的问题。阅读更多关于left joinhere

+0

在sql中有不同的方法来做同样的事情,我已经给出了一种方法。 – 2012-02-06 11:25:07

+0

-1:Downvoter请评论。如果@ doneay,当你完成它,请让我知道如果这是不正确的答案。 – 2012-02-06 11:29:24

+0

我没有说“应该”,“将会”是建议,“应该”是强制性的。反正更新了我的答案。 – 2012-02-06 12:08:49

1

我想你必须创建(生成循环)临时表的数字从1到N(其中N是计数表的MAX(Id))的完整序列。然后,将其加入该表并应用GROUP BY子句。

2

这不是很强劲,但如果你创建了一个临时表中的ID,你在它想要的,然后你可以离开了加入到你的表包含ID和计数器这将包括所有的值:

Declare @tempidtable as table (imaginaryid int) 

insert into @tempidtable (imaginaryid) values (1) 
insert into @tempidtable (imaginaryid) values (2) 
insert into @tempidtable (imaginaryid) values (3) 

select 
@temptable.imaginaryid, 
ISNULL(yourothertable.counter, 0) 
from @tempidtable 
left join yourothertable 
on @tempidtable.imaginaryid = yourothertable.id 

正如Tomek所说,你可以循环插入以便维护,或者可能将希望作为基础的ID存储在另一个表中,将此用作联接的基础,而不是临时表。

2

与所有可能的ID创建一个表:

create table Numbers (nr int primary key); 

declare i int default 1; 

while i < 100000 do 
    insert into Numbers (nr) values (i); 
    set i = i + 1; 
end while; 

然后你可以使用left join返回所有的数字:与你的表

select n.NR 
,  c.Counter 
from Numbers n 
left join 
     Counters c 
on  c.ID = n.NR