Redshift Correlated Subquery внутренняя ошибка - PullRequest
0 голосов
/ 07 марта 2020

У меня есть запрос в MYSQL, который считает products от указанного c поставщика с product_status, как Live, Pause, soldout, Partial-Soldout et c. Запрос включает Subquery, но отлично работает в Mysql. Для Redshift (Postgre v8.x) выдается ошибка correlated subquery pattern is not supported due to internal error

Запрос (POSTGRES)

SELECT COUNT(CASE WHEN (vendor_id = 6 AND status = 1) THEN 1 ELSE NULL END) AS "vex",
   COUNT(CASE WHEN (vendor_id = 6 AND status = 1 AND p.p_id IN (SELECT pov.p_id FROM product_option_value pov WHERE pov.p_id AND p.quantity != pov.quantity AND pov.quantity = 0 GROUP BY pov.p_id)) THEN 1 ELSE NULL END) AS "vex-Partial-Soldout",
   COUNT(CASE WHEN (vendor_id = 6 AND status = 1 AND p.quantity = 0) THEN 1 ELSE NULL END) AS "vex-Soldout",
   COUNT(CASE WHEN (vendor_id = 5 AND status = 1) THEN 1 ELSE NULL END) AS "vey-DXB",
   COUNT(CASE WHEN (vendor_id = 5 AND status = 1 AND p.p_id IN (SELECT pov.p_id FROM product_option_value pov WHERE pov._id AND p.quantity != pov.quantity AND pov.quantity = 0 GROUP BY pov.p_id)) THEN 1 ELSE NULL END) AS "vey-Partial-Soldout",
   COUNT(CASE WHEN (vendor_id = 5 AND status = 1 AND p.quantity = 0) THEN 1 ELSE NULL END) AS "vey-Soldout"
FROM product p

Структура таблицы

//Product p table
*  p_id *   model   *   vendor_id   *   status  * Quantity * 
* 1001  *   HB1     *      1        *   1       *  10      *
* 1002  *   HB2     *      6        *   1       *  17      *
* 1003  *   HB3     *      5        *   1       *  19      *
* 1004  *   HB4     *      2        *   1       *  3       *
* 1005  *   HB5     *      1        *   1       *  8       *
* 1006  *   HB6     *      6        *   1       *  55      *
* 1007  *   HB7     *      3        *   1       *  32      *
* 1008  *   HB8     *      5        *   1       *  6       *
* 1009  *   HB9     *      5        *   1       *  10      *


//product_option_value pov table
*   pov_id  *   p_id    *   opt_id    *   quantity   * 
*   1       *   1001    *   11        *   10         *
*   2       *   1002    *   11        *   17         *
*   3       *   1003    *   11        *   0          *
*   4       *   1004    *   11        *   3          *
*   5       *   1005    *   11        *   8          *
*   6       *   1006    *   11        *   0          *
*   7       *   1007    *   11        *   32         *
*   8       *   1008    *   11        *   6          *
*   9       *   1009    *   11        *   0          *

Group by необходимо в подзапросе, поэтому левое соединение также не решает проблему.

Ответы [ 2 ]

0 голосов
/ 07 марта 2020

Вы должны удалить «pov.p_id AND» сразу после предложения where из двух выражений, которые вычисляют «vex-Partial-Soldout» и «vey-Partial-Soldout». Затем он работает на postgreSQL9.6 и вывод совпадает с выводом вашей версии sqlserver.

SELECT COUNT(CASE WHEN (vendor_id = 6 AND status = 1) THEN 1 ELSE NULL END) AS "vex",
   COUNT(CASE WHEN (vendor_id = 6 AND status = 1 AND p.p_id IN (SELECT pov.p_id FROM product_option_value pov WHERE p.quantity != pov.quantity AND pov.quantity = 0 GROUP BY pov.p_id)) THEN 1 ELSE NULL END) AS "vex-Partial-Soldout",
   COUNT(CASE WHEN (vendor_id = 6 AND status = 1 AND p.quantity = 0) THEN 1 ELSE NULL END) AS "vex-Soldout",
   COUNT(CASE WHEN (vendor_id = 5 AND status = 1) THEN 1 ELSE NULL END) AS "vey-DXB",
   COUNT(CASE WHEN (vendor_id = 5 AND status = 1 AND p.p_id IN (SELECT pov.p_id FROM product_option_value pov WHERE p.quantity != pov.quantity AND pov.quantity = 0 GROUP BY pov.p_id)) THEN 1 ELSE NULL END) AS "vey-Partial-Soldout",
   COUNT(CASE WHEN (vendor_id = 5 AND status = 1 AND p.quantity = 0) THEN 1 ELSE NULL END) AS "vey-Soldout"
FROM product p

Примечание: я не уделил много внимания вашей логике c, так как рекомендуется избегать написания select заявления в пределах вашего выбора.

0 голосов
/ 07 марта 2020

Логика c в подзапросах довольно болезненная для подражания, поэтому я не уверен, что у меня она на 100% правильная. Например, пример данных, кажется, имеет только одну строку на продукт, но я не знаю, так ли это на самом деле. Или что такое opt_id, потому что это может показаться полезным в запросе, использующем таблицу pov.

При этом кажется, что вам просто нужны JOIN и GROUP BY, чтобы получить то, что Вы хотите - запрос, который намного проще и должен быть быстрее в любой базе данных.

В следующем запросе я также разделил двух поставщиков на разные строки. Это, по крайней мере, полезно для получения правильной логики c:

SELECT vendor_id,
       COUNT(DISTINCT p.p_id) AS num_products,
       SUM(CASE WHEN p.quantity <> pov.quantity AND pov.quantity = 0 THEN 1 ELSE 0 END) as partial_soldout,
       COUNT(DISTINCT CASE WHEN p.quantity = 0 THEN p.p_id END) as soldout
FROM product p LEFT JOIN
     product_option_value pov
     ON pov.p_id = p.p_pid
WHERE p.vendor_id IN (5, 6) AND p.status = 1
GROUP BY p.vendor_id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...