如何替换'表格'列b'与表b'。'列b'如果'表a'。'列b'匹配'表b'。'列a'

时间:2015-03-31 11:57:34

标签: mysql sql

我有多个与我公司销售的产品相关的表格被新产品取代,这随着时间的推移导致了多次发生。

我一遍又一遍地使用了以下查询,直到我在决赛桌中留下2个产品......

CREATE TABLE mar15a    
SELECT x.sku, x.superseded_sku FROM table x
JOIN table y ON y.sku = x.superseded_sku  

我现在有5张桌子(mar15a,mar15b,... mar15e) 他们遵循这种结构。

------------------------------------
| sku            | superseded_sku  |
------------------------------------
| PartA          | PartC           |
| PartB          | PartC           |
| PartC          | PartD           |

那么我现在如何将这些结合起来,最后得到一个最终列表,显示表D中表E的替代等等?

我希望这是有道理的,今天我的大脑很疼。

有一个sqlfiddle available here给出了更多的想法,我已经包含了表A的一部分和表B的所有内容。


我试过这个......

设置a。superseded_sku = b。superseded_sku 从mar15a a 在哪里。superseded_sku = b.sku INNER JOIN mar15b b ON b.sku = a.sku

哪个不行,但应该大致了解我想要实现的目标。

2 个答案:

答案 0 :(得分:0)

我对你想要的东西仍然有些模糊,但是如果我误解的话,会尝试解决方案然后修改它。

据我所知,你想要的只是通过这样的查询完成:

SELECT
    a.superseded_sku, d.sku
FROM
    mar15a a                JOIN

    mar15b b ON
        a.sku = b.superseded_sku    JOIN

    mar15c c ON
        b.sku = c.superseded_sku    JOIN

    marl5d d ON
        c.sku = d.superseded_sku

如果您能解释为什么不会产生您想要的结果,我可以根据需要进行修改。 。 。

答案 1 :(得分:0)

从您的sqlfiddle中的数据看,您已经取代了skus在一个表中被取代。这使得问题变得非常困难,并且使用单个查询可能是不可能的。

由于您事先并未知道sku已被取代多少次,因此我无法避免任何方法来避免在SQL之外处理数据。您必须对结果执行验证检查,以查看是否已取代任何已取代的skus。

问题的难度和复杂性表明您可能会发现重构模型更容易。 如果您拥有每个"产品"的ID,您可以保留skus的历史记录并使用日期范围来查找原始值和取代值(我使用" product"作为术语可能已经或可能未被取代的项目,不一定是实际库存项目)

在这种情况下,您的模型将如下所示:

CREATE TABLE sku_history (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
    `product_id` INT UNSIGNED NOT NULL,
    `sku` VARCHAR(19) NOT NULL,
    `datetime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP()
) ENGINE = 'MyISAM';

要获取起始sku,您需要将sku_history加入同一个表的版本,但按产品ID分组并使用最早的日期时间值,如下所示

SELECT 
    product_id,
    sku
FROM sku_history
JOIN (
    SELECT 
        product_id, 
        MIN(`datetime`) `datetime` 
    FROM sku_history
    GROUP BY product_id
) min USING (product_id, `datetime`)

要获得被取代的sku,你也可以这样做,但是将最早的日期时间换成最新的(更改MAX()的MIN())

对于决赛桌,您可以在product_id上将这些结果集连接在一起,并删除sku没有更改的任何结果,如下所示:

SELECT
    original.sku,
    superseded.sku AS superseded_sku
FROM (
    SELECT 
        product_id,
        sku
    FROM sku_history
    JOIN (
        SELECT 
            product_id, 
            MIN(`datetime`) `datetime` 
        FROM sku_history
        GROUP BY product_id
    ) min USING (product_id, `datetime`)
) original
JOIN (
    SELECT 
        product_id,
        sku
    FROM sku_history
    JOIN (
        SELECT 
            product_id, 
            MAX(`datetime`) `datetime` 
        FROM sku_history
        GROUP BY product_id
    ) max USING (product_id, `datetime`)
) superseded ON original.product_id = superseded.product_id
WHERE original.sku != superseded.sku;

如果要查找skus在特定日期范围之间(例如,在上个月和本月之间)的所有内容,您需要做的就是在每个子查询中的日期时间添加条件(例如WHERE& #39; datetime'>' 2015-03-01')