包含自身连接(使用子查询)并报告不存在的值(空值)的 MS Access 查询
MS Access query that includes a join to itself (using a subquery) and reports values that do not exist (null values)
我有以下 table 命名价格:
VERTEXID
TIMEID
PRICE
6001
20191231
104.3
6001
20181231
115.3
6001
20171231
138.3
6001
20161231
122.3
6002
20191231
102.3
6002
20190931
123.3
6002
20190631
167.3
6002
20181231
202.3
6002
20171231
402.3
6002
20170931
162.3
我想在 MS Access sql 中编写一个查询,它将找到 table 中的前 5 个 TIMEID,按降序排列,然后将为每个 VERTEXID I select 在 WHERE 子句中 return 对应的值 。如果记录不存在,我希望查询 return 存在的先前值(这是首选)或 null。这是我需要的输出示例:
VERTEXID
TIMEID
PRICE
6001
20191231
104.3
6001
20190931
104.3 (or null)
6001
20190631
104.3 (or null)
6001
20181231
115.3
6001
20171231
138.3
6002
20191231
102.3
6002
20190931
123.3
6002
20190631
167.3
6002
20181231
202.3
6002
20171231
402.3
我目前的情况是这样的:
SELECT P1.VERTEXID, P1.TIMEID, P1.PRICE
FROM PRICES P1
RIGHT JOIN (
SELECT DISTINCT TOP 5 P2.TIMEID
FROM PRICES P2
WHERE P2.TIMEID <= 20191231
ORDER BY P2.TIMEID DESC
) P3
ON P3.TIMEID = P1.TIMEID
WHERE P1.VERTEXID IN (6001,6002) AND P1.TIMEID <= 20191231
ORDER BY P1.VERTEXID, P1.TIMEID DESC
但它不会输出我需要的。非常感谢任何帮助!
如果您想要每个顶点 ID 的最近 5 行:
select p.*
from prices as p
where p.vertexid in (6001, 6002) and
p.timeid in (select top 5 p2.timeid
from prices as p2
where p2.vertexid = p.vertexid
order by p2.timeid desc
);
您在查询中对时间进行了过滤,但您提出的实际问题中并未提及。鉴于过滤是开启的timeid
,你需要的话直接放在子查询里就可以了。
编辑:
如果你想为所有顶点id使用相同的五个时间id(如果它们存在的话),你可以使用:
select p.*
from prices as p
where p.vertexid in (6001, 6002) and
p.timeid in (select top 5 p2.timeid
from prices as p2
where p2.vertexid in (6001, 6002)
order by p2.timeid desc
);
如果你只想为两个顶点共享timeids,你可以使用:
p.timeid in (select top 5 p2.timeid
from prices as p2
where p2.vertexid in (6001, 6002)
group by p2.timeid
having count(*) = 2
order by p2.timeid desc
);
好了:
SELECT J1.VERTEXID, J1.TIMEID, P4.PRICE
FROM (
SELECT DISTINCT P1.VERTEXID, P3.TIMEID
FROM PRICES P1,
(SELECT DISTINCT TOP 5 P2.TIMEID
FROM PRICES P2
WHERE P2.TIMEID <= 20191231
ORDER BY P2.TIMEID DESC
) P3
) J1
LEFT JOIN PRICES P4 ON J1.VERTEXID = P4.VERTEXID AND J1.TIMEID = P4.TIMEID
ORDER BY J1.VERTEXID, J1.TIMEID DESC
您必须根据需要添加过滤条件。
基本上您必须执行以下操作:
- 执行
CROSS JOIN
以获得 VERTEXID 和 TIMEID 的所有组合(即 J1
)
- 然后
LEFT JOIN
这个结果到 table 本身并得到相应的 PRICE 值
缺少价格将为 NULL。
我有以下 table 命名价格:
VERTEXID | TIMEID | PRICE |
---|---|---|
6001 | 20191231 | 104.3 |
6001 | 20181231 | 115.3 |
6001 | 20171231 | 138.3 |
6001 | 20161231 | 122.3 |
6002 | 20191231 | 102.3 |
6002 | 20190931 | 123.3 |
6002 | 20190631 | 167.3 |
6002 | 20181231 | 202.3 |
6002 | 20171231 | 402.3 |
6002 | 20170931 | 162.3 |
我想在 MS Access sql 中编写一个查询,它将找到 table 中的前 5 个 TIMEID,按降序排列,然后将为每个 VERTEXID I select 在 WHERE 子句中 return 对应的值 。如果记录不存在,我希望查询 return 存在的先前值(这是首选)或 null。这是我需要的输出示例:
VERTEXID | TIMEID | PRICE |
---|---|---|
6001 | 20191231 | 104.3 |
6001 | 20190931 | 104.3 (or null) |
6001 | 20190631 | 104.3 (or null) |
6001 | 20181231 | 115.3 |
6001 | 20171231 | 138.3 |
6002 | 20191231 | 102.3 |
6002 | 20190931 | 123.3 |
6002 | 20190631 | 167.3 |
6002 | 20181231 | 202.3 |
6002 | 20171231 | 402.3 |
我目前的情况是这样的:
SELECT P1.VERTEXID, P1.TIMEID, P1.PRICE
FROM PRICES P1
RIGHT JOIN (
SELECT DISTINCT TOP 5 P2.TIMEID
FROM PRICES P2
WHERE P2.TIMEID <= 20191231
ORDER BY P2.TIMEID DESC
) P3
ON P3.TIMEID = P1.TIMEID
WHERE P1.VERTEXID IN (6001,6002) AND P1.TIMEID <= 20191231
ORDER BY P1.VERTEXID, P1.TIMEID DESC
但它不会输出我需要的。非常感谢任何帮助!
如果您想要每个顶点 ID 的最近 5 行:
select p.*
from prices as p
where p.vertexid in (6001, 6002) and
p.timeid in (select top 5 p2.timeid
from prices as p2
where p2.vertexid = p.vertexid
order by p2.timeid desc
);
您在查询中对时间进行了过滤,但您提出的实际问题中并未提及。鉴于过滤是开启的timeid
,你需要的话直接放在子查询里就可以了。
编辑:
如果你想为所有顶点id使用相同的五个时间id(如果它们存在的话),你可以使用:
select p.*
from prices as p
where p.vertexid in (6001, 6002) and
p.timeid in (select top 5 p2.timeid
from prices as p2
where p2.vertexid in (6001, 6002)
order by p2.timeid desc
);
如果你只想为两个顶点共享timeids,你可以使用:
p.timeid in (select top 5 p2.timeid
from prices as p2
where p2.vertexid in (6001, 6002)
group by p2.timeid
having count(*) = 2
order by p2.timeid desc
);
好了:
SELECT J1.VERTEXID, J1.TIMEID, P4.PRICE
FROM (
SELECT DISTINCT P1.VERTEXID, P3.TIMEID
FROM PRICES P1,
(SELECT DISTINCT TOP 5 P2.TIMEID
FROM PRICES P2
WHERE P2.TIMEID <= 20191231
ORDER BY P2.TIMEID DESC
) P3
) J1
LEFT JOIN PRICES P4 ON J1.VERTEXID = P4.VERTEXID AND J1.TIMEID = P4.TIMEID
ORDER BY J1.VERTEXID, J1.TIMEID DESC
您必须根据需要添加过滤条件。
基本上您必须执行以下操作:
- 执行
CROSS JOIN
以获得 VERTEXID 和 TIMEID 的所有组合(即J1
) - 然后
LEFT JOIN
这个结果到 table 本身并得到相应的 PRICE 值
缺少价格将为 NULL。