Найдите самого маленького покупателя по крайней мере 1 заказом на покупку - PullRequest
0 голосов
/ 05 мая 2019

Мне нужно написать запрос, чтобы найти самого маленького покупателя, который купил хотя бы 1 товар

Вот данные: КЛИЕНТ:

enter image description here

ORDER_DETAIL:

enter image description here

Это мой запрос:

SELECT c.CUSTOMERID, c.age, c.name
from (
SELECT CUSTOMERID, COUNT(ORDERID) as "totalOrder"
FROM FACEBOOK_ORDER_DETAIL
GROUP BY CUSTOMERID 
HAVING COUNT(ORDERID) >=1) AS tbl
LEFT JOIN FACEBOOK_CUSTOMER c on c.CUSTOMERID = tbl.CUSTOMERID
order by c.age ;

Однако, приведенный выше запрос дает мне enter image description here

Но мне нужен список клиентов с минимальным возрастом.

Ответы [ 2 ]

1 голос
/ 05 мая 2019

Вам нужны только столбцы из customers, поэтому я бы сказал это следующим образом:

select c.*
from (select c.*,
             rank() over (order by age) as seqnum
      from customers c
      where exists (select 1
                    from facebook_order_detail fod
                    where fod.customerid = c.customerid
                   )
    ) c
where seqnum = 1;

В частности, для этого не нужно исключать или агрегировать дубликаты, поэтому это должно быть быстрее.И он может использовать индекс на face_book_details(customerid), а также, возможно, на customers(age, customerid).

1 голос
/ 05 мая 2019

Если вы действительно хотите, чтобы у вас был только один младший клиент, даже если есть связь, используйте LIMIT:

SELECT c.CUSTOMERID, c.age, c.name
FROM CUSTOMER c
INNER JOIN FACEBOOK_ORDER_DETAIL o
    ON c.CUSTOMERID = c.CUSTOMERID
ORDER BY
    c.age
LIMIT 1;

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

Если вместо этого вы хотите найти всех самых молодых клиентов, включая все связи, то для этого неплохой способ - аналитическая функция RANK:

SELECT DISTINCT CUSTOMERID, age, name
FROM
(
    SELECT c.CUSTOMERID, c.age, c.name, RANK() OVER (ORDER BY c.age) rnk
    FROM CUSTOMER c
    INNER JOIN FACEBOOK_ORDER_DETAIL o
        ON c.CUSTOMERID = o.CUSTOMERID
) t
WHERE rnk = 1;

Демо

Для более ранних версий MySQL мы можем использовать подзапрос в качестве обходного пути для отсутствия RANK:

SELECT DISTINCT c.CUSTOMERID, c.age, c.name
FROM CUSTOMER c
INNER JOIN FACEBOOK_ORDER_DETAIL o
    ON c.CUSTOMERID = c.CUSTOMERID
WHERE c.age = (SELECT MIN(t1.age)
               FROM CUSTOMER t1
               INNER JOIN FACEBOOK_ORDER_DETAIL t2
                   ON t1.CUSTOMERID = t2.CUSTOMERID);

Демо

...