Update field with count - sql

I need to count how many times an variable id value is repeated in field B of table 2, and update the value in field A of table 1 corresponding to the line which that variable id value is in the field B and the date.
UPDATE Table_1
SET Field_A = ( SELECT COUNT(*)
FROM Table_2
WHERE Table_2.Field_B = 1 AND Table_2.Field_3='2015-04-04')
WHERE Table_1.Field_B = 1 AND Table_3.Field_3='2015-04-04'
Something like this
UPDATE Table_1
SET Field_A = ( SELECT COUNT(*)
FROM Table_2
WHERE Table_2.Field_B = X AND Table_2.Field_3='xxxx-xx-xx')
WHERE Table_1.Field_B = X AND Table_3.Field_3='xxxx-xx-xx'
Table 1 Table 2
Field_3 Field_1 Field_3 Field_4 Field_1 Field_3
1 2 04-04-2015 200,00 1 04-04-2015
2 3 04-04-2015 300,00 1 04-04-2015
3 1 04-04-2015 150,00 2 04-04-2015
1 1 05-04-2015 853,00 2 04-04-2015
2 2 05-04-2015 200,00 2 04-04-2015
3 1 05-04-2015 200,00 3 04-04-2015
4 2 05-04-2015 3,00 1 05-04-2015
40,00 2 05-04-2015
Field 1 - TransactionCount 900,00 2 05-04-2015
Field 2 - SessionID 35,00 3 05-04-2015
Field 3 - Date 25,00 4 05-04-2015
Field 4 - TransactionSales 100,00 4 05-04-2015

Related

SQL Segmentation

I have this table
Customer
Amount
Date
Period
Group
77766
50
2022-02-28
1
2
77766
20
2022-03-31
2
2
77766
30
2022-04-30
3
3
12345
50
2022-02-28
1
1
12345
20
2022-03-31
2
2
12345
30
2022-04-30
3
3
and I'm trying to achieve this segmentation model where I assign a Group to its corresponding Period per Customer
Customer
Amount
Date
Period
Group
Group_Period1
Group_Period2
Group_Period3
77766
50
2022-02-28
1
2
2
2
3
77766
20
2022-03-31
2
2
2
2
3
77766
30
2022-04-30
3
3
2
2
3
12345
50
2022-02-28
1
1
1
2
3
12345
20
2022-03-31
2
2
1
2
3
12345
30
2022-04-30
3
3
1
2
3
I tried case function but it didn't work
select a.*,
case when a.Period=1 then Group end Grupo1 ,
case when a.Period=2 then Group2 end Grupo2 ,
case when a.Period=3 then Group3
end Grupo3
from a
I got this output:
Customer
Amount
Date
Period
Group
Group_Period1
Group_Period2
Group_Period3
77766
50
2022-02-28
1
2
2
null
null
77766
20
2022-03-31
2
2
null
2
null
77766
30
2022-04-30
3
3
null
null
3
12345
50
2022-02-28
1
1
1
null
null
12345
20
2022-03-31
2
2
null
2
null
12345
30
2022-04-30
3
3
null
null
3
Can anybody guide me to achieve the expected? Thank you in advice
You can use window function such as MAX() OVER () with conditionals for values of Period column such as
SELECT *,
MAX(CASE WHEN Period=1 THEN `Group` END)
OVER (PARTITION BY Customer) AS Group_Period1,
MAX(CASE WHEN Period=2 THEN `Group` END)
OVER (PARTITION BY Customer) AS Group_Period2,
MAX(CASE WHEN Period=3 THEN `Group` END)
OVER (PARTITION BY Customer) AS Group_Period3
FROM t -- replace with your table's name
where grouping is figured out through use of PARTITION BY clause
Demo
One approach can be via inline sub-query.
select *,
(select group_1 from cust a where a.customer = b.customer and period=1) Group_Period1,
(select group_1 from cust a where a.customer = b.customer and period=2) Group_Period2,
(select group_1 from cust a where a.customer = b.customer and period=3) Group_Period3
from cust b;
Fiddle here

Unable to use LAG function

I need to update a table as :
ID | START_DATE | response| FINAL_TREND
1 14-10-2021 4
1 15-10-2021 3
1 16-10-2021 2
1 17-10-2021 2
1 18-10-2021 3
1 19-10-2021 2
OUTPUT AS:
ID | START_DATE | response| FINAL_TREND
1 14-10-2021 4 NULL
1 15-10-2021 3 4
1 16-10-2021 2 3
1 17-10-2021 2 2
1 18-10-2021 3 2
1 19-10-2021 2 3
So, when running a code:
SELECT LAG(RESPONSE,1) OVER (ORDER BY START_DATE) AS NEW
FROM DUMMY_YC
Output as:
NULL
4
3
2
3
2
2
But when using same code in update AS:
UPDATE DUMMY_YC A SET A.RESPONSE = (SELECT LAG(B.RESPONSE,1) OVER (ORDER BY B.START_DATE) AS NEW
FROM DUMMY_YC B WHERE B.START_DATE=A.START_DATE)
output as:
7 rows updated.
But the actual updated value is
RESPONSE|
(null)
(null)
(null)
(null)
(null)
(null)
(null)
Helps will be appreciated. Working On Oracle SQL Developer.
I'd go with merge.
Before:
SQL> SELECT *
2 FROM test
3 ORDER BY id, start_date;
ID START_DATE RESPONSE FINAL_TREND
---------- ---------- ---------- -----------
1 14.10.2021 4 0
1 15.10.2021 3 0
1 16.10.2021 2 0
1 17.10.2021 2 0
1 18.10.2021 3 0
1 19.10.2021 2 0
6 rows selected.
Merge:
SQL> MERGE INTO test a
2 USING (SELECT b.id,
3 b.start_date,
4 b.response,
5 LAG (b.response, 1) OVER (ORDER BY b.start_date) AS final_trend
6 FROM test b) x
7 ON ( x.id = a.id
8 AND x.start_date = a.start_date)
9 WHEN MATCHED
10 THEN
11 UPDATE SET a.final_trend = x.final_trend;
6 rows merged.
After:
SQL> SELECT *
2 FROM test
3 ORDER BY id, start_date;
ID START_DATE RESPONSE FINAL_TREND
---------- ---------- ---------- -----------
1 14.10.2021 4
1 15.10.2021 3 4
1 16.10.2021 2 3
1 17.10.2021 2 2
1 18.10.2021 3 2
1 19.10.2021 2 3
6 rows selected.
SQL>

Generate a serial number based on quantity column in sql

Hi Experts I have a table like this
T1
Order_no
Qty
1
3
2
5
3
1
4
3
I need to generate a column 'serial no' having values based on 'qty'
Output needed
OrderNo
Qty
SerailNo
1
3
1
1
3
2
1
3
3
2
5
1
2
5
2
2
5
3
2
5
4
2
5
5
3
1
1
4
3
1
4
3
2
4
3
3
Any suggestions?
Thanks in advance!!
You don't mention the specific database so I'll assume you are using PostgreSQL, aren't you?
You can use a Recursive CTE to expand the rows. For example:
with recursive
n as (
select order_no, qty, 1 as serial_no from t1
union all
select order_no, qty, serial_no + 1
from n
where serial_no < qty
)
select * from n order by order_no, serial_no
Result:
order_no qty serial_no
--------- ---- ---------
1 3 1
1 3 2
1 3 3
2 5 1
2 5 2
2 5 3
2 5 4
2 5 5
3 1 1
4 3 1
4 3 2
4 3 3
See running example at DB Fiddle.
EDIT FOR ORACLE
If you are using Oracle the query changes a bit to:
with
n (order_no, qty, serial_no) as (
select order_no, qty, 1 from t1
union all
select order_no, qty, serial_no + 1
from n
where serial_no < qty
)
select * from n order by order_no, serial_no
Result:
ORDER_NO QTY SERIAL_NO
--------- ---- ---------
1 3 1
1 3 2
1 3 3
2 5 1
2 5 2
2 5 3
2 5 4
2 5 5
3 1 1
4 3 1
4 3 2
4 3 3
See running example at db<>fiddle.
You should first provide the database you're using. Whether it's oracle, Sql Server, PostGreSQL will determine which procedural language to use. It's very likely that you'll need to do this in two steps:
1st: Duplicate the number of rows based on the column Qty using a decreasing loop
2nd: You'll need to create a sequential partionned column based on the Qty column

Select from same column but multiples values and number of records with one specific value

ID Customer Status
1 ABC 1
2 ABC 2
3 ABC 3
4 ABC 1
5 PQR 1
6 PQR 2
7 PQR 3
8 XYZ 1
9 XYZ 3
I want to select customer who has both values "status=1" and "Status=2' and also total number of entry of same customer with Status=1.
So the result will be,
Customer totalEntryStatus1
ABC 2
PQR 1
How can I do this.
Thankyou !
select Customer, count(case when status = 1 then 1 end) totalEntryStatus1
from table
where Status in (1,2)
group by Customer
having count(distinct Status) = 2

Get TOP 1 row from multiple tables based on date

I have five tables in a SQL Server database. These tables are listed below and I want to select Data from these tables according to date. I tried searching but could not find solution for multiple tables. Please help
TABLE1
id PId CId
----------- ---------- ------------
1 P001 1
2 P002 2
3 P003 4
4 P004 5
TABLE2
id CId CNo ConId
----------- ---------- ------------ ----------
1 1 1 C123
2 1 2 PA444
3 1 3 PA456
4 2 1 AUX2398
5 2 2 AUX2345
6 4 1 PA123
7 5 1 C234
TABLE3
id CId CNo Label Date
----------- ---------- ------------ ---------- ----------
1 1 1 A 1/1/2000
2 1 2 A 15/10/2020
3 1 3 A 20/10/2020
4 2 1 A 15/10/2020
5 2 2 A 20/10/2020
6 4 1 A 20/10/2020
7 5 1 A 27/10/2020
TABLE4
id CId CNo Label Date
----------- ---------- ------------ ---------- ----------
1 1 1 B 20/10/2020
2 1 2 B 27/10/2020
3 1 3 B 22/10/2020
4 2 1 B 22/10/2020
5 2 2 B 26/10/2020
6 4 1 B 22/10/2020
7 5 1 B 30/10/2020
TABLE5
id CId CNo Label Date
----------- ---------- ------------ ---------- ----------
1 1 1 C 26/10/2020
2 1 2 C 1/1/2000
3 1 3 C 23/10/2020
4 2 1 C 25/10/2020
5 2 2 C 30/10/2020
6 4 1 C 25/10/2020
7 5 1 C 1/1/2000
I want to select Label and Date from Table 3, 4 and 5 where Date is >1/1/2000 and < than and close to 24/10/2020 and grouped according to PId, CId, ConId and CNo.
Desired result:
PId CId ConId CNo Label Date
-------- ---------- ---------- -------- --------- ----------
P001 1 C123 1 B 20/10/2020
P001 1 PA444 2 A 15/10/2020
P001 1 PA456 3 C 23/10/2020
P002 2 AUX2398 1 B 22/10/2020
P002 2 AUX2345 2 A 20/10/2020
P003 4 PA123 1 B 22/10/2020
P004 5 C234 1 - -
Any help will be appreciated. Thank you.
You can achieve this with a couple of CTE's; the first forms a UNION of TABLE3, TABLE4 and TABLE5; the second generates a row number based on the Date descending for each partition of PId, CId, ConId and CNo. We then select all rows from the second CTE where the row number is 1:
WITH CTE AS (
SELECT * FROM Table3 WHERE date > '2000-01-01'
UNION ALL
SELECT * FROM Table4 WHERE date > '2000-01-01'
UNION ALL
SELECT * FROM Table5 WHERE date > '2000-01-01'
),
CTE2 AS (
SELECT t1.PId, t1.CId, t2.ConId, t2.CNo, CTE.Label, CTE.Date,
ROW_NUMBER() OVER (PARTITION BY t1.PId, t1.CId, t2.ConId, t2.CNo ORDER BY CTE.Date DESC) AS rn
FROM TABLE1 t1
JOIN TABLE2 t2 ON t2.CId = t1.CId
LEFT JOIN CTE ON CTE.Cid = t2.CId AND CTE.CNo = t2.CNo AND CTE.Date < '2020-10-24'
)
SELECT PId, CId, ConId, CNo, Label, Date
FROM CTE2
WHERE rn = 1
ORDER BY PId, CId, CNo
Output:
PId CId ConId CNo Label Date
P001 1 C123 1 B 2020-10-20
P001 1 PA444 2 A 2020-10-15
P001 1 PA456 3 C 2020-10-23
P002 2 AUX2398 1 B 2020-10-22
P002 2 AUX2345 2 A 2020-10-20
P003 4 PA123 1 B 2020-10-22
P004 5 C234 1 - -
Demo on dbfiddle