таблица соединения SQL, не обеспечивающая идеальный результат - PullRequest
0 голосов
/ 26 апреля 2018

позвольте мне объяснить, что мне нужно, у меня есть 2 таблицы с именем A и B. B - это подтаблица для A.

Вот схема:

------------------------
Table B:
itemId version qty  AId
44       1      1   200
44       1      2   201
44       2      2   200
------------------------
Table A:
id  tId
200 100
201 100
------------------------

и вот что янужно: мне нужна сумма всех последних версий кол-во, которые имеют тот же tId.

вот мой запрос:

select sum(qty) as sum from B
left join A on A.id=B.AId
where itemId=44 and tId=100 and 
version=(select max(version) from B where itemId=44 and tId=100)

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

спасибо.

РЕДАКТИРОВАТЬ:

что именно мне нужно:

itemId version qty  AId
44       2      2   200
44       1      2   201

И результат суммы (кол-во)должно быть 4, потому что у них одинаковый tId и максимальная версия в каждом AId.

Ответы [ 6 ]

0 голосов
/ 26 апреля 2018

Наиболее эффективное решение проблемы в Postgres обычно используют (собственный) оператор distinct on ()

Таким образом, чтобы получить последнюю версию для каждого a.id, вы можете использовать:

select distinct on (a.id) b.*
from a 
  join b on a.id = b.aid
order by a.id, b.version desc;  

Вышеуказанное возвращает:

itemid | version | qty | aid
-------+---------+-----+----
    44 |       2 |   2 | 200
    44 |       1 |   2 | 201

Затем вы можете суммировать по результату:

select sum(qty) 
from (
  select distinct on (a.id) b.qty
  from a 
    join b on a.id = b.aid
  order by a.id, b.version desc
) t;

Обратите внимание, что обычно order by в производной таблице бесполезен, но в этом случае это необходимо, потому что иначе distinct on () не будет работать.

Онлайн пример: http://rextester.com/DRHK19268

0 голосов
/ 26 апреля 2018

Используйте функцию окна.

select itemid, version, qty, aid
from (
  select *, max(version) over (partition by AId) as latestVersion 
  from B
) as B
where version = latestVersion

, чтобы подвести итог

select tId, SUM(qty) AS qty_sum
from (
  select *, max(version) over (partition by AId) as latestVersion 
  from B
) as B
join A on B.AId = A.id
where version = latestVersion
group by tId
0 голосов
/ 26 апреля 2018

я думаю, что этот запрос поможет вам решить вашу проблему

    SELECT itemId, version, qty , AId FROM (
      SELECT itemId, version, qty , AId FROM b 
      LEFT JOIN a ON (b.aid = a.id)
    ) temp
    WHERE version = (SELECT MAX(version) FROM b WHERE b.aid = temp.aid)
   and temp.tid = 100 and temp.itemId = 44
0 голосов
/ 26 апреля 2018

Рабочий раствор

select b.* from B as b
inner join 
 (select AID,itemId,Max(version) as mVersion from B 
  group by AID,itemID) d 
on b.AID = d.AID and b.itemID = d.itemID and b.Version = d.mVersion
inner join A as a
on B.AID = a.id
where b.itemID = 44 --apply if you need 

результат

itemid  version qty aid
44         2    2   200
44         1    2   201

это даст вам результат в виде суммы количества

select itemID,sum(qty) from (
select b.* from B as b
inner join 
 (select AID,itemId,Max(version) as mVersion from B 
  group by AID,itemID) d 
on b.AID = d.AID and b.itemID = d.itemID and b.Version = d.mVersion
inner join A as a
on B.AID = a.id
where b.itemID = 44 --apply if you need 
) e group by itemID

результат

itemid  sum
44       4
0 голосов
/ 26 апреля 2018

Попробуйте это

DECLARE @TA Table (id int,tid int)
DECLARE @TB Table (itemid int, version int,qty int,AID int)

INSERT INTO @TA
SELECT 200, 100
UNION ALL
SELECT 201, 100


INSERT INTO @TB
SELECT 44,1,1,201
UNION ALL
SELECT 44,1,2,200
UNION ALL
SELECT 44,2,3,200
UNION ALL
SELECT 44,2,5,201


DECLARE @tid int
SET @tid = 100

SELECT XB.* FROM @Tb XB INNER JOIN
(SELECT Version,Max(AID) Aid FROM @TA A INNER JOIN @TB B ON A.id = B.AID AND tid = @tid Group By Version) X
ON X.version = XB.version and XB.AID = X.Aid
0 голосов
/ 26 апреля 2018
SELECT B.*
FROM B
INNER JOIN
(SELECT Aid,MAX(version) AS version FROM B WHERE itemId=44 GROUP BY AId) AS B1
ON B.Aid=B1.Aid 
AND B.version=B1.version
INNER JOIN
(SELECT * FROM A WHERE tId=100) AS A
ON A.id=B.Aid
Order BY B.aid

Для суммы кол-во

SELECT SUM(B.qty)
FROM B
INNER JOIN
(SELECT Aid,MAX(version) AS version FROM B WHERE itemId=44 GROUP BY AId) AS B1
ON B.Aid=B1.Aid AND B.version=B1.version
INNER JOIN
(SELECT * FROM A WHERE tId=100) AS A
ON A.id=B.Aid
GROUP BY A.tid

Выход

itemid  version qty aid
44      2       2   200
44      1       2   201

Демо

http://sqlfiddle.com/#!17/092dd/5

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...