2016-01-12 2 views
0

Я здесь совершенно новый и пробовал разные подсказки из сообщений Stackoverflow на SQL, но не смог решить эту проблему. У меня есть таблица, которая является результатом таблиц присоединился, выглядит следующим образомSQL: case when statement with over (partition by)

таблицы А

cust_id prod_type 

001   A 
001   A 
002   A 
002   B 
003   A 
003   C 

мне нужно применить логику: Если для каждого CUST_ID есть по крайней мере одно значение, где prod_type является B или C , затем верните соответствующее значение prod_type. Если для каждого Cust_ID все значения prod_type являются A, возвращение А.

Конечный результат я пытаюсь получить это

Таблица B

cust_id  prod_type 

001   A 
002   B 
003   C 

Я попытался с помощью

SELECT 
A.cust_id 
,CASE WHEN prod_type in ('B', 'C') THEN prod_type OVER (PARTITION BY A.cust_id) 
ELSE 'A' OVER (PARTITION BY A.cust_id) END AS product 
FROM ([Joined Tables]) AS A 

и кажется, что teradata не позволяет использовать over (clause) в case-case: ожидает ключевое слово END из prod_type и ключевого слова OVER.

+0

Что должно произойти, если у пользователя есть B & C? –

+0

B - это своего рода исторический продукт, который был заменен C. Старые клиенты продолжают использовать B, а только новые клиенты могут приобрести C. – Aoy

ответ

3

Вы хотите вернуть только одну строку на одного клиента с наилучшим соответствием product_type?

Если есть дополнительные столбцы:

SELECT 
    A.cust_id 
    ,prod_type 
    ,... 
FROM ([Joined Tables]) AS A 
QUALIFY 
    ROW_NUMBER() 
    OVER (PARTITION BY CUST_ID 
     ORDER BY CASE WHEN prod_type in ('B', 'C') -- best match first 
         THEN 1 
         ELSE 2 
        END, 
        prod_type) = 1 

В противном случае @ Frisbee-х MAX будет работать, но я предполагаю, что A/B/C не являются фактическими названиями продуктов:

SELECT 
    A.cust_id 
    ,COALESCE(MAX(CASE WHEN prod_type in ('B', 'C') THEN prod_type END) 
      ,MAX(CASE WHEN prod_type not in ('B', 'C') THEN prod_type END)) 
FROM ([Joined Tables]) AS A 
GROUP BY just_id 
+0

Это хорошо работает! Правильно ли я понимаю, что цель 'over() = 1' - вернуть все строки, удовлетворяющие условию внутри скобок? И вы правы, ABC не являются фактическими названиями продуктов, но строки – Aoy

+0

@Aoy: Да, это добавляет рейтинг для каждого клиента на основе ORDER BY и возвращает только первую строку ... – dnoeth