我有两个表 - Test,Child包含版本化数据。 关于列的说明:
TEST, CHILD Table
ID - Record id (not unique due to multiple versions)
MODSTAMP - Timestamp at which record is inserted
DELETEDDATE - Timestamp at which record is deleted; NULL value means record is not deleted yet.
COMPOSITE KEY = {ID, MODSTAMP}
CHILD Table
DATA - Foreign key that references Test(ID)
DATA2 - Foreign key that references Test(ID)
我正在研究在两个时间戳之间选择记录的要求 - $ FROMTIME和$ TOTIME。我可以通过运行自联接来选择Test表上的记录。
SELECT v.id, v.modstamp FROM test v
INNER JOIN
(SELECT Id, MAX(modstamp) AS MaxDateTime
FROM test where modstamp >= '2017-08-16 15:08:04 +00:00' and modstamp <= '2017-08-16 17:08:04 +00:00' GROUP BY Id) g
ON v.Id = g.Id
AND v.modstamp = g.MaxDateTime where v.deleteddate is null
我还需要选择相应子记录的最新版本(没有任何重复的记录ID,因此选择group by子句),其中选择了父记录。我的应用程序保存上述查询的结果,并运行以下查询为每个值['aaa','bbb']选择有效的子记录:
SELECT v.* FROM child v
INNER JOIN
(SELECT id, MAX(modstamp) AS MaxDateTime
FROM child where (data = ? or data is null) and modstamp <= '2017-08-16 17:08:04 +00:00' GROUP BY id
UNION
SELECT id, MAX(modstamp) AS MaxDateTime
FROM child where (data2 = ? or data2 is null) and modstamp <= '2017-08-16 17:08:04 +00:00' GROUP BY id
) g
ON v.id = g.id
AND v.modstamp = g.MaxDateTime
有人可以建议如何优化此解决方案吗?使用当前方法,如果选择了n个父记录,则将有n个内部联接将运行。
这是用于连接的查询,但会抛出“多部分标识符未找到错误”。还有其他任何方法可以重写查询吗? - 预期查询
SELECT v.* FROM child v
INNER JOIN (select distinct(id) from DATA) D
ON v.id = D.id
INNER JOIN
(SELECT id, MAX(modstamp) AS MaxDateTime
FROM child where (data = d.id or data is null) and modstamp <= '2017-08-16 17:08:04 +00:00' GROUP BY id
UNION
SELECT id, MAX(modstamp) AS MaxDateTime
FROM child where (data2 = d.id or data2 is null) and modstamp <= '2017-08-16 17:08:04 +00:00' GROUP BY id
) g
ON v.id = g.id
AND v.modstamp = g.MaxDateTime;
运行脚本的示例信息:
Test
| ID | MODSTAMP | DELETEDDATE |
Child
| ID | DATA | DATA2 | MODSTAMP | DELETEDDATE |
脚本(使用SQL Server):
drop table test;
drop table child;
CREATE TABLE TEST(ID VARCHAR(20), modstamp DATETIMEOFFSET, deleteddate DATETIMEOFFSET);
insert into test values('aaa', '2017-08-16 15:08:04 +00:00', null);
insert into test values('aaa', '2017-08-16 16:08:04 +00:00', null);
insert into test values('aaa', '2017-08-16 17:08:04 +00:00', null);
insert into test values('aaa', '2017-08-16 18:08:04 +00:00', '2017-08-16 18:08:04 +00:00');
insert into test values('bbb', '2017-08-16 17:08:04 +00:00', null);
CREATE TABLE CHILD(ID VARCHAR(20), DATA VARCHAR(10), DATA2 VARCHAR(10), modstamp DATETIMEOFFSET, deleteddate DATETIMEOFFSET);
insert into CHILD values('1', 'aaa', null, '2017-08-16 15:08:04 +00:00', null);
insert into CHILD values('1', null, 'bbb', '2017-08-16 16:08:04 +00:00', null);
insert into CHILD values('1', null, null, '2017-08-16 17:08:04 +00:00', null);
insert into CHILD values('2', 'aaa', null, '2017-08-16 15:08:04 +00:00', null);
insert into CHILD values('3', null, null, '2017-08-16 15:08:04 +00:00', null);
答案 0 :(得分:0)
您的查询看起来不错。我不会调用以下优化的查询,但另一种方法是使用ROW_NUMBER()
。
SELECT * FROM (
SELECT *, rownum = ROW_NUMBER() OVER (PARTITION BY id ORDER BY modstamp)
FROM child
WHERE (data = ? OR data IS NULL OR data2 = ? OR data2 IS NULL) AND modstamp <= '2017-08-16 17:08:04 +00:00'
) AS a where rownum = 1