SQL:ID x 在日期 y 的状态是什么(有更有效的方法吗?)

发布于 2024-11-12 15:32:24 字数 1012 浏览 3 评论 0 原文

我有两个表:一个包含 ID 列表,另一个包含有关这些 ID 的一些时间相关信息。

示例

ID_TABLE
ID
 1
 2
 3

INFO_TABLE
ID         START           END   STATE
 1    2000-01-01    2000-01-31       A
 1    2000-02-01    2000-03-31       B
 3    2000-02-01    2000-02-31       A
 3    2000-03-01    2000-05-31       C

(请注意,第二个表中不存在 ID=2)

现在我想将此信息转换为 平衡面板数据,这意味着我想知道在特定日期每个ID 存在什么STATE

我的 SQL 命令如下所示:

SELECT
  id_table.id,

  t1.state AS Jan,
  t2.state AS Feb,
  t3.state AS March

  FROM 
    id_table
    LEFT JOIN info_table AS t1
      ON id_table.id = t1.id
      AND '2000-01-15' BETWEEN t1.start AND t1.end
    LEFT JOIN info_table AS t2
      ON id_table.id = t2.id
      AND '2000-02-15' BETWEEN t2.start AND t2.end
    LEFT JOIN info_table AS t3
      ON id_table.id = t3.id
      AND '2000-03-15' BETWEEN t3.start AND t3.end
;

有更有效的方法吗?

I have two tables: one containing a list of IDs and one containing some time related information about those IDs.

example

ID_TABLE
ID
 1
 2
 3

INFO_TABLE
ID         START           END   STATE
 1    2000-01-01    2000-01-31       A
 1    2000-02-01    2000-03-31       B
 3    2000-02-01    2000-02-31       A
 3    2000-03-01    2000-05-31       C

(please notice, that ID=2 is not present in the second table)

Now I want to turn this information into balanced panel data, which means I want to know what STATE is present for every ID on certain dates.

My SQL-Command looks like this:

SELECT
  id_table.id,

  t1.state AS Jan,
  t2.state AS Feb,
  t3.state AS March

  FROM 
    id_table
    LEFT JOIN info_table AS t1
      ON id_table.id = t1.id
      AND '2000-01-15' BETWEEN t1.start AND t1.end
    LEFT JOIN info_table AS t2
      ON id_table.id = t2.id
      AND '2000-02-15' BETWEEN t2.start AND t2.end
    LEFT JOIN info_table AS t3
      ON id_table.id = t3.id
      AND '2000-03-15' BETWEEN t3.start AND t3.end
;

Is there a more efficient way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谈下烟灰 2024-11-19 15:32:24

我不完全确定我明白你的问题,但如果你链接的维基百科页面是可以参考的,那么你真正寻找的内容更接近于这个:

select t.id,
      '2000-01-01'::date + (m.mon || ' months')::interval as month,
      t.state
from generate_series(0, 11) as m (mon)
left join info_table t
on '2000-01-15'::date + (m.mon || ' months')::interval
   between t.start and t.end

如果你当前的查询是你真正需要的,那么你通过使用几何类型可以加快速度:

PostgreSQL 匹配间隔开始时间和结束时间与时间戳之间

I'm not entirely sure I get your question, but if the wikipedia page that you link is anything to go by, what you're really looking for is closer to this:

select t.id,
      '2000-01-01'::date + (m.mon || ' months')::interval as month,
      t.state
from generate_series(0, 11) as m (mon)
left join info_table t
on '2000-01-15'::date + (m.mon || ' months')::interval
   between t.start and t.end

In case your current query is the one you actually need, you can making faster by using a geometry type:

PostgreSQL matching interval between start and end time against timestamp

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文