SQL best-n-per-group,包含多个表上的不稳定数据

时间:2011-07-27 23:10:20

标签: sql greatest-n-per-group

我正试图解决一个最大的每组问题。我一直在阅读现有的解决方案,但似乎没有一个与我正在处理的怪癖相匹配。

情景:让我们说有一家石油公司,它有一系列油井。每口井都有许多油箱。每天,有人会读取每口井。有时他们也会读取坦克的读数,但是坦克读数的频率要低得多,并且可能会在几天内传播。

所有井和油罐读数都记录在数据库中,按日期组织。

CREATE TABLE "wellReadings" (
    "id" INT PRIMARY AUTO_INCREMENT,
    "date" DATETIME,
    "wellName" VARCHAR(10),
    ...
);

CREATE TABLE "tankReadings" (
    "id" INT PRIMARY AUTO_INCREMENT,
    "date" DATETIME,
    "well" INT NOT NULL,
    "tankName" VARCHAR(10),
    ...
);

问题:对于任何给定日期的井读数(在wellReadings表中),我想找到与该井相关的所有油罐的油罐读数(在tankReadings表中) ,在同一天拍摄。如果特定坦克在该日期没有阅读,我希望在该日期之前阅读最近的阅读。

到目前为止,我一直在尝试使用连接和subquerys,但是还没有能够将结果缩小到最近的坦克读数(我的测试查询继续给我所有坦克读数发生在或之前阅读日期)。相关子查询可能有效,但我的数据库不支持它们(SQLite)。

1 个答案:

答案 0 :(得分:1)

您可以尝试以下方式:

SELECT * FROM wellReadings AS well, tankReadings AS tank
 WHERE tank.well = well.id 
   AND tank.date =
       (SELECT MAX(tank2.date) FROM tankReadings AS tank2
         WHERE tank2.id = tank.id
           AND tank2.date <= well.date)

这可能不是最有效的方法,但它应该有效。

聚苯乙烯。如果某些井可能根本没有过去的油罐读数,您可能想要使用左连接:

SELECT * FROM wellReadings AS well
  LEFT JOIN tankReadings AS tank
    ON tank.well = well.id 
   AND tank.date =
       (SELECT MAX(tank2.date) FROM tankReadings AS tank2
         WHERE tank2.id = tank.id
           AND tank2.date <= well.date)