I have the following tables in MySQL Workbench:
MdV, MdV_has_Chain and Chain.
describe MdV
+------------+--------------+------+-----+-------------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------+-------+
| MdVID | varchar(255) | NO | PRI | NULL | |
| Source | longtext | YES | | NULL | |
| Chains | int unsigned | NO | | 0 | |
| CampaignID | varchar(255) | NO | MUL | No_Campaign | |
+------------+--------------+------+-----+-------------+-------+
describe MdV_has_Chain
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| MdVID | varchar(255) | NO | PRI | NULL | |
| ChainID | varchar(255) | NO | PRI | NULL | |
| Chain_Num | int unsigned | NO | | NULL | |
+-----------+--------------+------+-----+---------+-------+
describe Chain
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| ChainID | varchar(255) | NO | PRI | NULL | |
| Positions | int unsigned | NO | | 0 | |
| VectorID | varchar(255) | NO | | NULL | |
+-----------+--------------+------+-----+---------+-------+
Here they are in the EER diagram.
Currently the tables of interest hold the following mock data:
select * from mdv;
+-------------+-----------------+--------+-------------+
| MdVID | Source | Chains | CampaignID |
+-------------+-----------------+--------+-------------+
| ITS058-M152 | | 1 | C7 |
| ITS058-M182 | | 2 | No_Campaign |
| ITS058-M244 | Rational Design | 1 | C16 |
| ITS058-M253 | Rational Design | 2 | C17 |
| ITS058-M258 | | 1 | No_Campaign |
| TEST | | 0 | No_Campaign |
+-------------+-----------------+--------+-------------+
select * from mdv_has_chain;
+-------------+------------+----------------+
| MdVID | ChainID | chain_position |
+-------------+------------+----------------+
| ITS058-M152 | ITS058-Ch1 | 1 |
| ITS058-M182 | ITS058-Ch2 | 1 |
| ITS058-M182 | ITS058-Ch3 | 2 |
| ITS058-M244 | ITS058-Ch4 | 1 |
| ITS058-M253 | Ch1 | 2 |
| ITS058-M253 | ITS058-Ch5 | 1 |
| ITS058-M258 | ITS058-Ch6 | 1 |
+-------------+------------+----------------+
select * from chain;
+------------+-----------+-------------+
| ChainID | Positions | VectorID |
+------------+-----------+-------------+
| Ch1 | 2 | T343 |
| ITS058-Ch1 | 7 | ITS058-V240 |
| ITS058-Ch2 | 7 | ITS058-V278 |
| ITS058-Ch3 | 1 | R208 |
| ITS058-Ch4 | 6 | ITS058-V352 |
| ITS058-Ch5 | 7 | ITS058-V361 |
| ITS058-Ch6 | 6 | ITS058-V366 |
+------------+-----------+-------------+
To see what chains each MdV has I used the following query:
select mdv.mdvid, group_concat(mdv_has_chain.chainid order by mdv_has_chain.chain_num) as chainid, group_concat(mdv_has_chain.chain_num order by mdv_has_chain.chain_num) as chain_position from mdv inner join mdv_has_chain on mdv.mdvid = mdv_has_chain.mdvid group by mdv_has_chain.mdvid
+-------------+-----------------------+----------------+
| mdvid | chainid | chain_position |
+-------------+-----------------------+----------------+
| ITS058-M152 | ITS058-Ch1 | 1 |
| ITS058-M182 | ITS058-Ch2,ITS058-Ch3 | 1,2 |
| ITS058-M244 | ITS058-Ch4 | 1 |
| ITS058-M253 | ITS058-Ch5,Ch1 | 1,2 |
| ITS058-M258 | ITS058-Ch6 | 1 |
+-------------+-----------------------+----------------+
I was wondering how I would prevent same ChainIds or a combination of them from being entered to a different MdVID? For example how would I prevent the following insert from working:
insert into mdv_has_chain (mdvid, chainid, chain_num) values ("TEST", "ITS058-Ch2", 2), ("TEST", "ITS058-Ch3", 1)
ITS058-M182 already has those ChainIDs, but in different positions. Note that an MdV can have from 1 to N chains. Similarly, how would I allow permutations of ChainIds at different positions, but prevent entries with the same positions from being entered? I don't intend on implementing both things at once. I just wanted to know how I would achieve either individually.
Thank you for you time. Any help is appreciated.
Related
I have a table representing common values for two types of records and I have another two tables to hold the data that are different from each other. The table 1 is as follows
banking
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| officer | varchar(32) | NO | | NULL | |
| bank | varchar(64) | NO | | NULL | |
| branch | varchar(64) | NO | | NULL | |
| amount | int(11) | NO | | NULL | |
| date | date | NO | | NULL | |
| sys_date | date | NO | | NULL | |
| source_document | varchar(360) | NO | | NULL | |
+-----------------+--------------+------+-----+---------+----------------+
machinery_banking
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| banking_id | int(11) | NO | | NULL | |
| engine_no | varchar(64) | NO | | NULL | |
| chassis_no | varchar(64) | NO | | NULL | |
| receipt_number | varchar(64) | NO | | NULL | |
| payment_type | int(11) | NO | | NULL | |
+----------------+-------------+------+-----+---------+-------+
spare_parts_banking
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| banking_id | int(11) | NO | | NULL | |
| invoice_number | varchar(32) | NO | | NULL | |
+----------------+-------------+------+-----+---------+-------+
Each data that is entered to banking table has the other data in one of each tables machinery_banking or the spare_parts_banking.
I have the following data in the banking table
+----+---------+------------+------------+-----------+------------+------------+------------------------------------------------------------------------------------------+
| id | officer | bank | branch | amount | date | sys_date | source_document |
+----+---------+------------+------------+-----------+------------+------------+------------------------------------------------------------------------------------------+
| 1 | prasad | Sampath | Kaduruwela | 234234234 | 2017-06-28 | 2017-06-28 | image |
| 2 | prasad | Commercial | Colombo | 234234234 | 2017-05-28 | 2017-05-28 | image |
+----+---------+------------+------------+-----------+------------+------------+------------------------------------------------------------------------------------------+
I have the following data in the machinery_banking
+------------+-----------+------------+----------------+--------------+
| banking_id | engine_no | chassis_no | receipt_number | payment_type |
+------------+-----------+------------+----------------+--------------+
| 1 | 2324234 | NL234234 | RAN234 | 1 |
+------------+-----------+------------+----------------+--------------+
Data in the spare_parts_banking is as follows
+------------+----------------+
| banking_id | invoice_number |
+------------+----------------+
| 2 | INVRAN1 |
+------------+----------------+
I have tried the following query
SELECT a.id, a.officer, a.bank, a.branch, a.amount, a.date, a.sys_date, b.engine_no, b.chassis_no, a.source_document, c.invoice_number
FROM banking a,machinery_banking b, spare_parts_banking c
WHERE a.id = b.banking_id OR a.id = c.banking_id;
and ended up the following result
+----+---------+------------+------------+-----------+------------+------------+-----------+------------+------------------------------------------------------------------------------------------+----------------+
| id | officer | bank | branch | amount | date | sys_date | engine_no | chassis_no | source_document | invoice_number |
+----+---------+------------+------------+-----------+------------+------------+-----------+------------+------------------------------------------------------------------------------------------+----------------+
| 1 | prasad | Sampath | Kaduruwela | 234234234 | 2017-06-28 | 2017-06-28 | 2324234 | NL234234 | http://res.cloudinary.com/randeepa-com/image/upload/v1498455394/dmhxqal8hjcthhgav0n9.jpg | INVRAN1 |
| 2 | prasad | Commercial | Colombo | 234234234 | 2017-05-28 | 2017-05-28 | 2324234 | NL234234 | http://res.cloudinary.com/randeepa-com/image/upload/v1498455394/dmhxqal8hjcthhgav0n9.jpg | INVRAN1 |
+----+---------+------------+------------+-----------+------------+------------+-----------+------------+------------------------------------------------------------------------------------------+----------------+
The result I wish to obtain is as follows
+----+---------+------------+------------+-----------+------------+------------+-----------+------------+------------------------------------------------------------------------------------------+----------------+
| id | officer | bank | branch | amount | date | sys_date | engine_no | chassis_no | source_document | invoice_number |
+----+---------+------------+------------+-----------+------------+------------+-----------+------------+------------------------------------------------------------------------------------------+----------------+
| 1 | prasad | Sampath | Kaduruwela | 234234234 | 2017-06-28 | 2017-06-28 | 2324234 | NL234234 | http://res.cloudinary.com/randeepa-com/image/upload/v1498455394/dmhxqal8hjcthhgav0n9.jpg | |
| 2 | prasad | Commercial | Colombo | 234234234 | 2017-05-28 | 2017-05-28 | | | http://res.cloudinary.com/randeepa-com/image/upload/v1498455394/dmhxqal8hjcthhgav0n9.jpg | INVRAN1 |
+----+---------+------------+------------+-----------+------------+------------+-----------+------------+------------------------------------------------------------------------------------------+----------------+
What query can I use to get this result
The reason, why you have data duplication is because of the OR between conditions
I believe this should work
SELECT a.id,
a.officer,
a.bank,
a.branch,
a.amount,
a.date,
a.sys_date,
b.engine_no,
b.chassis_no,
a.source_document,
c.invoice_number
FROM banking a
LEFT JOIN machinery_banking b
ON a.id = b.banking_id
LEFT JOIN spare_parts_banking c
ON a.id = c.banking_id;
Also move to new JOIN syntax, it is much easier to comprehend.
SQL Join Syntax - Reference
Try this:
SELECT a.id, a.officer, a.bank, a.branch, a.amount, a.date, a.sys_date, b.engine_no, b.chassis_no, a.source_document, c.invoice_number
FROM banking a,machinery_banking b, spare_parts_banking c
WHERE a.id = b.banking_id(+)
AND a.id = c.banking_id(+);
I'm a pretty green novice with SQL still and have been tasked with something that looks incredibly tedious to accomplish. I need to move 58 of 61 columns from tableA to tableB. tableA has 61 columns and only 15 rows, tableB has 58 columns and zero rows right now. I've read multiple sources on how to achieve this (moving data from one table to a related one), but none specifically talk about this particular case I'm dealing with.
To further complicate things, the second table does not have the columns in the same order as the first, so this poses a problem as well. This SO post seemed promising, but it is working with a substantially smaller dataset: SQL: Move column data to other table in same relation . This one is also similar MYSQL - Move data from one table to a related one? . The problem is they both are moving to a larger table from a smaller table, not vis a vis.
Here's my initial query for attempting to make this transition happen (and was unsuccessful as the included error indicates):
INSERT INTO tableB SELECT * FROM tableA;
ERROR 1136 (21S01): Column count doesn't match value count at row 1
tableA
+-------------------------------+------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------------------+------------------+------+-----+-------------------+-----------------------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| staff_fk | int(11) unsigned | NO | | NULL | |
| hire_date | date | NO | | NULL | |
| position | varchar(75) | NO | | NULL | |
| manager | varchar(75) | NO | | NULL | |
| employment_application | char(1) | NO | | i | |
| resume | char(1) | NO | | i | |
| references_checked | char(1) | NO | | i | |
| new_hire_letter | char(1) | NO | | i | |
| clinical_training_initiated | char(1) | NO | | i | |
| name_badge_ordered | char(1) | NO | | i | |
| keycode_access | char(1) | NO | | i | |
| tf_up_setup | char(1) | NO | | i | |
| un_pw_setup | char(1) | NO | | i | |
| drug_screen | char(1) | NO | | i | |
| background_investigation | char(1) | NO | | i | |
| licenses_education_verified | char(1) | NO | | i | |
| cpr | char(1) | NO | | i | |
| clinic_tour_introductions | char(1) | NO | | i | |
| sick_tardy_phone_notification | char(1) | NO | | i | |
| work_sched_start_time | char(1) | NO | | i | |
| paydays | char(1) | NO | | i | |
| ds_pto | char(1) | NO | | i | |
| attendance_tardiness | char(1) | NO | | i | |
| evacuation_plan | char(1) | NO | | i | |
| osha | char(1) | NO | | i | |
| emp_handbook_receipt | char(1) | NO | | i | |
| internet_email_phone_usage | char(1) | NO | | i | |
| parking_building_access | char(1) | NO | | i | |
| dress_grooming | char(1) | NO | | i | |
| inclement_weather | char(1) | NO | | i | |
| mileage | char(1) | NO | | i | |
| hipaa_training | char(1) | NO | | i | |
| direct_deposit_auth | char(1) | NO | | i | |
| i9 | char(1) | NO | | i | |
| w4 | char(1) | NO | | i | |
| valid_id | char(1) | NO | | i | |
| update_ext_list | char(1) | NO | | i | |
| emerg_contact_form | char(1) | NO | | i | |
| med_dent_life_vision | char(1) | NO | | i | |
| 401k_pen_sh | char(1) | NO | | i | |
| centricity_access | char(1) | NO | | i | |
| centricity_training | char(1) | NO | | i | |
| phone_training | char(1) | NO | | i | |
| create_active_dir_account | char(1) | NO | | i | |
| email_access | char(1) | NO | | i | |
| drive_access | char(1) | NO | | i | |
| mcafee | char(1) | NO | | i | |
| hr_enrollment_forms | char(1) | NO | | i | |
| ds_signoff | char(1) | NO | | i | |
| ds_clincial_signoff | char(1) | NO | | i | |
| completed | datetime | YES | | NULL | |
| created | datetime | NO | | NULL | |
| last_update | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| portal_access | char(1) | NO | | i | |
| harvest | char(1) | NO | | i | |
| imms_link | char(1) | NO | | i | |
| eprescribe | char(1) | NO | | i | |
| state_alert_access | char(1) | NO | | i | |
| phone_agent | char(1) | NO | | i | |
| pc_tablet_setup | char(1) | NO | | i | |
+-------------------------------+------------------+------+-----+-------------------+-----------------------------+
61 rows in set (0.00 sec)
tableB:
+-------------------------------+------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------------------+------------------+------+-----+-------------------+-----------------------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| staff_fk | int(11) unsigned | NO | | NULL | |
| employment_application | char(1) | NO | | i | |
| resume | char(1) | NO | | i | |
| references_checked | char(1) | NO | | i | |
| new_hire_letter | char(1) | NO | | i | |
| clinical_training_initiated | char(1) | NO | | i | |
| name_badge_ordered | char(1) | NO | | i | |
| keycode_access | char(1) | NO | | i | |
| tf_up_setup | char(1) | NO | | i | |
| un_pw_setup | char(1) | NO | | i | |
| drug_screen | char(1) | NO | | i | |
| background_investigation | char(1) | NO | | i | |
| licenses_education_verified | char(1) | NO | | i | |
| cpr | char(1) | NO | | i | |
| clinic_tour_introductions | char(1) | NO | | i | |
| sick_tardy_phone_notification | char(1) | NO | | i | |
| work_sched_start_time | char(1) | NO | | i | |
| paydays | char(1) | NO | | i | |
| ds_pto | char(1) | NO | | i | |
| attendance_tardiness | char(1) | NO | | i | |
| evacuation_plan | char(1) | NO | | i | |
| osha | char(1) | NO | | i | |
| emp_handbook_receipt | char(1) | NO | | i | |
| internet_email_phone_usage | char(1) | NO | | i | |
| parking_building_access | char(1) | NO | | i | |
| dress_grooming | char(1) | NO | | i | |
| inclement_weather | char(1) | NO | | i | |
| mileage | char(1) | NO | | i | |
| hipaa_training | char(1) | NO | | i | |
| direct_deposit_auth | char(1) | NO | | i | |
| i9 | char(1) | NO | | i | |
| w4 | char(1) | NO | | i | |
| valid_id | char(1) | NO | | i | |
| update_ext_list | char(1) | NO | | i | |
| emerg_contact_form | char(1) | NO | | i | |
| med_dent_life_vision | char(1) | NO | | i | |
| 401k_pen_sh | char(1) | NO | | i | |
| centricity_access | char(1) | NO | | i | |
| centricity_training | char(1) | NO | | i | |
| phone_training | char(1) | NO | | i | |
| create_active_dir_account | char(1) | NO | | i | |
| email_access | char(1) | NO | | i | |
| drive_access | char(1) | NO | | i | |
| mcafee | char(1) | NO | | i | |
| portal_access | char(1) | NO | | i | |
| harvest | char(1) | NO | | i | |
| imms_link | char(1) | NO | | i | |
| eprescribe | char(1) | NO | | i | |
| state_alert_access | char(1) | NO | | i | |
| phone_agent | char(1) | NO | | i | |
| pc_tablet_setup | char(1) | NO | | i | |
| hr_enrollment_forms | char(1) | NO | | i | |
| ds_signoff | char(1) | NO | | i | |
| ds_clincial_signoff | char(1) | NO | | i | |
| completed | datetime | YES | | NULL | |
| created | timestamp | NO | | CURRENT_TIMESTAMP | |
| last_update | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------------------------------+------------------+------+-----+-------------------+-----------------------------+
58 rows in set (0.01 sec)
I'll include the schemas if anyone would like to see them.
I'm wondering if there's a way to do this without explicitly labeling each column in the INSERT INTO statement. Any help will be greatly appreciated!
No, there is no way to do this without labeling each column. There is no syntax in SQL for SELECT *_except_for_a_few_columns
You can generate the list of columns out of the INFORMATION_SCHEMA so you can cut down on tedious typing:
SELECT GROUP_CONCAT(column_name ORDER BY ordinal_position) AS _cols
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = 'mydatabase' AND table_name = 'tableA'
AND column_name NOT IN ('do', 'not', 'want')
To further complicate things, the second table does not have the columns in the same order as the first...
If the columns at least have the same names in both tables, you can use a column list in your INSERT statement regardless of the natural ordinal position of those columns defined in the table. In other words, the following works:
INSERT INTO tableB (col1, col4, col2, col6, col9)
SELECT col1, col4, col2, col6, col9 FROM tableA;
If the columns differ in number, order, and name, I'd recommend that you double-check that you're inserting into the correct table! :-)
Yes and that error is pretty straight forward and is saying that you can't use * and need to specify the column names explicitly like
INSERT INTO tableB
SELECT col1, col2, col3, ..., col58 FROM tableA;
Hello i am trying to run this select statement using this query and it is taking over 2 hours to run. I have set up all the index's to be correct. But it still takes forever is there something i am missing or a more efficient way of joining tables together that will speed this query up?
I have indexes set up for all items being joined together and they are the same length and data type.
SELECT
p.sap_article_id,
p.numeric_line_code,
p.uag_linecode,
p.uag_partnum,
p.part_description,
p.jobber_price,
p.jobber_core,
p.discount1,
p.discount2,
p.uom,
p.product_category,
w.as400_warehouse,
w.atp_qty,
p.updated,
t.regular_discount
FROM part p
LEFT JOIN tabjbmaw t ON t.accountnum = '73050'
AND p.numeric_line_code = t.numeric_line_code
AND p.sub_code = t.sub_code
JOIN warehouse w ON w.sap_article_id = p.sap_article_id;
+----+-------------+-----------+------+--------------------------------------------------+-----------------------+---------+----------------------------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+--------------------------------------------------+-----------------------+---------+----------------------------------+--------+-------------+
| 1 | SIMPLE | part | ALL | PRIMARY,sap_article,part_sap_article_id_fk | NULL | NULL | NULL | 389309 | |
| 1 | SIMPLE | warehouse | ref | article | article | 130 | inventory.part.sap_article_id | 5 | Using where |
| 1 | SIMPLE | tabjbmaw | ref | numeric_line_code_idx,subcode_idx,accountnum_idx | numeric_line_code_idx | 5 | inventory.part.numeric_line_code | 19 | |
+----+-------------+-----------+------+--------------------------------------------------+-----------------------+---------+----------------------------------+--------+-------------+
Thank you for your help
+-----------------------------+--------------+------+-----+---------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------------+--------------+------+-----+---------------------+-----------------------------+
| sap_article_id | varchar(24) | NO | PRI | | |
| sap_brand_id | varchar(20) | NO | | NULL | |
| uag_partnum | varchar(20) | NO | MUL | NULL | |
| uag_linecode | varchar(5) | NO | MUL | NULL | |
| cag_partnum | varchar(20) | NO | MUL | NULL | |
| cag_linecode | varchar(5) | NO | | NULL | |
| product_category_legacy | varchar(20) | NO | | NULL | |
| part_description | varchar(128) | NO | | NULL | |
| abc_indicator | varchar(8) | NO | | NULL | |
| pack_code | varchar(8) | NO | | NULL | |
| case_qty | int(11) | NO | | NULL | |
| per_car_qty | int(11) | NO | | NULL | |
| uom | varchar(6) | NO | | NULL | |
| upc_code | varchar(128) | NO | | NULL | |
| jobber_price | float(14,4) | YES | | NULL | |
| jobber_core | float(14,4) | YES | | NULL | |
| date_last_price_change | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| weight | float(14,4) | YES | | NULL | |
| weight_unit | varchar(6) | NO | | NULL | |
| dimension_type | varchar(6) | NO | | NULL | |
| length | float(14,4) | YES | | NULL | |
| width | float(14,4) | YES | | NULL | |
| height | float(14,4) | YES | | NULL | |
| updated | tinyint(1) | NO | | 0 | |
| superseded_sap_article_id | varchar(24) | YES | | NULL | |
| last_updated | timestamp | NO | | 0000-00-00 00:00:00 | |
| hour_updated | int(11) | YES | | NULL | |
| discount1 | float | YES | | NULL | |
| discount2 | float | YES | | NULL | |
| product_category | varchar(3) | YES | | NULL | |
| superseded_part_number | varchar(20) | YES | | NULL | |
| sub_code | varchar(3) | YES | MUL | NULL | |
| date_effective_price_change | date | YES | | NULL | |
| numeric_line_code | varchar(3) | YES | MUL | NULL | |
| list | float | YES | | NULL | |
+-----------------------------+--------------+------+-----+---------------------+-----------------------------+
I have indexes set up for all items being joined together
Yes, but I am guessing from the names of the indexes that each index only has one field.
Let's look at a few columns in the describe.
| table | possible_keys | key
+-----------+--------------------------------------------------+----------------
| part | PRIMARY,sap_article,part_sap_article_id_fk | NULL
| warehouse | article | article
| tabjbmaw | numeric_line_code_idx,subcode_idx,accountnum_idx | numeric_line_code_idx
It can use an index for numeric_line_code, subcode, and accountnum, but there are only three indexes each with one of the fields, and no index which has all the fields. You are making the optimizer choose one of the one field indexes, instead of providing one index it can use for all three fields.
Add an index on table tabjbmaw with the three fields numeric_line_code, subcode, and accountnum.
Extending #Sebas answer, you should select tabjbmaw first:
SELECT
p.sap_article_id,
p.numeric_line_code,
p.uag_linecode,
p.uag_partnum,
p.part_description,
p.jobber_price,
p.jobber_core,
p.discount1,
p.discount2,
p.uom,
p.product_category,
w.as400_warehouse,
w.atp_qty,
p.updated,
t.regular_discount
FROM tabjbmaw t
LEFT JOIN parts p ON p.numeric_line_code = t.numeric_line_code
AND p.sub_code = t.sub_code
JOIN warehouse w ON w.sap_article_id = p.sap_article_id
WHERE t.accountnum = '73050'
;
You could try to put your Left Join into the SELECT part as a Subselect. That 'may' speed things up a little.
Like this:
SELECT
p.sap_article_id,
p.numeric_line_code,
p.uag_linecode,
p.uag_partnum,
p.part_description,
p.jobber_price,
p.jobber_core,
p.discount1,
p.discount2,
p.uom,
p.product_category,
w.as400_warehouse,
w.atp_qty,
p.updated,
(SELECT t.regular_discount FROM tabjbmaw t WHERE t.accountnum = '73050' AND p.numeric_line_code = t.numeric_line_code AND p.sub_code = t.sub_code LIMIT 1)
FROM
part p
JOIN warehouse w ON w.sap_article_id = p.sap_article_id;
I have a sql statement that looks like this:
SELECT colID
FROM tableName
WHERE ColDateStart <='$lowerDate'
AND ColDateStart>='$upperDate'
AND ColVcamID='$id1'
AND ColVlviID='$id2'
AND ColSomeID='$id3';
All the columns in the WHERE statment are indexed columns.
When I run this it takes over a second. However when I run this without other Id3, the performance is considerably improved (0.03 seconds).
When I run explain, with otherId3, it uses an index merge using otherId1 and otherId3. However when I remove the otherId3, it uses the single index of otherId2.
Why does adding otherId3 make an impact on the performance?
Table Structure:
+----------------------+-------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+-------------+------+-----+---------------------+----------------+
| ColID | int(11) | NO | PRI | NULL | auto_increment |
| ColCustID | int(11) | NO | MUL | 0 | |
| ColCarrID | int(11) | NO | MUL | NULL | |
| ColTariID | int(11) | NO | MUL | 0 | |
| ColCarrierRef | varchar(30) | NO | MUL | | |
| ColNumbID | int(11) | NO | MUL | 0 | |
| ColVlviID | int(11) | NO | MUL | NULL | |
| ColVcamID | int(11) | NO | MUL | NULL | |
| ColSomeID | int(11) | NO | MUL | NULL | |
| ColVlnsID | int(11) | NO | MUL | NULL | |
| ColNGNumber | varchar(12) | NO | | | |
| ColOrigNumber | varchar(16) | NO | MUL | NULL | |
| ColCLIRestrictedFlag | int(2) | NO | | NULL | |
| ColOrigLocality | varchar(11) | NO | MUL | | |
| ColOrigAreaCode | varchar(11) | NO | MUL | | |
| ColTermNumber | varchar(16) | NO | MUL | NULL | |
| ColBatchNumber | varchar(10) | NO | | | |
| ColDateStart | date | NO | MUL | 0000-00-00 | |
| ColDateClear | date | NO | | 0000-00-00 | |
| ColTimeStart | time | NO | | 00:00:00 | |
| ColTimeClear | time | NO | | 00:00:00 | |
| ColCallLength | time | NO | | 00:00:00 | |
| ColRingLength | time | NO | | 00:00:00 | |
| ColEffectiveFlag | smallint(1) | NO | MUL | NULL | |
| ColUnansweredFlag | smallint(1) | NO | MUL | NULL | |
| ColEngagedFlag | smallint(1) | NO | | NULL | |
| ColRecID | int(11) | NO | MUL | NULL | |
| ColCreatedUserID | int(11) | NO | | 0 | |
| ColCreatedDatetime | datetime | NO | MUL | 0000-00-00 00:00:00 | |
| ColDirection | int(1) | NO | MUL | NULL | |
+----------------------+-------------+------+-----+---------------------+----------------+
Indexes
+-------+------------+-------------------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+-------------------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+
| tableName | 0 | PRIMARY | 1 | ColID | A | 18031283 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_ColCustID | 1 | ColCustID | A | 1339 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_ColNumbID | 1 | ColNumbID | A | 24366 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colOrigNumber | 1 | colOrigNumber | A | 4507820 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colOrigLocality | 1 | colOrigLocality | A | 36873 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colOrigAreaCode | 1 | colOrigAreaCode | A | 696 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colTermNumber | 1 | colTermNumber | A | 137643 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colDateStart | 1 | colDateStart | A | 3639 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colEffectiveFlag | 1 | colEffectiveFlag | A | 2 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colUnansweredFlag | 1 | colUnansweredFlag | A | 2 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colEngagedFlag | 1 | colUnansweredFlag | A | 2 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colTariID | 1 | colTariID | A | 91 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_CustID_DateStart | 1 | colCustID | A | 1339 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_CustID_DateStart | 2 | colDateStart | A | 693510 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_NumbID_DateStart | 1 | colNumbID | A | 24366 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_NumbID_DateStart | 2 | colDateStart | A | 4507820 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colRecID | 1 | colRecID | A | 214658 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colCarrierRef | 1 | colCarrierRef | A | 6010427 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colCustID_colTermNumber | 1 | colCustID | A | 1339 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colCustID_colTermNumber | 2 | colTermNumber | A | 143105 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colCreatedDatetime | 1 | colCreatedDatetime | A | 474507 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colDirection | 1 | colDirection | A | 2 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colVlviID | 1 | colVlviID | A | 4133 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colSomeID | 1 | colSomeID | A | 10 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colVcamID | 1 | colVcamID | A | 7 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colVlnsID | 1 | colVlnsID | A | 18 | NULL | NULL | | BTREE | |
| tableName | 1 | idx_colCarrID | 1 | colCarrID | A | 4 | NULL | NULL | | BTREE | |
+-------+------------+-------------------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+
First up, you have far too may indexes. Most of those indexes are likely pointless. If you aren't using a specific index for WHERE criteria, JOINs, or ORDERing, then remove it as it just slows things down.
Next up, for your query you specify 3 columns that are always in the query comprising 1x DATE and 2x INT columns. The DATE column should be first as a date range is pretty fast on an index, and then the two INTs. This gives a starting point of the following 3-column index
CREATE INDEX searchIndex
ON tableName (ColDateStart,ColVlviID,ColVcamID)
USING BTREE;
More information on that available here : http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html
I ordered the columns that way intentionally. ColDateStart for the date range filtering, followed by the other columns in decreasing order of cardinality. I selected ColVlviID as a second column as it has a cardinality of 4133 compared to ColVcamID having a cardinality of 7. This will allow MySQL to more efficiently reduce the matching rows.
Now, assuming colSomeID is the last column, I might instead do the following
CREATE INDEX searchIndex_someID
ON tableName (ColDateStart,ColVlviID,ColVcamID,ColSomeID)
USING BTREE;
This 3-column index will help MySQL get down to the applicable dataset before checking for that last ID. Optioanlly you could add a 4th column to that index at the end, if you are commonly filtering in another particular INT column.
As an aside, you may want to consider the following instead of the dateCol criteria
SELECT colID
FROM tableName
WHERE ColDateStart BETWEEN DATE('$lowerDate') AND DATE('$upperDate')
AND ColVcamID=$id1
AND ColVlviID=$id2
AND ColSomeID=$id3
The above all of course assumes that you are sanitising the variables before executing the query. I have removed the quotes from the $idx variables, as they should be numeric and therefore do not need to be entered as strings.
SELECT id
FROM tableName FORCE INDEX(`idx_otherId2`)
WHERE dateCol <='$lowerDate'
AND dateCol>='$upperDate'
AND otherId1='$id1'
AND otherId2='$id2'
AND otherId3='$id3';
I am attempting to write a migration script (between 2 versions of a program) to populate the phppos_permissions_actions table.
The rule for populating is: "If the user has permission for the module (based on phppos_permissions), then they are granted all action permissions for that module. (Which can be looked up in phppos_module_actions)".
I am trying to write a query or a set of queries that makes the following rule happen. Could someone guide me in the right direction? Below is my schema
mysql> describe phppos_modules;
+---------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| name_lang_key | varchar(255) | NO | UNI | NULL | |
| desc_lang_key | varchar(255) | NO | UNI | NULL | |
| sort | int(10) | NO | | NULL | |
| module_id | varchar(255) | NO | PRI | NULL | |
+---------------+--------------+------+-----+---------+-------+
4 rows in set (0.01 sec)
mysql> select * from phppos_modules;
+-------------------+------------------------+------+------------+
| name_lang_key | desc_lang_key | sort | module_id |
+-------------------+------------------------+------+------------+
| module_config | module_config_desc | 100 | config |
| module_customers | module_customers_desc | 10 | customers |
| module_employees | module_employees_desc | 80 | employees |
| module_giftcards | module_giftcards_desc | 90 | giftcards |
| module_item_kits | module_item_kits_desc | 30 | item_kits |
| module_items | module_items_desc | 20 | items |
| module_receivings | module_receivings_desc | 60 | receivings |
| module_reports | module_reports_desc | 50 | reports |
| module_sales | module_sales_desc | 70 | sales |
| module_suppliers | module_suppliers_desc | 40 | suppliers |
+-------------------+------------------------+------+------------+
10 rows in set (0.00 sec)
mysql> describe phppos_modules_actions;
+-----------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+-------+
| action_id | varchar(255) | NO | PRI | NULL | |
| module_id | varchar(255) | NO | PRI | NULL | |
| action_name_key | varchar(255) | NO | | NULL | |
| sort | int(11) | NO | | NULL | |
+-----------------+--------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
mysql>
mysql> select * from phppos_modules_actions;
+----------------+-----------+--------------------------------+------+
| action_id | module_id | action_name_key | sort |
+----------------+-----------+--------------------------------+------+
| add_update | customers | module_action_add_update | 1 |
| add_update | employees | module_action_add_update | 130 |
| add_update | item_kits | module_action_add_update | 70 |
| add_update | items | module_action_add_update | 40 |
| add_update | suppliers | module_action_add_update | 100 |
| delete | customers | module_action_delete | 20 |
| delete | employees | module_action_delete | 140 |
| delete | item_kits | module_action_delete | 80 |
| delete | items | module_action_delete | 50 |
| delete | suppliers | module_action_delete | 110 |
| search | customers | module_action_search_customers | 30 |
| search | employees | module_action_search_employees | 150 |
| search | item_kits | module_action_search_item_kits | 90 |
| search | items | module_action_search_items | 60 |
| search | suppliers | module_action_search_suppliers | 120 |
| see_cost_price | items | module_see_cost_price | 61 |
+----------------+-----------+--------------------------------+------+
16 rows in set (0.00 sec)
mysql> describe phppos_permissions
-> ;
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| module_id | varchar(255) | NO | PRI | NULL | |
| person_id | int(10) | NO | PRI | NULL | |
+-----------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> select * from phppos_permissions;
+------------+-----------+
| module_id | person_id |
+------------+-----------+
| config | 1 |
| customers | 1 |
| employees | 1 |
| giftcards | 1 |
| item_kits | 1 |
| items | 1 |
| receivings | 1 |
| reports | 1 |
| sales | 1 |
| suppliers | 1 |
| sales | 301 |
| sales | 741 |
| config | 759 |
| customers | 759 |
| employees | 759 |
| giftcards | 759 |
| item_kits | 759 |
| items | 759 |
| receivings | 759 |
| reports | 759 |
| sales | 759 |
| suppliers | 759 |
| sales | 776 |
+------------+-----------+
23 rows in set (0.00 sec)
mysql> describe phppos_permissions_actions;
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| module_id | varchar(255) | NO | PRI | NULL | |
| person_id | int(11) | NO | PRI | NULL | |
| action_id | varchar(255) | NO | PRI | NULL | |
+-----------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql>
Does
insert phppos_permissions_actions (module_id, person_id, action_id)
select distinct
phppos_permissions.module_id, phppos_permissions.person_id, action_id
from phppos_permissions
inner join phppos_modules_actions on phppos_permissions.module_id = phppos_modules_actions.module_id
order by module_id, person_id
solve your problem?