select a field values that are not found in another table - mysql

I need a query which should results a fields that are not found in another table. Let say,
table 1:
comp col1 col2 col3 col4
----------------------------------
nam1 1 1 b c
nam2 0 0 abc c
nam3 1 1 a c
nam4 1 1 b c
nam5 0 0 c c
table2:
name col1 col2
----------------------
b 3 f
a 4 f
c 5 f
result:
comp col3 col4
----------------------
nam2 abc c
the result be based on col3,col1=0,col2=0 on first table and name in second table..abc is not found in table2...
thanks in advance.

The question is not very clear, but if I understood you correctly, you want to select all rows from table1 where col1 and col2 are both 0, and col3 is not contained in the name column of table2. If so, your query should be simple enough:
SELECT comp, col3, col4
FROM table1
WHERE col1 = 0
AND col2 = 0
AND col3 NOT IN (SELECT name FROM table2);

As per the explanation the joining key between table1 and table2 is
table1.col3 = table2.name
Using this you can use the following query
select
t1.comp,
t1.col3,
t1.col4
from table1 t1
left join table2 t2 on t2.name = t1.col3
where t2.name is null

Related

SQL query optimization join union distinct

I have a query:
Select A.col1 as col1, B.col5 as col2, C.col10 as col3
FROM Table A
JOIN Table B on(A.col2 = B.col2)
JOIN table C on(C.col1 = B.col3)
UNION
SELECT A.col1 as col1, B.col5 as col2, NULL as col3
FROM Table A
JOIN Table B on (A.col2 = B. col2)
where A.col4 != 'somevalue'
Any way of making this faster??
Table A
--------
col1 col2 col4
gerry 1 'somevalue'
harry 2 'othervalue'
tom 3
sarah 4 'somevalue'
col2 of table A is the primary key
Table B
-------
col2 col3 col5
1 45 34
1 34 23
1 56 67
2 34 56
Primary key of B is (col2, col3)
Table C
-------
col1 col10
34 'heyya'
467 'tyga'
56 'pity'
Primary key of C is also composite. one of these keys is col1
Output:
col1 col2 col3
gerry 23 'heyya'
gerry 67 'pity'
gerry 34 NULL
harry 56 'heyya'
So values of B that have presence in C or have 'somevalue' in A are called. Also values having both are also called.
is this OK for you ? so you get all rows and if A.col4 <> 'somevalue' then you get NULL for col3
Select
A.col1 as col1
, B.col5 as col2
, C.col10 as col3
, if(A.col4 != 'somevalue', 1, 0) as col4
FROM Table A
JOIN Table B on(A.col2 = B.col2)
JOIN table C on(C.col1 = A.col3);

mysql case statement for counting

Table t1
col1 col2 col3
---- ---- ----
1 cat 2
2 dog 3
3 cat 4
4 dog 5
Table t2
id type
---- ----
1 a
2 a
3 b
4 b
I want to transform it such that it becomes this:
col2 a b
---- ---- ----
cat 2 4
dog 3 5
Query
Select t1.col2,
case when t2.type = 'a' then count(t1.col3) end as a,
case when t2.ab = 'b' then count(t1.col3) end as b
From mytable t1 join mytable2 t2 on t1.col1=t2.id where t1.col3 is not null
group by 1;
It populates only a or b column.
What is wrong with my query?
You need to move the case statement into the count() (or sum()) itself:
Select t1.col2,
count(case when t2.type = 'a' then 1 else null end) as a,
count(case when t2.type = 'b' then 1 else null end) as b
From mytable t1 join mytable2 t2 on t1.col1=t2.id where t1.col3 is not null
group by 1;

Mixing 3 sql queries in 1

I have 3 tables as follows
Table1
Id Name
1 abcd
2 bcd
3 dabc
Table2
Id2 Name2
2 xyz
3 def
4 mno
Table3
Id Id2 Value
1 4 1
2 3 1
3 4 1
Now,
From table1 : I have to select all Id where Name is %abc%
From table2: I have to select Id2 where Name2 is "mno"
From Table3: I have to change value to 0 from 1 where Id's value are from Table1 and Id2 is from Table2.
Table 1:
select Id from Table1 where Name like '%abc%'
Table2 :
select Id2 from Table2 where Name2 = "mno"
Table 3:
update Table3 set Value = 0 where Id in() and Id2=
But, I dont know how to make it 1 single query. Can anyone please guide me up ?
Refer to: prior stack article
You've not explained how T1 relates to T2, So I have assumed a cross join.
Whenever you have a record in T1 with name like '%abc%' (1,3) in your data..
and whenever you have a record in T2 with a name equal to 'mno' 4 then you want the value in table 3 to be 0
so the select we generate should produce
1,4
3,4
and when we inner join this back to table 3 it only selects
Id Id2 Value
1 4 1
3 4 1
Now we generate an update based on this select as outlined in the link provided above...
UPDATE table3
INNER JOIN (
SSELECT t1.ID t1ID, t2.id t2ID
FROM table1 t1
CROSS JOIN table2
WHERE t1.name like '%abc%'
and t2.name like = 'mno') B
on B.t1ID = t3.Id
and B.t2ID = T3.ID2
SET value = 0
Giving us a result of
Id Id2 Value
1 4 0
2 3 1
3 4 0
if we select * from table3
update t3
set t3.Value = 0
from Table3 t3
inner join Table1 t1
on t3.Id = t1.Id
inner join Table2 t2
on t3.Id2 = t2.Id2
where t1.Name like '%abc%' and t2.Name2 = 'mno'
OR
update Table3
set value = 0
where Id in (select Id from Table1 where Name like '%abc%')
and Id2 in (select Id2 from Table2 where Name2 = 'mno')
You should think about UPDATE ... WHERE EXISTS as follows:
update Table3 set Value = 0
WHERE EXISTS (SELECT 1 FROM Table1 where Name LIKE '%abc%' AND Table1.Id=Table3.Id )
AND EXISTS (SELECT 1 FROM Table2 where Name2 = "mno" AND Table2.Id2=Table3.Id2)

Show only differences between two rows in mysql

Having a (MySQL) audit table containing rows that are similar, is it possible to view only those columns that have different values?
For example, a table containing four columns where column key is primary key, and column id is the identifier to match rows:
key id col1 col2
1 123 B C
2 123 A C
3 456 B C
4 789 B A
5 789 B B
6 987 A C
In the example above I need the query to return only row 1, 2, 4, and 5 as they have matching id, and differing values in col1 and col2, ie B,A and B,A.
key id col1 col2
1 123 B
2 123 A
4 789 A
5 789 B
I know it might not be very efficient solution, but gives what you want. HERE try this:
SELECT A.ID, (CASE A.col1 WHEN B.col1 THEN NULL ELSE B.col1 END), (CASE A.col2 WHEN B.col2 THEN NULL ELSE B.col2 END) FROM tblName A
FULL OUTER JOIN tblName B
ON
A.ID=B.ID
WHERE
(A.col1=B.col1 AND A.Col2<>B.Col2)
OR
(A.col2<>B.col2 AND A.Col1=B.Col1)
INNER JOIN should give same result
This is a bit contrived, in the sense that adding more rows will give very different results - but anyway...
SELECT x.my_key
, x.id
, IF(y.col1=x.col1,'',x.col1) col1
, IF(y.col2=x.col2,'',x.col2) col2
FROM my_table x
JOIN my_table y
ON y.id = x.id
AND y.my_key <> x.my_key
WHERE (y.col1 <> x.col1 OR y.col2 <> x.col2)
ORDER
BY my_key;
Thanks for all responses which guided me.
Using your suggestions I made the sql like this:
SELECT
T1.KEY,
T1.ID,
CASE T2.COL1_DISTINCT_VALUES WHEN 1 THEN NULL ELSE T1.COL1 END AS COL1,
CASE T2.COL2_DISTINCT_VALUES WHEN 1 THEN NULL ELSE T1.COL2 END AS COL2
FROM
TAB1 T1
INNER JOIN
(
SELECT
ID,
COUNT(DISTINCT COL1) AS COL1_DISTINCT_VALUES,
COUNT(DISTINCT COL2) AS COL2_DISTINCT_VALUES
FROM
TAB1
GROUP BY
ID
) T2
ON T1.ID=T2.ID
WHERE
T2.COL1_DISTINCT_VALUES > 1
OR T2.COL2_DISTINCT_VALUES > 1
ORDER BY
KEY,ID;

Comma-separated columns in SQL Server

I have a problem: I have two tables
Table1 which has two columns
Col1 Col2
---- ------
a value1
b value1
b value1
And Table2
Col1 Col2
---- ------
1 a,b
2 a,c
3 a,b,c
I want result
Col1 Col2
----- -----
a 1,2,3
b 1,3
c 2,3
WITH C AS
(
SELECT T2.Col1,
S.Item
FROM Table2 AS T2
CROSS APPLY dbo.SplitStrings(T2.Col2, ',') AS S
)
SELECT C1.Item AS Col1,
(
SELECT ','+CAST(C2.Col1 AS VARCHAR(10))
FROM C AS C2
WHERE C1.Item = C2.Item
ORDER BY C2.Col1
FOR XML PATH(''), TYPE
).value('substring(text()[1], 2)', 'VARCHAR(MAX)') AS Col2
FROM C AS C1
GROUP BY C1.Item
SQL Fiddle
Try this:
NOTE: Not tested
select col1, [col2],
(select col1+',' from Table2 where Col2=ID
group by col1 for xml path('')) AS Col2
From Table1