Как я могу узнать любимый бренд нашего клиента по запросу? - PullRequest
0 голосов
/ 27 января 2012

Я хотел бы создать таблицу (или результат запроса) в этой форме

+---------------------+---------------------+
| Email               | Favourite Brand ID  |
+---------------------+---------------------+
| customer@gmail.com  |                  89 |
+-                   -+-                   -+
| another@gmail.com   |                 193 |
+-                   -+-                   -+

Мне удалось написать запрос, который генерирует список уникальных идентификаторов бренда с адресами электронной почты клиентов и количествомраз, что клиент купил эту марку.Результаты выглядят примерно так:

+---------------------+-----------+---------------+
| Email               | Brand ID  | CountOfOrders |
+---------------------+-----------+---------------+
| customer@gmail.com  |        89 |            10 |
+-                   -+-         -+-             -+
| another@gmail.com   |       193 |            32 |
+-                   -+-         -+-             -+
| duplicate@gmail.com |        20 |             2 |
+-                   -+-         -+-             -+
| duplicate@gmail.com |        47 |             5 |
+-                   -+-         -+-             -+

Очевидно, duplicate@gmail.com дважды приобрел у BrandID 20 и BrandID 47 5 раз, поэтому они появляются дважды.Большинство клиентов приобрели товары более чем у одного бренда.

Из этой информации, как я могу составить запрос, чтобы получить идентификатор бренда, который они приобрели у большинства?Я пробовал следующее, но это просто время ожидания:

SELECT [table1].Email, [table1].Brand, [table1].CountOfBrand
FROM [Customer Brand Purchases] AS [table1]
GROUP BY [table1].Email, [table1].Brand, [table1].CountOfBrand
WHERE [table1].CountOfBrand=(
    SELECT TOP 1 [table2].CountOfBrand 
    FROM [Customer Brand Purchases] AS [table2] 
    WHERE [table2].Email = [table1].Email 
    ORDER BY [table2].CountOfBrand DESC
);

О, и я, к сожалению, должен использовать Microsoft Access.Спасибо.

Ответы [ 4 ]

2 голосов
/ 27 января 2012

Гарет мне показался правильным. Я проверил свою собственную попытку, используя данные из вашего базового запроса, которые я сохранил в таблице с именем Customer_Brand_Purchases. Я также переименовал столбец Brand_ID.

SELECT
    c1.Email,
    c1.Brand_ID AS [Favourite Brand ID]
FROM
    Customer_Brand_Purchases AS c1
    INNER JOIN (
        SELECT
            Email,
            Max(CountOfOrders) AS MaxOfCountOfOrders
        FROM Customer_Brand_Purchases
        GROUP BY Email
        ) AS c2
    ON
        (c1.Email = c2.Email)
        AND (c1.CountOfOrders = c2.MaxOfCountOfOrders)
ORDER BY c1.Email;

Я могу подтвердить, что это работает в Access 2007, что означает, что он производит вывод, который, я думаю, вам нужен, без сообщений об ошибках.

Email               Favourite Brand ID
another@gmail.com                  193
customer@gmail.com                  89
duplicate@gmail.com                 47

Однако мой запрос почти совпадает с версией Гарета. Единственная причина, по которой я могу предложить, почему моя может работать для вас, когда его нет, заключается в том, что я избегал использовать квадратные скобки в подзапросе.

В некоторых ситуациях (детали которых мне не ясны) конструктор запросов Access 'перезапишет подзапрос из этой формы:

SELECT q.* FROM (SELECT something FROM YourTable) AS q

к этому ...

SELECT q.* FROM [SELECT something FROM YourTable]. AS q

И в этой второй форме двигатель БД будет задыхаться, если подзапрос содержит квадратные скобки. Кстати, это одна из причин, по которой следует избегать использования имен объектов, для которых требуется заключать в скобки ... таких как имена, содержащие пробелы.

OTOH, если моя версия также не сработает для вас, я подозреваю, что ваш базовый источник запросов слишком сложен, чтобы обработчик БД не мог с ним справиться, когда вы используете его здесь. Если это так, следуйте совету Филиппа, чтобы исходить из исходных таблиц, а не из запроса [Покупки бренда клиента].

2 голосов
/ 27 января 2012

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

Мой Access SQL немного заржавел, но я на 98% уверен, что это будет работать:

SELECT   CBP.Email, CBP.Brand AS [Favourite Brand ID]
FROM    [Customer Brand Purchases] AS CBP
        INNER JOIN
        (   SELECT  [Email], MAX(CountofBrand) AS [MaxCountofBrand]
            FROM    [Customer Brand Purchases]
            GROUP BY [Email]
        ) AS [MaxCBP]
            ON CBP.Email = MaxCBP.Email
            AND CBP.CountOfBrand = MaxCBP.MaxCountOfBrand

Единственным недостатком является то, что если конкретный клиент заказал 2 бренда одинаковое количество раз, он вернет 2 строки. Для решения этой проблемы потребуются дополнительные подзапросы с операторами MAX.

EDIT / ДОПОЛНЕНИЕ:

Если это абсолютно АБСОЛЮТНО, запрос возвращает 1 результат на адрес электронной почты, тогда вам необходимо учесть сценарий, в котором конкретный адрес электронной почты приобрел 2 бренда и равное количество раз, когда нет способа установить, какой из них является любимым как они совместный фаворит. Если бы это был я, я бы занимался этим на уровне приложений и объединял бы любимые бренды в одну строку. Тем не менее, это может быть сделано в SQL, просто помните, что один или несколько брендов могут быть скрыты с помощью этого:

SELECT   CBP.Email, CBP.Brand AS [Favourite Brand ID]
FROM    [Customer Brand Purchases] AS CBP
        INNER JOIN
        (   SELECT  CBP.Email, MAX(CBP.Brand) AS MaxBrand
            FROM    [Customer Brand Purchases] AS CBP
                    INNER JOIN
                    (   SELECT  [Email], MAX(CountofBrand) AS MaxCountofBrand
                        FROM    [Customer Brand Purchases]
                        GROUP BY [Email]
                    ) AS MaxCBP
                        ON CBP.Email = MaxCBP.Email
                        AND CBP.CountOfBrand = MaxCBP.MaxCountOfBrand
            GROUP BY Email
        ) AS MaxCBP
            ON CBP.Email = MaxCBP.Email
            AND CBP.Brand = MaxCBP.Brand
2 голосов
/ 27 января 2012

Таким образом, в предложении GROUP BY должны быть перечислены значения, в которые должна сворачиваться функция агрегированных данных MAX (). Я просто сделал это в SQLite (потому что я не собираюсь открывать Microsoft Access):

sqlite> create table purchases ( email varchar(255), brand_id int, order_count int );

sqlite> select * from purchases;

sqlite> insert into purchases values( 'customer@gmail.com', 89, 10 );
sqlite> insert into purchases values( 'another@gmail.com', 193, 32 );
sqlite> insert into purchases values( 'duplicate@gmail.com', 20, 2 );
sqlite> insert into purchases values( 'duplicate@gmail.com', 47, 5 );

sqlite> select * from purchases
customer@gmail.com|89|10
another@gmail.com|193|32
duplicate@gmail.com|20|2
duplicate@gmail.com|47|5

sqlite> .mode column
sqlite> .headers on
sqlite> select email, brand_id, max( order_count )from purchases group by email;

email              brand_id    order_count
-----------------  ----------  -----------
another@gmail.com  193         32               
customer@gmail.co  89          10               
duplicate@gmail.c  47          5       

Я полагаю, это то, что вы ищете, верно?

1 голос
/ 27 января 2012

После одного из ваших комментариев кажется, что вы здесь строите запросы на запросы.

Если вы действительно хотите узнать любимые бренды вашего клиента, я уверен, что было бы намного проще вернуться к исходным таблицам, построив запрос на ваших клиентах, строках заказа, ссылках на продукты и «бренде».Таблицы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...