在单个查询中查找多个值的第一条记录
Find first record of multiple values in single query
Table
timestamp | tracker_id | position
----------------------------------+------------+----------
2020-02-01 21:53:45.571429+05:30 | 15 | 1
2020-02-01 21:53:45.857143+05:30 | 11 | 1
2020-02-01 21:53:46.428571+05:30 | 15 | 1
2020-02-01 21:53:46.714286+05:30 | 11 | 2
2020-02-01 21:53:54.714288+05:30 | 15 | 2
2020-02-01 21:53:55+05:30 | 12 | 1
2020-02-01 21:53:55.285714+05:30 | 11 | 1
2020-02-01 21:53:55.571429+05:30 | 15 | 3
2020-02-01 21:53:55.857143+05:30 | 13 | 1
2020-02-01 21:53:56.428571+05:30 | 11 | 1
2020-02-01 21:53:56.714286+05:30 | 15 | 1
2020-02-01 21:53:57+05:30 | 13 | 2
2020-02-01 21:53:58.142857+05:30 | 12 | 2
2020-02-01 21:53:58.428571+05:30 | 20 | 1
输出
timestamp | tracker_id | position
----------------------------------+------------+----------
2020-02-01 21:53:45.571429+05:30 | 15 | 1
2020-02-01 21:53:45.857143+05:30 | 11 | 1
2020-02-01 21:53:55+05:30 | 12 | 1
如何在单个查询中找到第一条记录 WHERE tracker_id IN ('15', '11', '12')
?
我可以通过分别查询每个 tracker_id
:
来找到第一条记录
SELECT *
FROM my_table
WHERE tracker_id = '15'
ORDER BY timestamp
LIMIT 1;
您可以将 first_value
与嵌套的 select
查询一起使用:
select mt.*
from my_table mt
where mt.timestamp in (
select first_value(imt.timestamp) over (partition by imt.tracker_id order by imt.timestamp)
from my_table imt
where imt.tracker_id in ('11', '12', '15')
)
我假设 timestamp
是独一无二的,就像您在评论中所说的那样。您始终可以用主键替换连接列,例如 id
.
我已将您的时间戳列命名为 col1,因为我不建议您使用关键字来命名您的列。
select * from mytable m
where m.col1 = (select min(col1)
from mytable m1
where m.tracker_id = m1.tracker_id
group by tracker_id)
and m.tracker_id in (11,15,12);
在 Postgres 中,这可以使用 DISTINCT ON ()
子句来完成:
select distinct on (tracker_id) *
from the_table
where tracker_id in (11,12,15)
order by tracker_id, "timestamp" desc;
查找此查询:
如果你想运行查询选定的tracker_id
,你可以取消注释where子句
;WITH CTE AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY tracker_id ORDER BY timestamp)
duplicates, * FROM my_table -- WHERE tracker_id IN (15,11,12)
)
SELECT timestamp, tracker_id, position FROM CTE WHERE duplicates = 1
select distinct on (tracker_id) *
from the_table
where tracker_id in ( select distinct tracker_id from the_table)
order by tracker_id, "timestamp" desc;
如果您想要第一行与每个 IN
值相匹配,您可以使用 window 函数:
SELECT src.timestamp, src.tracker_id, src.position
FROM (
SELECT
t.timestamp, t.tracker_id, t.position,
ROW_NUMBER() OVER(PARTITION BY tracker_id ORDER BY timestamp DESC) myrownum
FROM mytable t
WHERE tracker_id IN ('15', '11', '12')
) src
WHERE myrownum = 1 -- Get first row for each "tracker_id" grouping
这将 return 匹配您的每个 IN
值的第一行,按 timestamp
排序。
select distinct on (tracker_id) *
from table
where tracker_id in (11,12,15)
order by tracker_id, "timestamp" asc;
我在这种情况下使用 postgres 时使用 distinct on
Table
timestamp | tracker_id | position
----------------------------------+------------+----------
2020-02-01 21:53:45.571429+05:30 | 15 | 1
2020-02-01 21:53:45.857143+05:30 | 11 | 1
2020-02-01 21:53:46.428571+05:30 | 15 | 1
2020-02-01 21:53:46.714286+05:30 | 11 | 2
2020-02-01 21:53:54.714288+05:30 | 15 | 2
2020-02-01 21:53:55+05:30 | 12 | 1
2020-02-01 21:53:55.285714+05:30 | 11 | 1
2020-02-01 21:53:55.571429+05:30 | 15 | 3
2020-02-01 21:53:55.857143+05:30 | 13 | 1
2020-02-01 21:53:56.428571+05:30 | 11 | 1
2020-02-01 21:53:56.714286+05:30 | 15 | 1
2020-02-01 21:53:57+05:30 | 13 | 2
2020-02-01 21:53:58.142857+05:30 | 12 | 2
2020-02-01 21:53:58.428571+05:30 | 20 | 1
输出
timestamp | tracker_id | position
----------------------------------+------------+----------
2020-02-01 21:53:45.571429+05:30 | 15 | 1
2020-02-01 21:53:45.857143+05:30 | 11 | 1
2020-02-01 21:53:55+05:30 | 12 | 1
如何在单个查询中找到第一条记录 WHERE tracker_id IN ('15', '11', '12')
?
我可以通过分别查询每个 tracker_id
:
SELECT *
FROM my_table
WHERE tracker_id = '15'
ORDER BY timestamp
LIMIT 1;
您可以将 first_value
与嵌套的 select
查询一起使用:
select mt.*
from my_table mt
where mt.timestamp in (
select first_value(imt.timestamp) over (partition by imt.tracker_id order by imt.timestamp)
from my_table imt
where imt.tracker_id in ('11', '12', '15')
)
我假设 timestamp
是独一无二的,就像您在评论中所说的那样。您始终可以用主键替换连接列,例如 id
.
我已将您的时间戳列命名为 col1,因为我不建议您使用关键字来命名您的列。
select * from mytable m
where m.col1 = (select min(col1)
from mytable m1
where m.tracker_id = m1.tracker_id
group by tracker_id)
and m.tracker_id in (11,15,12);
在 Postgres 中,这可以使用 DISTINCT ON ()
子句来完成:
select distinct on (tracker_id) *
from the_table
where tracker_id in (11,12,15)
order by tracker_id, "timestamp" desc;
查找此查询:
如果你想运行查询选定的tracker_id
,你可以取消注释where子句 ;WITH CTE AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY tracker_id ORDER BY timestamp)
duplicates, * FROM my_table -- WHERE tracker_id IN (15,11,12)
)
SELECT timestamp, tracker_id, position FROM CTE WHERE duplicates = 1
select distinct on (tracker_id) *
from the_table
where tracker_id in ( select distinct tracker_id from the_table)
order by tracker_id, "timestamp" desc;
如果您想要第一行与每个 IN
值相匹配,您可以使用 window 函数:
SELECT src.timestamp, src.tracker_id, src.position
FROM (
SELECT
t.timestamp, t.tracker_id, t.position,
ROW_NUMBER() OVER(PARTITION BY tracker_id ORDER BY timestamp DESC) myrownum
FROM mytable t
WHERE tracker_id IN ('15', '11', '12')
) src
WHERE myrownum = 1 -- Get first row for each "tracker_id" grouping
这将 return 匹配您的每个 IN
值的第一行,按 timestamp
排序。
select distinct on (tracker_id) *
from table
where tracker_id in (11,12,15)
order by tracker_id, "timestamp" asc;
我在这种情况下使用 postgres 时使用 distinct on