2014-06-04 2 views
2

У меня есть две таблицы, например:Получить сумму без группы, но с помощью подзапроса

BALANCE    VS 
╔══════╦══════╗  ╔══════╦═══════╗ 
║ V_ID ║ BAL ║  ║ V_ID ║ NAME ║ 
╠══════╬══════╣  ╠══════╬═══════╣ 
║ 1 ║ 1000 ║  ║ 1 ║ Carl ║ 
║ 1 ║ 500 ║  ║ 2 ║ Peter ║ 
║ 1 ║ -200 ║  ╚══════╩═══════╝ 
║ 2 ║ 350 ║  
║ 2 ║ 1000 ║  
╚══════╩══════╝ 

Теперь я сделал запрос типа:

select 
    NAME,sum(BAL) 
from VS,BALANCE 
where VS.V_ID = BALANCE.V_ID 
group by NAME 

и результат:

╔═══════╦══════╗ 
║ NAME ║ BAL ║ 
╠═══════╬══════╣ 
║ Carl ║ 1300 ║ 
║ Peter ║ 1350 ║ 
╚═══════╩══════╝ 

Но я хотел бы знать, как его сделано без предложение 'group by'. Что-то вроде подзапроса. Я пробовал разные вещи, но я не могу понять, как это будет работать. Я всегда заканчиваю результаты, как и все значения, суммированные в одну строку или результаты, подобные приведенной выше, но без группировки.

может быть кто-нибудь может помочь мне

приветствие

редактировать: забыли сумму()

+2

уверены, что ваш запрос дает результат, как вы показали, так как в запросе нет суммы(). –

+0

Любопытно, почему вы хотите избежать группового предложения? – fancyPants

+0

Без SUM он вернет BAL из одной из строк, которая соответствует NAME (т. Е. Группе по полю). Какое значение BAL, которое он возвращает, недофинансировано. – Kickstart

ответ

2

Чтобы получить текущий SQL для работы с использованием GROUP BY вам потребуется следующее (т.е. функция SUM агрегата): -

select  NAME, SUM(BAL) 
from VS, BALANCE 
WHERE VS.V_ID = BALANCE.V_ID 
group by NAME 

Обратите внимание, что это только ваш первоначальный SQL, минимально модифицированный для работы, и он по-прежнему использует неявное соединение, которое вы закодировали. Неявные присоединяется как правило, следует избегать, а лучше использовать явное INNER JOIN .... ON синтаксисом: -

select NAME, SUM(BAL) 
from VS 
INNER JOIN BALANCE 
ON VS.V_ID = BALANCE.V_ID 
group by NAME 

Если вы действительно хотите, чтобы избежать GROUP BY, то можно с помощью суб запроса, но, скорее всего, медленнее (как это эффективно должно выполнить дополнительный запрос для каждой строки тха основного запроса возвращает): -

select NAME, (SELECT SUM(BAL) FROM BALANCE WHERE BALANCE.V_ID = VS.V_ID) 
from VS 

EDIT, в ответ на ваш комментарий на вложенных запросах.

Корреляционные подзапросы эффективно заставляют MySQL получать набор результатов, а затем для каждой строки в результирующем наборе выполнять другой запрос. Большую часть времени они используются для получения совокупного значения (например, максимальное значение поля, связанного с строкой в ​​возвращаемой строке, но где GROUP BY по основному запросу не будет жизнеспособным).

Например, если у вас есть список комментариев для пользователя, но на каждой строке вы хотели знать дату последнего комментария от этого пользователя вы можете сделать следующее: -

SELECT users.user_name, comments.comment_date, (SELECT MAX(comment_date) FROM comments WHERE comments.user_id = users.id) AS latest_comment_date 
FROM users 
INNER JOIN comments 
ON users.id = comments.user_id 

Это может быть написано, чтобы сделать ноны коррелировать суб запрос с использованием GROUP BY, который затем присоединился: -

SELECT users.user_name, comments.comment_date, latest_comment_date 
FROM users 
INNER JOIN comments 
ON users.id = comments.user_id 
INNER JOIN 
(
    SELECT user_id, MAX(comment_date) AS latest_comment_date 
    FROM comments 
    GROUP BY user_id 
) sub1 
ON users.id = sub1.user_id 

Если вы имеете дело с большим количеством записей на пользователях это, вероятно, будет быстрее.

Однако, если вы имели дело с крошечным количеством записей на пользователях (и определение этого числа было довольно сложным), получение всех максимальных дат комментариев было бы лишними накладными расходами, и это заставило бы присоединиться к подзапросу, вряд ли будут использовать индексы.

+0

Не могу сказать, что я обвиняю вас, но это соединение было оставлено, поскольку это было просто показать исправление его существующего SQL, чтобы заставить его работать. Добавлен комментарий, чтобы сделать это яснее – Kickstart

+0

@kickstart Это работает. Удивительный человек. – user1613360

+0

Он работает, но коррелированные подзапросы вроде этого (т. Е. Подчиненный запрос, который имеет условие, основанное на основном запросе), как правило, не очень хорошая идея. – Kickstart

-1

Попробуйте присоединения таблицы:

select NAME,BAL from VS JOIN BALANCE ON VS.V_ID = BALANCE.V_ID 

Вернется

NAME | BAL 
------------- 
Carl | 1000 
Carl | 500 
Carl | -200 
Peter| 350 
Peter| 1000 

Дляполучить сумму БАЛА, вы должны использовать GROUP BY, иначе вы получите SUM всех строк

+0

Вы должны суммировать все остатки, а столбец имен должен быть уникальным. – user1613360

+0

его другим способом сделать это без предложения where, если вы добавите группу NAME, вы получите тот же результат, что и я. но как вы это сделаете без группы – Daniel

+0

@ Daniel Почему вы не можете использовать Group By? – Justinas

Смежные вопросы