![](/img/trans.png)
[英]How to join 2 tables with getting all rows from left table and only matching ones in right
[英]Compare Rows in oracle table and update matching ones
我有如下表格:
**ID tDate Product Price Quantity BuySell Status**
1 10-May-17 pppp $12 20 Buy Null
2 12-May-17 tttt $10 20 Sell Null
3 12-May-17 tttt $10 20 Buy Null
4 18-May-17 pppp $14 20 Sell Null
5 18-May-17 pppp $14 20 Buy Null
6 18-May-17 pppp $14 20 Sell Null
我需要更新名為STATUS的字段,並將其設置為“ Matched”,無論在哪里找到一對具有相等tDate,產品,價格和數量且不等於BuySell的貨幣。
以下是所需的結果:
**ID tDate Product Price Quantity BuySell Status**
1 10-May-17 pppp $12 20 Buy Null
2 12-May-17 tttt $10 20 Sell Matched
3 12-May-17 tttt $10 20 Buy Matched
4 18-May-17 pppp $14 20 Sell Matched
5 18-May-17 pppp $14 20 Buy Matched
6 18-May-17 pppp $14 20 Sell Null
注意#6如何不匹配,因為它只能與另一個null匹配。
我希望我可以用一個SQL語句執行此操作。
我現在正在做的事情可能是最糟糕的方法:我在python中加載到pandas數據幀中,然后循環比較每一行。
s = "SELECT ID, Account, product, Price, tDate, BuySell, Qty" + \
"FROM Table " + \
"WHERE Status IS NULL " + \
"ORDER BY Account, product, tDate, Price, Qty"
df = pd.read_sql(s, conn)
for i in range(len(df.index)-1):
if df.iloc[i, 1] == df.iloc[i+1, 1] \
and df.iloc[i, 2] == df.iloc[i+1, 2] \
and df.iloc[i, 3] == df.iloc[i+1, 3] \
and df.iloc[i, 4] == df.iloc[i+1, 4] \
and df.iloc[i, 5] != df.iloc[i+1, 5] \
and df.iloc[i, 6] == df.iloc[i+1, 6]:
s = "UPDATE Temp_Fees " + \
"SET Strategy = 'UNALLOCATED \ CANCELLED' " + \
"WHERE ID = " + str(df.iloc[i,0]) + \
" OR ID = " + str(df.iloc[i + 1, 0])
#custom function that will execute and commit statement
bb.EXECUTE(s)
#avoid reading a matched row
i = i + 1
謝謝
未經測試,但僅使用SQL的情況如下:
MERGE INTO your_table dst
USING (
SELECT ROW_NUMBER() OVER (
PARTITION BY tDate, Product, Price, Quantity, BuySell
ORDER BY ID
) AS idx,
COUNT( CASE BuySell WHEN 'Buy' THEN 1 END ) OVER (
PARTITION BY tDate, Product, Price, Quantity
) AS num_buy,
COUNT( CASE BuySell WHEN 'Sell' THEN 1 END ) OVER (
PARTITION BY tDate, Product, Price, Quantity
) AS num_sell
FROM your_table
) src
ON ( src.ROWID = dst.ROWID AND src.idx <= LEAST( src.num_buy, src.num_sell ) )
WHEN MATCHED THEN
UPDATE SET Status = 'Matched';
您可以獲取每個tdate的買賣對數並更新此類行。
MERGE INTO tablename dst
USING (select t.*,count(*) over(partition by tDate,Product,Price,Quantity,rn) as cnt
from (select t.*,row_number() over(partition by tDate,Product,Price,Quantity,buysell order by id) as rn
from tablename t) t
) src
ON (src.id = dst.id AND src.cnt=2)
WHEN MATCHED THEN
UPDATE SET Status = 'Matched';
運行此查詢以查看行號如何分配給買賣。
select t.*,count(*) over(partition by tDate,Product,Price,Quantity,rn) as cnt
from (select t.*,row_number() over(partition by tDate,Product,Price,Quantity,buysell order by id) as rn
from tablename t) t
這是添加到其他視圖的另一種觀點。 這僅解決匹配部分,而不解決更新或合並部分。 最近,我遇到了類似的問題,我需要查找與交易日期和位置匹配的記錄,但它們來自兩個不同的來源。 在這種情況下,必須對記錄進行排序,以便將類似的記錄放在一起。 內部查詢將記錄與之前的記錄和之后的記錄進行比較,如果它們匹配,則將其抓取。 然后,外部查詢確定它們是否滿足“差異”條件。 希望這可以幫助。
select sbs.trnsid, sbs.amount, sbs.transaction_date, sbs.posted_date, sbs.srcid,
sbs.credited_flag, sbs.accid, sbs.compid, sbs.badgeid, sbs.locid, sbs.date_credited,
sbs.searchable, sbs.priortime, sbs.nexttime, sbs.priorsource, sbs.nextsource
from
(select trnsid, amount, transaction_date, posted_date, srcid, credited_flag,
accid, compid, badgeid, locid, date_credited, transaction_date||locid as searchable,
lag(transaction_date||locid, 1) over (order by accid) as priortime,
lead(transaction_date||locid, 1) over (order by accid) as nexttime,
lag(srcid, 1) over (order by accid) as priorsource,
lead(srcid, 1) over (order by accid) as nextsource
from transactions_table
where accid = v_acct
and transaction_date >= to_date('10/01/2016 00:00:00', 'mm/dd/yyyy hh24:mi:ss')
and transaction_date <= to_date('04/23/2017 23:59:59', 'mm/dd/yyyy hh24:mi:ss')
and srcid in ('B', 'S') order by accid, transaction_date, locid) sbs
where (sbs.searchable = sbs.nexttime and sbs.srcid = 'S' and sbs.nextsource = 'B')
or (sbs.searchable = sbs.priortime and sbs.srcid = 'B' and sbs.priorsource = 'S');
merge into mytable t3
using (select t1.*, count(*) over (partition by tdate,product,price,quantity,field) as field2 from
(
select mytable.*, row_number() over (partition by mytable.tdate,mytable.product,mytable.price,mytable.quantity,mytable.buysell
order by id) field from
mytable) t1) t2
on (t2.id=t3.id and t2.field2='2')
when matched then
update set status='Matched';
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.