MYSQL — Создание одного sql-запроса из нескольких запросов

#php #mysql #entity-attribute-value

Вопрос:

Я использую MYSQL Adminer 4.8.0 4.8.1

Я пытаюсь сформировать один запрос из ниже выбранных запросов, можно ли их каким-либо образом выполнить?

Есть 4-5 запросов, поэтому я боюсь

 SELECT `value` from `core_config_data`
WHERE `path` = 'catalog/product/base_media_url';

SELECT `label`
FROM `catalog_product_entity_media_gallery_value`
WHERE `value_id` = (SELECT `value_id`
FROM `catalog_product_entity_media_gallery` 
WHERE `value` LIKE '%test%')
LIMIT 1;

SELECT `child_id`
FROM `catalog_product_relation`
WHERE `parent_id` = 9622
LIMIT 1;

SELECT `rule_price`
FROM `catalogrule_product_price`
WHERE  `product_id` = 9622
LIMIT 1;

SELECT value
FROM `catalog_product_entity_decimal`
WHERE `row_id` = 9622  AND `attribute_id` IN (SELECT `attribute_id` FROM `eav_attribute` 
WHERE `attribute_code` IN ('price','special_price'))

SELECT `value`
FROM `core_config_data`
WHERE `scope` = 'websites' AND `path` = 'currency/options/default' AND `scope_id` = 3';

SELECT e.sku,value from catalog_product_entity e
inner join catalog_product_entity_varchar v on e.entity_id = v.row_id and e.entity_id = 9622 and
attribute_id IN (select attribute_id from eav_attribute where attribute_code IN ('name','sku'));
```
 

Было бы очень и очень полезно, если бы я получил для этого один запрос. Не уверен, что это легко сделать. но я совсем новичок в mysql, поэтому не становлюсь точным.

Я пробовал использовать UNION , но это не сработает.

Я пытался

 SELECT parent.entity_id AS parent_id, 
       simple.entity_id AS simple_id, 
       parent.sku AS sku, simple.sku AS simple_sku 
       ccd.value AS base_media_url 
FROM catalog_product_entity AS parent 
JOIN catalog_product_super_link AS link ON parent.row_id = link.parent_id 
JOIN catalog_product_entity AS simple ON link.product_id = simple.entity_id 
LEFT JOIN core_config_data AS ccd ON path = 'catalog/product/base_media_url' 
WHERE parent.entity_id IN (9244) LIMIT 1 
 

но это не работает.

Комментарии:

1. для того, что вы пробовали , вы можете использовать условные обозначения только в функции, а не в теле функционального компонента. См. раздел Эффект использования.

2. не могли бы вы, пожалуйста, предложить мне исправить это ? Я был занят этим с прошлого дня

3. Я думаю, вам следует взглянуть на redux или mobx. Мне кажется, что вы немного смущены сохранением состояния вашего приложения. Контекст или хранилище сеансов вряд ли будут решением. Однако, если вы уверены в использовании sessionStorage, убедитесь, что объект глобального окна доступен при использовании sessionStorage.

4. Спасибо за предложение @keremistan

5. Как вы думаете, в чем польза от одного большого запроса с различными типами таблиц и данных? Возможно, объединить core_config_data запросы и, возможно, три, которые имеют product_id только условие. Я бы предпочел придерживаться нескольких небольших запросов. Кэшируйте выходные данные всех из них вместе, если вам нужно повысить производительность?

Ответ №1:

Метод 1: Объединение скаляров:

 SELECT a ... LIMIT 1;
SELECT b ... LIMIT 1;

-->

SELECT
    ( SELECT a ... LIMIT 1) AS a,
    ( SELECT b ... LIMIT 1) AS b ;
 

Если a есть что-то подобное COUNT(*) , то вы знаете, что будет ровно один результат; следовательно LIMIT 1 , в этом нет необходимости.

Если один из этих подзапросов может не возвращать никаких строк, вы получите NULL .

Метод 2: Выбор можно использовать практически везде, где можно использовать выражение. Вышесказанное, технически, является примером такого рода. Также…

 SELECT ... WHERE x = ( SELECT ... ) ...
 

Опять же, подзапрос должен возвращать одну строку, чтобы это было возможно.

 SELECT ...
    WHERE x LIKE CONCAT('%', ( SELECT ... ), '%')
    ...;
 

Это становится примерно таким после оценки подзапроса:

 SELECT
    WHERE x LIKE '%foo%'
    ...;
 

(Это неэффективно, но работает.)

Эти 3 похожи, но не обязательно эффективны друг с другом:

 SELECT ...
    WHERE x IN ( SELECT ... )

SELECT ... FROM A
    WHERE EXISTS( SELECT ... FROM B
                  WHERE B.x = A.x )

SELECT ... FROM A JOIN B ON B.x = A.x
 

Это похоже, но находит соответствующие элементы, отсутствующие в B:

 SELECT ... FROM A LEFT JOIN B ON B.x = A.x
    WHERE B.id IS NULL
    
 

UNION следует использовать для запросов с аналогичными выводами:

 SELECT x,y FROM A
UNION
SELECT x,y FROM B
 

Это приведет к получению любого количества строк из A и любого количества строк из B. Дубликаты удаляются , если вы используете UNION DISTINCT , или сохраняются, если вы используете UNION ALL .

ORDER BY ... LIMIT ... становится сложнее. OFFSET становится еще сложнее.

Производительность

  • Избегайте IN ( SELECT ...) этого, как правило, более медленного из трех.
  • Избегайте ввода подстановочных LIKE знаков ; посмотрите, будет ли FULLTEXT это лучшим вариантом.
  • INDEX(path) , INDEX(parent_id, child_id) («покрытие»), INDEX(scope, path, scope_id) ; может быть, другие, но мне нужно посмотреть SHOW CREATE TABLE .
  • Избегайте схемы подслушивания; это плохо сказывается на производительности. Я добавил ссылку; смотрите множество других обсуждений. Также: http://mysql.rjweb.org/doc.php/eav и http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta

Эти элементы, вероятно, более важны (для производительности), чем объединение утверждений вместе. Видишь https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem

Комментарии:

1. Спасибо за ответ @Rick, я пытаюсь это сделать

2. @devhs — Я добавил раздел о производительности.

Ответ №2:

Напишите хранимую процедуру, а затем CALL ее.

Декларация:

 DELIMITER //
CREATE PROCEDURE foo(...)
...
BEGIN
    statement 1;
    statement 2;
    statement 3;
    statement 4;
    statement 5;
END //
DELIMITER ;
 

Вызов:

 CALL foo(...);
 

Комментарии:

1. Спасибо за помощь, не могли бы вы обновить ответ со ссылкой на запросы, которые я добавил в вашу логику ? Я не совсем понимаю, как перевести мой запрос в логику.

2. @devhs — (1) Улучшите производительность на основе моих комментариев в моем другом ответе. (2) Укажите, какие параметры необходимы для этого сохраненного процесса-возможно, $path, 9622, » %test%»; другие вещи? О чем ('price','special_price')) ? Это всегда одно и то же, или пользователю может потребоваться изменить это? Если поклонник похож на phpMyAdmin, то сохраненный процесс предназначен для удобства , а не для производительности .