Update fields using Self Join - Teradata - join

I want to update CHAT_ACTIVITY_ID & CHAT_SMS_IND field in a table ABC.PERFORM_METRICS_F(History correction) using INTERACTION_SOURCE_KEY based on below criteria:
If CHAT_ACTIVITY_ID is NULL, update it with the CHAT_ACTIVITY_ID which is not null for that INTERACTION_SOURCE_KEY
Update CHAT_SMS_IND with the value that is present for not null CHAT_ACTIVITY_ID field. (Here for first example we will update 0 by 1 for INTERACTION SOURCE KEY - 21945)
Primary Index of the table ABC.PERFORM_METRICS_F: METRIC_SOURCE_KEY, METRIC_SOURCE, CALENDAR_DATE
I have tried something like below:
UPDATE A
FROM
(SEL * FROM ABC.PERFORM_METRICS_F WHERE CHAT_ACTIVITY_ID IS NULL) A,
(SEL * FROM ABC.PERFORM_METRICS_F WHERE CHAT_ACTIVITY_ID IS NOT NULL) B
SET CHAT_ACTIVITY_ID = B.CHAT_ACTIVITY_ID, CHAT_SMS_IND = B.CHAT_SMS_IND
WHERE A.INTERACTION_SOURCE_KEY = B.INTERACTION_SOURCE_KEY
AND A.INTERACTION_SOURCE_KEY IN ('21945','22045','22847');
Sample Data:
METRIC_SOURCE_KEY METRIC_SOURCE INTERACTION_SOURCE_KEY CHAT_ACTIVITY_ID CHAT_SMS_IND CALENDAR_DATE EXPECTED RESULT(NOTE)
21945 3 21945 6534908765426 1 2022-05-29
39827 4 21945 ? 0 2022-05-30 CHAT_ACTIVITY_ID & CHAT_SMS_IND should be carried down to this row
22045 3 22045 7345628390255 1 2022-06-15
25430 2 22045 ? 0 2022-06-17 CHAT_ACTIVITY_ID & CHAT_SMS_IND should be carried down to this row
22847 3 22847 6427690875346 1 2022-06-06
43216 4 22847 ? 0 2022-06-06 CHAT_ACTIVITY_ID & CHAT_SMS_IND should be carried down to this row
49567 2 22847 ? 0 2022-06-07 CHAT_ACTIVITY_ID & CHAT_SMS_IND should be carried down to this row
47289 2 22847 ? 0 2022-06-06 CHAT_ACTIVITY_ID & CHAT_SMS_IND should be carried down to this row

First, you want a subquery that returns a single row for each key, containing the values to apply to the rows with NULL. Then use that subquery as the source of the UPDATE. (Note that the target of the UPDATE should be a table not a subquery).
UPDATE A
FROM
ABC.PERFORM_METRICS_F A,
(SELECT INTERACTION_SOURCE_KEY, CHAT_ACTIVITY_ID, CHAT_SMS_IND
FROM ABC.PERFORM_METRICS_F
WHERE CHAT_ACTIVITY_ID IS NOT NULL
/* Ensure only one row per INTERACTION_SOURCE_KEY */
/* ORDER BY is required for ROW_NUMBER */
QUALIFY ROW_NUMBER() OVER (PARTITION BY INTERACTION_SOURCE_KEY ORDER BY CALENDAR_DATE DESC) = 1
) B
SET CHAT_ACTIVITY_ID = B.CHAT_ACTIVITY_ID, CHAT_SMS_IND = B.CHAT_SMS_IND
WHERE A.INTERACTION_SOURCE_KEY = B.INTERACTION_SOURCE_KEY
AND A.CHAT_ACTIVITY_ID IS NULL;
If you are certain there is only one non-NULL row per key, then you don't need the QUALIFY clause in the subquery.

Related

Google Sheets: I'd like a formula that will lookup an ID in a table, then count the number of non-blank cells in a range

For example, I would like the formula to lookup the UID 4119.502914 and count the number of non-blank cells in the range C2:G2. The result would be 0 in this case.
Here is the data table:
UID
Active since
Level A1 result
Level A2 result
Level B1 result
Level B2 result
Level C1 result
4119.502914
16/03/2022
32502.84434
16/03/2022
3439.094252
21/03/2022
B
78344.29029
05/08/2022
82511.53052
24/05/2022
40939.00908
16/03/2022
A
A+
A
A+
19481.28071
30/03/2022
6259.532774
04/08/2022
13352.59697
04/08/2022
A+
C
54786.31186
18/03/2022
82548.2726
16/03/2022
B+
B+
50125.47835
04/08/2022
27984.35676
04/08/2022
A
Here is the expected result:
UID
Count
4119.502914
0
32502.84434
0
3439.094252
1
78344.29029
0
82511.53052
0
40939.00908
4
19481.28071
0
6259.532774
0
13352.59697
2
54786.31186
0
82548.2726
2
50125.47835
0
27984.35676
1
Could try the following formula-
=COUNTIFS(INDEX($C$3:$G$15,XMATCH(H3,$A$3:$A$15)),"<>")

Query Function Order by problem Google Sheets

I already have the first part of the query ready, But I would like to order it with the newest date first. Can you please help!
=QUERY(Sheet3!A:I, "
SELECT D, -1 * SUM(I)
GROUP BY D
LABEL -1 * SUM(I) 'Balance Diario'
FORMAT D 'yyyy-MMM-dd',
-1 * SUM(I) '$#,##0.00'
")
Is this were you looking for?
=QUERY(Sheet3!A:I, "
SELECT D, -1 * SUM(I)
GROUP BY D
ORDER BY D DESC
LABEL -1 * SUM(I) 'Balance Diario'
FORMAT D 'yyyy-MMM-dd',
-1 * SUM(I) '$#,##0.00'
")
Put more ORDER BY D ASCorDESC
DESC is to reverse the order

How to count 2 columns with a range

A B C
Val 1 2
Val 2 1
Val 3 1
Item 1 Val 1 1
Item 2 Val 2 1
Item 3 Val 3 0
Item 4 Val 1 0
Consider the above sheet. In the first 3 rows I am counting how many times corresponding val# shows up in the sheet. I have done that with: =COUNTIF($B$5:$B, A1) However, I can't figure out how to make it count only if the value matches and column C doesn't have a 1 next to it on same row. Is this possible?
try COUNTIFS:
=COUNTIFS(B$5:B, A1, C$5:C, "<>"&1)
make sure C column is formatted as Number

SQLite LEFT JOIN count(*)?

I need to join two tables (well, actually two views) so that for every selected row of the left view, there is a count of rows from the right view. That sounds to me like a LEFT JOIN, but in SQLite (this test database) and a LEFT JOIN query:
SELECT TARGET.session_id session_id, TARGET.labeltype_id labeltype_id, TARGET.label_id label_id, count(SECONDARY.label_id) NOlabels
FROM segment_extended TARGET LEFT JOIN segment_extended SECONDARY
WHERE TARGET.session_id = SECONDARY.session_id AND TARGET.lt_name= "Word" AND SECONDARY.lt_name ="Comments"
AND ((SECONDARY.start <= TARGET.start AND TARGET.END <= SECONDARY.END) OR (TARGET.start <= SECONDARY.start AND SECONDARY.END <= TARGET.END))
AND TARGET.label != '' AND SECONDARY.label != ''
GROUP BY TARGET.session_id,TARGET.labeltype_id, TARGET.label_id;
I get only a small subset of what I would expect:
2 3 3 1
2 3 9 1
A more extended query gives the correct result:
SELECT session_id, labeltype_id, label_id, max(NOlabels) NOlabels
FROM (SELECT TARGET.session_id session_id, TARGET.labeltype_id labeltype_id, TARGET.label_id label_id, count(SECONDARY.label_id) NOlabels
FROM segment_extended TARGET , segment_extended SECONDARY
WHERE TARGET.session_id = SECONDARY.session_id AND TARGET.lt_name= "Word" AND SECONDARY.lt_name ="Comments"
AND ((SECONDARY.start <= TARGET.start AND TARGET.END <= SECONDARY.END) OR (TARGET.start <= SECONDARY.start AND SECONDARY.END <= TARGET.END))
AND TARGET.label != '' AND SECONDARY.label != ''
GROUP BY TARGET.session_id,TARGET.labeltype_id, TARGET.label_id
UNION
SELECT TARGET.session_id session_id, TARGET.labeltype_id labeltype_id, TARGET.label_id label_id, 0 NOlabels
FROM segment_extended TARGET
WHERE TARGET.lt_name= "Word"
AND TARGET.label != ''
GROUP BY TARGET.session_id,TARGET.labeltype_id, TARGET.label_id)
GROUP BY session_id, labeltype_id, label_id
ORDER BY session_id,labeltype_id, label_id
session_id labeltype_id label_id NOlabels
2 3 2 0
2 3 3 1
2 3 4 0
2 3 5 0
2 3 7 0
2 3 8 0
2 3 9 1
2 3 10 0
but it seems unnecessarily complicated. What am I doing wrong with the left join?
When doing a left join you have to count the null values from the left join as 0 records but still include them. You can accomplish this with a CASE construct in the inner query, then using the SUM aggregate function in the outer group-by.
SELECT session_id, labeltype_id, label_id, sum(has_label) NOlabels
FROM (
SELECT TARGET.session_id session_id, TARGET.labeltype_id labeltype_id, TARGET.label_id label_id, CASE WHEN SECONDARY.label_id is NULL then 0 else 1 END has_label
FROM
segment_extended TARGET
LEFT JOIN
segment_extended SECONDARY on
TARGET.session_id = SECONDARY.session_id
AND SECONDARY.lt_name ="Comments"
AND ((
SECONDARY.start <= TARGET.start AND TARGET.END <= SECONDARY.END)
OR (TARGET.start <= SECONDARY.start AND SECONDARY.END <= TARGET.END))
AND SECONDARY.label != ''
WHERE TARGET.lt_name= "Word" AND TARGET.label != '')
GROUP BY session_id, labeltype_id, label_id
Your join is not a left join.
A left join adds NULL values for the right table if there are no rows that match the join condition.
However, you query does not have a join condition, and the WHERE condition is not affect by the LEFT JOIN clause.
Replace WHERE with ON.

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery

declare #ProductDetails as table(ProductName nvarchar(200),ProductDescription nvarchar(200),
Brand nvarchar(200),
Categry nvarchar(200),
Grop nvarchar(200),
MRP decimal,SalesRate decimal,CurrentQuantity decimal,AvailableQty decimal)
declare #AvailableQty table(prcode nvarchar(100),Aqty decimal)
declare #CloseStock table(pcode nvarchar(100),
Cqty decimal)
insert into #CloseStock
select PCODE ,
0.0
from producttable
insert into #AvailableQty
select PCODE ,
0.0
from producttable
--Current Qty
--OpenQty
update #CloseStock set Cqty=((OOQTY+QTY+SRRQTY+PYQTY)-(STQTY+PRRQTY))
from
(
select PC.PCODE as PRODUCTCODE,
--Opening
(select case when SUM(PU.Quantity)is null then 0 else SUM(PU.Quantity) end as Q from ProductOpeningYearEnd PU
where PC.PCODE=PU.ProductName) as OOQTY,
--Purchase
(select case when SUM(PU.quantity)is null then 0 else SUM(PU.quantity) end as Q from purchase PU
where PC.PCODE=PU.prdcode ) as QTY,
--Sales
(select case when SUM(ST.QUANTITY)is null then 0 else SUM(ST.QUANTITY)end as Q2 from salestable ST
where PC.PCODE=ST.PRODUCTCODE and ST.status!='cancel' )as STQTY,
--Physical Stock
(select case when SUM(PS.Adjustment)is null then 0 else SUM(PS.Adjustment)end as Q3 from physicalstock PS
where PC.PCODE=PS.PCODE )as PYQTY,
--Sales Return
(select case when SUM(SR.quantity)is null then 0 else SUM(SR.quantity)end as Q3 from salesreturn SR
where PC.PCODE=SR.prdcode )as SRRQTY,
--Purchase Return
(select case when SUM(PR.quantity)is null then 0 else SUM(PR.quantity)end as Q3 from purchasereturn PR
where PC.PCODE=PR.prdcode )as PRRQTY
from producttable PC
group by PC.PCODE
)t
where PCODE=t.PRODUCTCODE
--Available
update #AvailableQty set Aqty=((CCqty-GIQty)+(GOQty))
--((OOQTY+QTY+SRRQTY+PYQTY)-(STQTY+PRRQTY))
from
(
select PC.PCODE as PRODUCTCODE,
--GoodsIn
(select case when SUM(GI.quantity)is null then 0 else SUM(GI.quantity) end as Q from goodsin GI
where PC.PCODE=GI.productcode) as GIQty,
--GoodsOut
(select case when SUM(GUT.quantity)is null then 0 else SUM(GUT.quantity) end as Q from goodsout GUT
where PC.PCODE=GUT.productcode ) as GOQty,
--Current Stock
(select CS.Cqty as Q from #CloseStock CS
where PC.PCODE=CS.pcode ) as CCqty
from producttable PC
group by PC.PCODE
)t
where prcode=t.PRODUCTCODE
insert into #ProductDetails
select PCODE,[DESCRIPTION],BRAND,CATEGORY,DEPARTMENT,MRP,SALERATE,0,0
from producttable
update #ProductDetails set CurrentQuantity=pcqty,AvailableQty=acqty
from
(
select pt.ProductName as pn,cs.Cqty as pcqty,ac.Aqty as acqty from #ProductDetails pt
inner join #CloseStock cs on pt.ProductName=cs.pcode
inner join #AvailableQty ac on pt.ProductName=ac.prcode
)t
where ProductName=t.pn
select * from #ProductDetails
end
This not working when productable in pcode field add ant (-.&) this kind of symbol i want to even allow in pcode field,
please help me how i can allow any symbol in query
(problem with this code)
update #AvailableQty set Aqty=((CCqty-GIQty)+(GOQty))
from
(
select PC.PCODE as PRODUCTCODE,
--GoodsIn
(select case when SUM(GI.quantity)is null then 0 else SUM(GI.quantity) end as Q from goodsin GI
where PC.PCODE=GI.productcode) as GIQty,
--GoodsOut
(select case when SUM(GUT.quantity)is null then 0 else SUM(GUT.quantity) end as Q from goodsout GUT
where PC.PCODE=GUT.productcode ) as GOQty,
--Current Stock
(select CS.Cqty as Q from #CloseStock CS
where PC.PCODE=CS.pcode ) as CCqty
from producttable PC
group by PC.PCODE
)t
where prcode=t.PRODUCTCODE
The problem here isn't with the symbols you're using, it's that you are assigning the value of a subquery to a single column in the result set. For example:
(select case when SUM(PR.quantity)is null then 0 else SUM(PR.quantity)end as Q3 from purchasereturn PR
where PC.PCODE=PR.prdcode )as PRRQTY
Note that this is allowed only if the subquery returns only a single value; otherwise, we don't know which of the values should be assigned to the column.
If you expect your subqueries to return multiple values and you just want an arbitrary one, use TOP 1 in the subquery to only return 1 value. Otherwise, you'll have to debug each subquery to figure out which returns multiple results and is causing the issue.

Resources