SQL Server 2008 : Updating a column based on other tables - sql-server-2008

TableA (id int, match char(15), multiple char(10))
int match multiple
1 100
2 101
3 102
4 103
TableB (match char(15), match2 char(10))
match match2
100 ABC
100 NBG
101 NYF
102 NHW
102 UYQ
103 WOT
Now, I want to populate TableA.multiple = "YES" if in TableB for corresponding match, there exists more than one match2.
Expected result.
int match multiple
1 100 YES
2 101 NULL
3 102 YES
4 103 NULL
Thanks in advance !
My FAILED try:
Update A
SET multiple = 'YES'
From tableA A
Inner join tableB B ON A.match = B.match
WHERE (Select count(distinct(B.match2)) from TableB) > 2

Start with an extra-verbose version, just for its clarity:
UPDATE TableA
SET multiple = 'YES'
WHERE match in (
-- isolate the multiples
SELECT match from (
-- count the matches
SELECT count(*) as c, match from TableB
GROUP BY match ) x
WHERE c > 1
)
With the HAVING clause, you can change this...
SELECT match from (
SELECT count(*) as c, match from TableB
GROUP BY match ) x
WHERE c > 1
...to this:
SELECT match from TableB
GROUP BY match
HAVING count(*) > 1
So now we have:
UPDATE TableA
SET multiple = 'YES'
WHERE match in (
SELECT match from TableB
GROUP BY match
HAVING count(*) > 1
)
I'm sure it can be made more compact, but I personally get confused by UPDATE statements containing non-obvious JOIN clauses, especially in the middle of the night when I get the call that "the database isn't working!"
Don't Make Me Think applies to coding, too.

UPDATE tableA
SET multiple = 'YES'
FROM TableA AS a
JOIN (SELECT match FROM tableB GROUP BY match HAVING COUNT(*) > 1) AS b ON a.match = b.match

UPDATE TableA a
SET multiple='YES'
FROM Tablea a,(SELECT match FROM Tableb GROUP BY match HAVING COUNT(*)>1)b
WHERE a.match=b.match

Related

How to check then display the result of two tables and check is exist or not-exist?

Tabel_A
---------
id name
1 Kursi
2 Roda
3 Gigi
Tabel_B
---------
id id_tabel_A
1 2
Result
--------
name Status
Kursi 0
Roda 1
Gigi 0
Query of the Result : …………………… ?
use left join and case when
select name, case when b.id_tabel_A is null then 0 else 1 end as status
from tableA a left join tableB b on a.id=b.id_tabel_A
You apply IF syntax
SELECT a.name,
IF(
(
SELECT count(b.id_tabel_A)
from Tabel_B as b
WHERE b.id_tabel_A = a.id -- connect
) > 0
, "YES", "NO") as status
from Tabel_A as a
I recommend using exists:
select a.name,
(exists (select 1
from tableB b
where a.id = b.id_tabel_A
)
) as status
from tableA a;
The reason I prefer exists is that it automatically handles duplicates in tableB. You don't have to worry about the query returning duplicate results.

Update record comparing different columns

What I'm trying is to generate a SQL statement that finds me in the rows that have repeated data, and at the same time in different columns.
My table is something like this:
ID DATE ONE TWO TRES status
-- ---------- --- --- --- -----
1 2018-02-18 21 22 23 B
2 2018-02-18 01 21 44 B
3 2018-02-18 55 66 77 B
What I have to do first is find the records that have the same date ... I have no problem.
The problem is when I try to compare columns ONE TWO and TRES to see if it has a value in common.
It is logical that I will have to go comparing from ONE to TWO, ONE to THREE and TWO to THREE.
In the example, row 1 and 2 have the same date and Column ONE has the same value as DOS and therefore it would have to update its status to E (error) ..
'UPDATE `table` SET `status` = "E" WHERE `DATE` = `DATE`'
Thank...
This query below will give you your desired result:
UPDATE TableName a
INNER JOIN
(
SELECT a.ID, b.ID AS ID2
FROM TableName a
INNER JOIN TableName b
ON a.Date = b.Date
AND
(
a.One = b.Two
OR a.One = b.Tres
OR a.Two = b.Tres
)
) b ON a.ID = b.ID OR a.ID = b.ID2
SET Status = 'E'
basically, what it does is it joins that table to a subquery which conditions you mentioned above to get the invalid rows and the resulting rows will be join again to itself and update its status to E.
Here's a Demo.

how to SELECT and Concat() column values based on several conditions SQL query?

newbie here to SQL. So I have two tables, let's take for example the two tables below.
Table A
set_num s_id s_val
100 3 AA
100 5 BB
200 3 AA
200 9 CC
Table B
s_id s_val phrase seq
1 DD 'hi' 'first'
3 AA 'hello' 'first'
6 EE 'goodnight' 'first'
5 BB 'world' 'second'
9 CC 'there' 'second'
4 FF 'bye' 'first'
I want to join Table A with Table B on two columns, like a composite key (s_id, s_val), and I want to return
set_num from Table A and the concatenation of phrases in Table B (which we will call entire_phrase, concat(...) AS entire_phrase).
The concatenation should also follow an order in which the phrases are to be concatenated. This will be determined by seq column in Table B for each phrase. "First" will indicate this phrase needs to come first and "Second", well comes next. I will like to do this with a SELECT query but not sure if this is possible without it getting to complex. Can I do this in SELECT or does this call for another approach?
Expected Output:
set_num entire_phrase
100 'hello world'
200 'hello there'
And not
set_num entire_phrase
100 'world hello'
200 'there hello'
Any help/approach will be greatly appreciated!
You can do it like this:
select temp1.set_num, concat(phrase1,' ',phrase2) as entire_phrase
from (
(
select set_num, b.phrase as phrase1
from TableA as A
join TableB as B
on a.s_id = b.s_id
and a.s_val = b.s_val
and b.seq = 'first'
) as temp1
join
(
select set_num, b.phrase as phrase2
from TableA as A
join TableB as B
on a.s_id = b.s_id
and a.s_val = b.s_val
and b.seq = 'second'
) as temp2
on temp1.set_num = temp2.set_num
)
Running here: http://sqlfiddle.com/#!9/d63ac3/1

why does where not exists expression does not give correct output

I have two tables :
Table:#a
id | name
10 | a
20 | b
30 | c
40 | d
50 | e
Table:#b
id | name
10 | a
30 | a
50 | a
I want all the #a table Id which are not present in #b
The following query works :
select * from #a as a
where not exists(select * from #b as b where a.id = b.id)
But I am not able to understand why the below query does not work
select * from #a as a
where exists(select * from #b as b where a.id <> b.id)
Why does where not exists expression does not give correct output
The first query does yield the right result : select all records from A where doesnt have appropriate match in B
But the second one is logically different.
Looking at :
;with A(id,name) as
(
select 10,'a' UNION ALL
select 20,'b' UNION ALL
select 30,'c' UNION ALL
select 40,'d' UNION ALL
select 50,'e'
) ,B(id,name) as
(
select 10,'a' UNION ALL
select 30,'a' UNION ALL
select 50,'a'
)
select * from a as a
where exists(select * from b as b where a.id <> b.id)
For each record from a, show that record if exists records from b with non-matched id.
So for 10,a (in a) there ARE(!) records from B where id is not 10 , hence it does YIELDS 10,a (from a)!
Now - do you see the problem ?

Complex SQL Querying: Two queries within the same table?

I have a table like:
ID | LABEL | SOME_VALUE
1 a rand_1
2 a NULL
3 b rand_9
4 c rand_3
5 c rand_3
6 c rand_3
7 d NULL
8 d rand_4
As you can see, ID is unique, label is not unique (can be 1 or more) and some_value is also not unique.
What I want to do is the following:
I want to get a unique list of LABELS, which exist in the database in more than one rows (min 2) and of which rows has SOME_VALUE not NULL.
So I would get:
ID | LABEL | SOME_VALUE
1 a rand_1
2 a NULL
7 d NULL
8 d rand_4
in return.
How can I achieve this?
There are two versions. First one does exactly as listed in results, eliminating rand_3 because even though it appears three times all the values are the same (I don't see distinct condition specified in question).
There must be a better way, but as they say I can't brain today, I have the dumb :-)
select *
from tbl
inner join
(
select label
FROM tbl
GROUP BY Label
HAVING count (distinct some_value)
+ sum(distinct case when some_value is null then 1 else 0 end) > 1
) a
on tbl.label = a.label
Second one retrieves C also following the requirements (some_value being not null for at least one of some_value).
select *
from tbl
inner join
(
select label
FROM tbl
GROUP BY Label
HAVING count(*) > 1 and count(some_value) > 0
) a
on tbl.label = a.label
And there is Sql Fiddle.
The HAVING parameter limits grouped items:
SELECT
Label
FROM dbo.TableName
WHERE NOT Some_Value IS NULL
GROUP BY Label
HAVING COUNT(*) > 2
SELECT t1.*
FROM yourTable t1
JOIN yourTable t2
ON t1.LABEL = t2.LABEL
AND t1.ID < t2.ID
WHERE t1.SOME_VALUE IS NOT NULL
OR t2.SOME_VALUE IS NOT NULL
This should work -
SELECT test.*
FROM (
SELECT label
FROM test
GROUP BY Label
HAVING COUNT(DISTINCT IFNULL(some_value, '~null~')) > 1
) AS tmp
INNER JOIN test
ON tmp.label = test.label;