Reputation: 13334
This is the case where a seemingly simple exercise turned to be nothing but. I couldn't even get my syntax straight.
Readings
table contains coordinates and time readings for multiple users. All I want at this time to organize it as consecutive time intervals for each user.
Data:
CREATE TABLE [Readings] (
user_id varchar(10),
reading_time int,
x decimal(10,2),
y decimal(10,2) );
INSERT INTO Readings VALUES
('u1', 60, 345, 400),
('u1', 100, 560,300),
('u2', 35, 1024, 250),
('u1', 90, 450, 450),
('u3', 150, 600, 100),
('u3', 100, 500, 125);
My erroneous code:
SELECT r.user_id, r.reading_time start_time, rm.reading_time end_time,
(CONVERT(varchar, r.x)+' ; '+CONVERT(varchar, r.y)) start_point,
(CONVERT(varchar, rm.x)+' ; '+CONVERT(varchar, rm.y)) end_point
FROM Readings r
JOIN (SELECT TOP 1 r2.user_id, r2.reading_time, r2.x, r2.y
FROM Readings r2
WHERE r2.user_id=r.user_id and
r2.reading_time < r.reading_time
ORDER BY r2.reading time desc) rm
ON r.user_id=rm.user_id
ORDER BY 1,2 desc;
Can you please point out my syntax error(s)?
Upvotes: 1
Views: 448
Reputation: 247730
Well part of your problem is you are referencing a table alias inside of a subquery, you can only do that if you are using an APPLY
:
SELECT r.user_id,
r.reading_time start_time,
rm.reading_time end_time,
(CONVERT(varchar(10), r.x)+' ; '+CONVERT(varchar(10), r.y)) start_point,
(CONVERT(varchar(10), rm.x)+' ; '+CONVERT(varchar(10), rm.y)) end_point
FROM Readings r
CROSS APPLY
(
SELECT TOP 1 r2.user_id, r2.reading_time, r2.x, r2.y
FROM Readings r2
WHERE r2.user_id=r.user_id and
r2.reading_time < r.reading_time
ORDER BY r2.reading_time desc
) rm
ORDER BY 1,2 desc;
Upvotes: 2
Reputation: 70658
You can't use the JOIN
like that, you need to use either CROSS APPLY
or OUTER APPLY
(assuming SQL Server). Also, please add length to varchars. Now, try this:
SELECT r.user_id, r.reading_time start_time, rm.reading_time end_time,
(CONVERT(varchar(10), r.x)+' ; '+CONVERT(varchar(10), r.y)) start_point,
(CONVERT(varchar(10), rm.x)+' ; '+CONVERT(varchar(10), rm.y)) end_point
FROM Readings r
OUTER APPLY (SELECT TOP 1 r2.user_id, r2.reading_time, r2.x, r2.y
FROM Readings r2
WHERE r2.user_id=r.user_id and
r2.reading_time < r.reading_time
ORDER BY r2.reading_time desc) rm
ORDER BY 1,2 desc;
Here is a demo for you to try.
Upvotes: 3