【问题标题】:Implementing a SQL query without window functions实现没有窗口函数的 SQL 查询
【发布时间】:2016-05-24 19:13:03
【问题描述】:

我已经读到,可以通过创造性地使用连接等来实现您在 SQL 窗口函数中可能执行的任何操作,但我不知道如何操作。我在这个项目中使用的是 SQLite,它目前没有窗口函数。

我有一个四列的表格:

CREATE TABLE foo (
   id INTEGER PRIMARY KEY,
   x REAL NOT NULL,
   y REAL NOT NULL,
   val REAL NOT NULL,
   UNIQUE(x,y));

还有一个方便的函数 DIST(x1, y1, x2, y2) 返回两点之间的距离。

我想要什么: 对于该表中的每一行,我希望同一张表中的整行在一定距离内 [例如 25 公里],并具有最低的“val”。对于具有相同“val”的行,我想使用最低距离作为决胜局。

我当前的解决方案是运行 n+1 个查询,这可行但很幸运:

SELECT * FROM foo;

...然后,对于返回的每一行,我运行 [其中“src”是我刚刚得到的行]:

SELECT * FROM foo
  WHERE DIST(foo.x, foo.y, src.x, src.y)<25
  ORDER BY val ASC, DIST(foo.x, foo.y, src.x, src.y) ASC
  LIMIT 1

但我真的希望它在一个查询中,部分是出于我自己的兴趣,部分是因为它使使用我拥有的其他一些工具变得更加容易。

【问题讨论】:

  • imo,使用标准 sql 不会便宜;-/ 您最终会针对整个表对每个外部行进行相关查询。或者对外部表中的每一行进行连接。对于测试的每一行,都必须计算距离。
  • 我其实不介意它是否相当昂贵;这被用于一些离线分析。我目前的解决方案也很慢,我只是对如何在单个查询中完成它的学术兴趣感到好奇 [还因为,正如我所说,它使使用我的其他一些工具变得更加容易]

标签: sql sqlite


【解决方案1】:

使用您的查询获取所需行的 ID,然后使用它来连接表:

SELECT *
FROM (SELECT foo.*,
             (SELECT id
              FROM (SELECT id,
                           x,
                           y,
                           foo.x AS foo_x,
                           foo.y AS foo_y,
                           val
                    FROM foo)
              WHERE DIST(foo_x, foo_y, x, y) < 25
              ORDER BY val, DIST(foo_x, foo_y, x, y)
              LIMIT 1
             ) AS id2
      FROM foo)
JOIN foo AS foo2 ON id2 = foo2.id;

【讨论】:

  • 我正在 sqlite 中尝试这个,但相关的子查询似乎不起作用;当我只运行顶级子查询 [select foo.*, (SELECT ...) FROM foo] 时,我得到“没有这样的列:foo.x”。似乎 sqlite 只支持 WHERE 子句中项目的相关子查询?
  • 这看起来像是 SQLite 中的一个错误(访问 foo.x 应该在 WHERE 和 ORDER BY 子句中都有效)。只需添加另一个间接...
猜你喜欢
  • 1970-01-01
  • 2018-04-29
  • 1970-01-01
  • 2018-12-23
  • 2015-11-22
  • 2014-03-10
  • 2021-12-05
  • 2021-07-09
  • 2018-11-14
相关资源
最近更新 更多