Выберите оператор на временной таблице для отображения строк, находящихся в данный момент, а не в активной таблице - PullRequest
0 голосов
/ 03 марта 2019

Начните с массива, в котором хранятся значения, которые входят в таблицу базы данных с именем 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 ║
╚═════════╩════════════╩═════════════════════╝

Выглядит хорошо, верно?

Теперь эта задача сравнения двух таблиц, показанных выше, и вывода сравнения между двумя.

Клянусь, это должно быть легко.Кажется, это должно быть легко.Мой желательный вывод - что-то как этот (или значения NULL в таблице producttags и producttags_temp тоже подойдут - просто вывод, который может показать мне сравнение текущего и нового.

Так вот, но это не обязательно должно быть так:

╔═══════════╦══════════════╦════════╦═════════════════════╗
║ 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 голосов
/ 09 марта 2019

Удалось объединить это вместе с помощью каждого, похоже, получился желаемый результат.

-- 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 ║
╚══════════════╩════════════════╩═════════════════════╩════════╝
0 голосов
/ 03 марта 2019

Я думаю, что этот запрос даст вам результаты, которые вы хотите.Сначала он создает список всех тегов в producttags и producttags_temp, которые он LEFT JOIN с producttags и producttags_temp, используя COALESCE для выбора значений из producttags_temp в предпочтении по сравнению с значениями из producttags (для случая, когда тег присутствует в обеих таблицах).Значение состояния создается путем проверки, не является ли значение productId_temp из producttags_temp НЕ НЕДЕЙСТВИТЕЛЬНЫМ, указывая, что в этой таблице была найдена более новая запись.

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

Демонстрация на 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;

Демонстрация на dbfiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...