I am trying to duplicate a page in the database and all related rows.
The problem I am having is because the page_group_id is an identifier for both tables. Is there any way of doing this without looping each of the new "page_groups" records?
pages (page_id, page_name, etc)
page_groups (page_group_id, page_id, etc)
page_group_items (page_group_id, item_id, etc)
UPDATE:
--
-- Table structure for table `pages`
--
CREATE TABLE IF NOT EXISTS `pages` (
`page_id` int(11) NOT NULL AUTO_INCREMENT,
`page_name` varchar(255) NOT NULL,
PRIMARY KEY (`page_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
--
-- Dumping data for table `pages`
--
INSERT INTO `pages` (`page_id`, `page_name`) VALUES
(1, 'My Page'),
(2, 'My other page');
-- --------------------------------------------------------
--
-- Table structure for table `page_groups`
--
CREATE TABLE IF NOT EXISTS `page_groups` (
`page_group_id` int(11) NOT NULL AUTO_INCREMENT,
`page_group_name` varchar(255) NOT NULL,
`page_id` int(11) NOT NULL,
PRIMARY KEY (`page_group_id`),
KEY `page_id` (`page_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
--
-- Dumping data for table `page_groups`
--
INSERT INTO `page_groups` (`page_group_id`, `page_group_name`, `page_id`) VALUES
(1, 'My Group', 1),
(2, 'My Group', 2);
-- --------------------------------------------------------
--
-- Table structure for table `page_group_items`
--
CREATE TABLE IF NOT EXISTS `page_group_items` (
`page_group_id` int(11) NOT NULL,
`item_id` int(11) NOT NULL,
KEY `item_id` (`item_id`),
KEY `page_group_id` (`page_group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `page_group_items`
--
INSERT INTO `page_group_items` (`page_group_id`, `item_id`) VALUES
(1, 1),
(1, 2),
(1, 3),
(2, 1),
(2, 2);
Since you're replacing the only unique identifier in each table (the primary key) when copying, I can't see a way of doing it without adding temporary anchor columns to the tables, do the copy and remove them again. Something like this;
ALTER TABLE pages ADD originalpageid INT;
UPDATE pages set originalpageid=page_id;
ALTER TABLE page_groups ADD originalpagegroupid INT;
UPDATE page_groups SET originalpagegroupid=page_group_id;
INSERT INTO pages (page_name,originalpageid)
SELECT page_name,originalpageid FROM pages;
INSERT INTO page_groups (page_group_name,page_id,originalpagegroupid)
SELECT page_group_name,MAX(pages.page_id),originalpagegroupid
FROM page_groups
JOIN pages
ON page_groups.page_id=originalpageid
GROUP BY originalpageid,page_group_name,originalpagegroupid;
INSERT INTO page_group_items(page_group_id,item_id)
SELECT MAX(page_groups.page_group_id),item_id
FROM page_group_items
JOIN page_groups
ON page_group_items.page_group_id=originalpagegroupid
GROUP BY originalpagegroupid,item_id;
ALTER TABLE pages DROP COLUMN originalpageid;
ALTER TABLE page_groups DROP COLUMN originalpagegroupid;
An SQLfiddle to test with
If the use case is doing it all the time in the system, it may not be the solution you're looking for, but for manual intervention it should work well.
As always, always back your database up before running SQL from random strangers on the Internet :)
Related
I am trying to upload some images to my database with some data, when I do this in localhost it's all work fine. But on the server, only some queries work fine. but others are not working.
This is my database pages table and papertag table
CREATE TABLE `pages`
(
`pageId` int(10) NOT NULL,
`paperId` varchar(255) NOT NULL,
`filePath` varchar(255) NOT NULL,
`fileType` varchar(20) NOT NULL,
`status` enum('0','1') NOT NULL,
`dateAndTime` datetime NOT NULL,
`description` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `pages`
--
ALTER TABLE `pages`
ADD PRIMARY KEY (`pageId`),
ADD KEY `paperId` (`paperId`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `pages`
--
ALTER TABLE `pages`
MODIFY `pageId` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=324;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `pages`
--
ALTER TABLE `pages`
ADD CONSTRAINT `pages_ibfk_1` FOREIGN KEY (`paperId`) REFERENCES `papers` (`paperId`) ON DELETE CASCADE ON UPDATE CASCADE;
COMMIT;
-----paper tag------
CREATE TABLE `papertag`
(
`tagId` int(11) NOT NULL,
`paperId` varchar(255) NOT NULL,
`tagName` varchar(255) NOT NULL,
`des` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `papertag`
--
ALTER TABLE `papertag`
ADD PRIMARY KEY (`tagId`),
ADD KEY `paperId` (`paperId`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `papertag`
--
ALTER TABLE `papertag`
MODIFY `tagId` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=460;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `papertag`
--
ALTER TABLE `papertag`
ADD CONSTRAINT `papertag_ibfk_1` FOREIGN KEY (`paperId`) REFERENCES `papers` (`paperId`) ON DELETE CASCADE ON UPDATE CASCADE;
COMMIT;
and this is my SQL query code in PHP file
$up22 = mysqli_query($connection, "INSERT INTO papertag(`paperId`, `tagName`) VALUES ('{$paperId}', '{$nme}')");
$up = mysqli_query($connection, "INSERT INTO pages(`paperId`, `filePath`, `fileType`, `status`, `dateAndTime`) VALUES ('{$paperId}', '{$img_dir}', '{$type}',2 , '{$date}' )");
I think you have to insert all columns with not null Constraint. you did not insert des column for example.
you need this code :
$up22 = mysqli_query($connection, "INSERT INTO papertag(`paperId`, `tagName`,`des`) VALUES ('{$paperId}', '{$nme}'),'{$des}'");
I have a scenario where i have one main table. Main table has 2 extra columns one is for table name (child table name) and other is for table id (child table id). when we enter the value in main table we also tell enter value in child table and then we enter the name of the table in main table name field and child id in the child field of the main table.
now when i query i need to join query with child table in a way that i picks up the table name from the column and join query with that table with concat function and then join on child id.
below is the structure of the table and also there values
CREATE TABLE IF NOT EXISTS `tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`tbl_type` enum('multi','gift','pledge') DEFAULT NULL,
`tbl_type_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
INSERT INTO `tbl` (`id`, `timestamp`, `tbl_type`, `tbl_type_id`) VALUES
(1, '2015-03-09 09:39:42', '', 1),
(2, '2015-03-09 22:43:23', 'multi', 2),
(3, '2015-03-09 23:26:38', 'gift', 1),
(4, '2015-03-10 09:46:15', 'pledge', 2);
-- --------------------------------------------------------
CREATE TABLE IF NOT EXISTS `tbl_gift` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`amount` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `tbl_gift` (`id`, `amount`) VALUES
(1, '1231200'),
(2, '1231200');
-- --------------------------------------------------------
CREATE TABLE IF NOT EXISTS `tbl_multi` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`amount` float(255,0) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
CREATE TABLE IF NOT EXISTS `tbl_pledge` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`amount` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `tbl_pledge` (`id`, `amount`) VALUES
(1, '10000'),
(2, '10200');
so this is simple hard code query
select * from tbl t left join tbl_gift g on g.id = t.tbl_type_id
but i want to make it dynamic i tried this
select * from tbl t left join (concat('tbl', '_', t.tbl_type)) g on g.id = t.tbl_type_id
should get the table which i need
(concat('tbl', '_', t.tbl_type))
but it get error
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '('tbl', '_', t.tbl_type)) g on g.id = t.tbl_type_id LIMIT 0, 30' at line 1
The comments by Ankit and Usedby answered your question.
SQL does not allow you to provide dynamically constructed table names as you attempted. They provided you with two options: 1) Construct your query dynamically on the PHP side, then SQL see only the static table names or
2) Use the SQL PREPARE command to construct the dynamic table name and the EXECUTE SQL command to execute it.
I am building a website for users to be able to make their own profile page with details about themselves, users shall also be able to create pages (similar to those on G+ & FB), however, they can either associate their current personal account with their page or create a separate page with a different account. There shall be many different pages (page types).
I've found this picture:
(source: tomtenthij.nl)
Which seems very interesting, however, how can I structure this in a better way, for example: College Page, or Collect & University Page, or University Page or Hospital Page or Company Page etc. Each have their own set of attributes etc. Any help would be appreciated. I was thinking if Page_type could help me separate each depending on if it is a Hospital or Company etc.
EDIT: I am a beginner in Database Schemas, I have no problem with the PHP code. But want to know of a better way to structure a Database schema for multiple users, pages etc.
I had a cursory look on the tables. I found it satisfactory + problematic (or just I'm not understanding right away). It shall be better if we go through all the tables one by one and discuss the things over the matter of days. One week's input and roll in, roll out of ideas can give us good confidence on what we are going to achieve. Right?
First of all I would like to identify all the possible relations
between a user and profile.
Secondly, I have to decide which will be my master table which will go
on to occupy the relations with rest of the tables. Tables those are
in or will come in the future. Don't forget that we have to put such a
design in place which will never mind any kind of extension.
I read the comment about the graph database. Don't mind that is not something we are ready in position to dive in there. You are right on the track, just need to polish ideas. I'm starting this discussion so that other people can also join here.
I often ran out of time, but will try my best to discuss things as
much as my knowledge can take me that far.
I think #Uours is on the right page but I would suggest a slightly different approach which would allow you to define attributes once and then use them on your various pages. Something like:
page_types
page_type_id (PK)
page_type_name (e.g. College, College & University, University, Hospital, Company, ...)
page_attributes
page_attribute_id (PK)
page_attribute_name (e.g. Name, Address, City, Country, Email, ...)
page_attribute_input_type (e.g. text, checkbox, date, email, password, radio, textarea, select, ...)
page_attribute_input_options (e.g. list of values, size=, maxlength=, pattern=, ...)
page_type_attributes
page_id (PK, FK)
page_attribute_id (PK, FK)
page_attribute_sequence (PK)
page_type_attribute_label (defaults to page_attribute_name but can be overriden in case the same attribute is used more than once on a page)
users
user_id (PK)
user_name
...
user_pages
user_page_id (PK)
user_id (FK)
user_page_type_id (FK)
user_page_name (What the user calls this page)
user_page_attributes
user_page_attribute_id (PK)
user_id (FK)
user_page_id (FK)
page_attribute_id (FK)
user_page_attribute_value
Good luck. Hope this helps.
If I understood your requirement correctly , I suppose this could be rough design of one way to implement User Pages :
user
user_id
user__name
user__password
user__email
...
...
page_type ( Holds Page Ids and Names of various Page Types )
page_type_id
page_type__name ( Ex: College , University , Company , ... )
page_attribute ( Holds the Structure/Attributes of various Page Types )
page_attribute_id
page_attribute__page_type_id
page_attribute__number
page_attribute__order
page_attribute__input_type ( Ex: 1: Text Line , 2: Text Area , 3: Drop Down List , ... )
page_attribute__options ( Ex: For input_type having multiple options , specify the list here as CSV )
user_page ( Holds Page Data for each Page for each User )
user_page_id
user_page__user_id
user_page__page_attribute_id
user_page__page_attribute_data
I've made a diagram of what i think the way to go. So here is it, the explaination & sql follow :
Explaination :
Account : store connection credential. Say you accept facebook login or twitter login, you must associate each credential to the same profil. So a user can login with 3 or more sort of account per profil.
page : Here you put every basic information about a page (whatever her type)
page_extrafield : here is the magic. In your PHP when a user choose 'Create a University page', you display the appropriate form with some fields. Then you save into the database only the field the user has filled. Like :
field_name = 'Established'
filed_value = '1909'
and for an enterprise page, the php form could send to sql :
field_name = 'CEO'
filed_value = 'Steve Jobs'
role : profil can(or not) create a page or multiple pages. And multiple user can manage a single page. So you need a role table to store each users role. Mine is basic like 'Admin','Editor' or 'Member' but you can go for more complicated !
So everything you have to do is a multiple form php with appropriate SQL.
Here is the BDD I used for this example, if you want to test it by your own :
-- Généré le : Mar 18 Février 2014 à 16:50
SET FOREIGN_KEY_CHECKS=0;
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT=0;
START TRANSACTION;
--
-- Base de données: `socialnetwork`
--
CREATE DATABASE `socialnetwork` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `socialnetwork`;
-- --------------------------------------------------------
--
-- Structure de la table `account`
--
DROP TABLE IF EXISTS `account`;
CREATE TABLE IF NOT EXISTS `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(250) NOT NULL,
`password` varchar(50) NOT NULL,
`credentialtype` enum('Email','Facebook','GPlus','Twitter') NOT NULL DEFAULT 'Email',
`profil_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `profil_id` (`profil_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
--
-- Contenu de la table `account`
--
INSERT INTO `account` (`id`, `username`, `password`, `credentialtype`, `profil_id`) VALUES
(1, 'luke#jedi.com', '*7AD0EBD5D5AF7AFF797419070CAEAF6A7671328A', 'Email', 1),
(2, '1197666810', '', 'Facebook', 1);
-- --------------------------------------------------------
--
-- Structure de la table `page`
--
DROP TABLE IF EXISTS `page`;
CREATE TABLE IF NOT EXISTS `page` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(50) NOT NULL DEFAULT 'Page' COMMENT 'type of the page ( university, College,etc)',
`name` varchar(200) NOT NULL COMMENT 'Page Name',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Store general data about page ( common to each page)' AUTO_INCREMENT=3 ;
--
-- Contenu de la table `page`
--
INSERT INTO `page` (`id`, `type`, `name`, `created_at`) VALUES
(1, 'UniversityPage', 'Oxford Official Page', '2014-02-18 16:41:12'),
(2, 'CompagnyPage', 'My Little Compagny', '2014-02-18 16:41:12');
-- --------------------------------------------------------
--
-- Structure de la table `page_extrafield`
--
DROP TABLE IF EXISTS `page_extrafield`;
CREATE TABLE IF NOT EXISTS `page_extrafield` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`field_name` varchar(100) NOT NULL COMMENT 'name of the specific field (like ''location'' or ''logo'')',
`filked_value` text NOT NULL,
`page_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `page_id` (`page_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Store every specialized field about the page (depend on the type of the page)' AUTO_INCREMENT=15 ;
--
-- Contenu de la table `page_extrafield`
--
INSERT INTO `page_extrafield` (`id`, `field_name`, `filked_value`, `page_id`) VALUES
(8, 'location', 'https://maps.google.com/maps?f=q&source=s_q&hl=fr&geocode=&q=oxford&sll=37.0625,-95.677068&sspn=61.323728,135.263672&vpsrc=0&t=h&ie=UTF8&hq=&hnear=Oxford,+Royaume-Uni&z=13&iwloc=A', 1),
(9, 'established', '1909', 1),
(10, 'Enrollment', '499 students', 1),
(11, 'Headmaster', 'Dennis Bisgaard', 1),
(12, 'logo', 'http://foo.com/logo.png', 2),
(13, 'Headquarters', 'San Fransisco', 2),
(14, 'CEO', 'John Doe', 2);
-- --------------------------------------------------------
--
-- Structure de la table `profil`
--
DROP TABLE IF EXISTS `profil`;
CREATE TABLE IF NOT EXISTS `profil` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pseudo` varchar(150) NOT NULL,
`name` varchar(100) NOT NULL,
`forname` varchar(100) NOT NULL,
`picture_url` varchar(500) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
--
-- Contenu de la table `profil`
--
INSERT INTO `profil` (`id`, `pseudo`, `name`, `forname`, `picture_url`, `created_at`) VALUES
(1, 'Jedy', 'Luke', 'Skywalker', 'pict1.jpg', '2014-02-18 16:39:06');
-- --------------------------------------------------------
--
-- Structure de la table `role`
--
DROP TABLE IF EXISTS `role`;
CREATE TABLE IF NOT EXISTS `role` (
`profil_id` int(11) NOT NULL,
`page_id` int(11) NOT NULL,
`access` enum('Admin','Editor','Member') NOT NULL DEFAULT 'Member',
PRIMARY KEY (`profil_id`,`page_id`),
KEY `page_id` (`page_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Contenu de la table `role`
--
INSERT INTO `role` (`profil_id`, `page_id`, `access`) VALUES
(1, 1, 'Admin'),
(1, 2, 'Editor');
--
-- Contraintes pour les tables exportées
--
--
-- Contraintes pour la table `account`
--
ALTER TABLE `account`
ADD CONSTRAINT `account_ibfk_1` FOREIGN KEY (`profil_id`) REFERENCES `profil` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Contraintes pour la table `page_extrafield`
--
ALTER TABLE `page_extrafield`
ADD CONSTRAINT `page_extrafield_ibfk_1` FOREIGN KEY (`page_id`) REFERENCES `page` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Contraintes pour la table `role`
--
ALTER TABLE `role`
ADD CONSTRAINT `role_ibfk_2` FOREIGN KEY (`page_id`) REFERENCES `page` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `role_ibfk_1` FOREIGN KEY (`profil_id`) REFERENCES `profil` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
SET FOREIGN_KEY_CHECKS=1;
COMMIT;
Have Fun and say if it works for you !
I am new in using advanced SQL queries and I am struggling with one query.
I have booking system created in php and it is using 4 tables:
site_days
site_timeslots
site_bookings
site_teams
each site_team is related to site_booking
each site_booking is related to site_timeslot
each site_timeslot is related to site_days
there can be more site_timeslots related to one site_day
there can be more site_bookings related to one site_timeslot
there can be more site_teams related to one site_bookings
you can create test tables with this sql:
-- Adminer 3.6.3 MySQL dump
SET NAMES utf8;
SET foreign_key_checks = 0;
SET time_zone = 'SYSTEM';
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
DROP TABLE IF EXISTS `site_bookings`;
CREATE TABLE `site_bookings` (
`id` int(11) NOT NULL auto_increment,
`timeslot_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO `site_bookings` (`id`, `timeslot_id`) VALUES
(1, 6443);
DROP TABLE IF EXISTS `site_days`;
CREATE TABLE `site_days` (
`id` int(11) NOT NULL auto_increment,
`date` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=93 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO `site_days` (`id`, `date`) VALUES
(85, '2013-04-01'),
(92, '2013-04-02');
DROP TABLE IF EXISTS `site_teams`;
CREATE TABLE `site_teams` (
`id` int(11) NOT NULL auto_increment,
`booking_id` int(11) NOT NULL,
`name` varchar(100) collate utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO `site_teams` (`id`, `booking_id`, `name`) VALUES
(1, 1, 'Avengers'),
(2, 1, 'Big Five');
DROP TABLE IF EXISTS `site_timeslots`;
CREATE TABLE `site_timeslots` (
`id` int(11) NOT NULL auto_increment,
`day_id` int(11) NOT NULL,
`date` date NOT NULL,
`starts` time NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7152 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO `site_timeslots` (`id`, `day_id`, `date`, `starts`) VALUES
(6443, 85, '2013-04-01', '08:00:00'),
(6444, 85, '2013-04-01', '08:10:00'),
(7098, 92, '2013-04-02', '08:00:00'),
(7099, 92, '2013-04-02', '08:10:00');
As a result I want to get ALL timeslots of table site_timeslots with few additional info:
- for each site_timeslot I want to know count of site_teams in all related bookings to that timeslot in total (for example if there are 2 site_bookings for that site_timeslot and each has 2 site_teams, then total count should be 4) and also count of related bookings.
I have tried this sql:
SELECT `site_teams`.`id` AS site_teams_id, `site_teams`.`name` AS site_teams_name, `site_teams`.`booking_id` AS site_teams_booking_id, `site_days`.`id` AS site_days_id, `site_days`.`date` AS site_days_date, `site_timeslots`.`id` AS site_timeslots_id, `site_timeslots`.`starts` AS site_timeslots_starts, `site_bookings`.`id` AS site_bookings_id, `site_bookings`.`timeslot_id` AS site_bookings_timeslot_id
FROM (`site_days`)
LEFT JOIN `site_timeslots` ON `site_timeslots`.`day_id` = `site_days`.`id`
LEFT JOIN `site_bookings` ON `site_bookings`.`timeslot_id` = `site_timeslots`.`id`
LEFT JOIN `site_teams` ON `site_teams`.`booking_id` = `site_bookings`.`id`
GROUP BY `site_teams`.`booking_id`
-> but i won't get timeslots which haven't got any site_bookings, please how I should alter this sql query to have in result:
site_timeslot per row
count of site_bookings related to that site_timeslot in new column 'count_of_site_bookings'
count of site_teams related to all site_bookings that are related to that site_timeslot in new column 'count_of_site_teams'
You can do this by LEFT JOINing starting on site_timeslots and then using COUNT on the 2 relevant fields to get the totals you are after
SELECT
sti.*,
COUNT(DISTINCT sb.id) AS count_of_site_bookings,
COUNT(DISTINCT ste.id) AS count_of_site_teams
FROM site_timeslots sti
INNER JOIN site_days sd
ON sd.id = sti.day_id
LEFT JOIN site_bookings sb
ON sb.timeslot_id = sti.id
LEFT JOIN site_teams ste
ON ste.booking_id = sb.id
GROUP BY sti.id
You can find this on SQL Fiddle http://sqlfiddle.com/#!2/1a253/2
I also did a previous version which used a subquery due to an incorrect assumption on my part, if you'd like to take a look at that for reference it's available also at http://sqlfiddle.com/#!2/9ccf2/10
How can I go about storing multiple values (numbers and words) within one field of a MySQL database and then extracting them again as and when I need them using MySQL and PHP?
For example, I want to store the dynamic values a user will enter using a form for example 1, 2, foo, tree, and monkey all in the same field in a database.
Then I want to extract it and put them on separate lines for example:
1
2
foo
tree
monkey
Any ideas?
MySQL 5.7.8 has a new data type that is JSON. You can store a JSON string with all the user information in that column.
Example:
CREATE TABLE table1 (jsonString JSON);
INSERT INTO table1 VALUES('{"car": "bmw", "year": "2006", "key": "value" }');
MySQL Reference
You can put all the values into an array and then serialize it:
$string = serialize(array(1, 2, 'foo', 'tree', 'monkey');
This will give you a string which you store in your database. Later, you can recover your array with de-serializing it:
$array = unserialize($string);
If you're referring to a datatype which can handle a whole slew of stuff, you can use text otherwise this is a bad idea and this is not how you should be storing data in a normalized relational database. Can you please provide information on what you're storing?
I'm a SQL noob myself so if any guru has a better schema strategy, let me know.. this is what I came up with:
Dump:
/*
Navicat MySQL Data Transfer
Date: 2009-10-20 03:01:18
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `job_scores`
-- ----------------------------
DROP TABLE IF EXISTS `job_scores`;
CREATE TABLE `job_scores` (
`job_id` int(2) NOT NULL,
`user_id` int(2) NOT NULL,
`rating` tinyint(2) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-- ----------------------------
-- Records of job_scores
-- ----------------------------
INSERT INTO `job_scores` VALUES ('1', '1', '10');
-- ----------------------------
-- Table structure for `jobs`
-- ----------------------------
DROP TABLE IF EXISTS `jobs`;
CREATE TABLE `jobs` (
`id` int(2) NOT NULL auto_increment,
`name` varchar(50) collate utf8_unicode_ci default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-- ----------------------------
-- Records of jobs
-- ----------------------------
INSERT INTO `jobs` VALUES ('1', 'plumber');
-- ----------------------------
-- Table structure for `users`
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(2) NOT NULL auto_increment,
`name` varchar(50) collate utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES ('1', 'John');
Example query:
SELECT
jobs.name as job_name, users.name as user_name, job_scores.rating
FROM
job_scores
INNER JOIN jobs ON jobs.id = job_scores.job_id
INNER JOIN users on users.id = job_scores.user_id
WHERE
user_id = 1
Result:
plumber John 10