SQL как получить последний результат из каждой объединенной таблицы - PullRequest
0 голосов
/ 02 мая 2020

Я хотел бы получить одну большую таблицу продуктов с самыми последними строками из всех соединенных таблиц с помощью MAX (ID) каждой группы (productToken), у которой есть уникальное имя продукта. Объединенные таблицы - товары (магазин), доступность (статус), описание (товары) и цена товара. Все они содержат уникальный 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

1 Ответ

2 голосов
/ 02 мая 2020

Я хотел бы получить одну большую таблицу продуктов с последними строками из всех соединенных таблиц

Я думаю, что вы хотите получить условия равенства с коррелированными подзапросами в предложении 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
...