Выберите записи из таблицы фактов с несколькими условиями в одной таблице измерений - PullRequest
0 голосов
/ 25 апреля 2019

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

FACT TABLE (записи):

| id | name | date | gender |

DIMENSION TABLE (ответы):

| record_id | question_id | value |

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

SELECT * FROM records r 
    left join answers a on r.id = a.record_id 
    left join answers a2 on r.id = a2.record_id 
    where (a.question_id = 1 and a.value = 2) 
    and (a2.question_id = 3 and a2.value = 1);

Есть ли альтернатива этому?

Ответы [ 3 ]

0 голосов
/ 25 апреля 2019

После еще нескольких копаний похоже, что наиболее масштабируемый и динамичный способ - использование EXISTS

SELECT * FROM records r  WHERE 
  EXISTS (SELECT * FROM answers WHERE record_id = r.id AND question_id = 1 AND value = 1) AND
  EXISTS (SELECT * FROM answers WHERE record_id = r.id AND question_id = 3 AND value = 1)
0 голосов
/ 29 апреля 2019

Я бы жестко закодировал список вопросов / значений, которые вы хотите, и использовал объединение:

with
 question_filter as (
    select 1 as question_id, 2 as value
    union select 3, 1
)
select *
from records r
join answers a
on r.id=a.record_id
join question_filter
using (question_id,value)
;
0 голосов
/ 25 апреля 2019

Если я правильно понимаю ваш вопрос, вам нужно:

   SELECT 
       *
     FROM records r 
LEFT JOIN answers a ON r.id            = a.record_id
                   AND a.question_id   = 1 
                   AND a.value         = 2 
LEFT JOIN answers a2 ON r.id           = a2.record_id 
                    AND a2.question_id = 3 
                    AND a2.value       = 1;
...