Optimizing SQL query from derived table - mysql

I have the following SQL query
select s.channel_id, count(1) as unique_views
from (
select m.channel_id
from view_statistics vs
inner join medias m on m.id = vs.media_id
group by m.channel_id, vs.session_id
) s
group by s.channel_id
that selects from this table view_statistics (which stores millions of rows, narrowed down to ~2M here for testing purposes):
CREATE TABLE `view_statistics` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`media_id` int(10) unsigned NOT NULL,
`file_id` int(10) unsigned NOT NULL,
`session_id` int(10) unsigned NOT NULL,
`browser_id` int(10) unsigned NOT NULL,
`device_id` int(10) unsigned NOT NULL,
`operating_system_id` int(10) unsigned NOT NULL,
`country_id` int(10) unsigned NOT NULL,
`datetime_from` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`datetime_to` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`datetime_yearly` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`datetime_monthly` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`datetime_weekly` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`datetime_daily` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`datetime_hourly` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`hits` int(10) unsigned NOT NULL,
`bytes` bigint(20) unsigned NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `view_statistics_datetime_hourly_index` (`datetime_hourly`),
KEY `view_statistics_session_id_datetime_hourly_index` (`session_id`,`datetime_hourly`),
KEY `view_statistics_datetime_daily_index` (`datetime_daily`),
KEY `view_statistics_session_id_datetime_daily_index` (`session_id`,`datetime_daily`),
KEY `view_statistics_datetime_weekly_index` (`datetime_weekly`),
KEY `view_statistics_session_id_datetime_weekly_index` (`session_id`,`datetime_weekly`),
KEY `view_statistics_datetime_monthly_index` (`datetime_monthly`),
KEY `view_statistics_session_id_datetime_monthly_index` (`session_id`,`datetime_monthly`),
KEY `view_statistics_datetime_yearly_index` (`datetime_yearly`),
KEY `view_statistics_session_id_datetime_yearly_index` (`session_id`,`datetime_yearly`),
KEY `view_statistics_media_id_foreign` (`media_id`),
KEY `view_statistics_file_id_foreign` (`file_id`),
KEY `view_statistics_browser_id_foreign` (`browser_id`),
KEY `view_statistics_device_id_foreign` (`device_id`),
KEY `view_statistics_operating_system_id_foreign` (`operating_system_id`),
KEY `view_statistics_country_id_foreign` (`country_id`),
CONSTRAINT `view_statistics_browser_id_foreign` FOREIGN KEY (`browser_id`) REFERENCES `statistic_browsers` (`id`),
CONSTRAINT `view_statistics_country_id_foreign` FOREIGN KEY (`country_id`) REFERENCES `statistic_countries` (`id`),
CONSTRAINT `view_statistics_device_id_foreign` FOREIGN KEY (`device_id`) REFERENCES `statistic_devices` (`id`),
CONSTRAINT `view_statistics_file_id_foreign` FOREIGN KEY (`file_id`) REFERENCES `files` (`id`),
CONSTRAINT `view_statistics_media_id_foreign` FOREIGN KEY (`media_id`) REFERENCES `medias` (`id`),
CONSTRAINT `view_statistics_operating_system_id_foreign` FOREIGN KEY (`operating_system_id`) REFERENCES `statistic_operating_systems` (`id`),
CONSTRAINT `view_statistics_session_id_foreign` FOREIGN KEY (`session_id`) REFERENCES `statistic_sessions` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1366805 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
And medias
CREATE TABLE `medias` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uuid` binary(16) NOT NULL,
`channel_id` int(10) unsigned NOT NULL,
`folder_id` int(10) unsigned NOT NULL,
`category_id` int(10) unsigned DEFAULT NULL,
`language_id` int(10) unsigned DEFAULT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(255) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
`description` text COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`validated` tinyint(1) NOT NULL DEFAULT 0,
`published` tinyint(1) NOT NULL DEFAULT 0,
`streams` tinyint(3) unsigned DEFAULT NULL,
`duration` decimal(7,2) DEFAULT NULL,
`client` enum('http','cli') COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`http_ip` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`http_user_agent` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`cli_user` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`cli_hostname` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`debug` tinyint(1) NOT NULL DEFAULT 0,
`v1` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Imported from V1',
`collected_at` timestamp NULL DEFAULT NULL,
`ready_at` timestamp NULL DEFAULT NULL,
`published_at` timestamp NULL DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`discarded_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`uniq` binary(32) GENERATED ALWAYS AS (unhex(sha2(concat_ws('|',`folder_id`,`name`,ifnull(`deleted_at`,0)),256))) STORED,
PRIMARY KEY (`id`),
UNIQUE KEY `medias_uuid_unique` (`uuid`),
UNIQUE KEY `medias_uniq_unique` (`uniq`),
KEY `medias_channel_id_foreign` (`channel_id`),
KEY `medias_folder_id_foreign` (`folder_id`),
KEY `medias_category_id_foreign` (`category_id`),
KEY `medias_language_id_foreign` (`language_id`),
KEY `medias_ready_at_index` (`ready_at`),
KEY `medias_discarded_at_index` (`discarded_at`),
CONSTRAINT `medias_category_id_foreign` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`),
CONSTRAINT `medias_channel_id_foreign` FOREIGN KEY (`channel_id`) REFERENCES `channels` (`id`),
CONSTRAINT `medias_folder_id_foreign` FOREIGN KEY (`folder_id`) REFERENCES `folders` (`id`),
CONSTRAINT `medias_language_id_foreign` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1036 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
Other related tables (browsers,device, operating_system, etc.) are listing tables, nothing fancy.
and altought the query is simple to me, it runs over many seconds with the following explain:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 649152 Using temporary; Using filesort
2 DERIVED m index PRIMARY medias_channel_id_foreign 4 NULL 1008 Using index; Using temporary; Using filesort
2 DERIVED vs ref view_statistics_media_id_foreign view_statistics_media_id_foreign 4 vod.m.id 644
I don't see how I can optimize this so simple query at all, can anyone point me to the right direction ?

An equivalent query would be:
select m.channel_id, count(distinct vs.session_id) as unique_views
from view_statistics vs
inner join medias m on m.id = vs.media_id
group by m.channel_id
Ideal indexes for this query would probably be medias(channel_id, id) (already exists) and view_statistics(media_id, session_id). However - It might already improve the performance with the given indexes.

Related

Insert into table results in "column cannot be null" but said column does not exist

I have a SQL table that when I try to insert a row into it I get
Error Code: 1048. Column 'chave_integracao_grupo' cannot be null
The table does not have a column named "chave_integracao_grupo".
I tried inserting data into said column but got the standard column does not exist error. I also checked and All the NOT NULL columns are receiving a default expressions.
Edit:
CREATE TABLE `empresas` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_grupo` int(11) NOT NULL DEFAULT '1',
`cnpj` varchar(18) DEFAULT NULL,
`id_estado` int(11) DEFAULT NULL,
`id_cidade` int(11) DEFAULT NULL,
`id_funcionalidade` int(11) NOT NULL DEFAULT '3',
`inscricao_estadual` varchar(15) DEFAULT NULL,
`razao_social` varchar(100) NOT NULL,
`nome_fantasia` varchar(50) NOT NULL,
`telefone` varchar(20) DEFAULT NULL,
`cep` varchar(12) DEFAULT NULL,
`endereco` varchar(50) DEFAULT NULL,
`bairro` varchar(50) DEFAULT NULL,
`numero` varchar(10) DEFAULT NULL,
`status` tinyint(4) NOT NULL DEFAULT '1',
`id_integracao_gerencial` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK_EMPRESAS_CIDADES` (`id_cidade`),
KEY `FK_EMPRESAS_ESTADOS` (`id_estado`),
KEY `FK_EMPRESAS_EMPRESASMATRIZ` (`id_grupo`),
KEY `FK_EMPRESAS_FUNCIONALIDADES` (`id_funcionalidade`),
CONSTRAINT `FK_EMPRESAS_CIDADES` FOREIGN KEY (`id_cidade`) REFERENCES `cidades` (`id`),
CONSTRAINT `FK_EMPRESAS_EMPRESASMATRIZ` FOREIGN KEY (`id_grupo`) REFERENCES `emp_grupo` (`id`),
CONSTRAINT `FK_EMPRESAS_ESTADOS` FOREIGN KEY (`id_estado`) REFERENCES `estados` (`id`),
CONSTRAINT `FK_EMPRESAS_FUNCIONALIDADES` FOREIGN KEY (`id_funcionalidade`) REFERENCES `emp_funcionalidades` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=utf8

"Foreign key constraint is incorrectly formed" while creating unique index

I was attempted to execute following queries:
CREATE TABLE `lob_sections` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`section_name` varchar(600) NOT NULL,
`lob_type` varchar(64) NOT NULL,
`agency_id` varchar(64) NOT NULL,
`display_order` tinyint(2) NOT NULL DEFAULT 1,
`active` tinyint(1) NOT NULL DEFAULT 1,
`created_date` timestamp NOT NULL DEFAULT current_timestamp(),
`last_modified_date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `unq_lob_sections` (`agency_id`,`lob_type`,`section_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `lob_custom_fields` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`section_id` int(11) NOT NULL,
`field_label` varchar(1400) NOT NULL,
`field_type` varchar(20) NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT 1,
`display_order` tinyint(3) NOT NULL DEFAULT 1,
`required` tinyint(1) NOT NULL DEFAULT 0,
`created_date` timestamp NOT NULL DEFAULT current_timestamp(),
`last_modified_date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`),
CONSTRAINT unq_section_field_label UNIQUE (section_id, field_label),
CONSTRAINT `fk_section_id` FOREIGN KEY (`section_id`) REFERENCES `lob_sections` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
lob_sections table is created successfully, but lob_custom_fields is not creating, it is throwing me following error:
#1005 - Can't create table abc_db.lob_custom_fields (errno: 150 "Foreign key constraint is incorrectly formed") (Details…)
When I click on Details, then it shows me reason "Create table abc_db.lob_custom_fieldswith foreign keyfk_section_id constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns.------------".
If I remove the line "CONSTRAINT unq_section_field_label UNIQUE (section_id, field_label)," from create table statement of lob_custom_fields table, then it created successfully.
How to add unique index in lob_custom_fields table? Create-Alter both are showing same error when I attempt to add unique index. Any help will be highly appreciated.
The error message says
Specified key was too long; max key length is 3072 bytes
The InnoDB internal maximum key length is 3500 bytes, but MySQL itself restricts this to 3072 bytes. This limit applies to the length of the combined index key in a multi-column index.
that is for mysql 8
so you must define
field_label varchar(1022)
That fits
CREATE TABLE `lob_sections` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`section_name` varchar(600) NOT NULL,
`lob_type` varchar(64) NOT NULL,
`agency_id` varchar(64) NOT NULL,
`display_order` tinyint(2) NOT NULL DEFAULT 1,
`active` tinyint(1) NOT NULL DEFAULT 1,
`created_date` timestamp NOT NULL DEFAULT current_timestamp(),
`last_modified_date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `unq_lob_sections` (`agency_id`,`lob_type`,`section_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `lob_custom_fields` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`section_id` int(11) NOT NULL,
`field_label` varchar(1022) NOT NULL,
`field_type` varchar(20) NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT 1,
`display_order` tinyint(3) NOT NULL DEFAULT 1,
`required` tinyint(1) NOT NULL DEFAULT 0,
`created_date` timestamp NOT NULL DEFAULT current_timestamp(),
`last_modified_date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`),
CONSTRAINT unq_section_field_label UNIQUE (section_id, field_label),
CONSTRAINT `fk_section_id` FOREIGN KEY (`section_id`) REFERENCES `lob_sections` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
db<>fiddle here

Adding a Foreign Key to MariaDB / MySQL table

I have 3 tables:
CREATE TABLE `channels` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`status` enum('active','inactive') NOT NULL DEFAULT 'active’,
`description` text DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=485 DEFAULT CHARSET=utf8;
CREATE TABLE `categories` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`content` text DEFAULT NULL,
`description` text DEFAULT NULL,
`status` enum('active','inactive') NOT NULL DEFAULT 'active',
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
`updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=128 DEFAULT CHARSET=utf8;
CREATE TABLE `events` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`content` text DEFAULT NULL,
`timezone` varchar(255) DEFAULT NULL,
`recurring` tinyint(1) NOT NULL DEFAULT 0,
`all_day` tinyint(1) NOT NULL DEFAULT 0,
`starts_at` timestamp NULL DEFAULT NULL,
`ends_at` timestamp NULL DEFAULT NULL,
`started_at` timestamp NULL DEFAULT NULL,
`completed_at` timestamp NULL DEFAULT NULL,
`status` enum('active','inactive','in_progress','complete') DEFAULT 'active',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=82 DEFAULT CHARSET=utf8;
I want to alter the events table to add more fields and add foreign keys to channel, event_type and client_event_type.
I've tried this:
alter table `events`
add `channel` int unsigned not null,
add `event_type` int unsigned not null,
add `client_event_type` int unsigned not null,
add constraint `events_channel_foreign` foreign key `channel` references `channels`(`id`),
add constraint `events_event_type_foreign` foreign key `event_type` references `categories`(`id`),
add constraint `events_clientEventType_foreign` foreign key `client_event_type` references `categories`(`id`),
It comes up with :
You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use
near 'references channels(id), add constraint
events_event_type_foreign foreig' at line 5
What am I doing wrong?
Thanks
You're missing parantheses:
alter table `events`
add `channel` int unsigned not null,
add `event_type` int unsigned not null,
add `client_event_type` int unsigned not null,
add constraint `events_channel_foreign` foreign key (`channel`) references `channels`(`id`),
add constraint `events_event_type_foreign` foreign key (`event_type`) references `categories`(`id`),
add constraint `events_clientEventType_foreign` foreign key (`client_event_type`) references `categories`(`id`)

how to optimize this query further more

I tried all i could do but could not get the least execution time.
SELECT e.code_assigned,
Count(DISTINCT tcp.id) AS total_qa,
Count(DISTINCT tcp.encounter_uid) AS total_records,
Sum(IF(tcp.qa_disagree = '1', tcd.weight, 0)) AS error_points,
Sum(IF(tcp.qa_disagree = '1',1,0)) AS total_disagree,
Sum(tcd.weight) AS total_qa_weight,
Count(DISTINCT CASE WHEN tcp.qa_disagree = '1' THEN tcp.encounter_uid end) AS total_disagree_record
FROM tbl_encounter_detail AS e
STRAIGHT_JOIN tbl_event_cpt_pro AS tcp ON tcp.encounter_uid = e.encounter_uid AND tcp.work_item_uid = e.work_item_uid
JOIN tbl_encounter as ed ON tcp.encounter_uid = ed.encounter_uid
LEFT JOIN tbl_code_weight AS tcd ON tcd.code = tcp.procedure_num
WHERE e.qa_complete = 1
GROUP BY code_assigned
UNION ALL
SELECT e.code_assigned,
Count(DISTINCT tcf.id) AS total_qa,
Count(DISTINCT tcf.encounter_uid) AS total_records,
Sum(IF(tcf.qa_disagree = '1', tcd.weight, 0)) AS error_points,
Sum(IF(tcf.qa_disagree = '1',1,0)) AS total_disagree,
Sum(tcd.weight) AS total_qa_weight,
Count(DISTINCT CASE WHEN tcf.qa_disagree = '1' THEN tcf.encounter_uid end) AS total_disagree_record
FROM tbl_encounter_detail AS e
STRAIGHT_JOIN tbl_event_cpt_fac AS tcf ON tcf.encounter_uid = e.encounter_uid AND tcf.work_item_uid = e.work_item_uid
JOIN tbl_encounter as ed ON tcf.encounter_uid = ed.encounter_uid
LEFT JOIN tbl_code_weight AS tcd ON tcd.code = tcf.procedure_num
WHERE e.qa_complete = 1
GROUP BY code_assigned
This query is hampering performance (this is the least that i am able to do) I don't know why am i not able to optimize it more. what is really hampering it? Please help.
new explain plan
for tbl_event_cpt_pro and tbl_event_cpt_fac
CREATE TABLE `tbl_event_cpt_pro` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`encounter_uid` int(11) NOT NULL,
`procedure_num` varchar(10) NOT NULL,
`procedure_qty` int(11) NOT NULL DEFAULT '1',
`procedure_modifier1` varchar(10) DEFAULT NULL,
`procedure_modifier2` varchar(10) DEFAULT NULL,
`procedure_provider` varchar(75) DEFAULT NULL,
`mid_provider` varchar(75) DEFAULT NULL,
`userid` varchar(50) NOT NULL,
`user_time_entered` datetime NOT NULL,
`qa_disagree` tinyint(1) NOT NULL DEFAULT '0',
`qa_procedure_num` varchar(10) DEFAULT NULL,
`qa_procedure_qty` int(5) DEFAULT NULL,
`qa_procedure_modifier` varchar(10) DEFAULT NULL,
`qa_procedure_provider` varchar(75) DEFAULT NULL,
`qa_note` varchar(255) DEFAULT NULL,
`qa_userid` varchar(50) DEFAULT NULL,
`qa_user_time_entered` datetime DEFAULT NULL,
`qa_reason` varchar(75) DEFAULT NULL,
`work_item_uid` int(11) NOT NULL,
`user_time_entered_utc` datetime DEFAULT NULL,
`cosigning_physician` varchar(75) DEFAULT NULL,
`procedure_date` date DEFAULT NULL COMMENT 'Date procedure was
performed. May not be date of service/admit date.',
`charge_code_select` varchar(20) DEFAULT NULL COMMENT 'If the
procedure CPT has multiple charge codes, this indicates the one chosen by coder',
`specialist` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Indicates Specialist outpatient procedure - ref IU and Sturdy',
`dos` date DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_enc_uid` (`encounter_uid`),
KEY `procedure_provider` (`procedure_provider`),
KEY `mid_provider` (`mid_provider`),
KEY `qa_procedure_provider` (`qa_procedure_provider`),
KEY `userid` (`userid`),
KEY `qa_userid` (`qa_userid`),
KEY `work_item_uid` (`work_item_uid`),
KEY `work_item_uid_2` (`work_item_uid`,`encounter_uid`),
KEY `cosigning_physician` (`cosigning_physician`),
KEY `code_index` (`procedure_num`),
CONSTRAINT `tbl_event_cpt_pro_ibfk_1` FOREIGN KEY (`encounter_uid`) REFERENCES `tbl_encounter` (`encounter_uid`),
CONSTRAINT `tbl_event_cpt_pro_ibfk_10` FOREIGN KEY (`work_item_uid`) REFERENCES `tbl_work_item` (`work_item_uid`) ON DELETE CASCADE,
CONSTRAINT `tbl_event_cpt_pro_ibfk_11` FOREIGN KEY (`userid`) REFERENCES `tbl_user` (`user_email_address`),
CONSTRAINT `tbl_event_cpt_pro_ibfk_12` FOREIGN KEY (`work_item_uid`, `encounter_uid`) REFERENCES `tbl_encounter_detail` (`work_item_uid`, `encounter_uid`),
CONSTRAINT `tbl_event_cpt_pro_ibfk_13` FOREIGN KEY (`cosigning_physician`) REFERENCES `tbl_provider` (`provider_lov`),
CONSTRAINT `tbl_event_cpt_pro_ibfk_2` FOREIGN KEY (`procedure_provider`) REFERENCES `tbl_provider` (`provider_lov`),
CONSTRAINT `tbl_event_cpt_pro_ibfk_3` FOREIGN KEY (`mid_provider`) REFERENCES `tbl_provider` (`provider_lov`),
CONSTRAINT `tbl_event_cpt_pro_ibfk_4` FOREIGN KEY (`qa_procedure_provider`) REFERENCES `tbl_provider` (`provider_lov`),
CONSTRAINT `tbl_event_cpt_pro_ibfk_5` FOREIGN KEY (`userid`) REFERENCES `tbl_user` (`user_email_address`),
CONSTRAINT `tbl_event_cpt_pro_ibfk_6` FOREIGN KEY (`qa_userid`) REFERENCES `tbl_user` (`user_email_address`),
CONSTRAINT `tbl_event_cpt_pro_ibfk_7` FOREIGN KEY (`work_item_uid`) REFERENCES `tbl_work_item` (`work_item_uid`),
CONSTRAINT `tbl_event_cpt_pro_ibfk_9` FOREIGN KEY (`encounter_uid`) REFERENCES `tbl_encounter` (`encounter_uid`) ON DELETE CASCADE
)
for tbl_encounter_detail
CREATE TABLE `tbl_encounter_detail` (
`enc_detail_uid` int(11) NOT NULL AUTO_INCREMENT,
`encounter_uid` int(11) NOT NULL,
`work_item_uid` int(11) NOT NULL,
`code_assigned` varchar(50) DEFAULT NULL,
`coding_start_time` datetime DEFAULT NULL,
`code_complete_ts` datetime DEFAULT NULL,
`code_complete` int(1) NOT NULL DEFAULT '0',
`suspend_active` int(1) DEFAULT NULL,
`qa_flag` int(1) NOT NULL DEFAULT '0',
`qa_complete` int(1) NOT NULL DEFAULT '0',
`qa_start_time` datetime DEFAULT NULL,
`qa_complete_ts` datetime DEFAULT NULL,
`qa_assigned` varchar(50) DEFAULT NULL,
`dataentry_complete` int(1) NOT NULL DEFAULT '0',
`dataentry_start_time` datetime DEFAULT NULL,
`dataentry_complete_ts` datetime DEFAULT NULL,
`dataentry_assigned` varchar(50) DEFAULT NULL,
`encounter_status` varchar(30) NOT NULL,
`dataentry_assigned_tec` varchar(50) DEFAULT NULL COMMENT 'Data entry user for Technical component',
`dataentry_complete_tec` int(1) NOT NULL DEFAULT '0' COMMENT 'Data Entry complete for Technical component; used only for split data entry clients',
`dataentry_assigned_pf` varchar(50) DEFAULT NULL COMMENT 'Data entry user for Profee component',
`dataentry_complete_pf` int(1) NOT NULL DEFAULT '0' COMMENT 'Data Entry complete for Profee component',
`qa_feedback` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Set when the QA reviewer has feedback on disagreements',
`qa_seen_by_coder_utc` datetime DEFAULT NULL COMMENT 'Set when the coder acknowledges QA feedback on this encounter',
`qa_dataentry` tinyint(1) DEFAULT '0' COMMENT 'Set if data entry requested QA',
`code_complete_pf` tinyint(1) DEFAULT '0' COMMENT 'When LiveCode and split data entry are active, this indicates Profee coding is done; otherwise ignored',
`qa_requested` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Whether QA was requested by Coder or Data Entry (vs random sample)',
PRIMARY KEY (`enc_detail_uid`),
UNIQUE KEY `uniq_wi_enc` (`work_item_uid`,`encounter_uid`),
KEY `idx_enc_uid` (`encounter_uid`),
KEY `idx_code_assigned` (`code_assigned`),
KEY `encounter_status` (`encounter_status`),
KEY `qa_assigned` (`qa_assigned`),
KEY `dataentry_assigned` (`dataentry_assigned`),
KEY `dataentry_assigned_tec` (`dataentry_assigned_tec`),
KEY `dataentry_assigned_pf` (`dataentry_assigned_pf`),
KEY `idx_qa_complete` (`qa_complete`),
KEY `idx_composite` (`qa_complete`,`code_assigned`,`encounter_uid`,`work_item_uid`),
CONSTRAINT `tbl_encounter_detail_ibfk_1` FOREIGN KEY (`encounter_uid`) REFERENCES `tbl_encounter` (`encounter_uid`),
CONSTRAINT `tbl_encounter_detail_ibfk_2` FOREIGN KEY (`work_item_uid`) REFERENCES `tbl_work_item` (`work_item_uid`),
CONSTRAINT `tbl_encounter_detail_ibfk_3` FOREIGN KEY (`code_assigned`) REFERENCES `tbl_user` (`user_email_address`),
CONSTRAINT `tbl_encounter_detail_ibfk_4` FOREIGN KEY (`qa_assigned`) REFERENCES `tbl_user` (`user_email_address`),
CONSTRAINT `tbl_encounter_detail_ibfk_5` FOREIGN KEY (`dataentry_assigned`) REFERENCES `tbl_user` (`user_email_address`),
CONSTRAINT `tbl_encounter_detail_ibfk_6` FOREIGN KEY (`dataentry_assigned_tec`) REFERENCES `tbl_user` (`user_email_address`),
CONSTRAINT `tbl_encounter_detail_ibfk_7` FOREIGN KEY (`dataentry_assigned_pf`) REFERENCES `tbl_user` (`user_email_address`),
CONSTRAINT `tbl_encounter_detail_ibfk_8` FOREIGN KEY (`encounter_status`) REFERENCES `tbl_encounter_status` (`id`)
)
for tbl_encounter
CREATE TABLE `tbl_encounter` (
`encounter_uid` int(11) NOT NULL AUTO_INCREMENT,
`patient_name` varchar(75) NOT NULL,
`patient_sex` varchar(1) NOT NULL,
`patient_dob` date NOT NULL,
`encounter_dos` date NOT NULL,
`batch_control` varchar(75) CHARACTER SET latin1 DEFAULT NULL,
`encounter_location` varchar(50) CHARACTER SET latin1 DEFAULT NULL,
`facility_id` varchar(75) NOT NULL,
`patient_mrn` varchar(20) NOT NULL,
`patient_fin` varchar(20) NOT NULL,
`encounter_lwbs` tinyint(1) DEFAULT NULL,
`encounter_ama` tinyint(1) DEFAULT NULL,
`encounter_reason_for_visit` varchar(300) DEFAULT NULL,
`encounter_chief_complaint` varchar(2048) DEFAULT NULL,
`encounter_ins_type` varchar(50) CHARACTER SET latin1 DEFAULT NULL,
`encounter_ins_1` varchar(75) CHARACTER SET latin1 DEFAULT NULL,
`encounter_ins_2` varchar(75) CHARACTER SET latin1 DEFAULT NULL,
`encounter_primary_type` varchar(75) CHARACTER SET latin1 DEFAULT NULL,
`encounter_primary_class` varchar(75) CHARACTER SET latin1 DEFAULT NULL,
`encounter_secondary_type` varchar(75) CHARACTER SET latin1 DEFAULT NULL,
`encounter_secondary_class` varchar(75) CHARACTER SET latin1 DEFAULT NULL,
`encounter_disch_diagnosis` varchar(75) CHARACTER SET latin1 DEFAULT NULL,
`encounter_disch_disp` varchar(75) CHARACTER SET latin1 DEFAULT NULL,
`encounter_type` varchar(75) CHARACTER SET latin1 DEFAULT NULL,
`encounter_assign_provider1` varchar(75) CHARACTER SET latin1 DEFAULT NULL,
`encounter_assign_provider2` varchar(75) DEFAULT NULL COMMENT 'Obsolete - should be dropped in future',
`encounter_admit_mode` varchar(75) CHARACTER SET latin1 DEFAULT NULL,
`load_time` datetime NOT NULL,
`enc_admit` datetime DEFAULT NULL COMMENT 'Datetime of inpatient admission.',
`import_loc` varchar(200) DEFAULT NULL COMMENT 'Source of record: typically file name and line number',
`import_line` bigint(20) unsigned DEFAULT NULL,
`attend_provider_uid` int(10) unsigned DEFAULT NULL,
`disch_time_utc` datetime DEFAULT NULL,
`last_adt_recorded_utc` datetime DEFAULT NULL COMMENT 'The EVN.2 recorded timestamp of the last ADT update applied. Used to ensure updates are applied in order.',
`loaded_disch_disp` varchar(75) DEFAULT NULL COMMENT 'The discharge disposition originally loaded from ED Log for this chart',
`admitted` tinyint(1) DEFAULT NULL,
`injury_real_date` date DEFAULT NULL,
`lmp_date` date DEFAULT NULL COMMENT 'Last Menstrual Period',
`transfer` tinyint(1) DEFAULT NULL COMMENT 'Coded in patient header when patient was transferred between facilities',
`transfer_dest` varchar(75) DEFAULT NULL COMMENT 'If chart is a transfer to another facility, the coder specifies the facility in this field',
`dos_end` date DEFAULT NULL,
`outpatient` tinyint(1) DEFAULT NULL,
`discharge` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`encounter_uid`),
KEY `idx_fac_id` (`facility_id`),
KEY `idx_name` (`patient_name`),
KEY `idx_dos` (`encounter_dos`),
KEY `attend_provider_uid` (`attend_provider_uid`),
KEY `idx_fin` (`patient_fin`),
KEY `idx_ins` (`encounter_primary_type`),
KEY `idx_prov` (`encounter_assign_provider1`),
KEY `idx_mrn_temp` (`patient_mrn`),
CONSTRAINT `tbl_encounter_ibfk_1` FOREIGN KEY (`attend_provider_uid`) REFERENCES `tbl_provider` (`provider_uid`)
)
for tbl_code_weight
Create Table: CREATE TABLE `tbl_code_weight` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`code` varchar(20) NOT NULL,
`weight` float NOT NULL,
KEY `idx_composite` (`code`,`weight`)
PRIMARY KEY (`id`)
)

MySQL - Why can't I add a foreign key here?

I'm not sure why I'm not able to add a particular foreign key here. These tables were generated via MySQL Workbench, and based on the MySQL documentation and on searching for other similar problems / solutions, I think everything is in order...yet I can't add one foreign key in particular:
inspection_statuses.inspection_id needs to reference inspection_responses.tpa_result
What am I missing / overlooking?
This is the statement I'm trying to use to add the new foreign key:
ALTER TABLE `vipsouth_app`.`inspection_statuses`
ADD CONSTRAINT `inspection_statuses_ibfk_3`
FOREIGN KEY (`inspection_id`)
REFERENCES `vipsouth_app`.`inspection_responses` (`tpa_result`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
And that produces this error:
Operation failed: There was an error while applying the SQL script to the database.
ERROR 1005: Can't create table vipsouth_app.#sql-1f48_7 (errno: 150 "Foreign key constraint is incorrectly formed")
CREATE TABLE `inspection_responses` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`inspection_request_id` int(10) unsigned NOT NULL,
`tpa_result` varchar(10) CHARACTER SET utf8 NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` int(10) unsigned NOT NULL DEFAULT '0',
`updated_at` timestamp NULL DEFAULT NULL,
`updated_by` int(10) unsigned DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`deleted_by` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
UNIQUE KEY `tpa_result_UNIQUE` (`tpa_result`),
KEY `inspection_responses_ibfk_1_idx` (`inspection_request_id`),
CONSTRAINT `inspection_responses_ibfk_1` FOREIGN KEY (`inspection_request_id`) REFERENCES `inspection_requests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
CREATE TABLE `inspection_statuses` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`inspection_request_id` int(10) unsigned NOT NULL,
`inspection_response_id` int(10) unsigned NOT NULL,
`tpa_code` varchar(4) COLLATE utf8_unicode_ci NOT NULL,
`user_id` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`inspection_id` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
`status` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`note` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL,
`url` varchar(1024) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` int(10) unsigned NOT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`updated_by` int(10) unsigned DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`deleted_by` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
KEY `inspection_statuses_ibfk_1_idx` (`inspection_request_id`),
KEY `inspection_statuses_ibfk_2_idx` (`inspection_response_id`),
CONSTRAINT `inspection_statuses_ibfk_1` FOREIGN KEY (`inspection_request_id`) REFERENCES `inspection_requests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `inspection_statuses_ibfk_2` FOREIGN KEY (`inspection_response_id`) REFERENCES `inspection_responses` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
The data types and constraints defined on both the columns should be exactly the same. Except for a foreign key can be NULLable.
This should do it for you. I did not get any error.
SET foreign_key_checks = 0;
CREATE TABLE `inspection_responses` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`inspection_request_id` int(10) unsigned NOT NULL,
`tpa_result` varchar(10) CHARACTER SET utf8 NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` int(10) unsigned NOT NULL DEFAULT '0',
`updated_at` timestamp NULL DEFAULT NULL,
`updated_by` int(10) unsigned DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`deleted_by` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
UNIQUE KEY `tpa_result_UNIQUE` (`tpa_result`),
KEY `inspection_responses_ibfk_1_idx` (`inspection_request_id`),
CONSTRAINT `inspection_responses_ibfk_1` FOREIGN KEY (`inspection_request_id`) REFERENCES `inspection_requests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `inspection_statuses` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`inspection_request_id` int(10) unsigned NOT NULL,
`inspection_response_id` int(10) unsigned NOT NULL,
`tpa_code` varchar(4) COLLATE utf8_unicode_ci NOT NULL,
`user_id` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`inspection_id` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
`status` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`note` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL,
`url` varchar(1024) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` int(10) unsigned NOT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`updated_by` int(10) unsigned DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`deleted_by` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
KEY `inspection_statuses_ibfk_1_idx` (`inspection_request_id`),
KEY `inspection_statuses_ibfk_2_idx` (`inspection_response_id`),
CONSTRAINT `inspection_statuses_ibfk_1` FOREIGN KEY (`inspection_request_id`) REFERENCES `inspection_requests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `inspection_statuses_ibfk_2` FOREIGN KEY (`inspection_response_id`) REFERENCES `inspection_responses` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
SET foreign_key_checks = 1;