检查日期和日期之间的日期,如果它在sql server中加载seprate表

时间:2015-04-08 05:48:42

标签: sql-server sql-server-2008 sql-server-2012

嗨朋友我在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中解决这个问题。

1 个答案:

答案 0 :(得分:0)

这种方法有很多东西可以引起我的问​​题,但为了简洁起见,我只会展示一些小改进来让你前进。

首先,样本地址表缺少PK,这通常是一个坏主意,当行数增加时,它可能真的会损害性能。在这个特定的样本中它并没有真正改变任何东西,但留下这样的差距可能会伤害你以后。 (或者你可能只是把它留给了样品,我不知道)。无论如何,这将解决问题:

ALTER TABLE [dbo].[Address] ADD [aid] INT IDENTITY(1,1) PRIMARY KEY NOT NULL; 

无论PK如何,您当前的计划如下: enter image description here 它并不漂亮。对于一些相当简单的事情,它包含了许多操作的方式,当数据量增加时,性能可能真的很糟糕。除了查看更大的图片和更改数据模型之外,还有一个简单的步骤可以帮助您改变这样的过程:

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;

这给出了以下计划: enter image description here 正如您所看到的,这是一个很少的步骤,应该在一定程度上提高性能。