update query result not reflecting in table - sql

I have two tables test1 and test2. What I need is, I would like to update one column in the table test2 with data from the table test1. My query is
UPDATE test2 t2
SET t2.name = (SELECT t1.name
FROM test1 t1
WHERE t1.id = t2.mob)
WHERE t2.mob IN (SELECT t1.id
FROM test1 t1
WHERE t1.id = t2.mob)
It's showing 3 Rows updated , But It's not reflecting in my table. My reference. Is there any issue in my query. Or what should I do alternately.

It wold be easier to use merge statement:
/* test tables */
SQL> create table test1(id1, name1) as
2 select level
3 , dbms_random.string('l', 7)
4 from dual
5 connect by level <= 5;
Table created
SQL> create table test2(id1, name1) as
2 select level
3 , cast(null as varchar2(11))
4 from dual
5 connect by level <= 5;
Table created
Tables' contents:
SQL> column name1 format a10;
SQL> select * from test1;
ID1 NAME1
---------- ----------
1 ouegwac
2 bptytsz
3 xwpnuqi
4 jrbxeza
5 hlckwvk
SQL> select * from test2;
ID1 NAME1
---------- ----------
1 NULL
2 NULL
3 NULL
4 NULL
5 NULL
Update test2.name1 column with data from test1.name1 column:
SQL> merge into test2 t
2 using test1 q
3 on (q.id1 = t.id1)
4 when matched then
5 update set t.name1 = q.name1
6 ;
5 rows merged
SQL> select * from test2;
ID1 NAME1
---------- ----------
1 ouegwac
2 bptytsz
3 xwpnuqi
4 jrbxeza
5 hlckwvk

UPDATE
(SELECT test2.name as t2, test1.name as t1
FROM test2
INNER JOIN test1
ON test2.MOB= test1.ID
) t
SET t.t2= t.t1

The WHERE part in your query is absolutely unnecessary because it always evaluates to TRUE. So the correct one to update all rows in t2 is:
UPDATE test2 t2
SET t2.name = (SELECT t1.name
FROM test1 t1
WHERE t1.id = t2.mob)
Also in PL/SQL Developer transactions are not commited automatically by default. You have to manually commit it by pressing that green arrow on the panel.

Related

ORA-01427 Single row subquery returns more than 1 row

This error seems to be popular and there are many related answers. However, the existing answers do not seem to apply to my situation.
I am simplifying my case using 2 tables: Test1 and Test3 (see illustration)
What I am trying to do is attempting to find the records in test3 table that does not match the value in field value1 (if the field check_condition1 = 1 if it is 0 then I do not care)
so basically the result should be similar to this query in this particular scenario:
select distinct t3.* from test3 t3, test1 t1
where t3.department=t1.department
and t3.value1 not in ('A','B');
However, if I use this statement:
select distinct t3.* from test3 t3, test1 t1
where t3.department=t1.department
and t3.value1 not in
(
case t1.CHECK_CONDITION1
when 0 then
(select '1' from dual where 1=2)
when 1 then
( select value1 from test1 where department=t3.DEPARTMENT)
end
)
I got this message:
ORA-01427: single-row subquery returns more than one row
01427. 00000 - "single-row subquery returns more than one row"
*Cause:
*Action:
I thought my subquery "select value1 from test1 where department=t3.DEPARTMENT" should return a set for t3.value1 to check against.
How should the statement be corrected? My goal is to use Test1 table as a control table, the fields Check_condition1, check_condition2 are the "switches" that could be turn on and off without having to change the main query.
Please advise if my thought make sense.
Attached are the script to create the tables test1 and test3 for easier duplication of my issue.
CREATE TABLE "TEST1"
( "DEPARTMENT" NUMBER(3,0),
"VALUE1" VARCHAR2(26 BYTE),
"VALUE2" VARCHAR2(26 BYTE),
"CHECK_CONDITION1" NUMBER(3,0),
"CHECK_CONDITION2" NUMBER(3,0)
)
Insert into TEST1 (DEPARTMENT,VALUE1,VALUE2,CHECK_CONDITION1,CHECK_CONDITION2) values (1,'A','Z',1,0);
Insert into TEST1 (DEPARTMENT,VALUE1,VALUE2,CHECK_CONDITION1,CHECK_CONDITION2) values (1,'B','Y',1,0);
CREATE TABLE "TEST3"
( "DEPARTMENT" NUMBER(3,0),
"VALUE1" VARCHAR2(26 BYTE),
"VALUE2" VARCHAR2(26 BYTE),
"VALUE3" VARCHAR2(26 BYTE)
);
Insert into TEST3 (DEPARTMENT,VALUE1,VALUE2,VALUE3) values (1,'A','T','Whatever');
Insert into TEST3 (DEPARTMENT,VALUE1,VALUE2,VALUE3) values (1,'Z','Y','Whatever');
Insert into TEST3 (DEPARTMENT,VALUE1,VALUE2,VALUE3) values (1,'B','Y','Whatever');
From the CASE expression documentation:
For both simple and searched CASE expressions, all of the return_exprs must either have the same datatype (CHAR, VARCHAR2, NCHAR, or NVARCHAR2, NUMBER, BINARY_FLOAT, or BINARY_DOUBLE) or must all have a numeric datatype. If all return expressions have a numeric datatype, then Oracle determines the argument with the highest numeric precedence, implicitly converts the remaining arguments to that datatype, and returns that datatype.
The return_expr of a CASE statement expects a single value so your sub-query:
( select value1 from test1 where department=t3.DEPARTMENT)
is what is raising the exception.
Instead use the filter on the sub-query:
select distinct t3.*
from test3 t3
INNER JOIN test1 t1
ON ( t3.department=t1.department )
WHERE t3.value1 not in (
select value1
from test1
where department=t3.DEPARTMENT
AND t1.CHECK_CONDITION1 = 1
)
Which, for your test data, outputs:
DEPARTMENT | VALUE1 | VALUE2 | VALUE3
---------: | :----- | :----- | :-------
1 | Z | Y | Whatever
db<>fiddle here
That would be something like this, I presume:
SQL> select distinct t3.*
2 from test3 t3 join test1 t1 on t3.department=t1.department
3 where t3.value1 not in
4 (select t1.value1 from test1 t1
5 where t1.department = t3.department
6 and 1 = case when t1.check_condition1 = 1 then 1
7 else 0
8 end
9 );
DEPARTMENT VALUE1 VALUE2 VALUE3
---------- ---------- ---------- ----------
1 Z Y Whatever
SQL>
If condition was 0, you said you don't care, so:
SQL> update test1 set check_condition1 = 0;
2 rows updated.
SQL> select distinct t3.*
2 from test3 t3 join test1 t1 on t3.department=t1.department
3 where t3.value1 not in
4 (select t1.value1 from test1 t1
5 where t1.department = t3.department
6 and 1 = case when t1.check_condition1 = 1 then 1
7 else 0
8 end
9 );
DEPARTMENT VALUE1 VALUE2 VALUE3
---------- ---------- ---------- ----------
1 B Y Whatever
1 A T Whatever
1 Z Y Whatever
SQL>

Get the Name from same table instead of ref(same column as id)

I have "tbl_students" with id, name ,referred_by_id
id name referred_by_id
1 test1 2
2 test2 1
3 test3 1
referred_by_id have id value only,
When I retrieve 2nd record
2 test2 1
but I want
2 test2 1 test1 (refname )
How can i do this?
As you said:
referred_by_id have id value only, When I retrieve 2nd record
2 test2 2
But the second record in the table you provided, is 2 test2 1.
Assuming that was a typo, and further you require an output like 2 test2 1 test1 (refname). Here is a simple query which might get what you want:
SELECT t1.*, t2.name AS refname
FROM tbl_students t1
JOIN tbl_students t2
ON t1.referred_by_id = t2.id
ORDER BY t1.id
For MySQL Fiddle.
For PostgreSQL Fiddle
If this is not what you were looking for, do tell.

SQL Server : retrieve records for a foreign key that don't have common values with another foreign key in the same table

I have a table with the following structure:
Id MemberId Field1 Field2 Data
--------------------------------------------------
1 1 12 abc 1232
2 2 13 asl 234
3 2 12 abc 2345
4 1 3 sd sfsd
5 1 5 45r ffgf
Given parameters member1 and member2, I have to return all id's from member1 that don't have the same values in Field1 and Field2 with member2.
Output example:
member1 = 1
member2 = 2
Expected output:
4
5
Because the the first record and the third record have the same values for Field1 and Field2.
How to achieve this?
I'm using SQL Server 2014.
Edit: I am not allowed to use cursors and temp tables (like #tempTable), I can use only table variables
If I understand correctly, you can use not exists:
select t.*
from t
where not exists (select 1
from t t2
where t2.member1 = t.member1 and
t2.id <> t.id and
(t2.field1 = t.field1 or t2.field2 = t.field2)
);

Copy column from another table with 'where'

I have two tables: Table1 and Table2
Table1
id name value source
----------- ----------- ----- ------------
1 a 4 10
2 b 5 10
3 c 6 11
Table2
set text
----------- -----------
7 h
8 g
I want to copy the 'value' column to Table2 from Table1, where table1.source = 10
set text value
----------- ----------- ---------
7 h 4
8 g 5
I tried this:
ALTER TABLE Table2 ADD value INT NOT NULL DEFAULT 0
UPDATE tb2
SET tb1.value = tb2.value
from Table2 tb2
JOIN Table1 tb1
ON tb1.source=10
it has given me this :
id name value
----------- ----------- ---------
7 h 4
8 g 4
It's updating Table2 rows with only the first source value from Table1.
What am I doing wrong ?
Thanks in advance!
If you are using sQL server ,use the below query to update the table2.
Note that the script is specific to the given sample data.
ALTER TABLE Table2
ADD value INT NOT NULL DEFAULT 0
GO
WITH cte_data
as
(SELECT ROW_NUMBER() OVER(ORDER BY [set])RNo,*
FROM Table2 )
UPDATE c
SET c.Value=t.Value
FROM cte_data c
JOIN Table1 t on c.RNo=t.Id
WHERE t.Source=10
Maybe you can try this:
insert into table2 (value) select (value) from table1 where table1.source = 10
Just add new "value" field in "table2" and try this approach.
You need a row number for the join. I would advise putting this in both tables:
WITH toupdate AS (
SELECT tb1.*,
ROW_NUMBER() OVER (PARTITION BY source ORDER BY id) as seqnum
FROM table1 tb1
)
UPDATE toupdate
SET tb1.value = tb2.value
FROM toupdate tb1 JOIN
(SELECT tb2.*,
ROW_NUMBER() OVER (ORDER BY set) as seqnum
FROM table2 tb2
) tb2
ON tb2.seqnum = tb1.seqnum
WHERE tb1.source = 10;

Get first row of each group in access2010

There are multiple way to get first row from each group, but none of my idea is working with access2010.
Do you have a solution to get first row in access2010 ?
Or
ID Name Age
1 Name1 3
2 Name2 4
3 Name1 2
4 Name2 5
It should get the top row in each group (name column) so the output would be
1 Name1 3
2 Name2 4
Here's a solution that still uses a sub query, but only once, instead of on each record.
SELECT T1.*
FROM mytable AS T1
WHERE T1.id IN (SELECT First(T2.id)
FROM mytable T2
GROUP BY T2.name)
select * from table t1 where ID in
(sel min(ID) from table where t1.name=name);