Nano Hash - криптовалюты, майнинг, программирование

Правильная сумма с несколькими подзаписями (postgresql)

Возможно, об этом уже спрашивали несколько раз, но я не знаю, как добиться правильного сома как от родителя, так и от ребенка.

Вот таблицы:

CREATE TABLE co
    (coid int4, coname text);    
INSERT INTO co
    (coid, coname)
VALUES
    (1, 'Volvo'),
    (2, 'Ford'),
    (3, 'Jeep'),
    (4, 'Toyota')

;

CREATE TABLE inv
    (invid int4, invco int4, invsum numeric(10,2));
INSERT INTO inv
    (invid, invco, invsum)
VALUES
    (1,1,100),
    (2,1,100),
    (3,2,100),
    (4,3,100),
    (5,4,100)
;

CREATE TABLE po
    (poid int4, poinv int4, posum int4);
INSERT INTO po
    (poid, poinv, posum)
VALUES
    (1,1,50),
    (2,1,50),
    (3,3,100),
    (4,4,100)
;

Я начал с этого простого запроса

SELECT    coname, sum(invsum)
FROM      inv
LEFT JOIN co ON coid=invco
GROUP BY  1
ORDER BY  1

Что дало правильный результат:

coname     sum
Ford       100
Jeep       100
Toyota     100 
Volvo      200

Затем я добавил запись po, и суммы стали неверными:

SELECT    coname, sum(posum) as po, sum(invsum)
FROM      inv
LEFT JOIN co ON coid=invco
LEFT JOIN po ON poinv=invid
GROUP BY  1
ORDER BY  1

Что умножило сумму для Volvo:

coname    po     sum
Ford      100    100
Jeep      100    100
Toyota    (null) 100 (no records for po = correct)
Volvo     100    300 (wrong sum for inv)

Как мне построить запрос, который дает правильный результат с несколькими подзаписями po? (Оконная функция?)

SQLfiddle: http://sqlfiddle.com/#!15/0d90c/12

18.09.2016

Ответы:


1

Выполните агрегирование перед объединениями. В вашем случае это немного сложно, потому что отношения между co и po, похоже, требуют inv:

SELECT co.coname, p.posum, i.invsum
FROM co LEFT JOIN
     (SELECT i.invco, sum(i.invsum) as invsum
      FROM inv i
      GROUP BY i.invco
     ) i
     ON co.coid = i.invco LEFT JOIN
     (SELECT i.invco, sum(po.posum) as posum
      FROM po JOIN
           inv i
           ON po.poinv = i.invid
      GROUP BY i.invco
     ) p
     ON co.coid = p.invco
ORDER BY 1;

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

18.09.2016
  • Разве не наоборот? co кажется просто словарной таблицей для inv.invco, поэтому не следует ли вам начать с inv? 18.09.2016
  • Я хочу составить список счетов-фактур с суммами. Я полагаю, это даст всем компаниям, даже те, у которых нет счетов-фактур? 18.09.2016
  • @sibert измените сначала LEFT JOIN на RIGHT JOIN. Гордон, я исправил псевдоним в вашем запросе. 18.09.2016
  • Не помогает. Будут тысячи компаний, у которых не будет счетов-фактур. Они будут иметь (нулевые) значения: sqlfiddle.com/#!15/ab645/1 18.09.2016
  • @сиберт. . . Если вам нужны только компании, у которых есть счета, используйте внутреннее соединение вместо левого соединения. 19.09.2016
  • Благодарю вас! Он работает как надо, но есть ли другой способ добиться этого? 19.09.2016
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..