在临时表上选择语句以显示当前不在活动表中的行

时间:2019-03-03 04:23:59

标签: mysql sql

从一个数组开始,该数组保存进入名为producttags的数据库表中的值。

$newproducttags = array ('Green', 'Synthetic', 'Clearance');

和另一个变量,该变量将其Foreign Key ID连接到另一个名为products的表

看起来与此类似

╔═════╦═══════╦═════════════════════╗
║ id  ║  MPN  ║     createdtime     ║
╠═════╬═══════╬═════════════════════╣
║ ... ║ ...   ║ ...                 ║
║ 517 ║ 0WV12 ║ 2019-01-05 02:42:33 ║
║ ... ║ ...   ║ ...                 ║
╚═════╩═══════╩═════════════════════╝

/

// in this case $fk_id = 517;
$fk_id = $this->db->run("SELECT id FROM `products` WHERE `MPN` = ?", [$MPN])->fetchColumn();

在执行查询SELECT * FROM producttags WHERE productID = 517时,它会带回

╔═══════════╦══════════════╦═════════════════════╗
║ productID ║     Tag      ║    lastmodified     ║
╠═══════════╬══════════════╬═════════════════════╣
║       517 ║ Blue         ║ 2019-02-02 15:00:23 ║
║       517 ║ Synthetic    ║ 2019-02-02 15:00:23 ║
║       517 ║ Monthly Sale ║ 2019-02-02 15:00:23 ║
╚═══════════╩══════════════╩═════════════════════╝

我试图用$newproducttags的内容创建一个临时表,然后将其与当前现有的producttags表进行比较。

这样做很容易。

CREATE TEMPORARY TABLE producttags_temp AS 
SELECT Tag AS Tag_temp, productID AS productID_temp, 
lastmodified AS lastmodified_Temp FROM producttags LIMIT 0;

使用foreach循环将$newproducttags中的值中的新产品标签插入到临时表中

foreach ($prodTagArr as $prodTag) {
$this->data = $this->db->run("INSERT INTO `producttags_temp` 
    (`Tag_temp`, `productID_temp`, `lastmodified_Temp`) 
        VALUES (?, ?, NOW())", 
             [$prodTag, $fk_id]);
}

这按预期工作。进行SELECT * FROM producttags_temp会返回:

╔═════════╦════════════╦═════════════════════╗
║ id_temp ║  Tag_temp  ║  lastmodified_temp  ║
╠═════════╬════════════╬═════════════════════╣
║     517 ║ Green      ║ 2019-02-03 12:00:55 ║
║     517 ║ Synthetic  ║ 2019-02-03 12:00:55 ║
║     517 ║ Clearance  ║ 2019-02-03 12:00:55 ║
╚═════════╩════════════╩═════════════════════╝

到目前为止看起来不错,对吧?

现在面临比较上面说明的两个表并输出两者之间的比较的挑战。

我发誓这应该很容易。看起来应该很容易。我想要的输出是这样的 (或者producttagsproducttags_temp表上的NULL值也很好-只是可以向我显示当前比较的输出和新的。

这样,但不必一定是这样:

╔═══════════╦══════════════╦════════╦═════════════════════╗
║ productID ║     Tag      ║ status ║    lastmodified     ║
╠═══════════╬══════════════╬════════╬═════════════════════╣
║       517 ║ Blue         ║      0 ║ 2019-02-02 15:00:23 ║
║       517 ║ Monthly Sale ║      0 ║ 2019-02-02 15:00:23 ║
║       517 ║ Green        ║      1 ║ 2019-02-03 12:00:55 ║
║       517 ║ Synthetic    ║      1 ║ 2019-02-03 12:00:55 ║
║       517 ║ Clearance    ║      1 ║ 2019-02-03 12:00:55 ║
╚═══════════╩══════════════╩════════╩═════════════════════╝

我不知道你们都希望我在尝试失败的过程中混淆线程。

SELECT * FROM producttags_temp  WHERE producttags_temp.Tag_temp 
NOT IN ( SELECT producttags.Tag FROM producttags 
WHERE producttags.productID = producttags_temp.productID_temp );

设法恢复producttags_temp / $newproducttags

中的结果
╔════════════════╦═══════════╦═════════════════════╗
║ productID_temp ║ Tag_temp  ║  lastmodified_temp  ║
╠════════════════╬═══════════╬═════════════════════╣
║            517 ║ Green     ║ 2019-02-03 12:00:55 ║
║            517 ║ Clearance ║ 2019-02-03 12:00:55 ║
╚════════════════╩═══════════╩═════════════════════╝

我假设需要某种JOIN,但是我很难找到可行的解决方案。该查询有效,但不包含任何Tag_temp值,仅包含预先存在的非临时表行。

SELECT * FROM producttags_temp 
WHERE producttags_temp.Tag_temp 
IN ( SELECT producttags.Tag FROM producttags 
WHERE producttags.productID = producttags_temp.productID_temp )

//像这样,但没有时间戳

╔═══════════╦══════════════╗
║ productID ║     Tag      ║
╠═══════════╬══════════════╣
║       517 ║ Blue         ║
║       517 ║ Monthly Sale ║
║       517 ║ Synthetic    ║
║       517 ║ Blue         ║
║       517 ║ Monthly Sale ║
║       517 ║ Synthetic    ║
║       517 ║ Blue         ║
║       517 ║ Monthly Sale ║
║       517 ║ Synthetic    ║
╚═══════════╩══════════════╝

这似乎应该是一个非常简单的联接,但是我已经尝试了几种不同的选项,但似乎没有一个提供我想要的输出。任何人都可以对此有所了解,这有点令人发疯:) 谢谢。

2 个答案:

答案 0 :(得分:0)

我认为此查询将为您提供所需的结果。它首先创建producttagsproducttags_temp中所有标签的列表,并使用LEFT JOIN将其producttagsproducttags_tempCOALESCE。从producttags_temp中选择值要优先于producttags中的值(对于两个表中都存在标签的情况)。通过检查productId_temp中的producttags_temp值是否不是NULL来创建状态值,这表明在该表中找到了较新的条目。

SELECT 
    COALESCE(p2.productId_temp, p1.productId) AS productId,
    COALESCE(p2.Tag_temp, p1.Tag) AS Tag,
    p2.productId_temp IS NOT NULL AS status,
    COALESCE(p2.lastmodified_temp, p1.lastmodified) AS lastmodified
FROM (SELECT Tag FROM producttags
      UNION
      SELECT Tag_temp FROM producttags_temp
      ) t
LEFT JOIN producttags p1 ON p1.Tag = t.Tag
LEFT JOIN producttags_temp p2 ON p2.Tag_temp = t.Tag
ORDER BY status

输出:

productId   Tag             status  lastmodified
517         Blue            0       2019-02-02 15:00:23
517         Monthly Sale    0       2019-02-02 15:00:23
517         Green           1       2019-02-03 12:00:55
517         Synthetic       1       2019-02-03 12:00:55
517         Clearance       1       2019-02-03 12:00:55

Demo on dbfiddle

更新

由于producttags_temp是一个临时表,因此在MySQL查询中不能多次使用它。只要lastmodified日期在该表中晚于producttags,您就可以使用以下查询代替

SELECT tag_temp as Tag, 
           productid_temp as productID, 
           MAX(lastmodified_temp) as lastmodified, 
           MAX(status)
FROM   (SELECT producttags_temp.tag_temp, 
               producttags_temp.productid_temp, 
               producttags_temp.lastmodified_temp, 
               1 AS status 
        FROM   producttags_temp 
        WHERE  productid_temp = 517 
        UNION ALL 
        SELECT producttags.tag, 
               producttags.productid, 
               producttags.lastmodified, 
               0 AS status 
        FROM   producttags 
        WHERE  productid = 517) t 
GROUP  BY tag_temp, productid_temp
ORDER  BY lastmodified;

Demo on dbfiddle

答案 1 :(得分:0)

设法在所有人的帮助下将其整合在一起,似乎具有所需的输出。

-- Temporary Table Creation
CREATE TEMPORARY TABLE producttags_temp AS SELECT Tag AS Tag_temp, productID AS productID_temp, lastmodified AS lastmodified_Temp FROM producttags LIMIT 0;
-- Insert Rows
INSERT INTO `producttags_temp` (`Tag_temp`, `productID_temp`, `lastmodified_Temp`) VALUES ('Green', 517, NOW());
INSERT INTO `producttags_temp` (`Tag_temp`, `productID_temp`, `lastmodified_Temp`) VALUES ('Synthetic', 517, NOW());
INSERT INTO `producttags_temp` (`Tag_temp`, `productID_temp`, `lastmodified_Temp`) VALUES ('Clearance', 517, NOW());

-- Actual Query
   SELECT tag_temp as Tag, 
           productid_temp as productID, 
           lastmodified_temp as lastmodified, 
           status 
FROM   (SELECT producttags_temp.tag_temp, 
               producttags_temp.productid_temp, 
               producttags_temp.lastmodified_temp, 
               1 AS status 
        FROM   producttags_temp 
        WHERE  productid_temp = 517 
        UNION ALL 
        SELECT producttags.tag, 
               producttags.productid, 
               producttags.lastmodified, 
               0 AS status 
        FROM   producttags 
        WHERE  productid = 517) t 
GROUP  BY Tag 
ORDER  BY lastmodified

输出:

╔══════════════╦════════════════╦═════════════════════╦════════╗
║     Tag      ║    productID   ║     lastmodified    ║ status ║
╠══════════════╬════════════════╬═════════════════════╬════════╣
║ Blue         ║            517 ║ 2019-03-02 23:19:08 ║      0 ║
║ Monthly Sale ║            517 ║ 2019-03-02 23:19:08 ║      0 ║
║ Green        ║            517 ║ 2019-03-08 19:37:46 ║      1 ║
║ Synthetic    ║            517 ║ 2019-03-08 19:37:46 ║      1 ║
║ Clearance    ║            517 ║ 2019-03-08 19:37:47 ║      1 ║
╚══════════════╩════════════════╩═════════════════════╩════════╝