I have two tables.
Table 1:
id_a,
id_b,
id_t
Table 2:
id_t,
name
If Table 2 name starts with a, I need to find out of anything
with matching id_ts also have matching id_as.
If Table 2 name starts with b, I need to find out of any row
with matching id_ts also have matching id_bs.
I need to know how many times these matches occur.
Table 1
id_a
id_b
id_t
1
0
123
1
0
123
2
0
123
0
4
456
0
4
456
0
5
456
0
5
456
0
5
456
0
6
456
0
7
456
Table 2
id_t
name
123
aaq
456
bws
So in this example, I want to see a result like
id_t
name
num_non_unique
123
aaq
1
456
bws
2
My current code is this:
SELECT
t2.id_t, t2.name, count(t1.*) AS num_non_unique
FROM
Table 2 AS t2
JOIN Table 1 as t1 ON t2.id_t = t1.id_t
WHERE
(t2.name like 'a%' and t1.id_a in (SELECT id_a FROM t1 GROUP BY id_a, id_t HAVING count(*) > 1))
OR (t2.name like 'b%' AND t1.id_b IN (SELECT id_b FROM t1 GROUP BY id_b, id_t HAVING count(*) > 1))
GROUP BY t1.name, t1.id_t
This doesn't currently give me the results I want.
With this code I seem to get the count of all available rows for id_b, and 1 + non_uniques for id_a (so with one non-unique, the value is 2, otherwise the column has a 1).
Any help is appreciated!
Schema and insert statements:
create table table_1(id_a int, id_b int, id_t int);
insert into table_1 values(1, 0, 123);
insert into table_1 values(1, 0, 123);
insert into table_1 values(2, 0, 123);
insert into table_1 values(0, 4, 456);
insert into table_1 values(0, 4, 456);
insert into table_1 values(0, 5, 456);
insert into table_1 values(0, 5, 456);
insert into table_1 values(0, 5, 456);
insert into table_1 values(0, 6, 456);
insert into table_1 values(0, 7, 456);
create table table_2 (id_t int, name varchar(50));
insert into table_2 values(123, 'aaq');
insert into table_2 values(456, 'bws');
Query:
with case1 as
(
select id_t, id_a
from table_1
group by id_t, id_a
having count(*)=1
),
case2 as
(
select id_t,id_b
from table_1
group by id_t,id_b
having count(*)=1
)
select id_t,name,
(case when t2.name like 'a%' then (select count(*) from case1 where case1.id_t=t2.id_t) when t2.name like 'b%' then (select count(*) from case2 where case2.id_t=t2.id_t) end)num_non_unique
from table_2 as t2
Output:
id_t
name
num_non_unique
123
aaq
1
456
bws
2
db<fiddle here
If I understand correctly, you want the count -- for each row in table_2 -- of the corresponding rows in table_1 where id_b only appears once.
One method is:
select t2.*, coalesce(cnt, 0)
from table_2 t2 left join
(select id_a, count(*) as cnt
from (select id_a, id_b
from table_1
group by id_a, id_b
having count(*) = 1
) t1
group by id_a
) t1
on t1.id_a = t2.id_a;
Try this Code:
select name,id_ts,sum(count_) "num_non_unique" from
(
select t1.id_a,t1.id_b,t1.id_ts,t2.name, count(*) "count_"
from tab1 t1
inner join tab2 t2 on t1.id_ts=t2.id_t
group by 1,2,3,4
having count(*)=1
)tab
group by 1,2
Explanation:
As you have mentioned in your question that one column value will always be same based of name starting character. So no need to check the starting of the name in your query.
Simply we will check the count of unique row and filter it by using condition having count(*)=1.
After getting the unique row simply group it to get the count of rows group by name and id_ts
DEMO
Can we achieve below scenario using single MERGE statement:
source table - table1
destination table- table2
when table1.id in table2.id
then update table1 SET phone_number=123456
when table1.id not in table2.id
then update table1 SET phone_number=555555
Note:- i am able to achieve the result using below query .
MERGE INTO table1 tbl1
USING table2 tbl2
ON (tbl1.id = tbl2.id)
WHEN MATCHED THEN
UPDATE SET tbl1.phone_number=123456;
update table1 set phone_number = 555555 where id not in (select id from table2);
Is there any way to achieve it by using only MERGE Statement ?
When no rows are matched then you can not use UPDATE (in WHEN NOT MATCHED). as there are no rows matched then which data should be updated?
Normal merge statement must have following structure:
MERGE <hint> INTO <table_name>
USING <table_view_or_query>
ON (<condition>)
WHEN MATCHED THEN <update_clause>
DELETE <where_clause>
WHEN NOT MATCHED THEN <insert_clause>
[LOG ERRORS <log_errors_clause> <reject limit <integer | unlimited>];
When there is no match then there are no rows found by oracle into your target table which matches with source table using ON condition then how can it update the record? which record it will update?
WHEN NOT MATCHED is illustrated as following in oracle documentation:
You can handle your scenario using MERGE as follows:
-- Oracle data creation
SQL> CREATE TABLE table1 ( id number, phone_number number );
Table created.
SQL> INSERT INTO table1
2 SELECT 1, 111 from dual UNION ALL
3 SELECT 2, 222 from dual UNION ALL
4 SELECT 3, 333 from dual UNION ALL
5 SELECT 4, 444 from dual;
4 rows created.
SQL> drop table table2;
Table dropped.
SQL> CREATE TABLE table2 ( id number );
Table created.
SQL> INSERT INTO table2
2 SELECT 1 from dual UNION ALL
3 SELECT 2 from dual;
2 rows created.
-- Your merge statement
SQL> MERGE INTO TABLE1 TBL1
2 USING (
3 SELECT T1.ID, T2.ID AS T2ID
4 FROM TABLE1 T1
5 LEFT JOIN TABLE2 T2 ON T1.ID = T2.ID
6 )
7 TBL2 ON ( TBL1.ID = TBL2.ID )
8 WHEN MATCHED THEN
9 UPDATE SET TBL1.PHONE_NUMBER = NVL2(TBL2.T2ID, 123456, 555555);
4 rows merged.
-- Result
SQL> SELECT * FROM TABLE1;
ID PHONE_NUMBER
---------- ------------
1 123456
2 123456
3 555555
4 555555
SQL>
Cheers!!
Just use an UPDATE statement:
Oracle Setup:
CREATE TABLE table1 ( id, phone_number ) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 2, 2 FROM DUAL;
CREATE TABLE table2 ( id ) AS
SELECT 1 FROM DUAL UNION ALL
SELECT 3 FROM DUAL;
Update:
UPDATE table1 t1
SET phone_number = COALESCE(
(
SELECT 123456
FROM table2 t2
WHERE t1.id = t2.id
),
555555
)
Output:
SELECT *
FROM table1
ID | PHONE_NUMBER
-: | -----------:
1 | 123456
2 | 555555
db<>fiddle here
The syntax you are looking for in a MERGE statement exists in SQL Server but is NOT valid in Oracle:
MERGE INTO table1 t1
USING table2 t2
ON ( t1.id = t2.id )
WHEN MATCHED THEN
UPDATE SET phone_number = 123456
WHEN NOT MATCHED BY SOURCE THEN
UPDATE SET phone_number = 555555;
db<>fiddle here
I got a table with 2 columns here.
| column1 | column2 |
| A | 1 |
| B | 1 |
| C | 2 |
| D | 1 |
I'm trying to execute a SELECT query that:
Selects a value FROM Column 2 WHILE Column 2 doesn't have the same value in a row which has Column 1 = "A"
SELECT column2 from mytable and column2 <> (SELECT * FROM mytable where column1 = 'A');
Basically I'm trying to execute a query that returns column1 values only when column2 is valued at "2" here.
But the project I'm making will be having column2 values random so I should use only columns names
Sorry if that's too confusing!
The subquery of your query returns multiple values. So you have to use NOT IN instead of <>:
SELECT column2
FROM mytable
WHERE column2 NOT IN (SELECT column2 FROM mytable WHERE column1 = 'A');
use corelated subquery
select t1.* from mytable t1
where not exists ( select 1 from mytable t2 where t2.column2=t1.column2 and column1='A')
or use not in
select t1.* from table_name t1 where t1.column2 not in ( select column2 from table_name where column1='A')
You could also use a join, for example:
select t1.column2
from mytable t1 left join
(select distinct t2.column2 from mytable t2 where t2.column1='A') t3 on t1.column2=t3.column2
where t3.column2 is null
I have a table 1 which is like this:
Id Values
100 1
100 2
100 3
110 1
110 2
110 4
120 3
I want the id where there is no 1 and 2 so my result should be like this
ID Values
120 3
you could try something like this.
SELECT id
,values_t
FROM Table1 t1
WHERE NOT EXISTS (
SELECT 1
FROM Table1 t2
WHERE t1.id = t2.id
AND t2.values_t IN (
1
,2
)
);
Fiddle
This makes a select of all data without id=1 or id=2
SELECT *
FROM Table2
WHERE values != 1 OR values != 2
Also you can use this as WHERE:
WHERE values > 2
SELECT Id, Values
FROM table2
WHERE Id Not in (select Id from table2 where Values IN (1,2))
this is your query
I have 2 tables and I'd like to substitute rows from Table1 where Customer value is duplicated (for example, B) with a row from Table2 with the same Customer.
Table 1:
Customer cod
A 2
B 1
B N/A
C 5
Table 2:
Customer cod
B 123
So the result should be:
Customer cod
A 2
B 123
C 5
The code could be something like:
INSERT INTO Table1
SELECT *
FROM Table2, Table1
WHERE Table1.Customer = Table2.Customer;
First insert wanted data from table2
INSERT INTO Table1
SELECT *
FROM Table2 t21
WHERE (SELECT count(*)
FROM Table1 t12
WHERE t12.Customer=t21.Customer) > 1;
Then remove duuplicates from table1 which are not matching cod from table 2
DELETE
FROM Table1 t11
WHERE ((SELECT count(*)
FROM Table1 t12
WHERE t11.Customer = t12.Customer)>1
AND NOT cod IN (SELECT cod
FROM Table2 t21
WHERE t11.Customer=t21.Customer))
OR t11.cod IS NULL;