Sql 选择不存在的行
假设我有一张桌子:Sql 选择不存在的行,sql,sql-server,sql-server-2008,sql-server-2005,sql-server-2008-r2,Sql,Sql Server,Sql Server 2008,Sql Server 2005,Sql Server 2008 R2,假设我有一张桌子: ColumnA ColumnB --------------------------------- 1 10.75 4 1234.30 6 2000.99 如何编写将导致以下结果的SELECT查询: ColumnA ColumnB --------------------------------- 1 10.75 2 0.00 3
ColumnA ColumnB
---------------------------------
1 10.75
4 1234.30
6 2000.99
如何编写将导致以下结果的SELECT查询:
ColumnA ColumnB
---------------------------------
1 10.75
2 0.00
3 0.00
4 1234.30
5 0.00
6 2000.99
您可以使用CTE创建表中从1到最大值的数字列表:
; with numbers as
(
select max(ColumnA) as nr
from YourTable
union all
select nr - 1
from numbers
where nr > 1
)
select nr.nr as ColumnA
, yt.ColumnB
from numbers nr
left join
YourTable yt
on nr.nr = yt.ColumnA
order by
nr.nr
option (maxrecursion 0)
创建一个TallyTable或NumberTable-请参见以下问题: 使用该表创建insert语句:
INSERT INTO YourTable (ColumnA, ColumnB)
SELECT Number FROM NumberTable
WHERE
NOT EXISTS (SELECT 1 FROM YourTable WHERE NumberTable.Number = YourTable.ColumnA)
-- Adjust this value or calculate it with a query to the maximum of the source table
AND NumberTable.Number < 230130
请尝试:
declare @min int, @max int
select @min=MIN(ColumnA), @max=MAX(ColumnA) from tbl
select
distinct number ColumnA,
isnull(b.ColumnB, 0) ColumnB
from
master.dbo.spt_values a left join tbl b on a.number=b.ColumnA
where number between @min and @max
您可以使用数字表或以下技巧生成一个序列,您可以将该序列与表保持外部连接。我假设您希望动态确定边界:
WITH Seq AS
(
SELECT TOP ((SELECT Max(ColumnA)FROM Table1) - (SELECT Min(ColumnA) FROM Table1) + 1)
Num = (SELECT Min(ColumnA) FROM Table1)+ Row_number() OVER (ORDER BY [object_id]) -1
FROM sys.all_objects)
SELECT ColumnA = Seq.Num,
ColumnB = COALESCE(t.ColumnB ,0.00)
FROM Seq
LEFT OUTER JOIN Table1 t
ON Seq.Num = t.ColumnA
用你的样品
值得一读:我收集了这样的表函数
create function dbo.GetNumbers(@Start int, @End int)
returns @Items table
(
Item int
)
as
begin
while (@Start <= @End)
begin
insert into @Items
values (@Start)
set @Start = @Start + 1
end
return
end
对于日期范围、时间、时区等,我有类似的表函数。您使用的是Microsoft SQL Server吗?是的,我的朋友,我在标记中注意到了这一点。当我第一次看到这个问题时,这些标记并不存在,因此感谢您的更新。因此,唯一需要的更改是从yt.ColumnB更改为ISNULLyt.ColumnB,0。多么奇妙的查询@Andomar很抱歉回复太晚,我只是觉得等待一点会有所帮助:
create function dbo.GetNumbers(@Start int, @End int)
returns @Items table
(
Item int
)
as
begin
while (@Start <= @End)
begin
insert into @Items
values (@Start)
set @Start = @Start + 1
end
return
end
declare @min int, @max int
set @min = 10
set @max = 20
select gn.Item
from dbo.GetNumbers(@min, @max) gn