道歉,如果这很难理解,我在一家调查公司工作,而且对SQL来说相对较新。
我有以下两个表:
targetReadings
id Epoch PointNumber Easting Northing
targetShift
ID Epoch PointNumber ShiftEasting ShiftNorthing
我们有数据自动进入 targetReadings 。然后我们在图表上绘制这些图表以在我们的网站上查看有时我们需要对我们的数据进行轮班。我需要一个将遍历数据并应用正确的移位值的查询。例如,如果我有一个名为R101
的点,其坐标为East 100, North 500
。这可能会受到打击,最新的阅读可能会East 101, North 501
。然后我会在 targetShift 中输入一个条目:
2015-01-01, R101, -1, -1
然后一周之后,它可能会再次被击倒并给我East 105, North 105
的读数。然后我会在 targetShift 中添加另一个条目:
2015-01-08, R101, -4, -4
我需要一个查询来运行 targetReadings 中的数据,并根据 targetShift 中的数据应用正确的班次。
我当前的查询是
SELECT
CASE WHEN a.Epoch > r.Epoch
THEN a.Easting + r.ShiftEasting
END as ShiftEast
, a.PointNumber
, a.Epoch
, r.Epoch
FROM
TargetReadings a
inner join targetShift r on r.PointNumber = a.PointNumber
这有效,但它会为 targetShift 中的每个条目带来一个结果,因为这是一个大型项目,每个点可能会有很多变化。我只想在 targetReadings 中的每个条目获得1个结果。
感谢您的帮助。
以下是一些示例数据,我有两个表的数据,下面是我想从查询中得到的结果:
TargetShift
PointNumber Epoch ShiftEasting ShiftNorthing
CB501 01/01/2014 00:00 0 0
CB501 01/01/2015 00:00 100000 100000
CB501 02/01/2015 00:00 200000 200000
TargetReadings
PointNumber Epoch Easting Northing
CB501 31/12/2014 00:01 528196.679 178392.171
CB501 31/12/2014 01:01 528196.679 178392.170
CB501 01/01/2015 00:01 528196.675 178392.165
CB501 01/01/2015 01:01 528196.676 178392.166
CB501 02/01/2015 00:01 528196.679 178392.167
CB501 02/01/2015 05:01 528196.679 178392.167
预期查询结果
PointNumber Epoch ShiftEasting ShiftNorthing
CB501 31/12/2014 00:01 528196.679 178392.171
CB501 31/12/2014 01:01 528196.679 178392.170
CB501 01/01/2015 00:01 628196.675 278392.165
CB501 01/01/2015 01:01 628196.676 278392.166
CB501 02/01/2015 00:01 728196.679 378392.167
CB501 02/01/2015 05:01 728196.679 378392.167
答案 0 :(得分:0)
在这种情况下使用CROSS APLLY
:
SELECT
CASE WHEN a.Epoch > r.Epoch
THEN a.Easting + r.ShiftEasting
END as ShiftEast, a.PointNumber, a.Epoch, r.Epoch
FROM TargetReadings a
cross apply( select top 1 ts.* from targetShift ts where ts.PointNumber = a.PointNumber order by ID desc) r
答案 1 :(得分:0)
尝试这样,它只是表明,
SELECT CASE
WHEN a.Epoch > r.Epoch
THEN a.Easting + r.ShiftEasting
END AS ShiftEast
,a.PointNumber
,a.Epoch
,r.Epoch
FROM TargetReadings a
INNER JOIN (
SELECT *
,ROW_NUMBER() OVER (
PARTITION BY PointNumber ORDER BY [datecolumn] DESC
) rn
FROM targetshift
) r ON r.PointNumber = a.PointNumber
WHERE r.rn = 1
答案 2 :(得分:0)
在检查了示例数据和您在评论中的说明之后,您似乎并不想总结所有轮班,但您只想添加最近的轮班,如果有的话。在这种情况下,OUTER APPLY
似乎是最佳选择。
示例数据:
DECLARE @TargetShift TABLE (PointNumber char(5), Epoch datetime, ShiftEasting float, ShiftNorthing float);
INSERT INTO @TargetShift (PointNumber, Epoch, ShiftEasting, ShiftNorthing) VALUES
('CB501', '2014-01-01T00:00:00', 0 , 0 ),
('CB501', '2015-01-01T00:00:00', 100000, 100000),
('CB501', '2015-01-02T00:00:00', 200000, 200000);
DECLARE @TargetReadings TABLE (PointNumber char(5), Epoch datetime, Easting float, Northing float);
INSERT INTO @TargetReadings (PointNumber, Epoch, Easting, Northing) VALUES
('CB501', '2014-12-31T00:01:00', 528196.679, 178392.171),
('CB501', '2014-12-31T01:01:00', 528196.679, 178392.170),
('CB501', '2015-01-01T00:01:00', 528196.675, 178392.165),
('CB501', '2015-01-01T01:01:00', 528196.676, 178392.166),
('CB501', '2015-01-02T00:01:00', 528196.679, 178392.167),
('CB501', '2015-01-02T05:01:00', 528196.679, 178392.167);
<强>查询强>
SELECT
R.PointNumber
, R.Epoch
, R.Easting + ISNULL(OA_Shift.ShiftEasting, 0) as ShiftEast
, R.Northing + ISNULL(OA_Shift.ShiftNorthing, 0) as ShiftNorth
FROM
@TargetReadings AS R
OUTER APPLY
(
SELECT TOP(1)
S.ShiftEasting
, S.ShiftNorthing
FROM @TargetShift AS S
WHERE
S.PointNumber = R.PointNumber
AND S.Epoch < R.Epoch
ORDER BY S.Epoch DESC
) OA_Shift
ORDER BY
R.PointNumber
, R.Epoch
;
<强>结果强>
PointNumber Epoch ShiftEast ShiftNorth
CB501 2014-12-31 00:01:00.000 528196.679 178392.171
CB501 2014-12-31 01:01:00.000 528196.679 178392.17
CB501 2015-01-01 00:01:00.000 628196.675 278392.165
CB501 2015-01-01 01:01:00.000 628196.676 278392.166
CB501 2015-01-02 00:01:00.000 728196.679 378392.167
CB501 2015-01-02 05:01:00.000 728196.679 378392.167
TargetReadings
OUTER APPLY
中的每一行都会找到TargetShift
中有PointNumber
的1行并且在TargetReadings
行之前的日期。
如果您在TargetShift
上向(PointNumber, Epoch DESC)
添加索引,则查询应该有效。
答案 3 :(得分:0)
Mat,在我看来,你需要在targetShift中为每个具有max(epoch)的pointNumber输入,即最新的条目。实现此目的的一种方法是添加一个条件来过滤到targetShift表,例如:
SELECT
CASE WHEN a.Epoch > r.Epoch
THEN a.Easting + r.ShiftEasting
END as ShiftEast
, a.PointNumber
, a.Epoch
, r.Epoch
FROM
TargetReadings a
inner join targetShift r on r.PointNumber = a.PointNumber
WHERE
r.epoch= (SELECT max(epoch)
FROM targetShift r1
WHERE r.Pointnumber= r1.Pointnumber)
另一点:有意或无意,您的查询将只返回在targetShift中有一个或多个条目的TargetReadings - 可能不是必需的。