выбрать все значения из измерения, для которого есть факты во всех других измерениях

Я попытался упростить, чтобы задать этот вопрос. Надеюсь, это будет понятно.

По сути, у меня есть таблица фактов с измерением времени, другим измерением и иерархическим измерением. Для целей вопроса предположим, что иерархическим измерением является почтовый индекс и штат. Другое измерение является просто описательным. Назовем это «клиент». Предположим, что есть 50 клиентов.

Мне нужно найти набор штатов, для которых существует хотя бы один почтовый индекс, в котором КАЖДЫЙ клиент имеет хотя бы одну строку фактов для каждого дня во временном измерении. Если у почтового индекса всего 49 клиентов, меня это не волнует. Если хотя бы один из 50 клиентов не имеет ценности хотя бы за 1 день в почтовом индексе, меня это не волнует. Наконец, мне также нужно знать, какие почтовые индексы подходят для выбора штата. Обратите внимание, что для каждого почтового индекса не требуется полный набор данных, требуется только наличие хотя бы одного почтового индекса.

Я не против сделать несколько запросов и выполнить некоторую обработку на стороне клиента. Это набор данных, который нужно генерировать только один раз в день и который можно кэшировать. Я даже не вижу особенно чистого способа сделать это с несколькими запросами, за исключением простой итерации грубой силы, и в наборе данных есть чертовски много «почтовых индексов» (на самом деле не почтовые индексы, но там примерно 100 000 записей на нижнем уровне иерархии и несколько сотен на верхнем уровне, поэтому zipcode->state является разумной аналогией)


person ideasculptor    schedule 06.04.2010    source источник


Ответы (1)


В качестве первой итерации вы можете попробовать следующее:

Предполагая

  • клиенты (список всех клиентов)
  • zip_codes (список всех почтовых индексов)
  • дни (список всех дней)
  • факты (таблица фактов)

Я считаю, что вы должны сломать его

1) получить клиентов и почтовые индексы, которые имеют факты на каждый день

SELECT zip_id, customer_id, COUNT(DISTINCT days)
FROM facts
GROUP BY zip_id, customer_id
HAVING COUNT(DISTINCT days) = (SELECT COUNT(*) FROM days) 

2) из ​​этого набора результатов проверьте наличие почтовых индексов, у которых есть все клиенты

SELECT zip_id, COUNT(DISTINCT customer_id)
FROM ( 
    SELECT zip_id, customer_id, COUNT(DISTINCT days)
    FROM facts
    GROUP BY zip_id, customer_id
    HAVING COUNT(DISTINCT days) = (SELECT COUNT(*) FROM days) 
    ) S
GROUP BY zip_id
HAVING COUNT(DISTINCT customer_id) = (SELECT COUNT(*) FROM customers)

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

person Unreason    schedule 06.04.2010
comment
Благодарю. Я понятия не имею, почему мне было так трудно обдумать это. - person ideasculptor; 07.04.2010