PL / SQL - Oracle 9.1 - PullRequest
       25

PL / SQL - Oracle 9.1

2 голосов
/ 26 мая 2011

Вот сценарий, над которым мы работаем здесь.У нас есть таблица клиентов и таблица продаж.Таблицы объединяются через идентификатор транзакции в таблице cust.

Покупатель может купить любой фрукт в магазине.

Что нам нужно сделать, это выяснить, например: сколько клиентов купили яблоки, прежде чем они купили вишню.

Table structure:

Cust - Cust ID, Transaction ID, ...
Sales - Transaction ID, Fruit ID, Insert date for record, ...

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

Таким образом, нам нужно выяснить, когда 1-ое яблоко и 1-я вишня куплены кастом, а затем проверить даты на них.

Ответы [ 2 ]

4 голосов
/ 26 мая 2011

Как транзакция_ид может быть столбцом / атрибутом для клиента? Это означает, что клиент может иметь только одну транзакцию.

Если у вас есть таблица с именами customer_id, fruit_id и sale_date, которые вы можете попробовать

select cust_id,
       min(case when fruit_id = 'Apple' then sale_date end) first_apple_purchase,
       min(case when fruit_id = 'Cherry' then sale_date end) first_cherry_purchase
from transactions
group by cust_id
having min(case when fruit_id = 'Apple' then sale_date end) <
        min(case when fruit_id = 'Cherry' then sale_date end)
2 голосов
/ 26 мая 2011

Я второе мнение Гэри о модели данных, но это не имеет отношения к вопросу.

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

select apple.cust_id
from
    ( select c.cust_id, min(s.sale_date) as sale_date
      from cust c
           join sales s 
                on s.transaction_id = c.transaction_id 
      where s.fruit_id = 'CHERRY'
      group by c.cust_id ) cherry
    ,     
    ( select c.cust_id, min(s.sale_date) as sale_date
      from cust c
           join sales s 
                on s.transaction_id = c.transaction_id 
      where s.fruit_id = 'APPLE'
      group by c.cust_id ) apple
where cherry.cust_id = apple.cust_id
and cherry.sale_date > apple.sale_date
/

Если значений FRUIT_ID меньше, тогда вариант с предложением Гари, вероятно, будет более эффективным:

select cust_id
from
    ( select c.cust_id
             , min(case when s.fruit_id = 'CHERRY' = s.sale_date else null end) as cherry_date
             , min(case when s.fruit_id = 'APPLE' = s.sale_date else null end) as apple_date
      from cust c
           join sales s 
                on s.transaction_id = c.transaction_id 
      group by c.cust_id ) cherry
where cherry_date > apple_date
/

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

...