Предположим, у меня есть три таблицы: user
, group
и xref
, таблица, которая дает им много-много RI.Как я могу проверить определенное значение во всех агрегированных строках?
я мог бы видеть, как каждая из групп принадлежит пользователь:
select
user.user_id,
user.user_name,
count(*) as group_count
from
user
inner join xref on user.user_id = xref.user_id
inner join group on group.group_id = xref.group_id
group by user.user_id, user.user_name
Все в порядке до сих пор. Но что, если мне нужна дополнительная информация? Я сообщаю об этом, и я хочу знать, является ли каждый пользователь разработчиком или Менеджером контента. Теперь, анти-закономерность:
select
user.user_id,
user.user_name,
count(*) as group_count,
max(case group.group_name when 'Developers' then 'Y' else null end)
as is_dev
max(case group.group_name when 'Content Management' then 'Y' else null end)
as is_cm
from
user
inner join xref on user.user_id = xref.user_id
inner join group on group.group_id = xref.group_id
group by user.user_id, user.user_name
Это работает, и производит ожидаемые результаты, но он чувствует себя очень плохо. То, что я хочу спросить Oracle заключается в следующем:
«Для каждого пользователя, покажите мне, сколько групп они в Кроме того, для всех имен групп для каждого пользователя, покажите мне, если„Разработчики“это один из. ценности."
То, что я на самом деле запрашиваемое это:.
«Для каждого пользователя, покажи мне, сколько групп они в Кроме того, для всех имен групп для каждого пользователя, покажи мне самое высокое значение, вырабатываемое этим выражением
case
. "
Причина, по которой это анти-модели является то, что я в основном полагаясь на то, что Y
происходит к «пузыриться» выше null
при оценке с max()
. Если кто-то захотел скопировать или увеличить этот запрос, они могли бы легко забыть о анти-шаблоне и случайно изменить возвращаемые значения на то, что не использует одно и то же неинтуитивное совпадение.
В принципе, запрос я хотел бы написать это:
select
user.user_id,
user.user_name,
count(*) as group_count,
any(group.group_name, 'Developers', 'Y', null) as is_dev,
any(group.group_name, 'Content Management', 'Y', null) as is_cm
from
user
inner join xref on user.user_id = xref.user_id
inner join group on group.group_id = xref.group_id
group by user.user_id, user.user_name
Я просеивание вокруг вариантов, и, кажется, есть несколько потенциалов:
first_value
мог но я не могу понять, как ограничить соответствующее окноpartition
правильными строками.- Аналитические функции с предложением
over
могут работать, но I do хотите свернуть столбцы, которые я группирую, поэтому он не выглядит идеально. - Беспокойно, кажется, есть функция
any
, зарегистрированная here, но она существует только в таинственном диалекте, называемом Oracle OLAP DML, который я не думаю, что могу получить доступ, используя только SQL на 10g. Но, кажется, точно что я хочу.
Это все, что у меня есть. Есть идеи?
Я признаю, что есть две очень простые идеи: «Сделайте это в коде» или «Сделайте это в PL/SQL», но это обман.:-)
может принадлежать пользователю как разработчикам, так и контент-менеджеров? это причина, по которой вам нужны два отдельных столбца? –
Вместо того чтобы помещать [SQL] в заголовок, я просто полагаюсь на тег «sql». –
@ вот сейчас. Да, вот почему. –