嗨朋友我在sql server中有小疑问请告诉我如何解决
表格:
patient:
pid | Date | Name
100 | 2015-01-01 |Abc
101 | 2015-02-20 |banu
102 |2015-03-14 |hari
`
Address:
Pid | Fromdate | ToDate | Address
100 | 2014-12-31 | 2015-02-01 | Hyd
101 | 2015-02-20 |2015-02-20 | Bang
102 | 2015-04-10 |2015_05_20 | Chen`
基于上表,我想在地址表中检查日期和todate之间的患者日期。 如果患者在fromdate和todate之间的日期在addtress中我想要加载单独的temparay表 在tempresult表中我只需要患者的名称栏和记录添加一个的标识 列状态。 f患者日期不在fromdate和todate之间在addtress中,我希望加载相同的temparay表 在tempresult表中。 Finaly Temp表结果如下所示:
Tablesname :##TempResult
Name | Status
Abc | Outdate
banu | Indate
hari | outdate
alter procedure test
as
begin
IF
OBJECT_ID('tempdb..##Result') IS NOT NULL
drop
table ##Result
create
table ##Result
(
Name
varchar(50),
Filter
varchar(10)
)
insert
into ##result
select
a.name, 'InDate' as Filter from patient a join address b on a.patientnumber=b.patientnumber
where
a.date <=b.fromdate and a.date >=b.todate
insert into ##result
select
a.name, 'outDate' as Filter from patient a join address b on a.patientnumber=b.patientnumber
where
a.date <>b.fromdate and a.date <>b.todate
select * from ##result
end
exec test
select * from ##result
它给出了正确的值。但是表现明智不是好方法 到期记录检查2次(已登记的记录)请告诉我任何其他方式 这个问题得到了解决。 另一种我试过的方式
alter procedure [dbo].[FindDate]
as
begin
IF OBJECT_ID('tempdb..##Address') IS NOT NULL
drop table ##Address
create table ##Address
(
id int identity(1,1),
patientnumber int,
fromdate date,
Todate date,
Address varchar(50)
)
IF OBJECT_ID('tempdb..##Result') IS NOT NULL
drop table ##Result
create table ##Result
(
Name varchar(50),
Filter varchar(10)
)
insert into ##Address
select patientnumber,fromdate,todate,address from Address
----------------------------------------------------
declare @acount int
select @acount=count(id) from ##Address
declare @i int
set @i=1
while @i<=@acount
begin
declare @pn int,@fromdate date,@todate date,@address varchar(50)
select @pn=patientnumber,@fromdate=fromdate,@todate=Todate from ##Address
where id=@i
set @i=@i+1
end
declare @bcount int
declare @in int
set @in=1
while @i<=@bcount
begin
select @bcount=count(1) from patient
where patientnumber=@pn and [patient].[date] between @fromdate and @todate
if @bcount<>0
begin
insert into ##Result
select name,'InDate' as Filter from patient
where patientnumber=@pn
end
else
print '4'
begin
insert into ##Result
select name,'OutDate' as Filter from patient
where patientnumber=@pn
end
---set @i=@i+1;
select * from ##Result
end
end
这个没有给出好的结果,它需要更多的时间用于3条记录。 请告诉我如何在sql server中解决这个问题。
答案 0 :(得分:0)
这种方法有很多东西可以引起我的问题,但为了简洁起见,我只会展示一些小改进来让你前进。
首先,样本地址表缺少PK,这通常是一个坏主意,当行数增加时,它可能真的会损害性能。在这个特定的样本中它并没有真正改变任何东西,但留下这样的差距可能会伤害你以后。 (或者你可能只是把它留给了样品,我不知道)。无论如何,这将解决问题:
ALTER TABLE [dbo].[Address] ADD [aid] INT IDENTITY(1,1) PRIMARY KEY NOT NULL;
无论PK如何,您当前的计划如下:
它并不漂亮。对于一些相当简单的事情,它包含了许多操作的方式,当数据量增加时,性能可能真的很糟糕。除了查看更大的图片和更改数据模型之外,还有一个简单的步骤可以帮助您改变这样的过程:
IF OBJECT_ID(N'[dbo].[test]', 'P') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[test];
END;
GO
CREATE PROCEDURE [test]
AS
BEGIN
IF OBJECT_ID('tempdb..##Result') IS NOT NULL
DROP
TABLE [##Result];
CREATE
TABLE [##Result]
(
[Name] VARCHAR(50) ,
[Filter] VARCHAR(10)
);
INSERT INTO [##Result]
SELECT [a].[Name] ,
CASE WHEN [a].[Date] <= [b].[Fromdate]
AND [a].[Date] >= [b].[ToDate] THEN 'InDate'
WHEN [a].[Date] <> [b].[Fromdate]
AND [a].[Date] <> [b].[ToDate] THEN 'outDate'
END AS [Filter]
FROM [dbo].[patient] [a]
JOIN [dbo].[Address] [b] ON [a].[pid] = [b].[Pid];
SELECT *
FROM [##Result];
END;
这给出了以下计划:
正如您所看到的,这是一个很少的步骤,应该在一定程度上提高性能。