首页 > 解决方案 > SQL如何从每个连接表中检索最新结果

问题描述

我想通过每个组(productToken)的MAX(ID)从所有连接的表中检索一个包含最新行的大型产品表,该组具有唯一的产品名称。连接表是 - 产品(商店)、可用性(状态)、描述(产品)和产品价格。所有这些都包含唯一的 productToken 并且可以通过添加新记录(独立地)随着时间的推移更改提到的表,所以我的目标是通过从每个表中检索最新记录来组成一个大表(包含有关产品的实际信息)。我的代码是这样的。第一个添加的产品运行良好,但是在将新记录添加到任何表后事情变得很奇怪(查询没有检索到结果)。

SELECT *
FROM products
JOIN productsStore ON products.productToken = productStore.productToken
JOIN productsStatus ON products.productToken = productsStatus.productToken
JOIN productsPrice ON products.produstToken = productsPrice.productToken
JOIN categories ON products.categoryToken = categories.categoryToken
WHERE products.shopToken = '$shopToken' 
    AND products.productID IN 
        (SELECT MAX(productID) 
        FROM products 
        GROUP BY productToken)
    AND productsPrice.productPriceID IN 
        (SELECT MAX(productPriceID) 
        FROM productsPrice
        GROUP BY produktToken)
    AND productsStatus.productStatusID IN 
        (SELECT MAX(productStatusID) 
        FROM productsStatus
        GROUP BY productToken)
    AND produktyStore.productStoreID IN 
        (SELECT MAX(productStoreID) 
        FROM productsStore
        GROUP BY productToken)
    AND categories.categoryID IN 
        (SELECT MAX(categoryID) 
        FROM categories
        GROUP BY categoryToken)
ORDER BY categories.categoryID DESC

标签: sqldatabasejoinmariadbgreatest-n-per-group

解决方案


我想从所有连接的表中检索一张包含最新行的大型产品表

我认为您希望where子句中具有相关子查询的相等条件,而不是in聚合查询的条件。这使您可以使用给定的“最新”记录过滤每个连接表productToken

SELECT *
FROM products p
JOIN productsStore  psr ON psr.productToken = p.productToken
JOIN productsStatus psu ON psu.productToken = p.productToken
JOIN productsPrice  ppr ON ppr.produstToken = p.productToken
JOIN categories     c   ON c.categoryToken  = p.categoryToken
WHERE 
    p.shopToken = '$shopToken' 
    AND p.productID         = (SELECT MAX(p1.productID)         FROM products      p1   WHERE p1.productToken   = p.productToken)
    AND psr.productStoreID  = (SELECT MAX(psr1.productStoreID)  FROM productsStore psr1 WHERE psr1.productToken = p.productToken)
    AND psu.productStatusID = (SELECT MAX(psu1.productStatusID) FROM productStatus psu1 WHERE psu1.productToken = p.productToken)
    AND ppr.productPriceID  = (SELECT MAX(ppr1.productPriceID)  FROM productsPrice ppr1 WHERE ppr1.productToken = p.productToken)
    AND c.categoryID        = (SELECT MAX(c1.categoryID)        FROM category      c1   WHERE c1.productToken   = p.productToken)

如果您正在运行 MySQL 8.0(或 MariaDB 10.3 或更高版本),则可以ROW_NUMBER()在子查询中使用:

SELECT *
FROM (
    SELECT p.*, ROW_NUMBER() OVER(PARTITION BY productToken ORDER BY productID DESC) rn
    FROM products p
) p
INNER JOIN (
    SELECT psr.*, ROW_NUMBER() OVER(PARTITION BY productToken ORDER BY productStoreID DESC) rn
    FROM productsStore psr
) psr ON psr.productToken = p.productToken AND psr.rn = 1
INNER JOIN (
    SELECT psu.*, ROW_NUMBER() OVER(PARTITION BY productToken ORDER BY productStatusID DESC) rn
    FROM productsStatus psu
) psu ON psu.productToken = p.productToken AND psu.rn = 1
INNER JOIN (
    SELECT ppr.*, ROW_NUMBER() OVER(PARTITION BY productToken ORDER BY productsPriceID DESC) rn
    FROM productsPrice ppr
) ppr ON ppr.productToken = p.productToken AND ppr.rn = 1
INNER JOIN (
    SELECT c.*, ROW_NUMBER() OVER(PARTITION BY productToken ORDER BY categoryID DESC) rn
    FROM categories c
) c ON c.productToken = p.productToken AND c.rn = 1
WHERE p.shopToken = '$shopToken' AND p.rn = 1

推荐阅读