从“有一个通过”关系查找最新记录

时间:2018-06-11 05:49:22

标签: sql postgresql join greatest-n-per-group

我有以下表格:

  • matrices - 矩阵名称和其他一些元数据。
  • matrix_values - 将2D矩阵的各种数据点存储为JSON值列(Postgres)。此外,属于关联的FK matrix_id
  • products - matrix_value可以通过加入表product加入matrix_value_products
    • matrix_values MAY 只与一个product相关联,但不是必须的;事实上,大多数都没有。这就是使用连接表而不是属于FK关系的原因,以避免在FK列中主要使用NULL值

ERD看起来像

enter image description here

每个矩阵有几个matrix_values,其中 A)没有一个与product相关联,或 B)所有这些都是与产品相关(可能是不同的产品)。

在场景 A 中,多个记录是2D矩阵的历史记录,其中最近创建的记录是当前表示。这种情况很容易让我找到最新的matrix_value

如何为方案 B 创建查询,以便查找每个产品的最新matrix_values条记录 ?对于下面的矩阵777,我想返回matrix_values条记录 2 (最近的产品 P )和 4 (最近的产品 Q )。

enter image description here

2 个答案:

答案 0 :(得分:1)

SELECT finalValues.* FROM
matrix_values AS finalValues
INNER JOIN matrix_value_products AS finalProducts 
ON finalProducts.matrix_value_id = finalValues.id
AND finalValues.created_at = (
    SELECT max(created_at) 
    FROM matrix_values 
    INNER JOIN matrix_value_products
    ON matrix_values.id = matrix_value_products.matrix_value_id
    WHERE matrix_value_products.product_id = finalProducts.product_id
)   
WHERE
        matrix_id = 777

实际上,您将连接两个表并将它们限制为相应Matrix的Matrix值。然后你通过一个子查询来限制整个Thing,该子查询只返回最新的(因此我认为最大值,即created_at是一个datetime(2)字段)条目。您必须使用相同的内部联接,因此您可以将其限制为与您最终要获得的Matrix值相关联的产品。

答案 1 :(得分:0)

你没有说明任何 DBMS 所以,我会使用 def moduleDirs = project.projectDir.listFiles() .findAll { def name = it.name // filter all inner's module it.isDirectory() && msExtension.modulePrefix.any { name.startsWith(it) } } Set<File> manifestSet = new HashSet<>() Set<String> modules = new HashSet<>() def sourceSetConf = { AndroidSourceSet sourceSet -> moduleDirs.each { def moduleName = it.name def dir = sourceSet.name sourceSet.assets.srcDirs "${moduleName}/src/${dir}/assets" sourceSet.java.srcDirs "${moduleName}/src/${dir}/java" sourceSet.res.srcDirs "${moduleName}/src/${dir}/res" sourceSet.aidl.srcDirs "${moduleName}/src/${dir}/aidl" // each AndroidManifest.xml def manifestFile = project.file("${moduleName}/AndroidManifest.xml") if (manifestFile != null && manifestFile.exists()) { manifestSet.add(manifestFile) } modules.add(moduleName) } } // for default main sources sourceSetConf(android.sourceSets.main) // for buildType sources android.buildTypes.each { def buildType = it.name android.sourceSets.getByName(buildType) { sourceSetConf(it) } } // for flavor sources android.productFlavors.each { def flavor = it.name android.sourceSets.getByName(flavor) { sourceSetConf(it) } } 这是ANSI SQL。

subquery