日期查询以返回两个表中存在的所有列

问题描述 投票:-1回答:2

这是我的查询,它应返回两个表中的所有列:

SELECT 
    FirstName, MiddleName, LastName
FROM 
    Users u
WHERE 
    CONVERT(VARCHAR, u.CreateTime, 103) > = GETDATE()-1 
    AND CONVERT(VARCHAR, u.CreateTime, 103) < GETDATE()
     OR CONVERT(VARCHAR, u.UpdateTime, 103) > = GETDATE()-1 
    AND CONVERT(VARCHAR, u.UpdateTime, 103) < GETDATE()
     OR CONVERT(VARCHAR, u.DeleteTime, 103) > = GETDATE()-1 
    AND CONVERT(VARCHAR, u.DeleteTime, 103) < GETDATE()
    AND CONVERT(VARCHAR, u.CreateTime, 103) ! = CONVERT(VARCHAR, u.DeleteTime, 103)

这是条件

  1. 报告应包含自昨天以来添加,更新(如果用户更新其FName,LName等)或已删除的所有用户
  2. 如果在同一天添加和删除用户,则不应在报告中看到用户信息
  3. 如果在同一天添加和更新用户,则报告应包含最新信息
  4. 如果用户在报告的同一天删除并重新读取,则应包含用户信息

表格:

Create Table #Users1 
(
    UniQueNumber Varchar(50),
    FName varchar (50),
    LName Varchar (50),
    CreateDate Datetime,
    DeleteStatus bool,
    UpdateTime DateTime,
    DeleteTime Datetime
)

INSERT INTO #Users1 
VALUES ('44354','Kumar','Shruthi-hh','06-21-2016 00:10:000',1,getdate()-1,'06-29-2016 00:10:000')
INSERT INTO #Users1 
VALUES ('44254','Shankar','Raj','06-22-2016 01:18:000',0,getdate(),null)
INSERT INTO #Users1 
VALUES ('34154','Babu','Swamy-k','06-23-2016 06:10:000',0,getdate(),null)
INSERT INTO #Users1 
VALUES ('35054','Mani','Kanta','06-24-2016 06:10:000',0,getdate(),null)
INSERT INTO #Users1 
VALUES ('35055','dsfdf','ett','06-25-2016 06:10:000',0,getdate(),null)
INSERT INTO #Users1 
VALUES ('35056','sss','sfd','06-26-2016 06:10:000',0,getdate(),null)
INSERT INTO #Users1 
VALUES ('35057','jkhk','sdd','06-27-2016 06:10:000',0,getdate(),null)
INSERT INTO #Users1 
VALUES ('35058','eer','s','06-30-2016 06:10:000',0,getdate(),null)
INSERT INTO #Users1 
VALUES ('35059','er','j','07-01-2016 06:10:000',0,getdate(),null)
sql
2个回答
3
投票

您需要使用一些括号来分隔您的子句。这将使您可以将多个需求评估为where子句中的一个总体要求:

SELECT  FirstName ,
    MiddleName ,
    LastName
FROM    Users u
WHERE   ( CONVERT(VARCHAR, u.CreateTime, 103) > = GETDATE() - 1
      AND CONVERT(VARCHAR, u.CreateTime, 103) < GETDATE()
    )
    OR ( CONVERT(VARCHAR, u.UpdateTime, 103) > = GETDATE() - 1
         AND CONVERT(VARCHAR, u.UpdateTime, 103) < GETDATE()
       )
    OR ( CONVERT(VARCHAR, u.DeleteTime, 103) > = GETDATE() - 1
         AND CONVERT(VARCHAR, u.DeleteTime, 103) < GETDATE()
       )
    AND CONVERT(VARCHAR, u.CreateTime, 103) ! = CONVERT(VARCHAR, u.DeleteTime, 103);

在此示例中,()中的所有内容在用于OR之前立即进行评估

在这里您的具体情况,您可以使用之间的子句:

where createTime between getdate() -1 and getdate()

玩一玩。

只是一些一般性意见:

您是否可以在将来创建需要排除的内容?

通常更好的做法(至少在SQLServer中)使用dateadd函数:

CONVERT(VARCHAR,u.UpdateTime ,103) > = dateadd(dd,-1,GETDATE()) 

将那些日期列转换为varchar就好了。我建议你在开始之前将getdate()转换为变量一次,或者如果它没有给你一个问题,就不要担心它,因为数据库应该能够从它的排序/语言中找出它。


0
投票

快速修复:

SELECT 
    FirstName,MiddleName,LastName
FROM 
    Users u
WHERE 
    u.CreateTime >= dateadd(d,-1,Convert(Date,GETDATE())) 
    AND u.CreateTime < Convert(Date,GETDATE()) OR u.UpdateTime > = dateadd(d,-1,Convert(Date,GETDATE()))
    AND u.UpdateTime < Convert(Date,GETDATE()) OR u.DeleteTime > = dateadd(d,-1,Convert(Date,GETDATE())) 
    AND u.DeleteTime < Convert(Date,GETDATE())
    AND u.CreateTime ! =  u.DeleteTime

你不必像你做CONVERT(VARCHAR,u.CreateTime,103)那样将日期转换为字符串。 此外,您必须使用括号在Where子句上更具体。 你必须记住'GetDate()'将DateTime作为DateTime列返回。所以在比较两个日期时你必须要小心。不只是日期。

例如:

'31-01-2016' > '31-01-2016 00:00:01' = false

编辑

顺便说一句,你的完整例子是这样的:

Create Table #Users1 (
    UniQueNumber Varchar(50),
    FirstName varchar (50),
    LastName Varchar (50),
    CreateTime Datetime,
    DeleteStatus bit,
    UpdateTime DateTime,
    DeleteTime Datetime
)

INSERT INTO #Users1 Values ('44354','Kumar','Shruthi-hh','06-21-2016 00:10:000',1,getdate()-1,'06-29-2016 00:10:000')
INSERT INTO #Users1 Values ('44254','Shankar','Raj','06-22-2016 01:18:000',0,getdate(),null)
INSERT INTO #Users1 Values ('34154','Babu','Swamy-k','06-23-2016 06:10:000',0,getdate(),null)
INSERT INTO #Users1 Values ('35054','Mani','Kanta','06-24-2016 06:10:000',0,getdate(),null)
INSERT INTO #Users1 Values ('35055','dsfdf','ett','06-25-2016 06:10:000',0,getdate(),null)
INSERT INTO #Users1 Values ('35056','sss','sfd','06-26-2016 06:10:000',0,getdate(),null)
INSERT INTO #Users1 Values ('35057','jkhk','sdd','06-27-2016 06:10:000',0,getdate(),null)
INSERT INTO #Users1 Values ('35058','eer','s','06-30-2016 06:10:000',0,getdate(),null)
INSERT INTO #Users1 Values ('35059','er','j','07-01-2016 06:10:000',0,getdate(),null)

select * from #Users1


Declare @nowDate Date
Set @nowDate = Convert(Date,GETDATE())

SELECT 
    FirstName,LastName
FROM 
    #Users1 u
WHERE 
    u.CreateTime >= dateadd(d,-1,@nowDate) 
    AND u.CreateTime < @nowDate OR u.UpdateTime > = dateadd(d,-1,@nowDate)
    AND u.UpdateTime < @nowDate OR u.DeleteTime > = dateadd(d,-1,@nowDate) 
    AND u.DeleteTime < @nowDate
    AND u.CreateTime ! =  u.DeleteTime

drop table #Users1

你仍然在Where条款中使用括号。

编辑2

在测试数据库中运行它。是另一种方法有两个表UserUserHistory

create table [User] (
    id int not null identity(1,1),
    firstName varchar(50),    
    lastName varchar(50),

    constraint PK_User primary key clustered (id)
)

create table UserHistory (
    id int not null identity(1,1),
    userId int not null,    
    actionType tinyint not null,
    actionDate datetime not null

    constraint PK_UserHistory primary key clustered (id),
    constraint FK_User_UserHistory foreign key (userId) references [User](id)
)

create unique index UIX_UserHistory on UserHistory( userId, actionType, actionDate)

insert into [user] ( firstName, lastName ) values
('tony', 'stark'),
('bruce', 'wayne'),
('clark', 'kent'),
('peter', 'parker')

insert into UserHistory ( userId, actionType, actionDate ) values
( 1, 1, '2016-01-01'),
( 2, 1, '2016-01-02'),
( 2, 2, '2016-01-03'),
( 3, 1, '2016-02-01'),
( 3, 3, '2016-02-01'),
( 4, 1, '2016-03-01'),
( 4, 2, '2016-03-01'),
( 4, 3, '2016-03-01'),
( 4, 1, '2016-04-01')
go

create view UserHistoryInfo as
with insCte as (
    select 
        a.id, max( ins.actionDate ) as lastInsertDate
    from
        [user] a
        left join userHistory ins on ( a.id = ins.userId ) and ( ins.actionType = 1 )
    group by a.id
),
updCte as (
    select 
        a.id, max( upd.actionDate ) as lastUpdateDate
    from
        [user] a
        left join userHistory upd on ( a.id = upd.userId ) and ( upd.actionType = 2 )
    group by a.id
),
delCte as (
    select 
        a.id, max( del.actionDate ) as lastDeleteDate
    from
        [user] a
        left join userHistory del on ( a.id = del.userId ) and ( del.actionType = 3 )
    group by a.id
)
select
    a.firstName,
    a.lastName,
    ins.lastInsertDate as lastInsertDate,
    upd.lastUpdateDate as lastUpdateDate,
    del.lastDeleteDate as lastDeleteDate
from
    [user] a
    left join insCte ins on ( a.id = ins.id )
    left join updCte upd on ( a.id = upd.id )
    left join delCte del on ( a.id = del.id )
go

select * from UserHistoryInfo
go


declare @ckeckDate datetime = '2016-01-02'

select *
from UserHistoryInfo
where
    (
        (        
            ( isNull( lastInsertDate, '1900-01-01' ) >= @ckeckDate )
            or ( isNull( lastUpdateDate, '1900-01-01' ) >= @ckeckDate )
            or ( isNull( lastDeleteDate, '1900-01-01' ) >= @ckeckDate )                
        )
        or ( isNull( lastInsertDate, '1900-01-01' ) = isNull( lastUpdateDate, '1900-01-01' ) )        
    )
    and ( isNull( lastInsertDate, '1900-01-01' ) <> isNull( lastDeleteDate, '1900-01-01' ) )
© www.soinside.com 2019 - 2024. All rights reserved.