I tried to update my main table --> budget with values from item_master table with condition
Here's the table structure
budget :
+-------------------+---------------+------+-----+------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+---------------+------+-----+------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| department | varchar(50) | YES | | NULL | |
| section | varchar(50) | YES | | NULL | |
| budget_id | varchar(50) | NO | | NULL | |
| carmaker | varchar(255) | YES | | NULL | |
| carline | varchar(255) | YES | | NULL | |
| phase | varchar(255) | YES | | NULL | |
| purpose | varchar(50) | YES | | NULL | |
| order_plan | varchar(50) | YES | | NULL | |
| required_date | varchar(50) | YES | | NULL | |
| subgroup | varchar(255) | YES | | NULL | |
| item_desc | varchar(255) | YES | | NULL | |
| item_code | varchar(255) | YES | | NULL | |
| qty | int(11) | YES | | NULL | |
| curr | char(3) | YES | | NULL | |
| price | decimal(20,2) | YES | | NULL | |
| amount_ori | decimal(20,2) | YES | | NULL | |
| amount | decimal(20,2) | YES | | NULL | |
| amount_reduce_ori | decimal(20,2) | NO | | NULL | |
| amount_reduce_usd | decimal(20,2) | NO | | NULL | |
| qty_reduce | decimal(20,2) | NO | | NULL | |
| qty_final | int(11) | YES | | NULL | |
| amount_final | decimal(20,2) | YES | | NULL | |
| status | varchar(50) | YES | | uncommited | |
| source | varchar(50) | YES | | NULL | |
| coa_production | char(7) | YES | | NULL | |
| coa_general | char(7) | YES | | NULL | |
| hfm_cr | char(6) | YES | | NULL | |
| hfm_pl | char(6) | YES | | NULL | |
| update_record | varchar(50) | YES | | NULL | |
| user | varchar(50) | YES | | NULL | |
+-------------------+---------------+------+-----+------------+----------------+
item_master :
+----------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| subgroup | varchar(255) | NO | | NULL | |
| item_desc | varchar(255) | NO | | NULL | |
| item_code | varchar(255) | NO | | NULL | |
| uom | varchar(255) | NO | | NULL | |
| price | decimal(20,2) | NO | | NULL | |
| coa_production | char(7) | NO | | NULL | |
| coa_general | char(7) | NO | | NULL | |
| hfm_cr | varchar(50) | NO | | NULL | |
| hfm_pl | varchar(50) | NO | | NULL | |
+----------------+---------------+------+-----+---------+----------------+
I'm trying to get coa_production or coa general , depend on purpose field
if the first three (3) characters = 'PRO' then use coa_production, else use coa_general with item_code as the unique string/foreign keys
Here's my current code :
UPDATE budget CASE
WHEN SUBSTR(purpose,1,3) = 'PRO' THEN
SET coa_production = (SELECT coa_production FROM item_master WHERE budget.item_code = item_master.item_code) ELSE
SET coa_general = (SELECT coa_general FROM item_master WHERE budget.item_code = item_master.item_code) END
my goal is when purpose = 'PRO' then the only field that has to be filled is coa_production using the value from item_master table, so does if purpose = 'GEN' then the only field that has to be filled is coa_general
I would express this using an update join:
UPDATE budget b
LEFT JOIN item_master im
ON b.item_code = im.item_code
SET
b.coa_production = CASE WHEN LEFT(b.purpose, 3) = 'PRO' THEN im.coa_production END,
b.coa_general = CASE WHEN LEFT(b.purpose, 3) = 'GEN' THEN im.coa_general END
WHERE
LEFT(b.purpose, 3) IN ('PRO', 'GEN');
Note that a left join (rather than an inner join) is required here, to keep the behavior the same as your original query. Using a left join, a NULL would be assigned to a column which did not find any matching record in the item_master table.
Related
I have a table with the following structure:
+-----------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+-------------------+-----------------------------+
| imovel_id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | | NULL | |
| img_dest | varchar(111) | YES | | NULL | |
| data_imob | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| finalidade_imob | varchar(51) | NO | MUL | NULL | |
| status_imob | varchar(51) | NO | | NULL | |
| tipo_imob | varchar(255) | YES | | NULL | |
| uf_imob | varchar(51) | NO | MUL | NULL | |
| cidade_imob | varchar(255) | NO | | NULL | |
| bairro_imob | varchar(255) | YES | | NULL | |
| rua_imob | varchar(255) | YES | | NULL | |
| vaga_imob | varchar(255) | YES | | NULL | |
| dorms_imob | char(2) | YES | | NULL | |
| tamanho_imob | varchar(222) | YES | | NULL | |
| valor_imob | varchar(255) | YES | | 0 | |
| titulo_imob | varchar(255) | YES | | NULL | |
| descricao_imob | longtext | YES | | NULL | |
| carac_imob | varchar(255) | YES | | NULL | |
+-----------------+--------------+------+-----+-------------------+-----------------------------+
If I run this query:
SELECT * FROM form_imovel LEFT JOIN (form_user) ON (form_user.user_id = form_imovel.user_id) WHERE MATCH(finalidade_imob,status_imob,tipo_imob,uf_imob,cidade_imob,bairro_imob,dorms_imob,valor_imob) AGAINST ('Comprar' IN BOOLEAN MODE);
Where Comprar is the value from finalidade_imob column, I have the right results, that work with all columns, except uf_imobcolumn.
The uf_imobcolumns have values like: SP,MG,RJ.
If I try run the following query, it returns empty:
SELECT * FROM form_imovel LEFT JOIN (form_user) ON (form_user.user_id = form_imovel.user_id) WHERE MATCH(finalidade_imob,status_imob,tipo_imob,uf_imob,cidade_imob,bairro_imob,dorms_imob,valor_imob) AGAINST ('SP' IN BOOLEAN MODE);
Even though that column has so many SP registers.
Fiddle example
I have the next GUI made in Python which lets me to load all the data saved in a MySQL table for tenants, and just one data from a related table called 'contracts' (marked with a red circle).
enter image description here
The Python code I use for loading this form is the next one:
def fill_entries():
i = lb.curselection()[0]
valor = lb.get(i)
nombs, apells = _arrendatarios[valor]
cursor.execute("SELECT *, c_cod FROM arrendatarios LEFT JOIN contratos ON arrendatarios.a_cc = contratos.a_cc WHERE a_nombres = %s AND a_apellidos = %s", (nombs, apells))
result = cursor.fetchall()
connect.commit()
for item in result:
d1 = item[1] #ID
d2 = item[2] #Mr/Mrs
d3 = item[3] #City
d4 = item[4] #Names
d5 = item[5] #Last names
#------------And so on
d53 = item[53] # Num Contract
cedula.set(d1)
titulo.set(d2)
residencia.set(d3)
nombres.set(d4)
apellidos.set(d5)
direccion.set(d6)
#------------And so on
numcontract.set(d53)# Num Contract
But the thing is that what I want from the contracts table is the c_cod data, not de c_id, because part of this table description is this:
MariaDB> desc contratos;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| c_id | int(11) | NO | UNI | NULL | auto_increment |
| c_cod | int(11) | NO | PRI | NULL | |
| a_cc | varchar(50) | YES | MUL | NULL | |
| inquilino | varchar(100) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
And if, for example, I run the query in MySQL I got this:
MariaDB> SELECT arrendatarios.a_cc, c_cod FROM arrendatarios LEFT JOIN contratos ON arrendatarios.a_cc = contratos.a_cc;
+------------+-------+
| a_cc | c_cod |
+------------+-------+
| 900157048 | NULL |
| 71337237 | NULL |
| 43057196 | 22789 |
| 542550033 | NULL |
| 3502278 | NULL |
| 3472265 | NULL |
| 32460023 | NULL |
| And so on... |
+------------+-------+
34 rows in set (0.01 sec)
But Python is not drawing me the c_cod from contracts table but the c_id as if I were running:
MariaDB> SELECT arrendatarios.a_cc, c_id FROM arrendatarios LEFT JOIN contratos ON arrendatarios.a_cc = contratos.a_cc;
+------------+------+
| a_cc | c_id |
+------------+------+
| 900157048 | NULL |
| 71337237 | NULL |
| 43057196 | 8 |
| 542550033 | NULL |
| 3502278 | NULL |
| 3472265 | NULL |
| 32460023 | NULL |
| And so on... |
+------------+------+
34 rows in set (0.00 sec)
No matter what column I write, it always draws me the same result, the c_id. I'm a newbie with MySQL, I just new the basic. So, am I using wrong LEFT JOIN? Because what I want is just to show tenant info and this contract number n matter if it has it or not.
Here's the description of the tenants table too.
MariaDB> desc arrendatarios;
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| a_id | int(11) | NO | UNI | NULL | auto_increment |
| a_cc | varchar(50) | NO | PRI | NULL | |
| a_titulo | varchar(20) | YES | | NULL | |
| a_reside | varchar(50) | YES | | NULL | |
| a_nombres | varchar(50) | YES | | NULL | |
| a_apellidos | varchar(50) | YES | | NULL | |
| a_direccion | varchar(50) | YES | | NULL | |
| a_telefono | varchar(50) | YES | | NULL | |
| a_envio | varchar(50) | YES | | NULL | |
| a_email | varchar(50) | YES | | NULL | |
| a_celular | varchar(50) | YES | | NULL | |
| a_dia | int(11) | YES | | NULL | |
| a_mes | varchar(10) | YES | | NULL | |
| a_cumple | date | YES | | NULL | |
| a_profesion | varchar(50) | YES | | NULL | |
| a_empresa | varchar(50) | YES | | NULL | |
| a_oficina | varchar(50) | YES | | NULL | |
| a_tel | varchar(50) | YES | | NULL | |
| a_fax | varchar(50) | YES | | NULL | |
| a_banco | varchar(50) | YES | | NULL | |
| a_tcuenta | varchar(10) | YES | | NULL | |
| a_numcuenta | varchar(50) | YES | | NULL | |
| a_tpersona | int(11) | YES | | NULL | |
| a_retefuente | int(11) | YES | | NULL | |
| a_reteiva | int(11) | YES | | NULL | |
| a_contribuyente | int(11) | YES | | NULL | |
| a_gfactura | int(11) | YES | | NULL | |
| a_gcheque | int(11) | YES | | NULL | |
| a_nota | varchar(200) | YES | | NULL | |
| co1_cc | varchar(50) | YES | | NULL | |
| co1_nombres | varchar(50) | YES | | NULL | |
| co1_dir | varchar(50) | YES | | NULL | |
| co1_tel1 | varchar(50) | YES | | NULL | |
| co1_cargo | varchar(50) | YES | | NULL | |
| co1_empresa | varchar(59) | YES | | NULL | |
| co1_oficina | varchar(50) | YES | | NULL | |
| co1_tel2 | varchar(50) | YES | | NULL | |
| co2_cc | varchar(50) | YES | | NULL | |
| co2_nombres | varchar(50) | YES | | NULL | |
| co2_dir | varchar(50) | YES | | NULL | |
| co2_tel1 | varchar(50) | YES | | NULL | |
| co2_cargo | varchar(50) | YES | | NULL | |
| co2_empresa | varchar(59) | YES | | NULL | |
| co2_oficina | varchar(50) | YES | | NULL | |
| co2_tel2 | varchar(50) | YES | | NULL | |
| co3_cc | varchar(50) | YES | | NULL | |
| co3_nombres | varchar(50) | YES | | NULL | |
| co3_dir | varchar(50) | YES | | NULL | |
| co3_tel1 | varchar(50) | YES | | NULL | |
| co3_cargo | varchar(50) | YES | | NULL | |
| co3_empresa | varchar(59) | YES | | NULL | |
| co3_oficina | varchar(50) | YES | | NULL | |
| co3_tel2 | varchar(50) | YES | | NULL | |
+-----------------+--------------+------+-----+---------+----------------+
53 rows in set (0.06 sec)
As commented this solved the problem:
cursor.execute("SELECT arrendatarios.*, c_cod FROM arrendatarios LEFT JOIN contratos ON arrendatarios.a_cc = contratos.a_cc WHERE a_nombres = %s AND a_apellidos = %s", (nombs, apells))
I want to be able to select classes that are starting on or after the next two hours up until the end of tomorrow's date but I am not sure of how to do this.
My current sql is below, I have only been able to select classes that are after today's date and after the current time. I want to be able to only return classes that start two hours after now up until the end of tomorrows date.
I am able to pass the current date and current time into my node.js function that will construct the sql statement. Also, I have access to moment.js library if I need to use this I could.
Any help would be appreciated.
SELECT DISTINCT b.name
, a.time
FROM class a
Inner join (SELECT class_id, count(clientid)
FROM bookings
GROUP BY class_id
HAVING count(clientid) < 10) as openClasses on
a.class_id = openClasses.class_id
JOIN class_detail b
ON a.class_id = b.id
JOIN branch c
ON a.branch_id = c.id
WHERE c.level <= ( SELECT d.level
FROM client d
WHERE d.facebook_id = 'xxxxxx'
)
AND a.date = '2016-08-17'
AND a.time >= '13.00.00';
My tables are as follows:
BOOKINGS
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id | bigint(20) | NO | PRI | NULL | |
| CLIENT_ID | int(11) | NO | | NULL | |
| CLASS_ID | int(11) | NO | | NULL | |
| STATUS | varchar(10) | NO | | NULL | |
+-----------+-------------+------+-----+---------+-------+
mysql> show fields from BRANCH;
+---------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+-------------+------+-----+---------+----------------+
| id | int(10) | NO | PRI | NULL | auto_increment |
| NAME | char(50) | NO | | NULL | |
| CONTACT_NO | char(50) | YES | | NULL | |
| MAP_IMG_PATH | char(200) | YES | | NULL | |
| ADDRESS | char(200) | YES | | NULL | |
| LEVEL | int(2) | NO | | NULL | |
| LOCATION | int(10) | YES | | NULL | |
| SECTOR_NAME | varchar(45) | YES | | NULL | |
| SECTOR_MAP_IMG_PATH | char(200) | YES | | NULL | |
+---------------------+-------------+------+-----+---------+----------------+
mysql> show fields from CLIENT;
+--------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| id | int(10) | NO | PRI | NULL | |
| NAME | char(50) | NO | | NULL | |
| DOB | int(8) | NO | | NULL | |
| LOCAL_BRANCH | int(10) | YES | | NULL | |
| FACEBOOK_ID | char(50) | NO | | NULL | |
| START_DATE | int(8) | NO | | NULL | |
| EMAIL | char(50) | YES | | NULL | |
| PIN | int(4) | YES | | NULL | |
| END_DATE | int(8) | NO | | NULL | |
| LEVEL | int(2) | YES | | NULL | |
| TEL | varchar(20) | YES | | NULL | |
+--------------+-------------+------+-----+---------+-------+
mysql> show fields from CLASS_DETAIL;
+--------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id | int(10) | NO | PRI | NULL | |
| NAME | char(50) | NO | | NULL | |
| DESCRIPTION | char(200) | NO | | NULL | |
| CATEGORY | varchar(4) | YES | | NULL | |
| ACHIEVE_TYPE | char(200) | YES | | NULL | |
| IMG_M | varchar(200) | YES | | NULL | |
| IMG_F | varchar(200) | YES | | NULL | |
+--------------+--------------+------+-----+---------+-------+
mysql> show fields from CLASS;
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| CLASS_ID | int(10) | YES | | NULL | |
| BRANCH_ID | int(10) | NO | | NULL | |
| DURATION | int(3) | YES | | NULL | |
| DATE | date | NO | | NULL | |
| TIME | time | NO | | NULL | |
| STATUS | char(1) | NO | | NULL | |
+-----------+---------+------+-----+---------+----------------+
7 rows in set (0.11 sec)
I have 4 tables as below ,i am trying to join these tables but the query is taking too long to execute.Please tell me how do i optimize this.
Trying to do below
1) using a sub query i am creating a table based on input date range
2) i require to group result based on bank then on district and then on state,so that i can filter results on front end as State-->District-->Bank
3) Also i need to avoid some junk data which i am doing using not like clause.
select substring(a.ifsc,1,4) as code,
s.new_state as state,
s.state_id as stid,
d.new_dist as dist,
b.ifbank as bank,
count(a.amt) as num,
sum(a.amt) as amt from
(SELECT * FROM mtr where orgdate between '$fdate_new' and '$tdate_new')
as a JOIN ifsc b on b.ifscd=a.ifsc
JOIN user c on a.excd=c.mtr
JOIN state_mapping s on b.state=s.org_state
JOIN dist_mapping d on b.dist=d.org_dist
where
s.state_id ='$stid' and
TRIM(d.new_dist) <> '' and
d.new_dist IS NOT NULL
group by bank,dist order by amt desc;
dist_mapping table
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| org_dist | varchar(20) | YES | | NULL | |
| new_dist | varchar(20) | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
ifsc table
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| ifscd | varchar(11) | NO | PRI | | |
| ifscbr | varchar(40) | YES | | NULL | |
| ifbank | varchar(40) | YES | | NULL | |
| newifsc | varchar(11) | YES | | NULL | |
| dist | varchar(20) | YES | | NULL | |
| state | varchar(20) | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
state_mapping table
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| org_state | varchar(20) | YES | | NULL | |
| new_state | varchar(20) | YES | | NULL | |
| state_id | int(2) | YES | | NULL | |
+-----------+-------------+------+-----+---------+-------+
user table
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| excode | int(2) | YES | | NULL | |
| mtr | int(2) | YES | | NULL | |
| exname | varchar(40) | YES | | NULL | |
| country | varchar(10) | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
mysql> desc mtr;
+---------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------------------+------+-----+---------+-------+
| excd | int(2) | NO | PRI | 0 | |
| orgdate | date | YES | | NULL | |
| amt | double(12,2) | YES | | NULL | |
| obank | int(1) | YES | | NULL | |
| brcd | int(5) | YES | | NULL | |
| brname | varchar(40) | YES | | NULL | |
| rname | varchar(40) | YES | | NULL | |
| bname | varchar(40) | YES | | NULL | |
| baddr | varchar(60) | YES | | NULL | |
| mob | varchar(32) | YES | | NULL | |
| ifsc | varchar(12) | YES | | NULL | |
+---------+---------------------+------+-----+---------+-------+
Subquery takes more time compare to join Please try this
select substring(a.ifsc,1,4) as code,
s.new_state as state,
s.state_id as stid,
d.new_dist as dist,
b.ifbank as bank,
count(a.amt) as num,
sum(a.amt) as amt
From mtr as a
JOIN ifsc b on b.ifscd=a.ifsc and orgdate between '$fdate_new' and '$tdate_new'
JOIN user c on a.excd=c.mtr
JOIN state_mapping s on b.state=s.org_state
JOIN dist_mapping d on b.dist=d.org_dist
where
s.state_id ='$stid' and `enter code here`
TRIM(d.new_dist) <> '' and
d.new_dist IS NOT NULL
group by bank,dist order by amt desc;
I have the following four tables in my database:
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| complex_id | int(11) | NO | PRI | NULL | auto_increment |
| complex_name | varchar(45) | NO | | NULL | |
+--------------+-------------+------+-----+---------+----------------+
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| machine_id | int(11) | NO | PRI | NULL | auto_increment |
| complex_id | int(11) | NO | MUL | NULL | |
| machine_name | varchar(45) | NO | | NULL | |
+--------------+-------------+------+-----+---------+----------------+
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| devices_id | int(11) | NO | PRI | NULL | auto_increment |
| machine_id | int(11) | NO | MUL | NULL | |
| description | varchar(255) | NO | | NULL | |
| location | varchar(255) | YES | | NULL | |
| verification | varchar(255) | YES | | NULL | |
| rack_num | varchar(8) | YES | | NULL | |
| section_num | varchar(8) | YES | | NULL | |
| color_or_number | varchar(16) | YES | | NULL | |
| normal_position | varchar(16) | YES | | NULL | |
+-----------------+--------------+------+-----+---------+----------------+
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| pnp_id | int(11) | NO | PRI | NULL | auto_increment |
| devices_id | int(11) | NO | MUL | NULL | |
| pnp_num | varchar(45) | NO | | NULL | |
+------------+-------------+------+-----+---------+----------------+
I am trying to get results formatted as follows (NULL values appear as blanks):
+------------+-------------+-----------------------+
| devices_id | description | pnpnum |
+------------+-------------+-----------------------+
| 1 | ex | 1234 |
| 2 | ex2 | 2345 |
| 3 | ex3 | |
| 4 | ex4 | 3456, 4567, 5678, 6879|
+------------+-------------+-----------------------+
Using the following SQL query,
SELECT *, GROUP_CONCAT(pnp.pnp_num separator ', ') pnpnum
FROM devices
JOIN pnp ON devices.devices_id = pnp.devices_id
WHERE devices.machine_id = 1
GROUP BY devices.devices_ID
ORDER BY devices.description;
my results are relatively close, however, I am unable to include a device if it has a null pnpnum.
+------------+-------------+-----------------------+
| devices_id | description | pnpnum |
+------------+-------------+-----------------------+
| 1 | ex | 1234 |
| 2 | ex2 | 2345 |
| 4 | ex4 | 3456, 4567, 5678, 6879|
+------------+-------------+-----------------------+
What is it that I am missing from my SQL statement that will allow me to include null values?
You need to use LEFT JOIN because even if there isn't a match, it will return all the results from the left table leaving the fields from the right table null.