Обновление столбца по значению, которое соответствует уникальному значению, приводит к тому, что подзапрос возвращает более 1 строки - PullRequest
0 голосов
/ 30 апреля 2019

У меня есть таблица с именем orders:

| order_id | user_id |
| 91881 | a001 |
| 82191 | a002 |
| 73817 | a001 |
| 91289 | a003 |
| 81828 | a002 |
| 82917 | a002 | 

Я хочу создать новую таблицу, состоящую из уникального user_id и количества заказов, сделанных пользователем.

| user_id | total_orders |
| a001 | 2 |
| a002 | 3 |
| a003 | 1 |

Для новой таблицы, которую я написал

CREATE TABLE new_table AS (SELECT DISTINCT user_id FROM orders);
ALTER TABLE new_table
    ADD (total_orders INT)

Проблема возникает, когда я пытаюсь обновить столбец total_orders, написав этот код

UPDATE new_table
SET new_table.total_orders = (
SELECT COUNT(DISTINCT(order_id)) FROM orders
GROUP BY user_id
ORDER BY user_id ASC)
WHERE new.user_id = (SELECT DISTINCT user_id FROM orders);

и в результате "Подзапрос возвращает более 1 строки"

Что следует изменить в коде обновления?

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 30 апреля 2019

Вы можете просто использовать агрегирование в своей исходной команде CREATE TABLE, чтобы одновременно создать столбец total_orders:

CREATE TABLE new_table AS
SELECT user_id, COUNT(order_id) AS total_orders
FROM orders
GROUP BY user_id;

SELECT * FROM new_table

Вывод:

user_id total_orders
a001    2
a002    3
a003    1

Однако этостатический и не обновляется, поскольку пользователь создает больше заказов.Вероятно, имеет смысл создать VIEW (точно такой же запрос, просто замените TABLE на VIEW):

CREATE VIEW new_table AS
SELECT user_id, COUNT(order_id) AS total_orders
FROM orders
GROUP BY user_id

Это даст обновленные результаты по мере добавления новых заказов в orders таблица.

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

1 голос
/ 30 апреля 2019

Ваша проблема: WHERE new.user_id = (SELECT DISTINCT user_id FROM orders);

Вы, вероятно, можете использовать обновление с объединением, чтобы сделать это:

UPDATE new_table as t0
JOIN (
    SELECT user_id, 
    COUNT(DISTINCT order_id) As total_orders 
    FROM orders 
    GROUP BY user_id
) as t1
    ON t0.user_id = t1.user_id 
SET t0.total_orders = t1.total_orders

Однако я подозреваю, что все это обновление неправильно с самого начала.Обычно сохранение значений, которые могут быть легко вычислены на лету, является ошибкой, особенно если они являются результатом вычислений в другой таблице.Наличие этого столбца total_orders означает, что вы должны продолжать синхронизировать его с фактическими данными в таблице orders - так что вам нужны триггеры в этой таблице для обновления, вставки и удаления - похоже на простое представление, содержащее данные, которые вы хотителучшее решение.

0 голосов
/ 30 апреля 2019

Вам просто нужен коррелированный подзапрос:

UPDATE new_table nt
    SET nt.total_orders = (SELECT COUNT(DISTINCT o.order_id))
                           FROM orders o
                           WHERE o.user_id = nt.user_id
                          )
    WHERE nt.user_id IN (SELECT o.user_id FROM orders o);

Тем не менее, я предполагаю, что order_id уникально в orders. Кроме того, вы, вероятно, хотите установить значение 0, если нет заказов.

Итак:

UPDATE new_table nt
    SET nt.total_orders = (SELECT COUN(*)
                           FROM orders o
                           WHERE o.user_id = nt.user_id
                          );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...