multi table content selection - php

I am working on Exam System. I have (student),(student_test),(test),(departments) tables having relationship with each others. When every student log in there is a link called take test which will redirect them to take test page.
Question: How can I get all the available related to student department tests from test table only if the student have not attended the test or in other words how to get all the test from test table that student haven't taken?
$select=$connection->query("SELECT
student.std_id,
student.department,
test.depart_id,
test.test_id,
test.test_name,
test.test_from,
std_test.stdid,
std_test.std_test_id
FROM student
INNER JOIN test
ON student.department = test.depart_id
INNER JOIN std_test
ON std_test.std_test_id <> test.test_id
I tried this code as well but not results.
SELECT
student.std_id,
student.department,
test.depart_id,
test.test_id,
test.test_name,
test.test_from,
std_test.stdid,
std_test.std_test_id
FROM student
INNER JOIN test
ON student.department = test.depart_id
INNER JOIN std_test
ON std_test.std_test_id <> test.test_id
WHERE test.test_id <> std_test.std_test_id AND student.std_id <> std_test.stdid
Schema Script
CREATE TABLE student (
std_id int(11) NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL,
f_name varchar(50) NOT NULL,
department int(11) NOT NULL,
semester varchar(255) NOT NULL,
pass varchar(255) NOT NULL,
email varchar(60) NOT NULL,
rollnumber varchar(20) NOT NULL,
PRIMARY KEY (std_id),
INDEX department (department),
UNIQUE INDEX email (email),
CONSTRAINT student_ibfk_1 FOREIGN KEY (department)
REFERENCES departments (dep_id) ON DELETE RESTRICT ON UPDATE RESTRICT
)
ENGINE = INNODB
AUTO_INCREMENT = 8
AVG_ROW_LENGTH = 8192
CHARACTER SET latin1
COLLATE latin1_swedish_ci;
CREATE TABLE test (
test_id int(11) NOT NULL AUTO_INCREMENT,
test_name varchar(80) NOT NULL,
test_date varchar(30) NOT NULL,
test_from datetime NOT NULL,
test_to datetime NOT NULL,
test_code varchar(30) NOT NULL,
test_conducter varchar(30) NOT NULL,
test_duration int(11) NOT NULL,
total_question int(11) NOT NULL,
session varchar(50) DEFAULT NULL,
subject_id int(11) NOT NULL,
semester_id int(11) NOT NULL,
depart_id int(11) NOT NULL,
status varchar(50) NOT NULL,
PRIMARY KEY (test_id),
INDEX depart_id (depart_id),
INDEX semester_id (semester_id),
INDEX subject_id (subject_id, semester_id, depart_id),
CONSTRAINT test_ibfk_1 FOREIGN KEY (subject_id)
REFERENCES subjects (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT test_ibfk_2 FOREIGN KEY (semester_id)
REFERENCES semester (sem_id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT test_ibfk_3 FOREIGN KEY (depart_id)
REFERENCES departments (dep_id) ON DELETE CASCADE ON UPDATE CASCADE
)
ENGINE = INNODB
AUTO_INCREMENT = 6
AVG_ROW_LENGTH = 16384
CHARACTER SET latin1
COLLATE latin1_swedish_ci;
CREATE TABLE std_test (
stdid int(11) NOT NULL,
std_test_id int(11) NOT NULL,
starttime timestamp DEFAULT CURRENT_TIMESTAMP,
endtime timestamp DEFAULT '0000-00-00 00:00:00',
progress enum ('over', 'inprogress') NOT NULL,
PRIMARY KEY (std_test_id),
INDEX stdid (stdid),
INDEX tstid (std_test_id),
CONSTRAINT std_test_ibfk_2 FOREIGN KEY (std_test_id)
REFERENCES test (test_id) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT std_test_ibfk_3 FOREIGN KEY (stdid)
REFERENCES student (std_id) ON DELETE RESTRICT ON UPDATE RESTRICT
)
ENGINE = INNODB
AVG_ROW_LENGTH = 16384
CHARACTER SET latin1
COLLATE latin1_swedish_ci;

untested and shortened, but this is, what i understand, when i read your question
SELECT ....
FROM student s
INNER JOIN test t ON t.depart_id = s.department
LEFT JOIN std_test st ON t.test_id = st.std_test_id
WHERE st.stdid IS NULL
should work now

Related

MySQL foreign key issue

I am having a problem trying to load my database into MySQL as I am having a few errors with my foreign keys. Things I have tried to do to fix this issue is:
- Putting foreign keys after the primary keys
Eg:
CREATE TABLE IF NOT EXISTS Passenger (
.......
PRIMARY KEY(tNum),
FOREIGN KEY (fNum) REFERENCES Flights(fNum),
FOREIGN KEY (fDate) REFERENCES Flights(fDate),
FOREIGN KEY (sCity) REFERENCES Flights(sCity),
FOREIGN KEY (eCity) REFERENCES Flights(eCity)
);
- Bunching the foreign keys in the format of
Eg:
ALTER TABLE Passenger ADD FOREIGN KEY (fNum, fDate, sCity, eCity) REFERENCES Flights(fNum, fDate, sCity, eCity);
The error I get is:
1005 - Can't create table 'airline.#sql-1d7_7c' (errno: 150)
My full code is:
DROP DATABASE IF EXISTS airline;
CREATE DATABASE IF NOT EXISTS airline;
USE airline;
CREATE TABLE IF NOT EXISTS Flights (
fNum char(6) not null,
pID char(4) not null,
fDate DATE not null,
eDate DATE not null,
sTime char(4) not null,
lTime char(4) not null,
sOStart char(4) null,
sOEnd char(4) null,
sCity varchar(30) not null,
eCity varchar(30) not null,
sOCity varchar(30),
sNum char(5) not null,
PRIMARY KEY (fNum)
);
CREATE TABLE IF NOT EXISTS Passenger (
tNum char(4) not null,
dPurch DATE not null,
pMethod varchar(30) not null,
fNum char(6) not null,
fDate DATE not null,
sCity varchar(30) not null,
eCity varchar(30) not null,
tType varchar(30) not null,
Price decimal(4,2) not null,
iType varchar(30) not null,
idNum char(8) not null,
fName varchar(30) not null,
lName varchar(30) not null,
Sex char(1) not null,
pAddress varchar(30) not null,
pPhone char(8) not null,
pEmail varchar(30) not null,
PRIMARY KEY(tNum)
);
CREATE TABLE IF NOT EXISTS Planes (
pID char(4) not null,
pType char(3) not null,
pDesc varchar(30) not null,
pRange char(4) not null,
Capacity char(3) not null,
mDate DATE not null,
pDate DATE not null,
sDate DATE not null,
PRIMARY KEY (pID)
);
CREATE TABLE IF NOT EXISTS Staff (
sNum char(5) not null,
sName varchar(30) not null,
sDOB DATE not null,
sAddress varchar(30) not null,
pCompany varchar(30) ,
pStart DATE ,
pEnd DATE ,
jID char(1) not null,
PRIMARY KEY (sNum)
);
CREATE TABLE IF NOT EXISTS Emergency (
eID char(5) not null,
sNum char(5) not null,
eName varchar(30) not null,
eAddress varchar(30) not null,
ePhone char(8) not null,
eEmail varchar(30) not null,
eRelationship varchar(30) not null,
PRIMARY KEY(eID)
);
CREATE TABLE IF NOT EXISTS Pilot (
sNum char(5) not null,
pID char(4) not null,
cDate DATE not null,
jID char(1) not null,
PRIMARY KEY(jID)
);
CREATE TABLE IF NOT EXISTS Attendant (
sNum char(5) not null,
tSDate Date not null,
tFDate Date not null,
tDesc Varchar(30) not null,
jID Char(1) not null,
PRIMARY KEY(jID)
);
ALTER TABLE Flights ADD FOREIGN KEY (pID) REFERENCES Planes(pID);
ALTER TABLE Flights ADD FOREIGN KEY (sNum) REFERENCES Staff(sNum);
ALTER TABLE Passenger ADD FOREIGN KEY (fNum) REFERENCES Flights(fNum);
ALTER TABLE Passenger ADD FOREIGN KEY (fDate) REFERENCES Flights(fDate);
ALTER TABLE Passenger ADD FOREIGN KEY (sCity) REFERENCES Flights(sCity);
ALTER TABLE Passenger ADD FOREIGN KEY (eCity) REFERENCES Flights(eCity);
ALTER TABLE Emergency ADD FOREIGN KEY (sNum) REFERENCES Staff(sNum);
ALTER TABLE Pilot ADD FOREIGN KEY (sNum) REFERENCES Staff(sNum);
ALTER TABLE Pilot ADD FOREIGN KEY (pID) REFERENCES Planes(pID);
ALTER TABLE Pilot ADD FOREIGN KEY (jID) REFERENCES Staff(jID);
ALTER TABLE Attendant ADD FOREIGN KEY (sNum) REFERENCES Staff(sNum);
ALTER TABLE Attendant ADD FOREIGN KEY (jID) REFERENCES Staff(jID);
For me this is the one it fails on first
ALTER TABLE Passenger ADD FOREIGN KEY (fDate) REFERENCES Flights(fDate);
Try adding an index on Flights.fdate first, then doing the foreign key and doing that for additional references until it works. Let me know if that works for you, it did for me.
By the way you might want to reconsider your schema there. Joins and relations should really be done on integers only. That schema will bog down fast as it grows. Also, and maybe this is just personal preference but I prefer first_name to fName. Easier to read for other developers, this isn't 1986, we can have human readbable names now :-)

Implicit MySQL Join on Update Statement - 0 rows affected

I'm trying to get this MySQL code to work, but it's saying 0 rows affected.
UPDATE assessments, assessment_types
SET assessments.assessment_type_id = assessment_types.id
WHERE (assessment_types.description = "Skills Assessment" AND assessments.id = 2);
Basically I have assessment_types with id and description column, and I just have the id in the assessments.assessment_type_id
I need to update the id.
I searched and couldn't find quite what I need for this.
Thanks!
Table Data:
assessment_types
id description
1 Knowledge Assessment
2 Skill Assessment
3 Personal Information
4 Natural Skills
Table Structure:
--
-- Table structure for table `assessments`
--
CREATE TABLE IF NOT EXISTS `assessments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_bin NOT NULL,
`acronym` varchar(255) COLLATE utf8_bin NOT NULL,
`assessment_type_id` int(11) NOT NULL,
`language_id` int(11) NOT NULL,
`date_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`date_updated` date NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `assessment_type_id` (`assessment_type_id`),
KEY `language_id` (`language_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=2385 ;
--
-- Table structure for table `assessment_types`
--
CREATE TABLE IF NOT EXISTS `assessment_types` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`description` varchar(255) CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=7 ;
You can try doing an explicit join of the two tables in your UPDATE statement:
UPDATE assessments a
INNER JOIN assessment_types at
ON a.assessment_type_id = at.id
SET a.assessment_type_id = at.id
WHERE (at.description = "Skills Assessment" AND a.id = 2);

MySQL - GROUP BY slow down the page

GROUP BY clause in the query below slow down the page, please help to resolve this issue
SELECT
`a`.*,
CONCAT(a.`firstname`, " ", a.`lastname`) AS `cont_name`,
CONCAT(a.`position`, " / ", a.`company`) AS `comp_pos`,
CONCAT(f.`firstname`, " ", f.`lastname`) AS `created_by`
FROM
`contacts` AS `a`
LEFT JOIN `users` AS `f` ON f.id = a.user_id
LEFT JOIN `user_centres` AS `b` ON a.user_id = b.user_id
WHERE b.centre_id IN (23, 24, 25, 26, 20, 21, 22, 27, 28)
GROUP BY `a`.`id`
ORDER BY `a`.`created` desc
Here the join with user_centres table is for centre wise filtering of data. EXPLAIN gives the result as:
- 1 SIMPLE a index PRIMARY,user_id,area_id,industry_id,country PRIMARY 4 NULL 20145 Using temporary; Using filesort
Our requirement is as below
Listing of all contacts in admin login
Centre wise listing of contacts in manager/clerk login
Total records in contact table is > 20K.
There will be multiple entry for users in user_centres table, ie: a user is assigned to more than one centre.
While executing the query in server by excluding GROUP BY is nearly 300k data which makes the problem.
Db stucture
Table structure for table contacts
CREATE TABLE IF NOT EXISTS `contacts` (
`id` int(11) NOT NULL,
`user_id` int(11) DEFAULT NULL,
`imported` tinyint(4) NOT NULL DEFAULT '0',
`situation` char(10) DEFAULT NULL,
`firstname` varchar(150) DEFAULT NULL,
`lastname` varchar(150) DEFAULT NULL,
`position` varchar(150) DEFAULT NULL,
`dob` datetime DEFAULT NULL,
`office_contact` varchar(100) DEFAULT NULL,
`mobile_contact` varchar(100) DEFAULT NULL,
`email` varchar(255) NOT NULL,
`company` varchar(150) DEFAULT NULL,
`industry_id` int(11) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
`city` varchar(150) DEFAULT NULL,
`country` int(11) DEFAULT NULL,
`isclient` tinyint(4) NOT NULL DEFAULT '0',
`classification` varchar(100) DEFAULT NULL,
`created` datetime NOT NULL,
`updated` datetime NOT NULL,
`unsubscribe` enum('Y','N') NOT NULL DEFAULT 'N'
) ENGINE=InnoDB AUTO_INCREMENT=25203 DEFAULT CHARSET=latin1;
Indexes for table contacts
ALTER TABLE `contacts`
ADD PRIMARY KEY (`id`), ADD KEY `user_id` (`user_id`),
ADD KEY `industry_id` (`industry_id`), ADD KEY `country` (`country`);
Constraints for table contacts
ALTER TABLE `contacts`
ADD CONSTRAINT `contacts_ibfk_4` FOREIGN KEY (`user_id`)
REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE NO ACTION,
ADD CONSTRAINT `contacts_ibfk_6` FOREIGN KEY (`industry_id`)
REFERENCES `industries` (`id`) ON DELETE SET NULL ON UPDATE NO ACTION,
ADD CONSTRAINT `contacts_ibfk_7` FOREIGN KEY (`country`)
REFERENCES `country` (`id`) ON DELETE SET NULL ON UPDATE NO ACTION;
Table structure for table users
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL,
`role_id` int(11) NOT NULL,
`email` varchar(250) NOT NULL,
`password` varchar(45) NOT NULL,
`salt` varchar(45) DEFAULT NULL,
`status_id` int(11) DEFAULT NULL,
`status` tinyint(1) DEFAULT '1',
`firstname` varchar(255) NOT NULL,
`lastname` varchar(255) NOT NULL,
`created` datetime DEFAULT NULL,
`updated` datetime DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
Indexes for table users
ALTER TABLE `users`
ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `email_UNIQUE` (`email`),
ADD KEY `type_id_idx` (`role_id`), ADD KEY `status_id_idx` (`status_id`);
Constraints for table users
ALTER TABLE `users`
ADD CONSTRAINT `role_id` FOREIGN KEY (`role_id`)
REFERENCES `users_roles` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `status_id` FOREIGN KEY (`status_id`)
REFERENCES `users_status` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `users_ibfk_1` FOREIGN KEY (`area`)
REFERENCES `area` (`id`) ON DELETE SET NULL ON UPDATE NO ACTION;
Table structure for table user_centres
CREATE TABLE IF NOT EXISTS `user_centres` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`area_id` int(11) NOT NULL,
`centre_id` int(11) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=72 DEFAULT CHARSET=utf8;
Indexes for table user_centres
ALTER TABLE `user_centres`
ADD PRIMARY KEY (`id`), ADD KEY `user_id` (`user_id`),
ADD KEY `centre_id` (`centre_id`), ADD KEY `area_id` (`area_id`);
Constraints for table user_centres
ALTER TABLE `user_centres`
ADD CONSTRAINT `user_centres_ibfk_1` FOREIGN KEY (`user_id`)
REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION,
ADD CONSTRAINT `user_centres_ibfk_2` FOREIGN KEY (`centre_id`)
REFERENCES `centre` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
Also please refer EXPLAIN screens - http://prntscr.com/6o5h8s
Index were not used because of the different ORDER BY a GROUP BY clauses.
http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html
You are spending a lot of time checking user_centres, but not needing anything from it. Remove it from the query.
users can be made into a correlates subquery:
SELECT `a`.*,
CONCAT(a.`firstname`, " ", a.`lastname`) AS `cont_name`,
CONCAT(a.`position`, " / ", a.`company`) AS `comp_pos`,
( SELECT CONCAT(f.`firstname`, " ", f.`lastname`)
FROM `users` AS `f` ON f.id = a.user_id
) AS `created_by`
FROM `contacts` AS `a`
GROUP BY `a`.`id`
ORDER BY `a`.`created` desc
Do you really need all 20K rows?? The sheer bulk of the result is part of the sluggishness.
Thanks all, based on the feedback got from all of you I have tried the query below now and give me the speed improvement from 30 secs to 15 secs
SELECT `a`.`id`, `a`.`user_id`, `a`.`imported`, `a`.`created`,
`a`.`unsubscribe`, CONCAT(a.firstname, " ", a.lastname) AS `cont_name`,
CONCAT(a.position, " / ", a.company) AS `comp_pos`,
( SELECT COUNT(uc.id)
FROM `user_centres` AS `uc`
WHERE (uc.user_id = a.user_id)
AND (uc.centre_id IN (29))
GROUP BY `uc`.`user_id`
) AS `centre_cnt`,
( SELECT GROUP_CONCAT(DISTINCT g.group_name
ORDER BY g.group_name ASC SEPARATOR ", ")
FROM `groups` AS `g`
INNER JOIN `group_contacts` AS `gc` ON g.id = gc.group_id
WHERE (gc.contact_id = a.id)
GROUP BY `gc`.`contact_id`
) AS `group_name`,
( SELECT CONCAT(u.`firstname`, " ", u.`lastname`)
FROM `users` AS `u`
WHERE (u.id = a.user_id)
) AS `created_by`, `e`.`name` AS `industry_name`
FROM `contacts` AS `a`
LEFT JOIN `industries` AS `e` ON e.id = a.industry_id
WHERE (1)
HAVING (centre_cnt is NOT NULL)
ORDER BY `a`.`id` desc
Let me know Is there a way to improve the speed and make the page loading below 5 secs.
Please see the interface (noted the filtering and sorting fields) - http://prntscr.com/6q6q70

Querying SQL multiple tables

I have a sql database with the following tables
Book Table
CREATE TABLE IF NOT EXISTS `books` (
`book_id` varchar(8) NOT NULL DEFAULT '',
`book_title` varchar(100) DEFAULT NULL,
`author1` varchar(20) NOT NULL,
`author2` varchar(20) DEFAULT NULL,
`publisher` varchar(20) NOT NULL,
`pub_year` year(4) NOT NULL,
`mod_id` varchar(8) NOT NULL,
`courseID` varchar(8) NOT NULL,
PRIMARY KEY (`book_id`),
KEY `id` (`book_id`),
KEY `book_id` (`book_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Courses Table
CREATE TABLE IF NOT EXISTS `courses` (
`courseID` varchar(8) NOT NULL,
`course_title` varchar(255) CHARACTER SET ascii NOT NULL,
`Entry_Year` int(1) NOT NULL,
`Duration` int(1) NOT NULL,
PRIMARY KEY (`courseID`),
KEY `courseID` (`courseID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Modules Table
CREATE TABLE IF NOT EXISTS `modules` (
`mod_id` varchar(8) NOT NULL,
`mod_title` varchar(255) NOT NULL,
`description` varchar(255) NOT NULL,
PRIMARY KEY (`mod_id`),
KEY `mod_title` (`mod_title`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Module Course Table
CREATE TABLE IF NOT EXISTS `mod_course` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`module` varchar(8) NOT NULL,
`course` varchar(8) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=31 ;
I would like to query the database to show all book details of a course. A course has many modules and modules have many books. I have tried the following query but I think there is a problem with my tables as well. (FYI 'BIT' is the id of a course that is in the module course table)
SELECT b.book_id, b.book_title, b.author1, b.author2, b.publisher, b.pub_year, b.mod_id, mc.course
FROM books b
JOIN mod_course mc
WHERE mc.course = 'BIT'
I have had a deeper look at this and offer the following suggestion which includes changes to the data model also. This solution will also allow you to have the same book used for several modules (if required in the future). Also note the new table mod_books
The full code for this (including the query) is below... hope its ok
CREATE TABLE IF NOT EXISTS books
(book_id varchar(8) NOT NULL DEFAULT '',
book_title varchar(100) DEFAULT NULL,
author1 varchar(20) NOT NULL,
author2 varchar(20) DEFAULT NULL,
publisher varchar(20) NOT NULL,
pub_year year(4) NOT NULL,
PRIMARY KEY (book_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS courses
(course_ID varchar(8) NOT NULL,
course_title varchar(255) CHARACTER SET ascii NOT NULL,
Entry_Year int(1) NOT NULL,
Duration int(1) NOT NULL,
PRIMARY KEY (course_ID)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS modules
(mod_id varchar(8) NOT NULL,
mod_title varchar(255) NOT NULL,
description varchar(255) NOT NULL,
PRIMARY KEY (mod_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS mod_books
(mod_id varchar(8) NOT NULL,
book_id varchar(8) NOT NULL,
PRIMARY KEY (mod_id,book_id),
FOREIGN KEY (mod_id) REFERENCES modules (mod_id),
FOREIGN KEY (book_id) REFERENCES books (book_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS mod_course
(ID int(11) NOT NULL AUTO_INCREMENT,
mod_id varchar(8) NOT NULL,
course_ID varchar(8) NOT NULL,
PRIMARY KEY (ID),
FOREIGN KEY (mod_id) REFERENCES modules (mod_id),
FOREIGN KEY (course_ID) REFERENCES courses (course_ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=31 ;
and the query would be
SELECT b.*
FROM mod_course mc
INNER JOIN mod_books mb
ON mb.mod_id = mc.mod_id
INNER JOIN books b
ON b.book_id = mb.book_id
WHERE mc.course_id = 'BIT'
based on the stated relationship course->module->books, you should drop the courseid column from the books table. the modid that you have is all you need.
the problem with your query is the missing join condition.
below the JOIN mod_course mc line you should add
ON mc.module = b.mod_id
After the keyword Join it should be ON not WHERE
SELECT B.*, MC.COURSE
FROM MODULECOURSE AS MC
INNER JOIN COURSES AS C
ON C.COURSE_TITLE = MC.COURSE
INNER JOIN BOOKS AS B
ON B.COURSEID= C.COURSEID

SQL error when generated SQL command with Doctrine PHP

I use Doctrine on my PHP web application with a MySQL database. I have a little problem with my request :
$q = Doctrine_Query::create()
->select('event.EventDate, event.EventId, player.PlayerId, player.FirstName,
player.LastName, player.Login, player.Email,
event_period.EventPeriodId, event.Type, event.Description,
period.StartHour, period.EndHour, player_event_period.Participate,
event_period.CourtNumber')
->from('Event event, Player player, Period period')
->leftJoin('player.PlayerEventPeriod player_event_period')
->leftJoin('player_event_period.EventPeriod event_period')
->where('period.PeriodId = event_period.PeriodId')
->andWhere('event.EventId = event_period.EventId');
if I show what is the generated MySQL command, I can see
SELECT e.eventid AS e__eventid, e.eventdate AS e__eventdate, e.type AS e__type, e.description AS e__description, p.playerid AS p__playerid, p.firstname AS p__firstname, p.lastname AS p__lastname, p.login AS p__login, p.email AS p__email, p2.periodid AS p2__periodid, p2.starthour AS p2__starthour, p2.endhour AS p2__endhour, p3.playereventperiodid AS p3__playereventperiodid, p3.participate AS p3__participate, e2.eventperiodid AS e2__eventperiodid, e2.courtnumber AS e2__courtnumber
FROM event e, player p, period p2
LEFT JOIN player_event_period p3 ON p.playerid = p3.playerid
LEFT JOIN event_period e2 ON p3.eventperiodid = e2.eventperiodid
WHERE (
p2.periodid = e2.periodid
AND e.eventid = e2.eventid
);
I get error :
#1054 - Unknown column 'p.playerid' in 'on clause'
What's wrong with my request ?
Thank you in advance
EDIT:
If that could help you. I have add the script that creates my database tables.
CREATE TABLE `event` (
`EventId` int(11) NOT NULL AUTO_INCREMENT,
`Type` varchar(100) NOT NULL,
`Description` text,
`EventDate` datetime NOT NULL,
`CreationDate` datetime NOT NULL,
`UpdateDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`EventId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `event_period` (
`EventPeriodId` int(11) NOT NULL AUTO_INCREMENT,
`PeriodId` int(11) NOT NULL,
`EventId` int(11) NOT NULL,
`CourtNumber` int(11) NOT NULL,
`CreationDate` datetime NOT NULL,
`UpdateDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`EventPeriodId`),
KEY `fk_event_period_to_period` (`PeriodId`),
KEY `fk_event_period_to_event` (`EventId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `period` (
`PeriodId` int(11) NOT NULL AUTO_INCREMENT,
`StartHour` time NOT NULL,
`EndHour` time NOT NULL,
`CreationDate` datetime NOT NULL,
`UpdateDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`PeriodId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `player` (
`PlayerId` int(11) NOT NULL AUTO_INCREMENT,
`Login` varchar(100) NOT NULL,
`Password` varchar(100) NOT NULL,
`RankId` int(11) NOT NULL DEFAULT '1',
`FirstName` varchar(100) NOT NULL,
`LastName` varchar(100) NOT NULL,
`Email` varchar(100) NOT NULL,
`ValidateId` varchar(100) NOT NULL,
`InscriptionDate` datetime NOT NULL,
`Enable` tinyint(1) NOT NULL,
`CreationDate` datetime NOT NULL,
`UpdateDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`PlayerId`),
KEY `fk_player_to_rank` (`RankId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `player_event_period` (
`PlayerEventPeriodId` int(11) NOT NULL AUTO_INCREMENT,
`PlayerId` int(11) NOT NULL,
`EventPeriodId` int(11) NOT NULL,
`Participate` tinyint(1) NOT NULL,
`CreationDate` datetime NOT NULL,
`UpdateDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`PlayerEventPeriodId`),
KEY `fk_player_event_period_to_player` (`PlayerId`),
KEY `fk_player_event_period_to_event_period` (`EventPeriodId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `event_period`
ADD CONSTRAINT `fk_event_period_to_period` FOREIGN KEY (`PeriodId`) REFERENCES `period` (`PeriodId`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `fk_event_period_to_event` FOREIGN KEY (`EventId`) REFERENCES `event` (`EventId`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `player`
ADD CONSTRAINT `fk_player_to_rank` FOREIGN KEY (`RankId`) REFERENCES `rank` (`RankId`);
ALTER TABLE `player_event_period`
ADD CONSTRAINT `fk_player_event_period_to_player` FOREIGN KEY (`PlayerId`) REFERENCES `player` (`PlayerId`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `fk_player_event_period_to_event_period` FOREIGN KEY (`EventPeriodId`) REFERENCES `event_period` (`EventPeriodId`) ON DELETE CASCADE ON UPDATE CASCADE;
Not sure how your models look but do your table called "player" have a column called "playerid" in it?
That's what mysql is complaining about.
[Edit]
I think that Doctrine prefers column names i lowercase.
(Can't remember if MySQL is case-sensitive regarding column names...)
Case sensitivity of MySQL column names depends on how the database/schema/tables are configured, but it looks like yours are case sensitive.
You haven't provided the entity definitions so I'm guessing at the issue, but try setting the name of the column.
For example for player id the annotation would be:
/**
* #Column(name="PlayerId", type="integer", length=11, nullable=false)
* #Id
* GeneratedValue(strategy="AUTO")
*/
protected $PlayerId;

Categories