Я считаю, что синтаксис предыдущих ответов является избыточным и трудно запоминаемым. Пандас представил метод query()
в v0.13, и я предпочитаю его. Для вашего вопроса вы можете сделать df.query('col == val')
Воспроизводится из http://pandas.pydata.org/pandas-docs/version/0.17.0/indexing.html#indexing-query
In [167]: n = 10
In [168]: df = pd.DataFrame(np.random.rand(n, 3), columns=list('abc'))
In [169]: df
Out[169]:
a b c
0 0.687704 0.582314 0.281645
1 0.250846 0.610021 0.420121
2 0.624328 0.401816 0.932146
3 0.011763 0.022921 0.244186
4 0.590198 0.325680 0.890392
5 0.598892 0.296424 0.007312
6 0.634625 0.803069 0.123872
7 0.924168 0.325076 0.303746
8 0.116822 0.364564 0.454607
9 0.986142 0.751953 0.561512
# pure python
In [170]: df[(df.a < df.b) & (df.b < df.c)]
Out[170]:
a b c
3 0.011763 0.022921 0.244186
8 0.116822 0.364564 0.454607
# query
In [171]: df.query('(a < b) & (b < c)')
Out[171]:
a b c
3 0.011763 0.022921 0.244186
8 0.116822 0.364564 0.454607
Вы также можете получить доступ к переменным в среде, добавив @
.
exclude = ('red', 'orange')
df.query('color not in @exclude')
Другой вариант - CROSS APPLY
Пример
Select B.*
From Inventory A
Cross Apply (
Select *
From (
Select *,RB = sum([Quantity]) over (Partition By SKU Order by Date Desc) - Quantity
From Purchase
Where SKU=A.SKU
) B1
Where RB<=A.Quantity
) B
вы можете сделать это с помощью INNER JOIN
при суммировании строк, я использую IIF для установки текущей строки на ноль в сумме, потому что я не хочу включать это в проверку [112 ]
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;
Я думаю, что вы, вероятно, могли бы сделать что-то вроде следующего (непроверенного):
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 строк, которые не превышают ваш инвентарь), я думаю, вы могли бы сделать что-то вроде:
[ 111]Это та же основная идея, но текущая сумма переключается только на подсчет предыдущих строк (не включая текущую строку), и соединение использует < а не < =. Таким образом, если количество предыдущих строк еще не составило инвентаризации, вы включите следующую строку (даже если эта сумма в настоящее время превышает запасы).