how to handle NA values in Target table - sql-server-2008

Hi Friends i have small doubt in sql server how to handle target table unmatched records replace with NA.please tell mehow to solve this issue in sql server.
TableA:
id | Descr
1 |ab
2 |bc
3 |de
5 |
6 |jk
TableB:
id | Descr
1 |
2 |
4 |
5 |
Here i want update tableB table Descr From TableA Based on id columns
i tried like below
merge TableB dest
using TbleA stag
on dest.id=stag.id
when matched then
UPDATE
SET
dest.[id]= CASE WHEN coalesce(ltrim(rtrim(stag.[id])),'') = '' THEN 'NA' ELSE ltrim(rtrim(stag.[id])) END
,dest. [descr]= CASE WHEN coalesce(ltrim(rtrim(stag.[descr])),'') = '' THEN 'NA' ELSE ltrim(rtrim(stag.[descr])) END
;
i got out put like below
TableB:
id | Descr
1 | ab
2 | bc
4 |
5 | NA
But i want output like below
TableB:
id | Descr
1 | ab
2 | bc
4 | NA
5 | NA
Please tell me how to handle NA values in sql server

You could use a left join with the update statement and set descr to NA where it is NULL. Try this:
UPDATE dest
SET dest.descr =
CASE
WHEN coalesce(ltrim(rtrim(stag.[descr])),'') = '' THEN 'NA'
WHEN stag.[descr] IS NULL THEN 'NA'
ELSE ltrim(rtrim(stag.[descr]))
END
FROM TableB dest
LEFT JOIN TableA stag on dest.id = stag.id;
Here's an SQL Fiddle to show it.

Related

MySQL Update table by matchig values in the same column

I have a table where I store data for different groups and I need to update one group if values in one column are matching.
the table looks like this:
prop_id | group_id | value | visible
1 | 1 | 10 | 1
1 | 2 | 10 | 1
1 | 3 | 15 | 1
2 | 1 | 10 | 1
2 | 2 | 10 | 1
2 | 3 | 10 | 1
So I want to set the visible column to 0 for the group_id=3 if the values in the value column are equal to group_id=1. In this case if value=10 for both group_id=1 and group_id=3 than set visible=0 for group_id=3
expected result after update
prop_id | group_id | value | visible
1 | 1 | 10 | 1
1 | 2 | 10 | 1
1 | 3 | 15 | 1
2 | 1 | 10 | 1
2 | 2 | 10 | 1
2 | 3 | 10 | 0
How is this possible?
Write it as a SELECT first.
Start simple, the rows that we want to update we know are group_id=3 and visible=1, so write a query that gets all of those rows:
SELECT g3.value
, g3.visible
FROM mytable g3
WHERE g3.group_id = 3
AND g3.visible = 1
We know the rows we want to update are in that set, but there are some additional conditions.
So we extend that. According to the spec, we need to find out if there are any matching group_id=1 rows that are visible=1 (matching on value).
We can do that check either with an EXISTS correlated subquery, or we can use a JOIN.
SELECT g3.group_id
, g3.value
, g3.visible
FROM mytable g3
WHERE g3.group_id = 3
AND g3.visible = 1
AND EXISTS ( SELECT 1
FROM mytable g1
WHERE g1.group_id = 1
AND g1.visible = 1
AND g1.value = g3.value
)
-or-
SELECT g3.group_id
, g3.value
, g3.visible
FROM mytable g3
JOIN mytable g1
ON g1.group_id = 1
AND g1.visible = 1
AND g1.value = g3.value
WHERE g3.group_id = 3
AND g3.visible = 1
Verify the query is returning the rows we want to update, under the specific conditions. (It is much easier to verify the results of a SELECT statement, and adjust as necessary, than it is an UPDATE statement.)
Once we have a SELECT query working and verified (returning the rows we want to update) we can convert it into an UPDATE statement. Replace the SELECT ... FROM with UPDATE and add a SET clause that is returning the rows
UPDATE mytable g3
JOIN mytable g1
ON g1.group_id = 1
AND g1.visible = 1
AND g1.value = g3.value
SET g3.visible = 0
WHERE g3.group_id = 3
AND g3.visible = 1
Use Self JOIN then UPDATE
You can try this.
UPDATE T t1
JOIN T t2 on t1.group_id = t2.group_id
and t1.rop_id<>t2.rop_id and t1.value > t2.value
SET t2.visible = 0
sqlfiddle:http://sqlfiddle.com/#!9/6f06de/1

mysql trigger is not working on wamp server

I have three tables namely:
tab_m_blood
tab_m_donar
tab_t_bloodstock
"tab_m_blood" entries are below:
bgId | bGroup
--------------------
1 | A+
2 | A-
3 | B+
4 | B-
5 | AB+
6 | AB-
7 | O+
8 | O-
tab_m_donar entries are below:
dId | donarName | donarAddress | donarContact | donarDisease | bgId | bloodUnit
---------------------------------------------------------------------------------
1 | a | xy | 111 | NA | 2 | 20
2 | b | uv | 222 | NA | 2 | 30
tab_t_bloodstock entries are below:
bgId | bUnit
------------
1 | 0
2 | 0
3 | 0
4 | 0
5 | 0
6 | 0
7 | 0
8 | 0
What i want is that when a donar donate their blood in "tab_m_donar",the blood stock for respective blood group will update in "tab_t_bloodstock"
I want to write a trigger on "tab_m_donar" which will act like when any data will insert on "tab_m_donar" ,the data will update "tab_t_bloodstock".
"bgId" in the "tab_t_bloodstock" is the FK of the PK-->"bgId" in the "tab_m_blood".
I already wrote the trigger below but it is not working:
CREATE TRIGGER updatestock AFTER UPDATE ON tab_m_doner
FOR EACH ROW
begin
if old.bgId is not null then
update tab_t_bloodstock
set bUnit=bUnit-old.bloodUnit
where bgId=old.bgId;
end if;
if new.bgId is not null then
update tab_t_bloodstock
set bUnit=bUnit+new.bloodUnit
where bgId=new.bgId;
end if;
end
Please help me out.
I can implement this on SQL Server but I actually don't know how to do it on MySQL
I guess there is a transformation you can implement manually
CREATE TRIGGER updatestock
ON dbo.tab_m_donar
AFTER INSERT, UPDATE, DELETE
AS
-- insert
Update tab_t_bloodstock
set bUnit = bUnit + i.bloodUnit
from tab_t_bloodstock s
inner join (
select i.bgId, i.bloodUnit
from Inserted i
left join Deleted d on i.dId = d.dId
where d.dId is null
) i on i.bgId = s.bgId
-- update
Update tab_t_bloodstock
set bUnit = bUnit + u.ins - u.dels
from tab_t_bloodstock s
inner join (
select i.bgId, i.bloodUnit ins, d.bloodUnit dels
from Inserted i
inner join Deleted d on i.dId = d.dId
) u on u.bgId = s.bgId
-- delete
Update tab_t_bloodstock
set bUnit = bUnit - d.bloodUnit
from tab_t_bloodstock s
inner join (
select d.bgId, d.bloodUnit
from deleted d
left join inserted i on i.dId = d.dId
where i.dId is null
) d on d.bgId = s.bgId
go

How to get single row when foreign key is similar

I have a table tbl_issue with columns
> serial_no.
Issue_no. (f.k)
From_Section
To_Section
+-----+---------------+-------------+-------------+
| id | issue no | from section| to_section |
+-----+---------------+-------------+-------------+
| 1 | 223 | MFA | N/A |
| 2 | 223 | N/A | LOG |
+----------+----------+-------------+--------------+
When I query the table on issue no. I get two rows, can anyone kindly help how can I get a single record and no 'N/A'
For the example you gave this would work:
WITH combined AS
(
SELECT i.issue_no,
CASE WHEN i.from_section = 'N/A' THEN i2.from_section ELSE i.from_section END from_section,
CASE WHEN i.to_section = 'N/A' THEN i2.to_section ELSE i.to_section END to_section
FROM dbo.tbl_issue i
INNER JOIN dbo.tbl_issue i2
ON i2.issue_no = i.issue_no
)
SELECT DISTINCT *
FROM combined c
WHERE c.from_section <> 'N/A' AND c.to_section <> 'N/A'
This is supposing that the 'N/A' is does not mean NULL...If you meant NULL replace "= 'N/A'" with IS NULL and replace "<> 'N/A'" with IS NOT NULL

Query to find if a foreign key is set

OK, I have two MySQL Tables:
TableA containing the following columns: idTableA and idTableB_FK
TableB containing the following columns: idTableB and idTableA_FK
The relationships are as follows:
One-to-Many relationship from TableA to TableB (TableA.idTableA is
the PK, and the FK for that relationship is TableB.idTableA_FK)
One-to-One relationship between TableA and TableB (TableB.idTableB
is the PK, and it is be represented in TableA.idTableB_FK). It is
a one-to-one relationship because you can only have one row in TableA to take a
foreign key value.
Assuming the following data in TableA
idTableA | idTableB_FK
-----------------------------
1 | 2
2 | 5
3 | 6
4 | 8
And the folloing in TableB
idTableB | idTableA_FK
------------------------------
1 | 1
2 | 1
3 | 2
4 | 2
5 | 2
6 | 3
7 | 3
8 | 4
Now, what I want a query that will display idTableA, idTableB, and will display is_set column. The is set is a yes/no field (or 1/0) where it is set to yes only if TableA.idTableB_FK has a corresponding set value for that FK. So for the above example:
idTableA | idTableB | is_set
---------------------------------------------
1 | 1 | no
1 | 2 | yes
2 | 3 | no
2 | 4 | no
2 | 5 | yes
3 | 6 | yes
3 | 7 | no
4 | 8 | yes
Thanks.
I think you are looking for something like this:
select
TableA.idTableA,
TableB.idTableB,
case when EXISTS(select null
from TableA TableA_1
where
TableA_1.idTableA = TableA.idTableA
and TableA_1.idTableB_FK = TableB.idTableB)
then 'yes' else 'no' end as is_set
from
TableB left join TableA
on TableB.idTableA_FK = TableA.idTableA
OK that was from memory but should do it. If it is wrong I can run it against something and fix it.
SELECT tb.idTableA_FK AS idTableA, tb.idTableB, tbb.idTableB IS NOT NULL AS is_set
FROM TableB AS tb LEFT JOIN TableA AS ta ON (tb.idTableA_FK = ta.idTableA)
LEFT JOIN TableB AS tbb ON (ta.idTableB_FK = tbb.idTableB)
I believe that this is what you're looking for:
SELECT a.idTableA, b.idTableB, c.idTableB_FK IS NOT NULL is_set
FROM TableA a, TableB b LEFT JOIN TableA c ON b.idTableB=c.idTableB_FK
WHERE b.idTableA_FK=a.idTableA
I ended up doing this:
SELECT b.idTableA_FK, b.idTableB ,
IF (
(SELECT a.idTableB_FK
FROM (TableA AS a)
WHERE a.idTableA = b.idTableA_FK
) = b.idTableB, TRUE, FALSE
) AS is_set
FROM (TableB AS b)
Which produced the correct results.
I like to thank all that responded, and I am voting up fthiella because his/her suggested solution was influential to my solution.

MySQL Select all differences between 2 tables?

I have 3 tables, 'old', 'new' and a 'result' table (from a phonebook database), they have the same structure and nearly the same entries.
old:
ID | name | number | email | ...
----+--------------------+--------+-------+-----
1 | foo | 123 | ...
2 | bar | 456 |
3 | entrry with typo | 012345 |
4 | John Doe | 123345 |
new:
ID | name | number | email | ...
----+--------------------+--------+-------+-----
1 | foo | 123 | ...
2 | bar | 456 |
3 | entry without typo | 012345 |
4 | John Doe | 12345 |
5 | newly added entry | 09876 |
From this 'new' table I would like to select all rows that are different from the 'old' table, so the result would be:
result:
ID | name | number | email | ...
----+--------------------+--------+-------+-----
3 | entry without typo | 012345 | ...
4 | John Doe | 12345 |
5 | newly added entry | 09876 |
including all entries that have changed data plus all entries that don't appear in 'old' table...
Not only to make it more complicated, there are about 10 columns in those tables (including ID, name, number, email and several flags and other info).
Is there any most performant solution for doing this or will I have to compare each column with a new query..?
You'll have to do some comparison on the old records for correctness but I think this is the most straight forward solution.
Update I was a little confused about icluding all entries that have changed data plus all entries that don't appear in 'old' table... So I added the where and modified the join clause
insert into result (id, name, number, email, ...)
select new.id, new.name, new.number, new.email, ...
from new
LEFT JOIN old
ON new.ID = old.id
WHERE
old.ID is null
OR
( new.name <> old.name
or
new.number <> old.number
or
new.email <> new.email
...)
SELECT new.*
FROM new
JOIN old ON new.id = old.id
WHERE (CONCAT(new.ID,new.name,new.number,etc...) <> CONCAT(old.ID,old.name,old.number,etc...))
That should pull up any records in the new table where at least one its fields differs from the equivalent record in the old table.
Assuming the IDs must match up in order to make the comparisons legitimate:
select n.*
from new n
left join old o on o.id = n.id
where o.id is null
or not (
and o.name = n.name
and o.number = n.number
and o.email = n.email
and ...)
Note, this solution handles the case where some of the fields can be NULL. If you use (o.name <> n.name) instead of not (o.name = n.name) you won't correctly consider NULLs to be different from non-nulls.