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
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.
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.
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
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 ?
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;