Click here to Skip to main content
15,886,258 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
I have question about SQL Server

Source: emp

id      | name  | check |deptname 
100     |  a    |  1    |ceo   
100     |  b    |  2    |hr
100     |  c    |  3    |po
100     |  d    |  5    |no
101     |  a    |  1    |pm
101     |  b    |  5    |ceo
102     |  a    |  1    |rn
102     |  b    |  2    |han

Here same id have check 2 and 5 values then we need to replace check values to 2 check values for that id.

Based on above table I want load/output data into target table like below

Target : emp1

id      | name  | check |deptname
100     |  a    |  1    |ceo
100     |  d    |  2    |hr
100     |  c    |  3    |po
101     |  a    |  1    |pm
101     |  b    |  5    |ceo
102     |  a    |  1    |rn
102     |  b    |  2    |han

and I tried like below

SQL
select 
    a1.id,
    a1.name,
    isnull(a2.[check],a1.[check]) as [check]
from 
    emp as a1
left outer join 
    emp as a2 on a2.id = a1.id
              and a1.[check] in (2,5)
              and a2.[check] in (2,5)
              and a2.[check] <> a1.[check]
where 
    a2.id is null
    or (a1.[check] = 5
        and a2.[check] = 2)

That query does not return the right result.

Please tell me how to write query to get the expected output in SQL Server
Posted
Updated 26-Sep-15 9:32am
v2

Check this:
SQL
DECLARE @emp TABLE(id INT, [name] VARCHAR(30), [check] INT, deptname VARCHAR(30))
INSERT INTO @emp (id, [name], [check], deptname)
VALUES(100, 'a', 1, ' ceo'),
(100, 'b', 2, ' hr'),
(100, 'c', 3, ' po'),
(100, 'd', 5, ' no'),
(101, 'a', 1, ' pm'),
(101, 'b', 5, ' ceo'),
(102, 'a', 1, ' rn'),
(102, 'b', 2, ' han')

UPDATE t1 SET [name] = t2.[name]
--SELECT t1.id, t2.[name], t1.[check], t1.deptname
FROM (
	SELECT id, [name], [check], deptname
	FROM @emp
	WHERE id = 100 AND [check]=2
	) AS t1 INNER JOIN  (
		SELECT id, [name], [check], deptname
		FROM @emp
		WHERE id = 100 AND [check]=5
	) AS t2 ON t1.id = t2.id 

DELETE 
FROM @emp
WHERE id = 100 AND [check]=5

SELECT *
FROM @emp
 
Share this answer
 
Comments
Wendelius 26-Sep-15 17:41pm    
Looks good.
Maciej Los 26-Sep-15 17:50pm    
Thank you, Mika.
Not sure if I understood the requirements correctly, but have a try with something like this
SQL
select a.id,
       a.name,
       a.[check],
       a.deptname
from emp a
where not exists (select 1
                  from emp b
                  where b.id = a.id
                  and   b.[check] = 2)
or   not exists (select 1
                  from emp b
                  where b.id = a.id
                  and   b.[check] = 5)
union all
select a.id,
       a.name,
       case a.[check]
          when 5 then 2
          else a.[check]
       end,
       a.deptname
from emp a
where exists (select 1
                  from emp b
                  where b.id = a.id
                  and   b.[check] = 2)
and  exists (select 1
                  from emp b
                  where b.id = a.id
                  and   b.[check] = 5)
and a.[check] <> 2
order by 1,3

I'm wondering about the deptname. In your example data all other values were from the row having originally value 5 but the deptname was from the row having check value 2. Not sure if this was intentional but if it was then that value should be fetched separately.
 
Share this answer
 
v2
Comments
Maciej Los 26-Sep-15 18:11pm    
Hmmm... I had wondered what to say...
As per performance perspective, i'm afraid, too many subqueries were used. What you think about that, Mika?
Wendelius 27-Sep-15 2:25am    
To be honest it's impossible to say since we know nothing about the indexing, file organization etc. EXISTS and NOT EXISTS clauses are often very fast but without running the execution costs in the target database it's hard to say.
Maciej Los 27-Sep-15 6:37am    
Agree, a 5!
Wendelius 27-Sep-15 7:29am    
Thanks!
Wendelius 27-Sep-15 4:46am    
Based on your new question in how to update and insert based on swap rows in sql server[^] this query seems to produce correct data except for 103 where again deptname differs. The result from the query for 103 is

103 G 2 hr

So I'm not sure why the deptname should be "Ja"...

However, as far as I can see you should be able to use the select as a basis for an insert statement. For example

INSERT INTO SomeOtherTable
SELECT ...

or if you want to create the new table on-the-fly, then perhaps

select a.id,
a.name,
a.[check],
a.deptname
into SomeOtherTable
from emp1 a
...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900