Update a table based on joining 4 tables - mysql

I have the following tables:
agent
+-------------------------------------+
| id | name | desc | comment |
|-------------------------------------+
| 1 | agent1 | agent 1 | sss |
| 2 | agent2 | agent 2 | eee |
|-------------------------------------|
agent_old
+-------------------------------------+
| id | name | desc | comment |
|-------------------------------------+
| 1 | agent1 | agent 1 | sss |
| 2 | agent3 | agent 3 | eee |
|-------------------------------------|
auth
+-------------------------------+
| id | login | password |
|-------------------------------+
| 1 | agent1 | xxxxxxx |
| 2 | agent2 | yyyyyy |
|-------------------------------|
auth_old
+-------------------------------+
| id | login | password |
|-------------------------------+
| 1 | oldagent1 | wwwwww |
| 2 | oldagent2 | qqqqqq |
|-------------------------------|
I need the resultant tables like this:
agent
+-------------------------------------+
| id | name | desc | comment |
|-------------------------------------+
| 1 | agent1 | agent 1 | sss |
| 2 | agent2 | agent 2 | eee |
|-------------------------------------|
auth
+-------------------------------+
| id | login | password |
|-------------------------------+
| 1 |oldagent1 | wwwwww |
| 2 | agent2 | yyyyyy |
|-------------------------------|
This is what I have got but does not run:
update auth a
set
a.login = oa.login,
a.password = oa.password
from (
select o.login,
o.password
from auth_old o
join agent na
join agent_old ago
on ago.id = o.id
and na.name = ago.name
and na.desc = ago.desc
) oa
where a.id = na.id

In mysql you could use this sintax but you have not an id in you from ( select ) oa .. i have added the o.id for this (hope is the right one)
update auth a
inner join (
select o.login,
o.password ,
na.id
from auth_old o
join agent na
join agent_old ago
on ago.id = o.id
and na.name = ago.name
and na.desc = ago.desc
) oa on a.id = oa.id
set
a.login = oa.login,
a.password = oa.password
(and as suggested by Bill Karvin you have a wrong table alias na instead of oa)

Related

Retrieve the most recent values on records on 3 primary keys mySql

I have this table
+--------+--------+------+----------+----+----+
| pm | pm2 | pm3 | date |at1 | at2|
+--------+--------+------+----------+----+----+
| 111111 | | | 1/12/19 | a | |
| 111111 | 1010 | | 1/12/19 | b | |
| 111111 | 1010 | | 5/12/19 | | e |
| 111111 | 1010 | 56 | 1/12/19 |a | d |
| 111111 | 1010 | 56 | 5/12/19 | | c |
+---------------------------------------------+
and my desired output is the following:
+--------+--------+------+----------+----+----+
| pm | pm2 | pm3 | date |at1 | at2|
+--------+--------+------+----------+----+----+
| 111111 | | | 1/12/19 | a | |
| 111111 | 1010 | | 5/12/19 | b | e |
| 111111 | 1010 | 56 | 5/12/19 | a | c |
+---------------------------------------------+
What I want to do is check the combination of the three pms, and then update each of the fields with the most recent value (if there is any - if not then it just keeps the value it already has)
I am using this code
select * from tab INNER JOIN(select pm1, pm2, pm3, MAX(date) as maxdt
from tab
group by pm1, pm2, pm3)ms
on (tab.pm1 = ms.pm1 and tab.pm2 = ms.pm2 and tab.pm3 = ms.pm3 and date = maxdt)
but it is not entirely working and I am not so familiar with sql. Someone that could help me? Thank you!
There are nulls in the columns pm2 and pm3, so instead of = in the ON clause you should use <=> (NULL-safe equal to operator) and in the select list use coalesce():
select t.pm, t.pm2, t.pm3, t.date,
coalesce(t.at1, g.at1) at1, coalesce(t.at2, g.at2) at2
from tab t inner join (
select pm, pm2, pm3,
max(date) date, max(at1) at1, max(at2) at2
from tab
group by pm, pm2, pm3
) g on g.pm = t.pm and g.pm2 <=> t.pm2 and g.pm3 <=> t.pm3 and g.date = t.date
See the demo.
Results:
| pm | pm2 | pm3 | date | at1 | at2 |
| ------ | ---- | --- | ------------------- | --- | --- |
| 111111 | | | 0001-12-19 00:00:00 | a | |
| 111111 | 1010 | | 0005-12-19 00:00:00 | b | e |
| 111111 | 1010 | 56 | 0005-12-19 00:00:00 | a | c |

Join 3 Tables in a MySql Query

i have this 3 tables in a MySql Database.
users
+----+------+--------+------+
| Id | Name | Status | Role |
+----+------+--------+------+
| 1 | A | Aktiv | Op |
| 2 | B | Aktiv | Op |
| 3 | C | Aktiv | Op |
| 4 | D | Aktiv | Op |
+----+------+--------+------+
cnt
+----+------+------------+------+
| Id | Name | Date | Type |
+----+------+------------+------+
| 1 | A | 2017-11-09 | Web |
| 2 | B | 2017-11-09 | Web |
| 3 | C | 2017-11-09 | Web |
| 4 | C | 2017-11-09 | Inb |
| 5 | A | 2017-11-09 | Web |
+----+------+------------+------+
Lead
+----+------+------------------+------------+
| Id | Name | Date | Type |
+----+------+------------------+------------+
| 1 | A | 2017-11-09 00:24 | Imported |
| 2 | B | 2017-11-09 09:32 | Activation |
| 3 | B | 2017-11-09 10:56 | Activation |
| 4 | D | 2017-11-09 12:21 | Activation |
| 5 | D | 2017-11-10 12:22 | Activation |
+----+------+------------------+------------+
I'm trying to join them in a main table but with no success, the query i'm using is:
SELECT IFNULL(u.Name,'Total') as "Name",
Sum(IF(c.Type = 'Web',1,0)) as "Cnt Web",
Sum(IF(l.Type = 'Activation',1,0)) as "Lead Web"
FROM users u
LEFT JOIN cnt c ON u.Name = c.Name and c.Date = '2017-11-09'
LEFT JOIN lead l ON u.Name = l.Name and l.Date>= '2017-11-09' AND l.Date< '2017-11-10'
WHERE u.Status = 'Aktiv' AND u.Role = 'Op'
GROUP BY u.Name WITH ROLLUP
The result i need is a table like this:
+----+------+--------+---------+
| Id | Name | Cnt Web| Lead Web|
+----+------+------------------+
| 1 | A | 2 | 0 |
| 2 | B | 1 | 2 |
| 3 | C | 1 | 0 |
| 4 | D | 0 | 1 |
+----+------+------------------+
When i try to join the first table with the second or the first with the third, i get the correct result, but i can't get the needed result when i join them all.
Any answer is the most welcomed. Thank you in advance.
Here's a solution using correlated sub-queries
SELECT u.Id,
u.Name,
(SELECT COUNT(Name) FROM cnt WHERE Name = u.name AND type = 'Web' AND Date = '2017-11-09') AS cnt_web,
(SELECT COUNT(Name) FROM lead WHERE Name = u.name AND type = 'Activation' AND Date>= '2017-11-09' AND Date< '2017-11-10') AS cnt_lead
FROM users u
WHERE u.Status = 'Aktiv' AND u.Role = 'Op'

Mysql, repeat row by the max count of details

I have two tables
Master table
|-----------|--------|------------|
| id_client | name | ci |
|-----------|--------|------------|
| 1 | B | 123 |
| 2 | A | 234 |
| 3 | C | 345 |
|-----------|--------|------------|
Detail of equipments
|-----------|--------------|
| id_client | id_equipment |
|-----------|--------------|
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
|-----------|--------------|
The result that I expected is:
All clientes with or without equipments
|-----------|----------------|----------------|
| id_client | id_equipment | numberEquipment|
|-----------|----------------|----------------|
| 1 | 1 | Equip1 |
| 1 | 2 | Equip2 |
| 2 | 3 | Equip1 |
| 2 | - | Equip2 |
| 3 | - | Equip1 |
| 3 | - | Equip2 |
|-----------|----------------|----------------|
Client 1 have two equipments and this is the max cant of equipments assigned, then, all clientes with minor than two have to fill the detail empty two times. client 2 have one equipment assigned, the second will be empty, and cliente 3 doesnt have any equipment, then the two equipments will be empty.
I was implemented crosstab on jasperreport, i have to define de columnGroup, when the name of group Equipment1, equipment2... etc, doesnt exist on any row this column group doesnt show.
I hope someone can helpme.
Thanks.
SELECT CONCAT('EQUIPMENT ',g.ennum) AS numberEquipment,
g.ID_CLIENTE as id_client, g.ID_EQUIPO as id_equipment,
(SELECT #running1:= 0) AS running1,(SELECT #previous1:= 0) AS previous1
FROM (
SELECT c.ID_CLIENTE, eq.ID_EQUIPO
#running1:=if(#previous1=concat(eq.ID_CLIENTE),#running1,0) + 1 as ennum, #previous1:=concat(eq.ID_CLIENTE)
FROM CLIENTE AS c
LEFT JOIN detail_equipments AS eq ON eq.ID_CLIENTE = c.ID_CLIENTE
ORDER BY c.ID_CLIENTE ) AS g
GROUP BY g.ID_CLIENTE, g.ID_EQUIPO
ORDER BY ID_CLIENTE, g.ennum
this show
|-----------|----------------|----------------|
| id_client | id_equipment | numberEquipment|
|-----------|----------------|----------------|
| 1 | 1 | Equip1 |
| 1 | 2 | Equip2 |
| 2 | 3 | Equip1 |
| 3 | - | Equip1 |
|-----------|----------------|----------------|

Update column value by querying concatenated column values with another table value

I have two tables as below. The Id column value in both the tables mentioned below is auto-incremented.
Group
+----+-----------+----------------+
| Id | GroupId | GroupName |
+----+-----------+----------------+
| 1 | 10 | Grp1#abc.com |
| 2 | 20 | Grp2#abc.com |
| 3 | 30 | Grp3#xyz.com |
| 4 | 40 | Grp4#def.com |
+----+-----------+----------------+
Customer
+---+-----------------+------------+----------+---------------+
| Id | GroupAliasName | Domain | GroupId | CustomerName |
+---+-----------------+------------+----------+---------------+
| 1 | Grp1 | abc.com | null | Cust1 |
| 2 | Grp2 | abc.com | null | Cust2 |
| 3 | Grp3 | xyz.com | null | Cust3 |
| 4 | Grp4 | def.com | null | Cust4 |
+---+-----------------+------------+----------+---------------+
Now from Customer table 'GroupAliasName' and 'Domain' when concatenated as 'GroupAliasName#Domain' is equivalent to 'GroupName' in Group table.
Using the concatenated value from Customer table, I need to pull the 'GroupId' from the Group table and populate the same in Customer table's 'GroupId' as below
Customer
+----+----------------+------------+----------+---------------+
| Id | GroupAliasName | Domain | GroupId | CustomerName |
+----+----------------+-----------+---------+-----------------+
| 1 | Grp1 | abc.com | 10 | Cust1 |
| 2 | Grp2 | abc.com | 20 | Cust2 |
| 3 | Grp3 | xyz.com | 30 | Cust3 |
| 4 | Grp4 | def.com | 40 | Cust4 |
+----+----------------+------------+----------+---------------+
The query which I tried is as below
UPDATE Customer SET GroupId =
(SELECT GroupId FROM Group G
WHERE GroupName =
(SELECT CONCAT(GroupAliasName, '#', Domain) AS GroupName
FROM Customer
WHERE Domain IS NOT NULL) AND G.GroupName = GroupName);
But I get error as 'Subquery returns more than 1 row'.
Please suggest or provide your inputs.
Try this:
update customer as cust
inner join `group` grp on concat(cust.groupaliasname, '#', cust.domain) = grp.groupname
set cust.groupId = grp.groupId;
Try with somethings like this
UPDATE Customer as c
INNER JOIN Group as g on ( CONCAT(c.GroupAliasName, '#', c.Domain) = g.GroupName)
SET c.GroupId = g.GroupId;

Left join select using Propel ORM

I have 3 table
major table:
+----+------------+
| id | major |
+----+------------+
| 1 | Computer |
| 2 | Architect |
| 3 | Designer |
+----+------------+
classroom table:
+----+----------+-------+
| id | major_id | name |
+----+----------+-------+
| 1 | 1 | A |
| 2 | 1 | B |
| 3 | 1 | C |
| 4 | 2 | A |
| 5 | 2 | B |
| 6 | 3 | A |
+----+----------+-------+
and finally, student_classroom table
+----+------------+--------------+----------+
| id | student | classroom_id | status |
+----+------------+--------------+----------+
| 1 | John | 1 | Inactive |
| 2 | Defou | 2 | Active |
| 3 | John | 2 | Active |
| 4 | Alexa | 1 | Active |
| 5 | Nina | 1 | Active |
+----+------------+--------------+----------+
how can I use propel to build query below
select
a.id,
a.major,
b.number_of_student,
c.number_of_classroom
from major a
left join (
select
major.major_id,
count(student_classroom.id) as number_of_student
from major
left join classroom on classroom.major_id = major.id
left join student_classroom on student_classroom.classroom_id = classroom.id
where student_classroom.`status` = 'Active'
group by major_id
) b on b.major_id = a.major_id
left join (
select
major.major_id,
count(classroom.id) as number_of_classroom
from major
left join classroom on classroom.major_id = major.id
group by major_id
) c on c.major_id = a.major_id
Because I want the final result would be something like this, I spend hours trying to figure it out without success.
+----+------------+-------------------+---------------------+
| id | major | number_of_student | number_of_classroom |
+----+------------+-------------------+---------------------+
| 1 | Computer | 4 | 3 |
| 2 | Architect | 0 | 2 |
| 3 | Designer | 0 | 1 |
+----+------------+-------------------+---------------------+
Try this
select
m.id,
m.major,
count(distinct s.id) as number_of_student ,
count(distinct c.id) as number_of_classroom
from major m
left join classroom c on
(m.id = c.major_id)
left join student_classroom s
on (s.classroom_id = c.id and c.major_id = m.id and s.status = 'active')
group by m.id
order by m.id