2010-08-27 2 views
1

У меня есть следующий SQL-запрос:Как добавить третью таблицу в SQL запрос, содержащий SUM

SELECT porel.refcode, podetail.ponum, SUM(podetail.orderqty * podetail.unitcost) AS Total 
FROM podetail 
LEFT JOIN porel ON podetail.ponum = porel.ponum 
WHERE porel.poline=podetail.poline AND porel.reftype = 'SPEX' 
GROUP BY porel.refcode, podetail.ponum 
ORDER BY porel.refcode, podetail.ponum 

, который прекрасно работает, чтобы принести мне список ponums и их суммарные значения против refcodes.

Теперь я хочу добавить третью колонку vendor.name. Таблица vendor имеет поле vendorid, которое оно разделяет с таблицей podetail.

Существует несколько podetail записей с одинаковыми ponum, но они также будут соответствовать vendorid.

Может кто-нибудь посоветует, как бы я добавил в поле vendor.name, не возвращая лишние строки?

+0

Можете ли вы добавить структуру таблиц, образцов данных для строк, ожидаемого результата и т. Д. В виде скриншота или текстового режима? – shahkalpesh

+0

@shahkalpesh - Я не работаю сейчас, поэтому не могу сделать это прямо сейчас, но опубликую это в понедельник. –

ответ

2

Heya, Rogue. Я хотел сказать немного больше, чем в комментариях, так что здесь. более

Один простой диагностики с верхней части моей головы это:

SELECT 
    porel.refcode, 
    podetail.ponum, 
    SUM(podetail.orderqty * podetail.unitcost) AS Total, 
    podetail.vendorid 
FROM 
    podetail 
    LEFT JOIN porel 
    ON podetail.ponum = porel.ponum 
WHERE 
    porel.poline = podetail.poline 
    AND porel.reftype = 'SPEX' 
GROUP BY 
    porel.refcode, 
    podetail.ponum, 
    podetail.vendorid 
ORDER BY 
    refcode, 
    ponum 

В здесь, мы не присоединиться к vendor вообще, принимая таблицу полностью из уравнения. Вместо этого мы просто свернем podetail.vendorid s.

Можете ли вы разместить вывод этого запроса?

+0

Пожалуйста, пожалуйста, стреляйте сейчас! Я выполнил запрос по вашему запросу и проверял результаты, выполнив 'SELECT * от поставщика WHERE vendorid = * и т. Д. ', Когда заметил, что * есть * несколько поставщиков с одинаковым вендором! В таблице поставщиков есть записи для нескольких отделов (компаний), а разные отделы могут иметь один и тот же 'vendornum', но для разных поставщиков. Какая ошибка школьника: -s Я теперь добавил 'AND podetail.company = vendor.company' в предложение' WHERE', и он работает. Спасибо вам за вашу помощь и извините, что потратили впустую ваше время. –

+0

@Rogue - Awesome. Еще одна вещь: вы несколько раз спрашивали о вложенном «SELECT ... WHERE EXISTS ... SELECT». Когда люди получают больше строк, чем вы ожидаете от 'JOIN', они не уверены, почему это так точно, но у них возникает соблазн добавить в него синтаксис« исправить », например« DISTINCT »,« TOP », MAX', 'WHERE IN ...' и т. Д. Иногда это прекрасно, но очень часто это означает, что что-то не так, и вы маскируете его. Просто имейте это в виду, когда вы снова столкнетесь с этой ситуацией. Во всяком случае, достаточно проповедовать - удачи с остальными вашими запросами. :) – Matt

+0

Большое спасибо, я определенно буду помнить это в будущем. Я исхожу из большей части программирования, чем DB, поэтому, хотя я довольно быстро подбираю синтаксис SQL, я все еще спотыкаюсь о некоторых тонкостях проектирования базы данных; поэтому ваши справки и проверки здравомыслия были неоценимы. –

2

Добавьте его в GROUP BY. Я предположил, что для каждого podetail.ponum будет один поставщик. Кстати, ваш текущий запрос преобразует левое соединение во внутреннее соединение из-за porel.reftype = 'SPEX' в предложении Where.

SELECT porel.refcode, 
     podetail.ponum, 
     SUM(podetail.orderqty * podetail.unitcost) AS Total, 
     vendor.name 
FROM  podetail 
     INNER JOIN vendor ON podetail.vendorid = vendor.vendorid 
     LEFT JOIN porel ON podetail.ponum = porel.ponum 
WHERE porel.poline=podetail.poline 
AND  porel.reftype = 'SPEX' 
GROUP BY porel.refcode, 
     podetail.ponum, 
     vendor.name 
ORDER BY porel.refcode, 
     podetail.ponum 
+0

Спасибо за ваш ответ, Мартин, я новичок в SQL, так что это большая помощь. Ваше решение почти работает, но оно возвращает несколько идентичных ponums, все с одинаковым Total, но с разными именами поставщиков. Я думаю, что мой первоначальный вопрос, возможно, не был достаточно конкретным, чтобы уточнить; есть несколько записей в виде podetail с одинаковым ponum (это строки в заказе на покупку), но мне нужно общее количество для заказа на поставку в целом, поэтому мне как-то нужно выработать orderqty * unitcost для каждой записи podetail, а затем добавить эти итоги вместе для записей с одинаковым ponum. Надеюсь, это имеет смысл. –

+0

@Rogue - Но если есть несколько имен поставщиков, которые вы хотите вернуть в свой запрос, тогда? –

+0

Существует только одно имя поставщика, связанное с каждой записью поподложки (через поле vendorid). Там, где есть несколько записей в Podetail с одним и тем же ponum, у всех их есть тот же vendorid. –

0
SELECT porel.refcode, 
     podetail.poline, 
     podetail.ponum, 
     SUM(podetail.orderqty * podetail.unitcost) AS Total, 
     vendor.name 
FROM  podetail 
     INNER JOIN vendor ON podetail.vendorid = vendor.vendorid 
     LEFT JOIN porel ON podetail.ponum = porel.ponum 
WHERE porel.poline=podetail.poline 
AND  porel.reftype = 'SPEX' 
GROUP BY porel.refcode, 
     podetail.ponum, 
     vendor.name 
ORDER BY porel.refcode, 
     podetail.poline, 
     podetail.ponum 

Я думаю, вам не хватает на необходимость включения podetail.poline в вашем SELECT и GROUP BY.

+0

Спасибо за ваш ответ. Добавление 'podetail.poline', как вы предлагаете, показывает один и тот же« полин »несколько раз для каждого повторного« ponum ». Чем больше я смотрю на это, тем больше кажется, что соединение с таблицей «vendor» неверно и поэтому возвращает повторяющиеся строки. –

+0

Я видел другой запрос, который использовал вложенный 'SELECT' с' WHERE EXISTS', но не знаком с построением такого запроса. Может ли это быть решением? –

0

Поскольку вы агрегирование podetails, просто агрегатные имена поставщиков:

SELECT porel.refcode, podetail.ponum 
, MAX(vendor.name) as VendorName 
, SUM(podetail.orderqty * podetail.unitcost) AS Total 
FROM podetail 
LEFT JOIN vendor on podetail.vendorid = vendor.vendorid 
LEFT JOIN porel ON podetail.ponum = porel.ponum 
WHERE porel.poline=podetail.poline AND porel.reftype = 'SPEX' 
GROUP BY porel.refcode, podetail.ponum 
ORDER BY porel.refcode, podetail.ponum 

Или использовать MIN(), если вы предпочитаете.

+0

Спасибо за предложение. Агрегирование имен поставщиков также не работает. Выполнение вашей версии запроса возвращает одну строку для каждого 'ponum' (именно этого я хочу), но имя и значения поставщика неверны. Я мог ошибаться, но агрегирование поставщиков, похоже, идет по нему с неправильного направления; тем более, что без агрегации запрос возвращает несколько разных поставщиков для одного и того же po, что неверно. Я бы предположил, что попытка объединения нескольких разных поставщиков всегда будет иметь шанс вернуть неправильного поставщика. –

+0

Несомненно, должен быть способ подключения таблицы 'vendor' таким образом, чтобы он возвращал только правильный поставщик. Может быть, через вложенный оператор SELECT? –

+0

Вы, очевидно, не полностью описали ссылку на внешний ключ от podetail к поставщику. Как только мы узнаем, что однозначно идентифицирует podetail, porel и vendor, мы дадим вам ответы, которые возвращают результаты, которые вы хотите. – bbadour