Select every alternate days for selecting bus journey direction - php

I am working on a bus ticket reservation systems . In this,I have made tables for all the routes and within the table I have added fields like bus_number,fare etc . Now our buses travels every alternate days in vice versa direction,ie if a bus travels from X->Y on 21-12-2011,the the same bus will travel Y->X on next date . So how am going to get the direction for a bus ? If I made tables for each bus service provider and add bus numbers add a identifier like 'to' for a date , I think it will be possible to to know the status for all next days . I dont know if its a good idea , so please help me.

Without knowing the precise details of your existing tables it is a little difficult to provide a definitive solution. Anyway, here's a suggestion of how you could hold buses along with their stops and fares:
CREATE TABLE `bus` (
`id` int unsigned not null primary key auto_increment,
`bus_number` varchar(55) not null,
UNIQUE KEY `busUidx1` (`bus_number`)
) ENGINE=InnoDB;
CREATE TABLE `bus_stop` (
`id` int unsigned not null primary key auto_increment,
`stop_description` varchar(250) not null,
UNIQUE KEY `bus_stopUidx1` (`stop_description`)
) ENGINE=InnoDB;
CREATE TABLE `bus_route` (
`id` int unsigned not null primary key auto_increment,
`bus_id` int unsigned not null,
`route_date` date not null,
`bus_start_stop_id` int unsigned not null,
`bus_end_stop_id` int unsigned not null,
`fare` decimal (10,2) not null,
UNIQUE KEY `bus_stopUidx1` (`bus_id`,`route_date`),
CONSTRAINT `fk_bus_route_bus_fk1` FOREIGN KEY (`bus_id`) REFERENCES `bus` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_bus_route_stop_fk1` FOREIGN KEY (`bus_start_stop_id`) REFERENCES `bus_stop` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_bus_route_stop_fk2` FOREIGN KEY (`bus_end_stop_id`) REFERENCES `bus_stop` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB;
Using this model you should be able to store a list of buses (in the bus table), a list of all possible stops (in the bus_stop table) and bus routes for a given date. It will also allow you the flexibility to break the 'bus travels from X > Y and then always travels back from Y > X' rule which, if the buses that I have travelled on in the past are anything to go by, might prove useful ;-)
EDIT
So here is some sample data to try and illustrate my answer further:
insert into bus (bus_number) values ('Red Bus 1');
insert into bus (bus_number) values ('Red Bus 2');
insert into bus (bus_number) values ('Yellow Bus 1');
insert into bus (bus_number) values ('Yellow Bus 2');
insert into bus_stop (stop_description) values ('Stop 1');
insert into bus_stop (stop_description) values ('Stop 2');
insert into bus_stop (stop_description) values ('Stop 3');
insert into bus_stop (stop_description) values ('Stop 4');
insert into bus_route (bus_id,route_date,bus_start_stop_id,bus_end_stop_id,fare)
values (
(select id from bus where bus_number = 'Red Bus 1'),
'2011-12-11',
(select id from bus_stop where stop_description = 'Stop 1'),
(select id from bus_stop where stop_description = 'Stop 2'),
3.45);
insert into bus_route (bus_id,route_date,bus_start_stop_id,bus_end_stop_id,fare)
values (
(select id from bus where bus_number = 'Red Bus 1'),
'2011-12-12',
(select id from bus_stop where stop_description = 'Stop 2'),
(select id from bus_stop where stop_description = 'Stop 1'),
3.45);
insert into bus_route (bus_id,route_date,bus_start_stop_id,bus_end_stop_id,fare)
values (
(select id from bus where bus_number = 'Yellow Bus 1'),
'2011-12-11',
(select id from bus_stop where stop_description = 'Stop 3'),
(select id from bus_stop where stop_description = 'Stop 4'),
1.95);
insert into bus_route (bus_id,route_date,bus_start_stop_id,bus_end_stop_id,fare)
values (
(select id from bus where bus_number = 'Yellow Bus 1'),
'2011-12-12',
(select id from bus_stop where stop_description = 'Stop 4'),
(select id from bus_stop where stop_description = 'Stop 3'),
1.95);
And finally a query to join the tables together:
select b.bus_number,
br.route_date,
bs.stop_description as start,
be.stop_description as end,
br.fare
from bus_route br
inner join bus b on b.id = br.bus_id
inner join bus_stop bs on bs.id = br.bus_start_stop_id
inner join bus_stop be on be.id = br.bus_end_stop_id;

Related

Trigger to update a count based on another table

I am working on a php project for managing employees.
i have two tables employee and department with the department number being a relation between the two. department has an attribute that contains a count of employees based on the deparment number.
So where i'm stuck is that i want the employee count to be automatically inserted, so what do you think i should do
Thanks in advance
If you don't want to use (or have access to) a trigger, but want to abstract the logic, you could use a view (docs).
So assuming the below data, and the idea of having the entire department table and the employee count dynamically calculated, you could have the following query:
CREATE TABLE
`employees`
(
`employeeID` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(50),
`department_number` INT
);
CREATE TABLE
`departments`
(
`department_number` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(50)
);
INSERT INTO
`departments`
(`department_number`, `name`)
VALUES
(1, 'Tech Department'),
(2, 'Admin Department');
INSERT INTO
`employees`
(`name`, `department_number`)
VALUES
('John Doe', 1),
('Jane Doe', 1),
('Jimmy Doe', 2);
Then the query:
SELECT
DepartmentTbl.*,
DepartmentEmployeeTbl.employee_count
FROM
`departments` AS DepartmentTbl
LEFT JOIN
(
SELECT
`department_number`,
COUNT(`employeeID`) AS `employee_count`
FROM
`employees`
GROUP BY
`department_number`
) AS DepartmentEmployeeTbl
ON DepartmentTbl.department_number = DepartmentEmployeeTbl.department_number
Gives the result:
department_number | name | employee_count
-------------------------------------------------------
1 | Tech Department | 2
2 | Admin Department | 1
SQLFiddle - http://sqlfiddle.com/#!9/3e0b54/1
So to create this view, you could use:
CREATE OR REPLACE VIEW `departments_employee_count` AS
SELECT
DepartmentTbl.*,
DepartmentEmployeeTbl.employee_count
FROM
`departments` AS DepartmentTbl
LEFT JOIN
(
SELECT
`department_number`,
COUNT(`employeeID`) AS `employee_count`
FROM
`employees`
GROUP BY
`department_number`
) AS DepartmentEmployeeTbl
ON DepartmentTbl.department_number = DepartmentEmployeeTbl.department_number
Then you could call the view as:
SELECT
*
FROM
`departments_employee_count`
Instead of storing and updating the value each time something is changed you should just calculate it when needed.
You can use count to do it.
Example
SELECT department_number, count(*) FROM employee GROUP BY department_number

LEFT JOIN with condition is not returning data desired

I would like to do a left join using MYSQL. Currently I have a table something like this:
CREATE TABLE `books` (
`bookId` int(11) NOT NULL,
`bookTitle` varchar(100) NOT NULL,
`bookAuthor` varchar(100) NOT NULL,
`bookStatus` tinyint(1) NOT NULL,
`bookDeleteFlag` tinyint(1) NOT NULL
);
CREATE TABLE `lends` (
`lendId` int(11) NOT NULL,Primary
`lendBookId` int(11) NOT NULL,
`lendBorrowerName` Varchar(100) NOT NULL,
`lendBorrowStatus` int(11) NOT NULL,
`lendReturnStatus` int(11) NOT NULL,
);
insert into books values (1, 'The Da Vinci Code', 'Dan Brown', 1,0)
insert into books values (2, 'Theory of Relativity', 'Albert Einstein', 1,0)
insert into books values (3, 'Harry Potter', 'J K Rowling', 1,0)
insert into books values (1, '1', 'Chris', 1,1)
insert into books values (2, '1', 'Lilly', 1,0)
insert into books values (3, '2', 'Chris', 1,0)
insert into books values (3, '3', 'Chris', 1,1)
The desired output like this
bookId bookTitle availability
-----------------------------------------------
1 The Da Vinci Code 0
2 Theory of Relativity 0
3 Harry Potter 1
I am basically developing a Library management module. I want the availability of that book to be listed on book search page.
The current code that i have is:
SELECT B.bookTitle,
L.lendBorrowerName AS takenName,
count(L.lendStatus) AS taken
FROM books as B
LEFT JOIN lends AS L ON B.bookId = L.lendBookID
WHERE L.lendReturnStatus = 0 // if i remove this code, all rows in books table is listed. However i loose the ability to check the availability of that book
GROUP BY B.bookTitle
What is the typical solution for this problem?
Thanks in advance.
You need to move the condition in the where clause to the on clause. When no rows match, then the column has a value of NULL and the WHERE condition fails:
SELECT B.bookTitle,
L.lendBorrowerName AS takenName,
count(L.lendStatus) AS taken
FROM books as B LEFT JOIN
lends AS L
ON B.bookId = L.lendBookID AND
L.lendReturnStatus = 0
GROUP BY B.bookTitle;
SELECT B.bookTitle,
sum(L.lendReturnStatus = 0) = 0 AS availibility
FROM books as B
LEFT JOIN lends AS L ON B.bookId = L.lendBookID
GROUP BY B.bookTitle

Set random values from an array into database

I'm working on a PHP project with MYSQL database. I have a table of groups of students. Each group has an examiner. What i want to do is that i want to set two examiners for each group randomly. How to do it?
MySQL Code:
create table groups (
groupID int(10) not null,
nbStudents int not null,
avgGPA DOUBLE NOT NULL,
projectName varchar(50) not null,
advisorID int,
examiner1ID int,
examiner2ID int,
adminID int not null,
primary key (groupID)
);
create table faculty (
name varchar(30) not null,
facultyID int(10) not null,
email varchar(30) not null,
mobile int(15) not null,
primary key (facultyID)
);
examiner1ID and examiner2ID are foreign keys from the table faculty.
Here is a very convoluted way to do it. It uses 2 subqueries to pick faculty members, and insert .. on duplicate key to update the examiners IDs.
insert into groups
(groupID, examiner1ID, examiner2ID)
select groupID,
#x:=(select facultyID from faculty order by rand() limit 1),
(select facultyID from faculty where facultyID <> #x order by rand() limit 1)
from groups
on duplicate key update examiner1ID=values(examiner1ID), examiner2ID=values(examiner2ID);
#x is a user-defined-variable. In this case, it is used to store the first random faculty member. <> #x makes sure we don't pick the same faculty member in both slots.
Since groupID is a unique key, when we try to insert a row with an existing unique key, it will update the existing row instead of inserting it. That's what on duplicate key update clause is used for.
set different examiners for each group:
insert into groups
(groupID, examier1ID, examier2ID)
select a.groupID, max(if(b.id%2, b.facultyID, 0)), max(if(b.id%2, 0, b.facultyID))
from (
select #row:=#row+1 id, groupID
from groups a
join (select #row:=0) b) a
join (
select #row:=#row+1 id, facultyID
from (
select facultyID
from faculty a
order by rand()) a
join (select #row:=0) b) b on a.id = ceil(b.id/2)
group by a.groupID
on duplicate key update examiner1ID=values(examiner1ID), examiner2ID=values(examiner2ID);

How to total up entries in a database

I'm using a MySQL database which has a 'Staff' column. Example:
ID BUSINESS STAFF
1 Business 1 Bob
2 Business 2 Bill
3 Business 3 Paul, Bill
4 Business 4 Bob
I'm aiming to create a pie chart showing how many businesses each member of staff has, using the Google Charts API, and I'm having trouble counting total amounts.
The chart uses the formatting:
var data = google.visualization.arrayToDataTable([
['Staff', 'Business'],
['Bob', 2],
['Bill', 2],
['Paul', 1]
]);
How would I go about echoing a count of these lines? I've spent a fun 40 minutes messing up COUNT queries, with absolutely no joy.
There is a common theme in the comments here and that is normalization. As a rule it is A Bad Thing to represent multiple values as a comma-separated list in a single column.
Here is a working example of an alternate DB design that should get you going in the right direction:
create table staff
(
id int unsigned not null primary key auto_increment,
staffName varchar(250),
unique key `staffUIdx1` (staffName)
) ENGINE=InnoDB;
create table business
(
id int unsigned not null primary key auto_increment,
businessName varchar(250),
unique key `staffUIdx1` (businessName)
) ENGINE=InnoDB;
CREATE TABLE staffBusiness
(
id int unsigned not null primary key auto_increment,
staffId int unsigned not null,
businessId int unsigned not null,
unique key `staffBusinessUIdx1` (staffId,businessId),
CONSTRAINT `fk_staffBusiness_staff1` FOREIGN KEY (`staffId`) REFERENCES `staff` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_staffBusiness_business1` FOREIGN KEY (`businessId`) REFERENCES `business` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB;
insert into staff (staffName) values ('Bob');
insert into staff (staffName) values ('Bill');
insert into staff (staffName) values ('Paul');
insert into staff (staffName) values ('George');
insert into business (businessName) values ('Business 1');
insert into business (businessName) values ('Business 2');
insert into business (businessName) values ('Business 3');
insert into business (businessName) values ('Business 4');
insert into staffBusiness (staffId,businessId)
select s.id,b.id from staff s join business b
where s.staffName = 'Bob' and b.businessName in ('Business 1','Business 4');
insert into staffBusiness (staffId,businessId)
select s.id,b.id from staff s join business b
where s.staffName = 'Bill' and b.businessName in ('Business 2','Business 3');
insert into staffBusiness (staffId,businessId)
select s.id,b.id from staff s join business b
where s.staffName = 'Paul' and b.businessName in ('Business 3');
...and then the query would look like this:
select staffName as Staff,count(sb.id) as Business
from staff s
left outer join staffBusiness sb on s.id = sb.staffId
group by staffName;
I've included a 4th member of staff called 'George' to show that a normalized approach allows you to have members of staff with no business too.
I develop this code according your question ,you should change according your table and fields also change server configuration server name,user,password,database
$server="server";
$user="user";
$password="password";
$database="database";
$cid=mysql_connect($server,$user,$password);
mysql_select_db($database,$cid);
$query="select * from table";
$rs=mysql_query($query,$conn);
$val=0;
while($row=mysql_fetch_array($rs))
{
$data=$row['business'];
$val=$val+trim(str_replace("Business","", "$data"));
}
$total=$val;
I used this code and i found total ;

retrieving records with concat statement in sql

i have this query and i want to concat the names of the student. Where should I put the concat statement?
"concat(text,LPAD(id,4,'0'))"
The text and id here is from students table. this is the query:
"SELECT p.*, s.* FROM students s, payments p
where s.id=p.id and level='Grade 3' and amount>='1500'"
Table
-students table-
create table students(
text char(5)NOT NULL,
id int(11)NOT NULL AUTO_INCREMENT,
name varchar(250),
address varchar(250)
PRIMARY KEY(id)
)
-payments-
create table payments(
p_id int(11)NOT NULL AUTO_INCREMENT,
amount varchar(250),
id int,
PRIMARY KEY(p_id)
FOREIGN KEY(id) REFERENCES students(id);
)
Thank you!
Try this :
SELECT p.*, s.*, concat(s.text,LPAD(s.id,4,'0')) as student_names
FROM students s, payments p
where s.id=p.id and level='Grade 3' and amount>='1500'

Categories