3 присоединения и где пункт вместе - PullRequest
2 голосов
/ 26 июня 2009

у меня 3 стола

bl_main (bl_id UNIQUE, bl_area)
bl_details (bl_id UNIQUE, name) 
bl_data(bl_id, month, paper_tons, bottles_tons)

bl_id не является уникальным в последней таблице. Там будет несколько строк одного и того же bl_id.

Я пытаюсь получить данные следующим образом

bl_id | name | bl_area | sum(paper_tons) | sum (bottles_tons) | paper_tons | bottles_tons

sum(paper_tons) должен вернуть сумму всех бумажных тонн за тот же bl_id, что и январь-декабрь.

Используя приведенный ниже запрос, я могу корректно получить все данные, за исключением того, что в результате есть несколько случаев bl_ids(From bl_data table).

SELECT bl_main.bl_id,name,bl_area,sums.SummedPaper, sums.SummedBottles,paper_tons,bottles_tons
FROM bl_main
JOIN bl_details ON 
    bl_main.bl_id= bl_details.bl_id
left outer JOIN bl_data ON
    bl_data.bl_id= bl_main.bl_id
left outer JOIN (
    SELECT bl_id, SUM(Paper_tons) As SummedPaper, SUM(bottle_tons) As SummedBottles 
FROM bl_data

GROUP by bl_id) суммы ВКЛ sums.bl_id = bl_main.bl_id

Я хочу получить только уникальные значения bl_ids без повторов, и он должен содержать bl_id с максимальным месяцем, а не все месяцы для одного и того же bl_id.

Например:

INCORRECT


**0601**    University Hall     75.76   17051   1356    4040    1154    **11**     
**0601**    University Hall     75.76   17051   1356    9190    101     **12**  
**0605**    UIC Student     22.86   3331    14799   0   356   **8**   

CORRECT   
**0601**    University Hall     75.76   17051   1356    9190    101     **12**  
**0605**    UIC Student     22.86   3331    14799   0   356   **8**  

Я знаю, что могу получить максимальное значение, используя

WHERE Month = (SELECT MAX(Month)

но где именно я должен добавить это в запрос и должен ли я изменить определение соединения. Любая помощь высоко ценится, как я новичок в SQL. Заранее спасибо.

Ответы [ 5 ]

1 голос
/ 26 июня 2009

У вас есть две таблицы, которые, вероятно, следует объединить в одну (bl_main и bl_details). Но если оставить в стороне, то вам нужен подзапрос самостоятельного объединения, чтобы выбрать строку с максимальным месяцем. Что-то вроде следующего (не проверено):

SELECT bl_main.bl_id, bl_details.name, bl_main.bl_area, sums.sum_paper_tons,
       sums.sum_bottles_tons, maxmonth.paper_tons, maxmonth.bottles_tons
FROM bl_main
INNER JOIN bl_details ON bl_main.bl_id = bl_details.bl_id
LEFT OUTER JOIN (SELECT bl_id, SUM(paper_tons) AS sum_paper_tons, 
                        SUM(bottles_tons) AS sum_bottles_tons
                 FROM bl_data
                 GROUP BY bl_id) sums ON bl_main.bl_id = sums.bl_id
LEFT OUTER JOIN (SELECT bl_id, paper_tons, bottles_tons
                 FROM bl_data data2
                 INNER JOIN (SELECT bl_id, MAX(month) AS max_month
                             FROM bl_data
                             GROUP BY bl_id) m
                    ON m.bl_id = data2.bl_id
                    AND m.max_month = data2.month) maxmonth
    ON bl_main.bl_id = maxmonth.bl_id
0 голосов
/ 26 июня 2009

Я хотел бы просто добавить комментарий к ответу, который дал ЛК, но у меня пока нет 50 очков репутации. Это ссылка на статью, которая, как мне кажется, объясняет этот вопрос и добавляет, почему решение, которое дал lc, является правильным.

http://www.sqlteam.com/article/how-to-use-group-by-with-distinct-aggregates-and-derived-tables

0 голосов
/ 26 июня 2009

Ваше предложение JOIN

left outer JOIN bl_data ON
  bl_data.bl_id= bl_main.bl_id

не указывает, какой месяц выбрать для данных, отображаемых с помощью paper_tons и bottle_tons.

Вы можете обновить этот JOIN, чтобы он содержал только максимальный месяц, и это должно ограничить количество записей, например:

left outer JOIN (SELECT bl_id, MAX(Month) as Month from bl_data GROUP BY bl_id) as Month
  ON Month.bl_id = bl_main.bl_id
left outer JOIN bl_data ON
  bl_data.bl_id = bl_main.bl_id AND bl_data.Month = Month.bl_Month
0 голосов
/ 26 июня 2009

Я думаю, что этот запрос - то, что вы ищете

SELECT bl_main.bl_id,name, bl_area, sums.SummedPaper, sums.SummedBottles, paper_tons, bottles_tons
FROM bl_main
    JOIN bl_details ON bl_main.bl_id= bl_details.bl_id
    left outer JOIN bl_data ON    bl_data.bl_id= bl_main.bl_id
    left outer JOIN
    (
        SELECT bl_id, month, SUM(Paper_tons) As SummedPaper, SUM(bottle_tons) As SummedBottles 
        FROM bl_data
        WHERE month in
        (SELECT MAX(month) FROM bl_data GROUP BY bl_id)
        GROUP BY bl_id, month
    ) sums ON sums.bl_id = bl_main.bl_id
0 голосов
/ 26 июня 2009

Вы можете присоединиться к таблице, содержащей месяц против себя, используя подзапрос формы:

Select *
From mytable m
    Inner Join (Select max(Month) as Month, myId
                From mytable
                Group By myId) mnth
        On mnth.myId = m.myId and mnth.Month = m.Month
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...