write query using joins using condition - mysql

there arr two tables table1,table2.
table1:
number
type
name
1100
1
steve
1100
2
john
1100
2
jack
.....
and so on for different numbers
similiarly table2:
number
type
name
1100
1
abraham
1100
2
john
1100
2
jack
and so on for different numbers...
Expected output:join two tables based on equal number and equal type but on name condition it should print where there is mismatch.for example in above john had type '2' in table 1 and in table 2 also there is john but for type '1' it is mismatch as steve <> abraham.I am doing this query but the output contains rows with jack and john too:
number
type
name1
name2
1100
1
steve
abraham
1100
2
john
jack
1100
2
jack
john
here the number of rows in table 1 and table 2 are equal similiarly number of rows for each type in each table are also equal
select * from table1,table2 where table1.number=table2.number and table1.type=table2.type and table1.name <> table2.name
expected output:
number
type
name1
name2
1100
1
steve
abraham
As you can see above I have given the output which I got for my query(it contains jack,John pairs but I don't want them as for type '2' names are same in both tables)but if you see for type '1' names are different in both tables so I want to print them.if names are different in type'2' for both tables I want them too as output but here in example names are same in both tables for type '2'.Can anyone help me..?

I think this will do what you want.
SELECT table1.number
,table1.type
,table1.name
,table2.name
FROM table1
JOIN table2 ON
table2.number = table1.number AND
table2.type = table1.type AND
table1.name NOT IN (SELECT t2.name
FROM table2 t2
WHERE t2.number = table1.number AND
t2.type = table1.type)

Related

Need to filter out conditional values from MySql table

I stuck with this kind of scenario wherein I need to extract the IDs based on this logic.
In this example, I want to extract the following combination in the output:
INCLUDE the result if:
source has one or more combinations of - Raja, Ravi or Sam
And
Exclude the ID if:
Source has one or more combinations of - Jane, Jake, or Jude.
ID
Source
1
Raja
1
Ravi
2
Sam
2
Raja
3
Jake
3
Raja
3
Sam
3
Jane
4
Sam
4
Jake
4
Jude
Output, I'm expecting as:
ID
1
2
This source table will always have more than 1 source value for each id.
Thanks in advance.
Use aggregation and set the conditions in the HAVING clause:
SELECT ID
FROM tablename
GROUP BY ID
HAVING SUM(Source IN ('Raja', 'Ravi', 'Sam')) > 0
AND SUM(Source IN ('Jane', 'Jake', 'Jude')) = 0;
See the demo.
a good example to use EXISTS and NOT EXISTS.
Here is a way to do this
select distinct t.id
from table t
where exists (select 1
from table t2
where t2.id=t.id
and t2.name in ('Raja','Ravi','Sam')
and not exists(select 1
from table t3
where t3.id=t.id
and t3.name in ('Jane','Jake','Jude')
)

Mysql update row value in table based on different row

I have the following table structure
TABLE A
Productid price groupId
1 100 A
2 99 A
3 0 A
4 50 B
5 49 B
6 0 B
I populate table A with prices from table B joining on Id. Sometimes table B doesn't have prices.
In cases were b doesn't have price I want to update the price to be another price from that same group, as I can't have a price of zero.
Is there an way to update table a price column using itself based on group? e.g. update productId 3 price to be the price of another product in it's group (1 or 2)
TABLE A after update
Productid price groupId
1 100 A
2 99 A
3 100 A
4 50 B
5 49 B
6 49 B
It seems silly but these are the business rules (it makes sense irl I simplified the problem for the example)
When I tried the following I got Error:
update 'Table A' t1
join (select price ,groupId from 'table A' where Price > 0 group by
groupId) as t2
on t1.groupId = t2.GroupId
SET t1.Price = t2.Price
(conn=58292) Can't reopen table: 'Table A'
I've thought of creating a third temporary table but that seems.... wrong? I am sure there must be a way to do this using update statement and joins
I would phrase the query as:
update tablea a
inner join (select groupId, max(price) price from tablea group by groupId) a1
on a1.groupId = a.groupId
set a.price = a1.price
where a.price = 0 and a1.price > 0
Notes:
the table name should be surrounded with single quotes (those stand for literal strings) - if your table name really contains spaces, then use backticks for quoting (or better, yet, fix the table name!)
I changed the subquery to make it a valid aggregation query - yours has non-aggregated columns that do not belong to the group by clause, which is not a good practice, and might generate errors, depending on the SQL mode of your database
In this demo on DB Fiddlde with your sample data, the content of the table after update is:
Productid | price | groupId
--------: | ----: | :------
1 | 100 | A
2 | 99 | A
3 | 100 | A
4 | 50 | B
5 | 49 | B
6 | 50 | B

Select data from multiple tables in mysql database

I have a database with multiple tables that I am selecting from. In some tables I have 2 entries fr the same case and while selecting I want to retrieve both those values. My issue is if out of 8 tables 2 tables have two entries for a column then in the final output i see 4 rows for the same case with columns populated from all the tables which makes it difficult to know which columns have two entries.
Example
Table1:
case_id company_id date location_type
1 123 08-07-2020 rest1
2 234 01-01-1999 rest2
3 456 01-01-1995 rest1
Table2:
Case_id type Series
1 A ABCD
1 A GEFT
2 B TRFG
3 A HJKL
Table3:
Case_id type Series
1 A UIPO
2 A GGTH
3 B TYUI
The query:
SELECT Table1.company_id,"|",Table2.type, Table3.type FROM Table1
LEFT JOIN Table2 ON Table1.case_id = Table2.case_id
LEFT JOIN Table3 ON Table1.case_id = Table3.case_id
where Table1.location_type = "rest1"
This is what I get:
company_id type type
123 A A
123 A A
456 A B
How do I get:
company_id type type
123 A A
123 A NULL
456 A B

How can I retrieve multiple rows from a table and display the combined information in a single query?

I have used a dynamic form builder plugin in WordPress. When I input some data from this form data inserted in the table. The table looks like below.
id entry_id field_id slug value
1 1 fld_7213434 name abc
2 1 fld_5474822 father def
3 1 fld_4459896 gender Female
4 1 fld_6364274 village_name ijk
20 2 fld_7213434 name J Jahan
21 2 fld_5474822 father Md Ali
22 2 fld_4459896 gender Female
23 2 fld_6364274 village_name ijk
I need to show this table's data like below
S.N. name father gender village_name
1 abc def Female ijk
2 J Jahan Md Ali Female Adabor
How can I do that?
One idea is to join the table to itself:
SELECT
t1.entry_id `S.N.`,
t1.value name,
t2. value father,
t3.value gender,
t4.value village_name
FROM mytable t1
LEFT JOIN mytable t2 ON t2.entry_id = t1.entry_id AND t2.field_id = 'fld_5474822'
LEFT JOIN mytable t3 ON t3.entry_id = t1.entry_id AND t3.field_id = 'fld_4459896'
LEFT JOIN mytable t4 ON t4.entry_id = t1.entry_id AND t4.field_id = 'fld_6364274'
WHERE
t1.field_id = 'fld_7213434'
Of course, instead of mytable you have to use your correct table name that you have not mentioned in your question.
A join is the Cartesion product (Wikipedia) of all involved tables. After filtering the resulting set of rows for those with the correct combinations (in this case, entry_id and field_id must be filtered), you get exactly what you want.
For performance reasons, you might want to have an index on the columns entry_id and field_id, but you'll find out.

Find difference in 2 tables / recordsets MySQL

I have 2 tables in MySQL DB (A and B)
Both have very similar structure since table B has records that are inserted with all data each time user changes his data in table A to have full history of changes. Column Lastupdate is INT type and keeps time of update in UNIX timestamp format
So let’s say tables have records like that:
TableA
Id User_id Name1 Name2 Lastname Lastupdate
1 12 John Alexander Smith 1405594757
2 27 Marry Ann Poppins 1405594877
3 51 Jean Claude VanFist 1405594677
Table B
Id User_id Name1 Name2 Lastname Lastupdate
1 12 John Alexander Smit 1405594747
2 27 Marry Ann Poppins 1405594757
3 51 Jean Claude VanFist 1405594757
1 12 John 1405594727
1 12 John Alex 1405594737
3 51 Jean VanFist 1405594757
For each record from table A I would like to see comparison with the most current record of table B (basing on Lastupdate) with the information which field was changed
So for user_id = 12 I would have something like
Id User_id Name1 Name2 Lastname Lastupdate
1 12 John Changed name2:Alexander Changed lastname:Smith 1405594757
I was trying something like that
SELECT if(u1.name1 <> u2.name1, CONCAT("Changed: ",u1.name1), u1.name1)
FROM tableA u1,tableB u2
WHERE u1.user_id = 7433 AND u2.user_id = 7433
But it seems not to be right way please advise
This should indicate what field values changed as well as what they were and what they became:
select a.user_id,
case when a.name1 <> b.name1 then concat(b.name1,' changed to ',a.name1) else null end as name1_chg,
case when a.name2 <> b.name2 then concat(b.name2,' changed to ',a.name2) else null end as name2_chg,
case when a.lastname <> b.lastname then concat(b.lastname,' changed to ',a.lastname) else null end as lastname_chg
from tablea a
join tableb b
on a.user_id = b.user_id
where b.lastupdate = (select max(x.lastupdate)
from tableb x
where x.lastupdate < a.lastupdate and x.user_id = a.user_id)