This is my SQL code which links users to items based on tutorials:
CREATE TABLE IF NOT EXISTS `users` (
`user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
`user_password_hash` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`user_email` varchar(254) COLLATE utf8_unicode_ci NOT NULL,
`user_access_level` tinyint(3) unsigned NOT NULL DEFAULT '0',
`user_active` tinyint(1) NOT NULL DEFAULT '0',
`user_activation_hash` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
`user_password_reset_hash` char(40) COLLATE utf8_unicode_ci DEFAULT NULL,
`user_password_reset_timestamp` bigint(20) DEFAULT NULL,
`user_failed_logins` tinyint(1) NOT NULL DEFAULT '0',
`user_last_failed_login` int(10) DEFAULT NULL,
`user_registration_datetime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`user_registration_ip` varchar(39) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0.0.0.0',
PRIMARY KEY (`user_id`),
UNIQUE KEY `user_name` (`user_name`),
UNIQUE KEY `user_email` (`user_email`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `item` (
`item_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`item_title` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
`item_location` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
`item_description` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
`item_datetime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`item_status` int(1) unsigned NOT NULL,
PRIMARY KEY (`item_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
http://sqlfiddle.com/#!9/fd011
I'm getting a bit confused about how to link the items to the user. It seems like I need something called a foreign key on the items, a bit like this in my item table:
FOREIGN KEY (user_id) REFERENCES user(ID)
I can't seem to get it to compile and query successfully. Can anyone please show me the right way to associate the items with the user.
You need to add the user_id column to the items table along with the constraint:
CREATE TABLE IF NOT EXISTS `users` (
`user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
`user_password_hash` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`user_email` varchar(254) COLLATE utf8_unicode_ci NOT NULL,
`user_access_level` tinyint(3) unsigned NOT NULL DEFAULT '0',
`user_active` tinyint(1) NOT NULL DEFAULT '0',
`user_activation_hash` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
`user_password_reset_hash` char(40) COLLATE utf8_unicode_ci DEFAULT NULL,
`user_password_reset_timestamp` bigint(20) DEFAULT NULL,
`user_failed_logins` tinyint(1) NOT NULL DEFAULT '0',
`user_last_failed_login` int(10) DEFAULT NULL,
`user_registration_datetime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`user_registration_ip` varchar(39) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0.0.0.0',
PRIMARY KEY (`user_id`),
UNIQUE KEY `user_name` (`user_name`),
UNIQUE KEY `user_email` (`user_email`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `item` (
`item_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
user_id int unsigned,
`item_title` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
`item_location` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
`item_description` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
`item_datetime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`item_status` int(1) unsigned NOT NULL,
PRIMARY KEY (`item_id`),
FOREIGN KEY (user_id) REFERENCES users(user_id)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
The SQL Fiddle is here.
I should point out a few other things:
Pay attention to the database engine you are using. MyISAM doesn't actually enforce the relationship.
Having weird dates as the default value is probably less useful than just using NULL.
I'm not sure if there is a value to having explicit collations for every character definition, unless your database is going to be supporting a wide variety of collations.
Don't use single quotes for numeric constants. So, if a value is declared as a tinyint, set the default ot 0 not '0' (this doesn't affect performance in a CREATE TABLE statement; it is just misleading).
#GordonLindoff's solution is one method, but that assumes that each item belongs to exactly one user, and an item cannot be referenced by multiple users. If you have a many-to-many relationship, where a user can have multiple items and an item can be referenced by multiple users, then you need a third table that links them together:
CREATE TABLE IF NOT EXISTS `user_item` (
`user_id` int(11) unsigned NOT NULL,
`item_id` int(11) unsigned NOT NULL,
PRIMARY KEY (`user_item`,`item_id`),
FOREIGN KEY (user_id) REFERENCES users(user_id),
FOREIGN KEY (item_id) REFERENCES items(item_id)
)ENGINE=Innodb DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
The Foreign Key constraints enforce that for every row in user_item that the user_id exists in users, and the item_id exists in items. And as was mentioned in a previous comment, that you will need Innodb to have the foreign key constraints enforced.
Related
I am using workbench and I am trying to create a database with a table:
I just put this create database in the sql editor and execute it.
Of course I googled first for the error. But I cant find anything for this specific case.
-- Dumping database structure for v2_financieel
CREATE DATABASE IF NOT EXISTS `v2_financieel` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `v2_financieel`;
-- Dumping structure for table v2_financieel.facturen_azie
CREATE TABLE IF NOT EXISTS `facturen_azie` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`kantoor_id` int(10) unsigned NOT NULL,
`factuurnummer` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
`factuurdatum` date NOT NULL,
`merknaam_id` int(10) unsigned NOT NULL,
`klant_id` int(10) unsigned NOT NULL,
`omschrijving` varchar(191) COLLATE utf8_unicode_ci NOT NULL,
`aantal_afslagen` decimal(10,1) unsigned NOT NULL,
`bonnummers` varchar(191) COLLATE utf8_unicode_ci DEFAULT NULL,
`valuta` char(3) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'EUR',
`koers` decimal(8,4) unsigned NOT NULL,
`koersdatum` date NOT NULL,
`bedrag_euro` decimal(10,2) NOT NULL,
`bedrag_valuta` decimal(10,2) NOT NULL,
`btw` decimal(10,2) NOT NULL,
`factuurbedrag` decimal(10,2) NOT NULL,
`betaald` tinyint(1) NOT NULL DEFAULT '0',
`extra_bedrag` decimal(10,2) NOT NULL,
`extra_omschrijving` varchar(191) COLLATE utf8_unicode_ci DEFAULT NULL,
`creditfactuur` tinyint(1) NOT NULL DEFAULT '0',
`credit_id` int(11) NOT NULL DEFAULT '0',
`betalingsdatum` date NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `facturen_azie_factuurnummer_unique` (`factuurnummer`),
KEY `facturen_azie_merknaam_id_foreign` (`merknaam_id`),
KEY `facturen_azie_klant_id_foreign` (`klant_id`),
KEY `facturen_azie_kantoor_id_foreign` (`kantoor_id`),
FULLTEXT KEY `search_azie` (`factuurnummer`,`omschrijving`),
CONSTRAINT `facturen_azie_kantoor_id_foreign` FOREIGN KEY (`kantoor_id`) REFERENCES `kantoren` (`id`),
CONSTRAINT `facturen_azie_klant_id_foreign` FOREIGN KEY (`klant_id`) REFERENCES `klanten` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=496 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
But I get this errror:
12:02:40 CREATE TABLE IF NOT EXISTS `facturen_azie` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `kantoor_id` int(10) unsigned NOT NULL, `factuurnummer` varchar(10) COLLATE utf8_unicode_ci NOT NULL, `factuurdatum` date NOT NULL, `merknaam_id` int(10) unsigned NOT NULL, `klant_id` int(10) unsigned NOT NULL, `omschrijving` varchar(191) COLLATE utf8_unicode_ci NOT NULL, `aantal_afslagen` decimal(10,1) unsigned NOT NULL, `bonnummers` varchar(191) COLLATE utf8_unicode_ci DEFAULT NULL, `valuta` char(3) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'EUR', `koers` decimal(8,4) unsigned NOT NULL, `koersdatum` date NOT NULL, `bedrag_euro` decimal(10,2) NOT NULL, `bedrag_valuta` decimal(10,2) NOT NULL, `btw` decimal(10,2) NOT NULL, `factuurbedrag` decimal(10,2) NOT NULL, `betaald` tinyint(1) NOT NULL DEFAULT '0', `extra_bedrag` decimal(10,2) NOT NULL, `extra_omschrijving` varchar(191) COLLATE utf8_unicode_ci DEFAULT NULL, `creditfactuur` tinyint(1) NOT NULL DEFAULT '0', `credit_id` int(11) NOT NULL DEFAULT '0', `betalingsdatum` date NOT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `facturen_azie_factuurnummer_unique` (`factuurnummer`), KEY `facturen_azie_merknaam_id_foreign` (`merknaam_id`), KEY `facturen_azie_klant_id_foreign` (`klant_id`), KEY `facturen_azie_kantoor_id_foreign` (`kantoor_id`), FULLTEXT KEY `search_azie` (`factuurnummer`,`omschrijving`), CONSTRAINT `facturen_azie_kantoor_id_foreign` FOREIGN KEY (`kantoor_id`) REFERENCES `kantoren` (`id`), CONSTRAINT `facturen_azie_klant_id_foreign` FOREIGN KEY (`klant_id`) REFERENCES `klanten` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=496 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci Error Code: 1005. Can't create table `v2_financieel`.`facturen_azie` (errno: 150 "Foreign key constraint is incorrectly formed") 0.359 sec
I am creating a web portal for an organization and I am a bit confused on this part.
They will be receiving donations from their registered members as well as guests. I was thinking of creating a users table that is solely used for registered members and no guests etc. because users table will contain unique "email" column and I don't want it to be null.
For donations, I can add user_id foreign key for users table.
What I am thinking of doing is that I should add "name" and "mobile" columns in donations table, so that if it's a guest, we should only get his name and phone number and put in donations table. Do you think this is the right way?
For just demo purpose I am showing you the table:
users table
CREATE TABLE IF NOT EXISTS `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`mobile` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`status` tinyint(1) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`),
UNIQUE KEY `users_mobile_unique` (`mobile`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
donations table
CREATE TABLE IF NOT EXISTS `donations` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned DEFAULT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`mobile` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`status` tinyint(1) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `users_user_id_foreign` (`user_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
Any help would be much appreciated.
Thanks
There are many ways to solve data problems - some better than others. I would not have a separate user table if you are already getting some details. Rather have a REGISTERED_USER column or along those lines to denote a "full user" versus a partial. Then everything stays relatively simple AND the user has an option to become a full user later, which I assume you want for donations... :)
First query:
SELECT
u.id,
u.first_name,
u.last_name,
u.tazkera_id,
cu.relation_type,
CASE csp.`shift`
WHEN '1' THEN 'Morning'
WHEN '2' THEN 'Afternoon'
else 'Neither'
END AS shift
FROM `course_user` as cu
LEFT JOIN `courses` as c ON c.id = cu.`course_id`
LEFT JOIN (
select users.id,
users.first_name,
users.last_name,
users.tazkera_id
FROM `users`
) as u ON u.id = cu.`user_id`
left JOIN `course_schedule_prefs` as csp ON csp.`user_id` = cu.`user_id`
Where cu.relation_type = 1 group by cu.`user_id`;
Second Query:
SELECT
u.id,
u.first_name,
u.last_name,
u.tazkera_id,
cu.relation_type,
CASE csp.`shift`
WHEN '1' THEN 'Morning'
WHEN '2' THEN 'Afternoon'
else 'Neither'
END AS shift
FROM `course_user` as cu
LEFT JOIN `courses` as c ON c.id = cu.`course_id`
LEFT JOIN users as u ON u.id = cu.`user_id`
left JOIN `course_schedule_prefs` as csp ON csp.`user_id` = cu.`user_id`
Where cu.relation_type = 1 group by cu.`user_id`;
Tables :
users:
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`last_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`is_password_reset` int(11) NOT NULL DEFAULT '0',
`login_ip` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`login_date` datetime DEFAULT NULL,
`last_login_ip` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`last_login_date` datetime DEFAULT NULL,
`is_email_address_verified` int(11) NOT NULL DEFAULT '0',
`failed_login_attempts` int(11) DEFAULT NULL,
`last_failed_login_date` datetime DEFAULT NULL,
`tazkera_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`province_code` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`district_code` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`village` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`home_address` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`promote_unique_user_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`remember_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`forgot_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`email_confirm_token` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`district_other` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`father_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`training_provider_id` int(10) unsigned DEFAULT NULL,
`is_profile_completed` int(11) DEFAULT NULL,
`active` int(11) DEFAULT '1',
`picture` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`small_picture` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`last_poll` bigint(20) DEFAULT NULL,
`last_password_reset` date DEFAULT NULL,
`presence_status` int(11) DEFAULT NULL,
`auto_presence` int(11) NOT NULL DEFAULT '0',
`last_activity` timestamp NULL DEFAULT NULL,
`trash` tinyint(4) NOT NULL DEFAULT '0',
`login_approval` tinyint(4) NOT NULL DEFAULT '0',
`lang` varchar(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'en',
`cover` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`small_cover` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`forum_reputation` int(11) NOT NULL DEFAULT '0',
`forum_suspension_date` date DEFAULT NULL,
`forum_status` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`),
KEY `users_training_provider_id_foreign` (`training_provider_id`),
CONSTRAINT `users_training_provider_id_foreign` FOREIGN KEY (`training_provider_id`) REFERENCES `training_providers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1000038 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
course_users:
CREATE TABLE `course_user` (
`course_id` int(10) unsigned DEFAULT NULL,
`user_id` int(10) unsigned DEFAULT NULL,
`relation_type` int(11) DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
KEY `course_user_course_id_foreign` (`course_id`),
KEY `course_user_user_id_foreign` (`user_id`),
CONSTRAINT `course_user_course_id_foreign` FOREIGN KEY (`course_id`) REFERENCES `courses` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `course_user_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
courses;
CREATE TABLE `courses` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`curriculum_id` int(10) unsigned DEFAULT NULL,
`training_center_id` int(10) unsigned DEFAULT NULL,
`training_coordinator_id` int(10) unsigned DEFAULT NULL,
`focal_point_id` int(10) unsigned DEFAULT NULL,
`start_date` date DEFAULT NULL,
`end_date` date DEFAULT NULL,
`start_time` time DEFAULT NULL,
`end_time` time DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`shift` int(11) DEFAULT NULL,
`stage_id` int(10) unsigned DEFAULT NULL,
`stream_id` int(10) unsigned DEFAULT NULL,
`unit_id` int(10) unsigned DEFAULT NULL,
`master_trainer_id` int(10) unsigned DEFAULT NULL,
`status` int(11) DEFAULT NULL,
`pre_test_generated` int(11) NOT NULL DEFAULT '0',
`post_test_generated` int(11) NOT NULL DEFAULT '0',
`conduct_days` int(11) DEFAULT NULL,
`no` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`evaluation_available` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `courses_curriculum_id_foreign` (`curriculum_id`),
KEY `courses_training_coordinator_id_foreign` (`training_coordinator_id`),
KEY `courses_focal_point_id_foreign` (`focal_point_id`),
KEY `courses_stage_id_foreign` (`stage_id`),
KEY `courses_stream_id_foreign` (`stream_id`),
KEY `courses_unit_id_foreign` (`unit_id`),
KEY `courses_master_trainer_id_foreign` (`master_trainer_id`),
KEY `courses_training_center_id_foreign` (`training_center_id`),
CONSTRAINT `courses_curriculum_id_foreign` FOREIGN KEY (`curriculum_id`) REFERENCES `curriculums` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `courses_focal_point_id_foreign` FOREIGN KEY (`focal_point_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `courses_master_trainer_id_foreign` FOREIGN KEY (`master_trainer_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `courses_stage_id_foreign` FOREIGN KEY (`stage_id`) REFERENCES `stages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `courses_stream_id_foreign` FOREIGN KEY (`stream_id`) REFERENCES `streams` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `courses_training_center_id_foreign` FOREIGN KEY (`training_center_id`) REFERENCES `training_centers` (`id`),
CONSTRAINT `courses_training_coordinator_id_foreign` FOREIGN KEY (`training_coordinator_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `courses_unit_id_foreign` FOREIGN KEY (`unit_id`) REFERENCES `units` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=139 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
course_schedule_prefs;
CREATE TABLE `course_schedule_prefs` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`cunduct_days` int(11) DEFAULT NULL,
`training_centers` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`shift` int(11) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`user_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `course_schedule_prefs_user_id_foreign` (`user_id`),
CONSTRAINT `course_schedule_prefs_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
My question is , which one of this query is good in term of performance and accuracy. Why ?
first query: I join directly with table; select all columns of table.
Second query: I used subquery inside of join; select only those element which I need it.
Note : My main question is about users table which is in join
There are too many possibilities here. There is no simple, 'straight', answer.
With LEFT JOIN (instead of JOIN), the Optimizer cannot start with the subquery, which it would usually like to do.
If there is a WHERE clause and it is useful for filtering rows, the Optimizer would like to start with the table that is filtered the most. Your WHERE clause smells like a flag, which is usually not very useful.
If a subquery has a GROUP BY or LIMIT, then it may significantly shrink the number of rows to work with. (Not in your case.) This might make the subquery approach better.
If cu has INDEX(relation_type, user_id), the Optimizer may decide that handling all of the WHERE and GROUP BY leads to the best bet, thereby starting with cu as the 'first' table.
In old versions of MySQL, subqueries in JOIN ( SELECT ... ) had no way of getting an index, thereby leading to inefficient table scans of that tmp table. In new versions (starting with 5.6, I think), the Optimizer takes the extra step (which costs something) to generate the optimal index ((id) in this case) after creating the tmp table and before JOINing it.
More
2 more table definitions needed.
Do you have the indexes I suggested?
InnoDB really needs a PRIMARY KEY - See many:many for advice on course_user.
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;
I don't know if it's just been a long day or what, but I cannot figure out the query that I need to run here. We have two tables - One for leads generated and one for reports. The leads table has basic lead info, along with the Source (Campaign) of the lead. However, we need to know the number of leads that an ACCOUNT has received within a date range. Here is the relevant table structure:
client_leads:
id
source
date
client_reports:
account
campaign
date
The 'source' column contains the same values as the 'campaign' column. So, how would I achieve the following:
Say there are 10 leads in the leads table, each with the campaign that generated the lead. There are 10 accounts in the reports table, each with hundreds of campaigns. I need to list each account and how many leads it has in the leads table.
I just can't get the logic straight in my head. I've tried everything that I can think of and it's just not working out for me. If you need further explanation, let me know. I'm trying to describe the problem to the best of my ability.
Edit:
CREATE TABLE `client_leads` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`site_id` int(10) DEFAULT NULL,
`ip` varchar(255) DEFAULT NULL,
`source` varchar(255) DEFAULT NULL,
`kw` varchar(255) DEFAULT NULL,
`adgroup` varchar(255) DEFAULT NULL,
`time` time DEFAULT NULL,
`date` date DEFAULT NULL,
`dayweek` varchar(255) DEFAULT NULL,
`first_name` varchar(255) DEFAULT NULL,
`last_name` varchar(255) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
`city` varchar(255) DEFAULT NULL,
`postal_code` char(5) DEFAULT NULL,
`state` char(2) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`preferred_phone` varchar(10) DEFAULT NULL,
`alternate_phone` varchar(10) DEFAULT NULL,
`level_of_education` varchar(255) DEFAULT NULL,
`program_of_interest` varchar(255) DEFAULT NULL,
`organic` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `site_id` (`site_id`),
KEY `date_indeces` (`time`,`date`,`dayweek`) USING BTREE,
CONSTRAINT `site_id` FOREIGN KEY (`site_id`) REFERENCES `client_sites` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8
CREATE TABLE `client_reports` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`account` varchar(255) DEFAULT NULL,
`friendly_name` varchar(255) DEFAULT NULL,
`sites_id` int(10) DEFAULT NULL,
`service` varchar(255) DEFAULT NULL,
`date` date DEFAULT NULL,
`campaign` varchar(255) DEFAULT NULL,
`adgroup` varchar(255) DEFAULT NULL,
`keyword` varchar(255) DEFAULT NULL,
`impressions` int(10) DEFAULT NULL,
`clicks` int(10) DEFAULT NULL,
`cost` float DEFAULT NULL,
`max_cpc` float DEFAULT NULL,
`avg_pos` float DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `stats` (`impressions`,`clicks`,`cost`),
KEY `date` (`date`),
KEY `campaign` (`campaign`),
KEY `adgroup` (`adgroup`),
KEY `keyword` (`keyword`),
KEY `service` (`service`),
KEY `sites_id` (`sites_id`),
CONSTRAINT `sites_id` FOREIGN KEY (`sites_id`) REFERENCES `client_sites` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=109167 DEFAULT CHARSET=utf8
Edit Again:
client_reports table data viewable at http://pastebin.com/T532W3Eq
client_leads table data viewable at http://pastebin.com/9cjWEvck
SELECT cr.account, cr.campaign, cr.date, COUNT(cl.id) AS number_of_leads
FROM client_reports cr
LEFT JOIN client_leads cl
ON cl.source = cr.campaign
GROUP BY cl.source