Update column in table depending on table data - sql

I am working on a table on SQL where I need to fill in a new column depending on the value of 2 other columns in the table.
The rules are:
- New column = 1 if Row id = 1 and the group id for that row has more rows with the same group id (See pic)
- New column = 2 if Row id >= 2
- Anything else will make the new column 0
Table
This is my query to update the new column which works:
UPDATE t1 SET t1.New_Column = CASE WHEN t1.RowID >= 2 THEN 2
ELSE CASE WHEN t1.RowID = 1 and (SELECT count(*) FROM dbo.__test1 as t2 WHERE t2.GroupID = t1.GroupID) > 1
THEN 1 ELSE 0 END END from dbo.__test1 as t1
The end table result(Correct):
I want to know if there is a better and more efficient way of updating the new column as I feel calling the table within the select to count the number of group id's doesn't seem right?
Thanks

It will be faster to get the counts at the table level instead of row.
Removed one level of your CASE expression too - that probably won't change anything but it's a little cleaner to my eyes.
UPDATE t
SET t.NewColumn = CASE WHEN t2.RowID >=2 THEN 2
WHEN t2.RowID = 1 AND cnt > 1 THEN 1
ELSE 0
END
FROM dbo.__test1 t
JOIN (SELECT GroupID, COUNT(*) cnt
FROM dbo.__test1
GROUP BY GroupID) t2 on t.GroupID = t2.GroupID

Related

oracle query to get count of added, updated and deleted records based on the date filter

I have a table structure like below
ID OLDID col1 status
1 0 txt1 A - inserted record
2 0 txt1 I - deleted record
3 0 txt1 I - updated record
4 3 txt1 I - updated record
5 4 txt1 I - updated record
6 5 txt1 I - deleted record
7 0 txtx I - updated record
8 7 txt1 A - updated record
I wanted to count the inserted, updated and deleted record in this table, please help me with the oracle query to fetch the count of the records, below are the logic
The logic for new record is ID is new ID and old id is 0 and status is A.
The updated record's status is I, the id of this record will be inserted into the new record's old id column.
the deleted record status with I with old id 0, and the second condition is status is I and ID will not be in OLD id column.
I have tried my best to explain the case, please let me know if any more details are needed. help me with the oracle query.
below query seems to be working, but if no deleted record then I wanted to have 0 for it but in the below query only returns records which have >0 counts, can any expert optimize it, please
SELECT sub.status, COUNT(*)
FROM (SELECT CASE
WHEN yt.oldid = 0 AND yt.status = 'A' THEN 'Insert'
WHEN yt.status = 'I' and QID not in (select oldid from FROM your_table where TO_CHAR (record_date,'MM/YYYY')='04/2020' ) THEN 'Delete'
ELSE 'Update' END AS status
FROM your_table yt where TO_CHAR (record_date,'MM/YYYY')='04/2020')
GROUP BY sub.status;
Neep experts help here, please.
You can use CASE..WHEN and self LEFT JOIN as follows:
SELECT T.*,
CASE WHEN T.OLDID = 0 AND T.STATUS = 'A' THEN 'Insert'
WHEN T.STATUS = 'I' AND T1.ID IS NOT NULL THEN 'Update'
WHEN T.STATUS = 'I' AND T.OLDID = 0 AND T1.ID IS NULL THEN 'Delete'
END AS RECORD_OP
FROM YOUR_TABLE T
LEFT JOIN YOUR_TABLE T1 ON T.ID = T1.OLDID

SQL: Update every entry with value from another entry that share same column value

I have the following table trn_ReceiptLog
I am wondering if it's possible to update amount of entry #1 to have same as entry #2 IF amount of entry #1 is 0?
I have over 5000 of these entries that need to be updated, basically something like:
UPDATE trn_ReceiptLog SET amount = (SELECT amount FROM trn_ReceiptLog WHERE receipt_type = 0) WHERE amount = 0
But I am not sure how to do it for all entries individually, do I need some sort of loop?
Condition 1: Receipt type will always be 0 of the one where amount needs to be taken from.
Condition 2: person_id will always be identical across two of these.
Condition 3 (Optional): Only perform this update IF there is only one receipt_type = 9 (Sometimes there might be 3 or 4 entries with same person_id and being receipt_type 9
You can use window functions to calculate the information needed for the conditions. Then the logic is simple:
with toupdate as (
select t.*,
max(case when receipt_type = 9 then amount else 0 end) over (partition by person_id) as amount_9,
sum(case when receipt_type = 9 then 1 else 0 end) over (partition by person_id) as num_9s
from t
)
update toupdate
set amount = amount_9
where receipt_type = 0;
With a self join:
update t
set t.amount = tt.amount
from trn_ReceiptLog t inner join trn_ReceiptLog tt
on tt.person_id = t.person_id
where t.receipt_type = 9 and tt.receipt_type = 0 and t.amount = 0
and not exists (
select 1 from trn_ReceiptLog
where entry_id <> t.entry_id and person_id = t.person_id and receipt_type = 9
)
The last part of the WHERE clause with AND NOT EXISTS... is the 3d optional condition.
See a simplified demo.

oracle sql - compare row 1 and two, show results in row 3?

My table holds type 2 change history; so if recordID 123 has a change made by a user, then 'latest_effective' gets set to FALSE and the newly created record with recordID 123 has 'latest_effective' set to TRUE.
I'm looking for a query that returns the new record & the record that was just changed with a third row that is TRUE if there is a change in that column and FALSE if not.
select RecordID,1 latest_effective,Column1,Column2, etc...
from YourTable
where latest_effective = 1
union all
select RecordID,0 latest_effective,Column1,Column2, etc...
from YourTable
where latest_effective = 0
union all
select t.RecordID,-1 latest_effective,
case t.Column1 when f.Column1 then 'FALSE' else 'TRUE' end AS Column1
case t.Column2 when f.Column2 then 'FALSE' else 'TRUE' end AS Column2, etc...
from YourTable AS t
inner join YourTable AS f
on f.RecordID = t.RecordID
and f.latest_effective = 0
where t.latest_effective = 1
order by RecordID,latest_effective desc

results of a sub table in the top level query

Not sure how to title this so please feel free to retitle.
I have two tables with a one to many relationship.
Table1
|ID|NAME|...|
Table2
|ID|Table1_ID|StartDate|EndDate|
I am trying to write a query that given a date will return the following
|TABLE1.ID|TABLE1.NAME|are any rows of table 2 in date|
I have a one to many between table 1 and table 2. I want to pass in a date to the query. If any of the many relationships in table 2 have a start date < passed in date and an end date > passed in date or end date is null then I want column 3 of result to be true. Otherwide I want it to be false.
Consider the example
|ID|NAME|...|
| 1|APPLE| ...|
| 2|PEAR| ...|
Table2
|ID|Table1_ID|StartDate|EndDate|
|1|1|01-01-2014|null|
|2|1|01-01-2014|01-02-2014|
|3|2|01-01-2014|01-02-2014|
if I pass in 01-01-2014 then I expect two rows with IDs 1 and 2 and both to be true (all rows match)
if I pass in 01-03-2014 then I expect two rows with ID 1 true (match on first row) and ID 2 to be false (because third row is outside of this date)
I am trying to do this in SQL to eventually convert to JPA. If there are any JPA functions that can do this then that would be good to know. Else I'll do a native query
Any pointers would be great!
Thanks
This should give you what you want:
select x.*, 'PASS' as checker
from table1 x
where exists
(select 'x'
from table2 y
where y.table1_id = x.table1_id
and y.startdate <= '01-01-2014'
and (y.enddate >= '01-01-2014' or y.enddate is null))
union all
select x.*, 'FAIL' as checker
from table1 x
where not exists
(select 'x'
from table2 y
where y.table1_id = x.table1_id
and y.startdate <= '01-01-2014'
and (y.enddate >= '01-01-2014' or y.enddate is null))
I don't know if I understand your question.
So, please, be patient... ;)
Try something like this:
select t1.id, t1.name,
case when t2.Table1_ID is null
then 'false'
else 'true' end as boolean_value
from Table1 t1,
(select distinct Table1_ID
from Table2
where yourdate >= StartDate
and (yourdate <= EndDate or EndDate is null) t2
where t1.id = t2.id (+);

Exclude rows if column values are equal of same table

![TABLE][1]
Hello All,
I have a table with above records where you can 2 entries for each N_ID. I would like to get the records from this only if below condition is satisfied.
Say for example
Status column value is 1 & 2 for N_ID =2 and 2 & 1 for N_ID=5 which means status value is different(i.e Both 1 & 2).
But if you see N_ID=3, Status column has 1 & 1 which is same.
So i want the records excluding N_ID which has same status value(i.e Which has 1 & 1 or 2 & 2 and so on).
In above case, i want only the records with N_ID=2,5.
thanks
You can use EXISTS
SELECT * FROM dbo.TableName t1
WHERE EXISTS(
SELECT 1 FROM dbo.TableName t2
WHERE t1.N_ID = t2.N_ID
AND t1.Status <> t2.Status
)
You can exclude the rows where you have more than one occurrence of the same status per ID
SELECT *
FROM TABLENAME tb
WHERE tb.N_ID NOT IN (
SELECT tb.N_ID
FROM TABLENAME tb
GROUP BY tb.N_ID, tb.CONFIG_TYPE, tb.STATUS
HAVING COUNT(*) > 1)
Try option with EXISTS() and check COUNT(*)
SELECT *
FROM dbo.test16 t
WHERE t.Config_Type != 2 AND EXISTS (
SELECT 1
FROM dbo.test16 t2
WHERE t.Networkelemenid = t2.Networkelemenid
GROUP BY t2.Networkelemenid, t2.Config_Type
HAVING COUNT(DISTINCT t2.Status) > 1
)
This script grouped data on t2.Config_Type. HAVING COUNT(DISTINCT t2.Status) specifies that only unique rows can appear in the result set.(e.g. 1,2 = 2; 1,1 or 2,2 = 1)
For second condition you need this script
SELECT *
FROM dbo.test41 t
WHERE t.Config_Type != 2 AND EXISTS (
SELECT 1
FROM dbo.test41 t2
WHERE t.Networkelemenid = t2.Networkelemenid
GROUP BY t2.Networkelemenid, t2.Config_Type, t2.Status
HAVING COUNT(t2.Status) > 1
)