update one row only in oracle sqldevelop - oracle

I am newbie in oracle sqldevelop.
i have trouble in update table like this.
table1
+----+-----------+------------+
| id | acoount | date |
+----+-----------+------------+
| | John | 2/6/2016 |
| | John | 2/6/2016 |
i have table with name table1. i want to update id where the update only one rows.
Example :
+----+-----------+------------+
| id | acoount | date |
+----+-----------+------------+
| 1 | John | 2/6/2016 |
| 2 | John | 2/6/2016 |
how the solution. Thanks

Oracle Setup:
CREATE TABLE table1 ( id, account, "date" ) AS
SELECT CAST( NULL AS INT ), 'John', DATE '2016-06-02' FROM DUAL UNION ALL
SELECT CAST( NULL AS INT ), 'John', DATE '2016-06-02' FROM DUAL;
Update:
MERGE INTO TABLE1 d
USING ( SELECT ROWNUM AS id, ROWID AS rid FROM Table1 ) s
ON ( d.ROWID = s.RID )
WHEN MATCHED THEN
UPDATE SET d.id = s.id;
Result:
SELECT * FROM table1;
ID ACCOUNT date
---------- ------- -------------------
1 John 2016-06-02 00:00:00
2 John 2016-06-02 00:00:00

Related

Delete query inoracle db is fast but select query running too long

I have below table with 160,000 rows. When I use SELECT ID FROM mytable WHERE id NOT IN ( SELECT max(id) FROM mytable GROUP BY user_id); query is running very long and not finishing (I wait for 1 Hr) but when I use delete FROM mytable WHERE id NOT IN (SELECT max(id) FROM mytable GROUP BY user_id); query is running in 0.5 seconds. Why??
---------------------------------------------------------------------------------------------------
| id | MyTimestamp | Name | user_id ...
----------------------------------------------------------------------------------------------------
| 0 | 1657640396 | John | 123581 ...
| 1 | 1657638832 | Tom | 168525 ...
| 2 | 1657640265 | Tom | 168525 ...
| 3 | 1657640292 | John | 123581 ...
| 4 | 1657640005 | Jack | 896545 ...
-----------------------------------------------------------------------------------------

Insert into a new table with values from session state and another table

I want to insert from a procdure into a new table like the below
The unit_id is from a table called lms_units and it has a FK to lms_qualifications called qualification_id
The table will have 1 Trainer with 1 qualification and all the units that go with it
insert into LMS_TRAINER_QUALI_UNITS
(
lms_trainer_quali_units_id,
Trainer_id,
Qualification_id,
unit_id
)
Values
(
lms_trainer_quali_units_id_seq.nextval,
:P2_Trainer_id,
:P6_qualification_id,
Unit_id --- this will have many values
)
Oracle Setup:
CREATE TABLE lms_qualifications (
Qualification_id, Title, Code
) AS
SELECT 33450, 'Lifter', 123 FROM DUAL;
CREATE TABLE LMS_UNITS (
Unit_id, Qualification_id, description
) AS
SELECT 69052, 33450, 'Elective' FROM DUAL UNION ALL
SELECT 69053, 33450, 'core' FROM DUAL UNION ALL
SELECT 69054, 33450, 'core' FROM DUAL UNION ALL
SELECT 69055, 33450, 'Elective' FROM DUAL UNION ALL
SELECT 69056, 33450, 'Elective' FROM DUAL;
Expected on LMS_TRAINER_QUALI_UNITS
+----------------------------+------------+------------------+---------+
| lms_trainer_quali_units_id | Trainer_id | Qualification_id | unit_id |
+----------------------------+------------+------------------+---------+
| 50001 | 4500 | 33450 | 69052 |
| 50002 | 4500 | 33450 | 69053 |
| 50003 | 4500 | 33450 | 69054 |
| 50004 | 4500 | 33450 | 69055 |
| 50005 | 4500 | 33450 | 69056 |
+----------------------------+------------+------------------+---------+
You can use INSERT INTO ... SELECT to copy values from one table to another:
insert into LMS_TRAINER_QUALI_UNITS (
lms_trainer_quali_units_id,
Trainer_id,
Qualification_id,
unit_id
)
SELECT lms_trainer_quali_units_id_seq.nextval,
:P2_Trainer_id,
Qualification_id,
Unit_id
FROM LMS_UNITS
WHERE Qualification_id = :P6_qualification_id

Update between tables

I have two tables (ORACLE11) :
TABLE1: (ID_T1 is TABLE1 primary key)
| ID_T1 | NAME | DATEBEGIN | DATEEND |
| 10 | test | 01/01/2017 | 01/06/2017 |
| 11 | test | 01/01/2017 | null |
| 12 | test1 | 01/01/2017 | 01/06/2017 |
| 13 | test1 | 01/01/2017 | null |
TABLE2: (ID_T2 is TABLE2 primary key and ID_T1 is TABLE2 foreign key on TABLE1)
| ID_T2 | ID_T1 |
| 1 | 10 |
| 2 | 11 |
| 3 | 11 |
| 4 | 12 |
| 5 | 13 |
I need to delete all rows from TABLE1 where TABLE1.DATEEND = 'null'
But first I must update TABLE2 to modify TABLE2.ID_T1 to the remaining record in TABLE1 for the same NAME :
TABLE2:
| ID_T2 | ID_T1 |
| 1 | 10 |
| 2 | 10 |
| 3 | 10 |
| 4 | 12 |
| 5 | 12 |
I tried this:
UPDATE TABLE2
SET TABLE2.ID_T1 = (
SELECT TABLE1.ID_T1
FROM TABLE1
WHERE TABLE1.DATEBEGIN = '01/01/2017'
AND TABLE1.DATEEND IS NOT NULL
)
WHERE TABLE2.ID_T1 = (
SELECT TABLE1.ID_T1
FROM TABLE1
WHERE TABLE1.DATEBEGIN = '01/01/2017'
AND TABLE1.DATEEND IS NULL
);
But I don't know how to join on TABLE1.NAME and do it for all rows of TABLE2. Thanks in advance for your help.
First create a temp table to find out which id is to be retained for which name. In the case od multiple possible values, I have selected one by ascending order or id_t1.
create table table_2_update as
select id_t1, name from (select id_t1, name row_number() over(partition by
name order by id_t1) from table1 where name is not null) where rn=1;
Create next table to know which id of table2 connects to which name of table1.
create table which_to_what as
select t2.id_t2, t2.id_t1, t1.name from table1 t1 inner join table2 t2 on
t1.id_t1 = t2.id_t2 group by t2.id_t2, t2.id_t1, t1.name;
Since this newly created table now contains id and name of table1, and id of table2, merge into it to retain one to one case of id and name of table1.
merge into which_to_what a
using table_2_update b
on (a.name=b.name)
when matched then update set
a.id_t1=b.id_t1;
Now finally we have a table which contains the final correct values, you can either rename this tale to table2 or merge original table2 on the basis of id of new table and original table2.
merge into table2 a
using which_to_what a
on (a.id_t2=b.id_t2)
when matched then update set
a.id_t1=b.id_t1;
Finally delete null values from table1.
delete from table1 where dateend is null;
You can do this by joining table1 to itself, joining on the name column. Use the first table (a) to link to table2.id_t1 and the second table (b) to get the t1_id where dateend is not null.
UPDATE table2
SET table2.id_t1 = (
select b.id_t1
from table1 a, table1 b
where a.name = b.name
and b.dateend is not null
and a.id_t1 = table2.id_t1
)
WHERE EXISTS (
select b.id_t1
from table1 a, table1 b
where a.name = b.name
and b.dateend is not null
and a.id_t1 = table2.id_t1
);
This assumes that there will only be one table1 record where dateend is not null.

Oracle group by SQL query by matching varchar field

I have a table structure (that I did not design nor can I change) that uses a varchar field to store an attribute about the entity. I would like to write a SQL query to search for two attributes in particular and combine multiple result rows into single rows. To illustrate, my tables are similar to this:
company
=============
| id | name |
-------------
| 1 | co1 |
| 2 | co2 |
| 3 | co3 |
=============
agent
====================================
| id | name | company_id | type |
------------------------------------
| 1 | Tom | 1 | 'type1' |
| 2 | Bob | 1 | 'type2' |
| 3 | Bill | 2 | 'type1' |
| 4 | Jack | 2 | 'type2' |
| 5 | John | 3 | 'type1' |
| 6 | Joe | 3 | 'type2' |
====================================
type1 and type2 are hard-coded into the software as valid values (again, I didn't write it), so a search for these values should be successful (null is permitted). So, I must base my search off of these values.
As a novice, I could write this SQL:
select c.name, a.name, a.type
from company c
inner join agent a on c.id = a.company_id
and sort through these results in my software (Java program):
===========================
| c.name | a.name | type |
---------------------------
| co1 | Tom | type1 |
| co1 | Bob | type2 |
| co2 | Bill | type1 |
| co2 | Jack | type2 |
| co3 | John | type1 |
| co3 | Joe | type2 |
===========================
But, I was hoping there would be a way to combine the rows into something more efficient:
-- my failed attempt at writing this query
select c.name, a.name as type_1_agent, a.name as type_2_agent
from company c
inner join agent a on c.id = a.company_id
group by c.id -- ?
where -- ?
results:
======================================
| name | type_1_agent | type_2_agent |
--------------------------------------
| co1 | Tom | Bob |
| co2 | Bill | Jack |
| co3 | John | Joe |
======================================
Is this possible?
Oracle version:
WITH company (id, name) AS (
SELECT 1, 'co1' FROM DUAL UNION ALL
SELECT 2, 'co2' FROM DUAL UNION ALL
SELECT 3, 'co3' FROM DUAL
),
agent (id, name, company_id, type) AS (
SELECT 1, 'Tom', 1, 'type1' FROM DUAL UNION ALL
SELECT 2, 'Bob', 1, 'type2' FROM DUAL UNION ALL
SELECT 3, 'Bill', 2, 'type1' FROM DUAL UNION ALL
SELECT 4, 'Jack', 2, 'type2' FROM DUAL UNION ALL
SELECT 5, 'John', 3, 'type1' FROM DUAL UNION ALL
SELECT 6, 'Joe', 3, 'type2' FROM DUAL
)
SELECT
company_name, type_1_agent, type_2_agent
FROM
(SELECT company.name company_name, agent.name agent_name, type FROM company JOIN agent ON company.id = agent.company_id)
PIVOT (
MAX(agent_name) agent
FOR type IN ('type1' type_1, 'type2' type_2)
)
ORDER BY
company_name
You can do this with PIVOT functionality, like so:
select company,type_1_agent,type_2_agent
from
(select a.name as agentname, a.type as agenttype,c.name as company
from agent a
inner join company c on c.id = a.company_id
) s
pivot
(max(agentname) for agenttype in ('type1' type_1_agent,'type2' type_2_agent)) p
order by company
Demo
Of course, in this case we hard coded the values for type. This can be made dynamic to accomodate an unknown number of these values.

add column check for format number to number oracle

I need to add a column to a table that check for input to be a max value of 999 to 999, like a soccer match score. How do I write this statement?
example:
| Score |
---------
| 1-2 |
| 10-1 |
|999-999|
| 99-99 |
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE SCORES (Score ) AS
SELECT '1-2' FROM DUAL
UNION ALL SELECT '10-1' FROM DUAL
UNION ALL SELECT '999-999' FROM DUAL
UNION ALL SELECT '99-99' FROM DUAL
UNION ALL SELECT '1000-1000' FROM DUAL;
Query 1:
SELECT SCORE,
CASE WHEN REGEXP_LIKE( SCORE, '^\d{1,3}-\d{1,3}$' )
THEN 'Valid'
ELSE 'Invalid'
END AS Validity
FROM SCORES
Results:
| SCORE | VALIDITY |
|-----------|----------|
| 1-2 | Valid |
| 10-1 | Valid |
| 999-999 | Valid |
| 99-99 | Valid |
| 1000-1000 | Invalid |

Resources