SQL: 3 самостоятельно объединяются, а затем объединяются - PullRequest
0 голосов
/ 08 апреля 2009

У меня есть 2 таблицы для объединения определенным образом. Я думаю, что мой запрос правильный, но не уверен.

select t1.userID, t3.Answer Unit, t5.Answer Demo  
FROM    
    table1 t1  
    inner join (select * from table2) t3 ON t1.userID = t3.userID   
    inner join (select * from table2) t5 ON t1.userID = t5.userID  
where  
    NOT EXISTS (SELECT * FROM table1 t2 WHERE t2.userID = t1.userID AND t2.date > t1.date)  
    and NOT EXISTS (SELECT * FROM table2 t4 WHERE t4.userID = t3.userID and t4.counter > t3.counter)  
    and NOT EXISTS (SELECT * FROM table2 t6 WHERE t6.userID = t5.userID and t6.counter > t5.counter)  
    and t1.date_submitted >'1/1/2009'  
    and t3.question = Unit  
    and t5.question = Demo  
order by  
    t1.userID  

Из таблицы1 я хочу отдельный идентификатор пользователя, где дата> 01.01.2009

table1      
userID    Date
1         1/2/2009  
1         1/2/2009  
2         1/2/2009  
3         1/2/2009  
4         1/1/2008  

Итак, результат, который я хочу получить из таблицы1, должен быть таким:

userID  
1  
2  
3  

Затем я хочу присоединить это по userID к таблице2, которая выглядит следующим образом:

table2 
userID    question   answer   counter
1         Unit       A        1
1         Demo       x        1
1         Prod       100      1
2         Unit       B        1
2         Demo       Y        1
3         Prod       100      1
4         Unit       A        1
1         Unit       B        2
1         Demo       x        2
1         Prod       100      2
2         Unit       B        2
2         Demo       Z        2
3         Prod       100      2
4         Unit       A        2

Я хочу объединить table1 с table2 с таким результатом:

userID    Unit    Demo
1         B       X
2         B       Z

Другими словами,
выберите отдельный идентификатор пользователя из таблицы 2, где вопрос = единица измерения для наибольшего счетчика
а затем
выберите отличный идентификатор пользователя из таблицы 2, где вопрос = Демо для самого высокого счетчика.

Я думаю, что я сделал 3 самостоятельных соединения, а затем соединил эти 3 вместе.

Как вы думаете, это правильно?

1 Ответ

3 голосов
/ 08 апреля 2009
SELECT  du.userID, unit.answer, demo.answer
FROM    (
        SELECT  DISTINCT userID
        FROM    table1
        WHERE   date > '1/1/2009'
        ) du
LEFT JOIN
        table2 unit
ON      (userID, question, counter) IN
        (
        SELECT  du.userID, 'Unit', MAX(counter)
        FROM    table2 td
        WHERE   userID = du.userID
                AND question = 'Unit'
        )
LEFT JOIN
        table2 demo
ON      (userID, question, counter) IN
        (
        SELECT  du.userID, 'Demo', MAX(counter)
        FROM    table2 td
        WHERE   userID = du.userID
                AND question = 'Demo'
        )

Наличие индекса на table2 (userID, question, counter) значительно улучшит этот запрос.

Поскольку вы упомянули SQL Server 2005, следующее будет проще и эффективнее:

SELECT  du.userID,
        (
        SELECT  TOP 1 answer
        FROM    table2 ti
        WHERE   ti.user = du.userID
                AND ti.question = 'Unit'
        ORDER BY
                counter DESC
        ) AS unit_answer,
        (
        SELECT  TOP 1 answer
        FROM    table2 ti
        WHERE   ti.user = du.userID
                AND ti.question = 'Demo'
        ORDER BY
                counter DESC
        ) AS demo_answer
FROM    (
        SELECT  DISTINCT userID
        WHERE   date > '1/1/2009'
        FROM    table1
        ) du

Для агрегирования:

SELECT  answer, COUNT(*)
FROM    (
        SELECT  DISTINCT userID
        FROM    table1
        WHERE   date > '1/1/2009'
        ) du
JOIN    table2 t2
ON      t2.userID = du.userID
        AND t2.question = 'Unit'
GROUP BY
        answer
...