2016-08-07 4 views
0

Извините за неинформируемое название, я не знаю, как назвать эту операцию. Вот пример, который, я надеюсь, поможет.SQL - Как выполнить эту операцию соединения?

У нас есть пользователи, для которых мы регистрируем события. События могут быть разных типов. Мы хотим создать отчет (новую таблицу), который будет указывать, если событие произошло для пользователя; например:

Events    x EventInfo   = UserEvent  
---     ---      --- 
UserId | EventId  EventId | Type   UserId | login | verify 
------------------ -----------------  ------------------------   
1  | 1   1  | login   1  | True | True 
1  | 2   2  | verify  2  | False | False 
2  | 3   3  | login    

Дополнительные ограничения:

  • Мы не знаем, типы событий, предварительно (ни их имя или число различных типов)
  • должно происходить исключительно в базе данных
+0

, потому что вы не знайте количество или имена типов событий загодя, которые вам нужны в качестве столбцов, вам нужно будет использовать динамический sql, чтобы обнаружить эти детали и создать инструкцию select, используя условную агрегацию, такую ​​как ответ @sgeddes. – Matt

ответ

1

Что вы пытаетесь сделать, это форма таблицы pivot. Вот один вариант использования conditional aggregation:

select e.userid, 
    max(case when ei.type = 'login' then 'True' else 'False' end) as login, 
    max(case when ei.type = 'verify' then 'True' else 'False' end) as verify 
from events e 
    join eventinfo ei on e.eventid = ei.eventid 
group by e.userid 

Вам может понадобиться outer join, если у вас есть записи в вашем event таблицы, которые не существуют в eventinfo таблице.


Если вы не знаете type, вы должны будете использовать dynamic sql, Есть много примеров там:

+0

Это, вероятно, работает для простого примера, но не выполняется в случае, когда мы не знаем типы событий на момент написания запроса. Можно ли обобщить ваше решение? – Winks

+0

@Winks - только что заметил ваши изменения и проблемы. Вам нужно использовать 'dynamic sql' для создания' pivot'. Посмотрите на этот ответ bluefeet, отличный пример, используя 'if' вместо' case', но работает одинаково. – sgeddes

Смежные вопросы