sql join table,没有提供完美的结果

时间:2018-04-26 05:01:32

标签: sql postgresql tsql

让我解释一下我需要什么,我有2个名为A和B的表.B是A的子表。

这是Schema:

------------------------
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

Sum(qty)的结果必须为4,因为它们具有相同的tId并且在每个AId中都有Max版本。

6 个答案:

答案 0 :(得分:1)

使用窗口功能。

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

试试这个

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

答案 3 :(得分:0)

工作解决方案

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

答案 4 :(得分:0)

我认为此查询可以帮助您解决问题

    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

答案 5 :(得分:0)

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