编辑:我正在使用SQL Server 2014
我需要编写一个查询以仅返回行数,其中行数的总和覆盖其他表中的行数。
我正在处理两个表。库存表和购买历史表。我想从购买历史记录表中返回特定库存项目的行,其中所述行中的总和覆盖库存表中的现有数量,按最新的购买日期到最早的日期排序。
示例:
库存表
-------------------
| SKU | Quantity |
-------------------
| 1234 | 10 |
-------------------
购买历史记录表
--------------------------------
| SKU | Quantity | Date |
--------------------------------
| 1234 | 5 | 2019-01-01 |
| 1234 | 3 | 2018-12-01 |
| 1234 | 9 | 2018-11-01 |
| 1234 | 4 | 2018-10-01 |
| 1234 | 12 | 2018-09-01 |
--------------------------------
这是我期望的结果
--------------------------------
| SKU | Quantity | Date |
--------------------------------
| 1234 | 5 | 2019-01-01 |
| 1234 | 3 | 2018-12-01 |
| 1234 | 9 | 2018-11-01 |
--------------------------------
因为5 + 3 + 9涵盖了我们库存中的10。
也许我缺少一些简单的东西,但我只是想不出如何使结果停在第三条记录上。
此外,如果可能的话,我真的更希望避免使用循环。
任何帮助将不胜感激,因为我只是无法将头缠在这个头上。
答案 0 :(得分:1)
另一个选择是交叉申请
示例
final ListAdapter adapter = new SimpleAdapter(
MainActivity.this,
resultsdatalist,
R.layout.list_item,
new String[]{"resultid", "result"},
new int[]{R.id.resultid, R.id.result}) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
return view;
}
};
lv.setAdapter(adapter);
答案 1 :(得分:0)
我认为您可能可以执行以下操作(未经测试):
SELECT ph.sku, ph.quantity, ph.date
FROM
(SELECT
purchasehistory.*,
SUM(quantity) OVER (PARTITION BY sku ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as tquantity
FROM purchasehistory) ph inner join inventory i
on ph.sku = i.sku
WHERE
ph.tquantity <= i.quantity
这里的想法是在内部查询中计算运行总和,然后与库存表联接。我已经对ORDER BY日期进行了假设,但是您可以进行调整。
编辑:因此,基于注释,您希望前N行使用所有库存(而不是不超过库存的前N行),我认为您可以执行以下操作:
SELECT ph.sku, ph.quantity, ph.date
FROM
(SELECT
purchasehistory.*,
SUM(quantity) OVER (PARTITION BY sku ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) as tquantity
FROM purchasehistory) ph inner join inventory i
on ph.sku = i.sku
WHERE
ph.tquantity < i.quantity
这是相同的基本思想,但是运行总和被切换为仅对前一行进行计数(不包括当前行),并且联接使用<而不是<=。这样,如果前一行的数量尚未总计到库存中,则将包括下一行(即使该总数现在已超过库存)。
答案 2 :(得分:0)
您可以使用INNER JOIN来完成
在对行求和时,我使用IIF将当前行的总和设置为零,因为我不想在检查中包括该行
begin try drop table #Phistory end try begin catch end catch;
begin try drop table #inventory end try begin catch end catch;
SELECT 1234 SKU,5 Quantity, cast('20190101' as date) [date] into #Phistory;
INSERT #Phistory (SKU, Quantity,[date]) VALUES (1234,3,'20181201'), (1234,9,'20181101'),(1234,4,'20181001'),(1234,12,'20180901'),(1235,3,'20181201'), (1235,9,'20181101'),(1235,4,'20181001'),(1235,12,'20180901'),(1235,500,'20180801'),(1235,50,'20180601');
select 1234 SKU, 10 quantity into #inventory;
insert #inventory values(1235,99);
SELECT p1.SKU,
p1.Quantity,
p1.[Date],
SUM(p2.quantity) RunningTotal
FROM #Phistory p1
JOIN #PHistory p2
ON p1.SKU = p2.sku and p2.date >= p1.date
GROUP BY p1.SKU,
p1.Quantity,
p1.[Date]
HAVING SUM(IIF(p1.date = p2.date , 0 , p2.quantity))
<= (SELECT inv.quantity from #inventory inv where inv.sku = p1.sku)
order by p1.sku,p1.date DESC;