Я получаю «Скалярный подзапрос содержит более одной строки» для следующего запроса, который я написал.Может кто-нибудь, пожалуйста, поправьте меня?

#mysql #sql

#mysql #sql

Вопрос:

Две таблицы

  1. клиент (идентификатор, имя, страна)

таблица клиентов

  1. покупка (id, customer_id, год)

Таблица ПОКУПОК

Я хотел бы видеть следующие 3 вещи

идентификатор каждого клиента (переименуйте столбец cus_id),
имя каждого клиента (переименуйте столбец cus_name)
идентификатор покупки их последней покупки (переименуйте столбец latest_purchase_id)

Пожалуйста, обратите внимание, что идентификаторы покупок представляют собой сочетание целого числа и символа, поэтому, чтобы найти последний идентификатор, мне нужно найти последний год.Возможна многократная покупка в год

Мой код :

 select customer.id as cus_id,customer.name as cus_name,purchase.id as latest_purchase_id
from customer
 join purchase
 on customer.id=purchase.customer_id
 where purchase.id=(select id
from purchase p1
where year = ( select max(year)
              from purchase p2
              where p1.customer_id=p2.customer_id))
         ;
 

пример вывода

 cus_id cus_name latest_purchase_id
1      John        786F
 

Я получаю скалярный подзапрос, получающий более одной ошибки строки.

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

1. Предоставьте примерные данные и какими должны быть ваши результаты. Ошибка сообщает вам о проблеме, один из ваших подзапросов возвращает более одной строки. Вы можете изменить его на оператор IN вместо =, если это ваши желаемые результаты

2. конечно, позвольте мне добавить пример данных

Ответ №1:

Это ваша проблема:

 select c.id as cus_id, c.name as cus_name, p.id as latest_purchase_id
from customer c join
     purchase p
     on c.id = p.customer_id
where p.id = (select p2.id
-----------^
              from purchase p2
              where p2.year = (select max(p3.year)
                               from purchase p3
                               where p2.customer_id = p3.customer_id
                              )
            );
 

Чтобы исправить эту проблему, измените значение = на in . Однако, без описания того, что вы делаете, я не могу сказать, делает ли это что-нибудь полезное.

Если вам нужна последняя покупка для каждого клиента, я думаю о чем-то подобном:

 select c.id as cus_id, c.name as cus_name, p.id as latest_purchase_id
from customer c join
     purchase p
     on c.id = p.customer_id join
     (select p2.customer_id, max(p2.year) as max_year
      from purchase p2
      group by p2.customer_id
     ) p2
     on p2.customer_id = p.customer_id and
        p2.max_year = p.year;
 

Ответ №2:

Вы можете попробовать ниже —

 select customer.id as cus_id,customer.name as cus_name,purchase.id as 
latest_purchase_id
from customer join purchase p1 on customer.id=p1.customer_id
where year = 
( select max(year) from purchase p2
              where p1.customer_id=p2.customer_id)
 

Ответ №3:

скалярный подзапрос получает более одной строки

Это означает (select id from purchase p1 ...) , что возвращает более одной строки. И хорошо… вы не можете использовать простой equal ( = ) для нескольких строк.

У вас есть два варианта:

  1. Вам нужно убедиться, что он возвращает одну строку, возможно, используя MAX() функцию (или другую), как в:
     where purchase.id = (select MAX(id)
      from purchase p1 ...
     
  2. Используйте оператор агрегатора (например ANY ). Например:
     where purchase.id = ANY (select id
      from purchase p1 ...