I have two cubes lets say c1,c2 and I have to make adjustments from c2 to c1
In c1 I have
loan_id
basis_adjutment
participant_pct
2345
123
346
In c2 I have
loan_id
adj_element
txn_amt
2345
bal
678
2345
bal
984
2345
bal
2435
2345
gain
676
2345
gain
7689
2345
gain
234
When adj_element = bal i should take the corresponding txn_amt and print in basis_adjutment and When adj_element = gain I should take the corresponding txn_amt and print in participant_pct. the joining keys is loan_id The output look like
loan_id
basis_adjutment
participant_pct
2345
123
346
2345
678
676
2345
984
7689
2345
2435
234
in total there should be 4 rows( 1 row from c1 and 3 rows from c2 no additional rows. ) can anyone help me out how I can achieve this in hive
Could you please try this SQL -
select loan_id, basis_adjutment, participant_pct from c1
union all
select distinct -- distinct will ensure no duplicates
c1.loan_id,
case when adj_element = 'bal' then txn_amt end basis_adjutment,
case when adj_element = 'gain' then txn_amt end participant_pct
from c1
join c2 on c1.loan_id = c2.loan_id
Related
I have data in Telephone table, something as below:
ID
area
exch
line
ext
tel_type_cde
tel_seq_num
modified_dttm
1234
482
876
789
1234
0
0
01-01-2023
1234
483
877
123
0
1
01-02-2023
1234
123
234
456
1234
1
0
01-01-2023
1235
483
877
456
0
1
01-01-2023
1236
483
877
123
0
0
01-02-2023
1236
123
234
456
1234
0
1
01-02-2023
1236
483
877
458
0
2
01-03-2023
For an ID/tel_type_cde combination there might be multiple rows and telephone sequence number is used to derive from latest number which needs to considered further
Expected output
ID
area
exch
line
ext
tel_type_cde
1234
483
877
123
0
1234
123
234
456
1234
1
1235
483
877
456
0
1236
483
877
458
0
Drafted below query so far, but not working as expected
select distinct on (ID)
ID,
area,
exch,
line,
ext,
tel_type_cde
from telephone
order by ID,tel_seq_num desc;
Appreciate any help!
try this :
SELECT DISTINCT ON (id, tel_type_cde)
id, area, exch, line, ext, tel_type_cde
FROM telephone
ORDER BY id, tel_type_cde, tel_seq_num DESC ;
You can use the RANK window function with a common table expression to get the expected results
WITH cte AS (
SELECT ID, area, exch, line, ext, tel_type_cde, RANK() OVER (PARTITION BY id, tel_type_cde ORDER BY tel_seq_num DESC) as r
FROM telephone
)
SELECT
ID, area, exch, line, ext, tel_type_cde
FROM cte
WHERE r = 1;
Fiddle
I'm looking at different blockchain transactions and wanted to create a running balance of a given asset based on INPUT_ADDRESS (the address sending the currency) INPUT_AMOUNT (the amount being sent by an INPUT_ADDRESS), OUTPUT_ADDRESS (the address receiving the currency) and OUTPUT_AMOUNT (the amount being received by an OUTPUT_ADDRESS)
Here's a sample of a table I'm using:
BLOCK_DATE | BLOCK_HEIGHT | TRANS_HASH | INPUT_ADDRESS | OUTPUT_ADDRESS | INPUT_AMOUNT | OUTPUT_AMOUNT
01/11/2020 190 15c7853 abc xyz1 -0.01 0.0001
01/11/2020 190 14v9876 abc xyz2 -0.50 0.70
01/11/2020 191 19vc842 abc xyz3 -5.03 0.413
01/12/2020 192 20ff4d3 abc xyz4 -0.06 0.201
01/12/2020 192 154gf34 xyz1 abc -0.07 0.18
01/12/2020 192 45f4ti5 ggg abc -0.10 0.24
01/12/2020 192 33cv5c5 jjj abc -0.08 1.13
If I were to calculate a running sum of address abc, what's an efficient way of going about this? I tried using something like:
SELECT BLOCK_DATE, BLOCK_HEIGHT, TRANS_HASH, INPUT_ADDRESS, OUTPUT_ADDRESS, INPUT_AMOUNT, OUTPUT_AMOUNT, SUM (INPUT_AMOUNT) OVER (ORDER BY DATE) AS RunningAgeTotal
FROM TRANSACTION_TABLE
WHERE INPUT_ADDRESS = abc
In this particular example, the total balance for abc would be the sum of OUTPUT_AMOUNT where abc is the OUTPUT_ADDRESS (i.e 0.18 + 0.24 + 1.13) + the sum of INPUT_AMOUNT where abc is the INPUT_ADDRESS (i.e. -0.01 + -0.50 + -5.03 + -0.06). So, 1.55 + (-5.60) = -4.05
But I don't think this is the right way of going about this and I'm not sure how to account for the OUTPUT_AMOUNT (e.g. when abc receives is an OUTPUT_ADDRESS and receives an OUTPUT_AMOUNT)
Is this what you want?
select t.*,
sum(case when input_address = 'ABC' then input_amount
when output_address = 'ABC' then output_amount
end) over (order by block_date) as running_amount
from transaction_table t
where 'ABC' in (input_address, output_address);
This is a cumulative sum of the amounts aligned with the input/output columns.
EDIT:
You may want:
sum(case when input_address = 'ABC' then input_amount
when output_address = 'ABC' then output_amount
end) over (order by block_date, block_height) as running_amount
I'm looking for the best way to produce the result set in the scenario provided. My cust3 column isn't identifying the repeated values in the indvid2 column. The end result I'm looking for is to exclude the rows where key1 and key2 match (ids:1,2,6 and 7), then sum accounts where the acctids match.If there's a better way to code this, I welcome all suggestions. Thanks!
WITH T10 as (
SELECT acctid,invid,(
case
when invid like '%-R' then left (InvID,LEN(invid) -2) else InvID
END) as InvID2
FROM table x
GROUP BY acctID,invID
),
T11 as (
SELECT acctid, Invid2, COUNT(InvID2) as cust3
FROM T10
GROUP BY InvID2,acctid
HAVING
COUNT (InvID2) > 1
)
select DISTINCT
a.acctid,
a.name,
b.invid,
C.invid2,
D.cust3,
b.amt,
b.key1,
b.key2
from table a
inner join table b (nolock) on a.acctid = b.acctid
inner join T10 C (nolock) on b.invid = c.invid
inner join T11 D (nolock) on C.invid2 = D.invid2
Resultset
id acctID name invid invid2 Cust3 amt key1 key2
1 123 James 101 101 2 $500 NULL 6789
2 123 james 101-R 101 2 ($500) 6789 NULL
3 123 James 102 102 2 $350 NULL NULL
4 123 James 103 103 2 $200 NULL NULL
5 246 Tony 98-R 98 2 ($750) 7423 NULL
6 432 David 45 45 2 $100 NULL 9634
7 432 David 45-R 45 2 ($100) 9634 NULL
8 359 Stan 39-R 39 2 ($50) 6157 NULL
9 753 George 95 95 2 $365 NULL NULL
10 753 George 108 108 2 $100 NULL NULL
Desired Resultset
id acctID name invid invid2 Cust3 amt key1 key2
1 123 James 101 101 2 $500 NULL 6789
2 123 james 101-R 101 2 ($500) 6789 NULL
3 123 James 102 102 1 $350 NULL NULL
4 123 James 103 103 1 $200 NULL NULL
5 246 Tony 98-R 98 1 ($750) 7423 NULL
6 432 David 45 45 2 $100 NULL 9634
7 432 David 45-R 45 2 ($100) 9634 NULL
8 359 Stan 39-R 39 1 ($50) 6157 NULL
9 753 George 95 95 1 $365 NULL NULL
10 753 George 108 108 1 $100 NULL NULL
Then to sum amt by acctid
id acctid name amt
1 123 James $550
2 246 Tony ($750)
3 359 Stan ($50)
4 753 George $465
Something like:
;WITH Keys as (
SELECT Key1.acctID, [Key] = Key1.Key1
FROM YourTable as Key1
INNER JOIN YourTable as Key2
ON Key1.Key1 = Key2.Key2 and Key1.acctID = Key2.acctID
)
SELECT t.acctID, t.name, amt = SUM(t.amt)
FROM YourTable as t
LEFT JOIN Keys as k
ON t.acctID = k.acctID and (t.Key1 = [Key] or t.Key2 = [Key])
WHERE k.acctID is Null
GROUP BY t.acctID, t.name
I am working with a Raiser's Edge database using SQL Server 2005. I have written SQL that will produce a temporary table containing details of direct debit instalments. Below is a small table containing the key variables for the question I'm going to ask, with some fictional data:
Donor_ID Instalment_ID Instalment_Date Amount
1234 1111 01/01/2011 £5.00
1234 1112 01/02/2011 £0.00
1234 1113 01/03/2011 £5.00
1234 1114 01/04/2011 £5.00
1234 1115 01/05/2011 £0.00
1234 1116 01/06/2011 £0.00
2345 2111 01/01/2011 £0.00
2345 2112 01/02/2011 £5.00
2345 2113 01/03/2011 £5.00
2345 2114 01/04/2011 £0.00
2345 2115 01/05/2011 £0.00
2345 2116 01/06/2011 £0.00
As you will see, some of the values in the Amount column are £0.00. This can occur when a donor has insufficient funds in their account, for example.
What I'd like to do is write a SQL query that will create a field containing an incremental count of consecutive £0.00 payments that resets after a non-£0.00 payment or after a change in Donor_ID. I have reproduced the above data below, with the field I'd like to see.
Donor_ID Instalment_ID Instalment_Date Amount New_Field
1234 1111 01/01/2011 £5.00
1234 1112 01/02/2011 £0.00 1
1234 1113 01/03/2011 £5.00
1234 1114 01/04/2011 £5.00
1234 1115 01/05/2011 £0.00 1
1234 1116 01/06/2011 £0.00 2
2345 2111 01/01/2011 £0.00 1
2345 2112 01/02/2011 £5.00
2345 2113 01/03/2011 £5.00
2345 2114 01/04/2011 £0.00 1
2345 2115 01/05/2011 £0.00 2
2345 2116 01/06/2011 £0.00 3
To help clarify what I'm looking for, I think what I'm looking to do would be similar to a winning streak field on a list of a football team's results. For example:
Opponent Score Winning_Streak
Arsenal 1-0 1
Liverpool 0-0
Swansea 3-1 1
Chelsea 2-1 2
Fulham 4-0 3
Stoke 0-0
Man Utd 1-3
Reading 2-1 1
I've considered various options, but have made no progress. Unless I've missed something obvious, I think that a solution more advanced than my current SQL programming level might be required.
If I am thinking about this problem correctly, I believe that you want a row number when the Amount is 0.00 pounds.
Select 0 as As InsufficientCount
, Donor_ID
, Installment_ID
, Amount
From [Table]
Where Amount > 0.00
Union
Select Row_Number() Over (Partition By Donor_ID Order By Installment_ID)
, Donor_ID
, Installment_ID
, Amount
From [Table]
Where Amount = 0.00
This union select should only give you 'ranks' where the Amount equals 0.
Am calling your new field streakAmount
ALTER TABLE instalments ADD streakAmount int NULL;
Then, to update the value:
UPDATE instalments
SET streakAmount =
(SELECT
COUNT(*)
FROM
instalments streak
WHERE
streak.donor_id = instalments.donor_id
AND
streak.instalment_date <= instalments.instalment_date
AND
(streak.instalment_date >
-- find previous instalment date, if any exists
COALESCE(
(
SELECT
MAX(instalment_date)
FROM
instalments prev
WHERE
prev.donor_id = instalments.donor_id
AND
prev.amount > 0
AND
prev.instalment_date < instalments.instalment_date
)
-- otherwise min date
, cast('1753-1-1' AS date))
)
)
WHERE
amount = 0;
http://sqlfiddle.com/#!6/a571f/18
i am really struggling with this pivot and hoped reaching out for help and enlightenment might help.
Say i have the following table....
Table A
type actId date rowSort order value value_char colName
------------------------------------------------------------------------------------
checking 1003 2011-12-31 2 1 44 44 Amount
checking 1003 2011-12-31 2 2 55 55 Interest
checking 1003 2011-12-31 2 3 66 66 Change
checking 1003 2011-12-31 2 4 77 77 Target
checking 1003 2011-12-31 2 5 88 88 Spread
savings 23456 2011-12-31 1 1 999 999 Amount
savings 23456 2011-12-31 1 2 888 888 Interest
savings 23456 2011-12-31 1 3 777 777 Change
savings 23456 2011-12-31 1 4 666 666 Target
savings 23456 2011-12-31 1 5 555 555 Spread
And i want to transpose to table b
checking chkId date rowSort order chkvalue chkValchar colName savings savId savVal savValChar
-------------------------------------------------------------------------------------------------------------------
checking 1003 2011-12-31 2 1 44 44 Amount savings 23456 999 999
checking 1003 2011-12-31 2 2 55 55 Interest savings 23456 888 888
checking 1003 2011-12-31 2 3 66 66 Change savings 23456 777 777
checking 1003 2011-12-31 2 4 77 77 Target savings 23456 666 666
checking 1003 2011-12-31 2 5 88 88 Spread savings 23456 555 555
I can admit this is beyond my skills at the moment.
I believe i need to do a pivot on this table, using the rowSort (identify savings vs checking) along with ordering using the order column. This maybe wrong and that is why i am here.
Is a pivot the right way to go? Am i right to assume my pivot is to use the aggregate max(rowSort)?
Assuming rowSort from `checking equal to rowSort+1 from savings and the rows link though field value, this should do it:
SELECT DISTINCT
a.type as checking,
a.actId as chkId,
a.date,
a.rowSort+1,
a.order,
a.value as chkvalue,
a.value_char as chkValchar,
a.colName,
b.type as 'savings',
a.actId as savId,
b.value as savVal,
b.value_char as savValChar
FROM tablea a
INNER JOIN tablea b ON b.rowSort = a.rowSort+1 and b.value = a.value
Based on the requirements you presented, you will not use a PIVOT for this query, you will want to JOIN your table to itself. The query below should give you the records that you want without having to use a DISTINCT
select c.type as checking
, c.actId as chkid
, c.date
, c.rowsort
, c.[order]
, c.value as chkvalue
, c.value_char as chkValchar
, c.colName
, s.type as savings
, s.actId as savId
, s.value as savVal
, s.value_char as savValchar
from t1 c
inner join t1 s
on c.rowsort = s.rowsort + 1
and c.[order] = s.[order]
See SQL Fiddle with Demo