我有两个表来表示用户的状态以及状态更改的时间戳。我有这样的设置:
StatusTable
user_id updated_status timestamp
---------------- ---------------- -----------------------
1617 PENDING 2018-02-21 01:06:01.000
1617 DONE 2018-02-21 01:01:01.000
1617 PENDING 2018-02-06 01:06:01.000
OverrideStatusTable
user_id updated_status timestamp
---------------- -------------------------------- -----------------------
1617 2018-02-23 08:12:40.297
1617 DONE-A 2018-02-14 15:10:49.717
1617 DONE-B 2018-02-14 15:10:35.850
1617 2018-02-14 15:09:23.973
1617 DONE-A 2018-02-14 14:59:30.113
我尝试将两个表合并为一个按时间戳排序的结果,其中OverriddeStatusTable中的值覆盖StatusTable中的值,但OverrideStatus表中的updated_status为空时除外,其中最新状态来自而是显示StatusTable,但显示OverrideStatusTable中已清除值的时间戳。所以我希望我的查询结果看起来像这样:
user_id updated_status timestamp
---------------- ---------------- -----------------------
1617 PENDING 2018-02-23 08:12:40.297
1617 DONE-A 2018-02-14 15:10:49.717
1617 DONE-B 2018-02-14 15:10:35.850
1617 PENDING 2018-02-14 15:09:23.973
1617 DONE-A 2018-02-14 14:59:30.113
1617 PENDING 2018-02-06 01:06:01.000
我试图弄清楚最好的方法是什么 - 请记住,我最终会在我的.NET项目中将这两个表作为DataTables加载并使用它们查询它们LINQ。但是现在我只想确保我的逻辑正确。
现在我的查询设置如下:
select *
from StatusTable
where user_id='1617'
UNION
select *
from OverrideStatusTable
where user_id='1617' and updated_status != ''
order by update_date desc
但这并没有让我接近我想要的东西。输出结果是:
user_id updated_status timestamp
---------------- -------------------------------- -----------------------
1617 PENDING 2018-02-21 01:06:01.000
1617 DONE 2018-02-21 01:01:01.000
1617 DONE-A 2018-02-14 15:10:49.717
1617 DONE-B 2018-02-14 15:10:35.850
1617 DONE-A 2018-02-14 14:59:30.113
1617 PENDING 2018-02-06 01:06:01.000
有人可以帮帮我吗?谢谢!
答案 0 :(得分:0)
一个完整的猜测,如果我是诚实的,但也许......
USE Sandbox;
GO
CREATE TABLE StatusTable (user_id int,
updated_status varchar(10),
[timestamp] datetime2(3));
GO
CREATE TABLE OverrideStatusTable (user_id int,
updated_status varchar(10),
[timestamp] datetime2(3));
GO
INSERT INTO StatusTable
VALUES
(1617 ,'PENDING', '2018-02-21 01:06:01.000'),
(1617 ,'DONE', '2018-02-21 01:01:01.000'),
(1617 ,'PENDING', '2018-02-06 01:06:01.000');
INSERT INTO OverrideStatusTable
VALUES
(1617 ,NULL, '2018-02-23 08:12:40.297'),
(1617 ,'DONE-A', '2018-02-14 15:10:49.717'),
(1617 ,'DONE-B', '2018-02-14 15:10:35.850'),
(1617 ,NULL, '2018-02-14 15:09:23.973'),
(1617 ,'DONE-A', '2018-02-14 14:59:30.113');
GO
SELECT *
FROM (SELECT TOP 1
user_id,
updated_status,
[timestamp]
FROM StatusTable
WHERE user_id = 1617
ORDER BY [Timestamp] ASC) ST
UNION
SELECT user_id,
ISNULL(updated_status,'PENDING'),
[timestamp]
FROM OverrideStatusTable OST
WHERE user_id = 1617
ORDER BY [timestamp] DESC;
GO
DROP TABLE StatusTable;
DROP TABLE OverrideStatusTable;
答案 1 :(得分:0)
您的结果可以通过以下方式获得:
select ost.userid, ost.status, ost.timestamp
from OverrideStatusTable ost
where status is not null
union all
select ost.userid,
(select top 1 st.status
from statustable st
where st.user_id = ost.user_id and
st.timetamp <= ost.timestamp
) as status,
ost.timestamp
from OverrideStatusTable ost
where status is null
union all
select st.*
from statustable st
where timestamp > (select max(ost.timestamp) from OverrideStatusTable ost where ost.userid = st.userid);