I have three tables:
STUDENT table:
create table student
(
sid int auto_increment primary key,
fname varchar(30),
lname varchar(30)
);
COURSE table:
create table course
(
cid int auto_increment primary key,
ctype text,
cclass text,
cduration int,
certification int,
cteacher text,
standard_course_fee int,
);
STUDENT_PAYMENT table:
create table student_payment
(
transaction_id int auto_increment primary key,
sid int,
cid int,
paidamount int,
paiddate date,
paymentdue int,
FOREIGN KEY (sid) REFERENCES student(sid),
FOREIGN KEY (cid) REFERENCES course(cid)
);
I wrote this query:
select
sid, fname, lname, cid, ctype, cclass, paidamount, paiddate, paymentdue
from
student, student_payment, course
where
course.cid = student_payment.cid and
student.sid = student_payment.sid and
sid = 1;
To get expect output table like this:
|sid| fname | lname | ctype | cclass | paidamount | paiddate | paymentdue |
---------------------------------------------------------------------------
but I get an error:
Column sid in field list is ambiguous
Please someone correct my query.
You need to add alise as below. Also, use the join instead of adding all the tables in FROM
select student.sid,fname,lname,course.cid,ctype,cclass,paidamount,paiddate,paymentdue
from student
inner join student_payment on student.sid=student_payment.sid
inner join course on course.cid=student_payment.cid
where student.sid=1;
Related
I have a table:
table1:
CREATE TABLE product(
product_id INT AUTO_INCREMENT NOT NULL,
name VARCHAR (30),
price DECIMAL(20),
PRIMARY KEY (product_id)
);
table2:
CREATE TABLE people(
people_id INT AUTO_INCREMENT NOT NULL,
adress_id INT,
name VARCHAR (20),
lastName VARCHAR (20),
email VARCHAR (50),
PRIMARY KEY (people_id ),
);
auxiliary table:
CREATE TABLE buy (
people_id INT,
product_id int,
productAmount INT,
PRIMARY KEY (people_id , product_id)
);
I have to write a query:
Select all people who have NOT to buy any products.
SELECT * FROM people
LEFT JOIN buy ON people.people_id = buy.people_id
WHERE buy.people_id IS NULL
GROUP BY people.people_id
Cheers
You can use
Select * From People Where people_id not in (Select people_id from buy);
You can use:
select * from people where people_id not in (select distinct people_id from buy);
Any Query.
select * from people a
where not exists (
select 1 from buy x where x.people_id = a.people_id
)
I want to crate a table Person in mysql which has the values: Name, ID, Password, some other information and a table called items which has the values of Item,price, stock so each Person would have its information and a table of items that is unique for this exact Person.
So it would look something like this.
+------+-------+-------+
| ID | Name | Pass |
+------+-------+-------+-+
| 1165 | Exc |Itm|Pr|St|
| | +---------+
+------+-------| Sc|20|1 |
+---------+
I would be interested if it could be done in MYSQL, if it's not possible, what is possible for my situation.
Two tables, with a foreign key constraint.
As a simplistic example, the person table
CREATE TABLE person
( id INT NOT NULL PRIMARY KEY COMMENT 'PK'
, name VARCHAR(30)
) ENGINE=InnoDB
;
and the item table
CREATE TABLE item
( id INT NOT NULL PRIMARY KEY COMMENT 'PK'
, person_id INT NOT NULL COMMENT 'FK ref person.id'
, item VARCHAR(30)
, price DECIMAL(20,2)
, stock DECIMAL(18,0)
, CONSTRAINT FK_item_person FOREIGN KEY (person_id)
REFERENCES person (id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB
This implements a one-to-many relationship. A person can have zero, one or more item. An item belongs to exactly one person.
INSERT INTO person (id, name) VALUES
(1165,'Exc')
, (1066,'Foo')
;
INSERT INTO item (id, person_id, item, price, stock) VALUES
( 42, 1165, 'Sc', 20, 1 )
, ( 43, 1066, 'Ba', 12, 11 )
, ( 44, 1066, 'Co', 3, 2 )
;
CREATE TABLE Person (
ID int,
Name varchar(100),
Pass varchar(100),
PRIMARY KEY ID);
CREATE TABLE Item(
ID int,
Item varchar(100),
Price varchar(100),
Stock varchar(100),
FOREIGN KEY (ID) REFERENCES Person(ID)
);
those create 2 different tables.
This selects all and joins them.
Select * from Persons p
inner join Item i on p.ID = i.ID
I'm new here in the community and I need your help in MySQL.
We have 3 Tables as follows:
student
lectures
student_visits_lectures(N:M Relationship)
student=({id},name,{id})
lectures=({lid},title{lid})
student_visits_lectures=({student,lectures})
What is the query for?:
List all students which visit all lectures.
For example:
We have students
We have 3 lectures(Math,English,Sport)
Now I want all students which visit all lectures.
Sorry for my broken English and formatting. I'll do my best in the future, but this is very important for me.
Thanks in advance!
Greetings
first add student's id and lectures's into student_visits_lectures table as foreign keys.
then write query as : select student from student_visits_lectures where sbl.student_id = student.id.
This is my current query:
SELECT name FROM student INNER JOIN student_visits_lectures ON student.id=student_visits_lectures.id INNER JOIN lectures ON student_visits_lectures.lid= lectures.lid
I did it guys. Thank you for all quick replying.
This is the solution:
We have 3 tables:
student
id | name
----------
1 | Jack
2 | Rick
lectures
lid | title
----------
1 | Math
2 | English
3 | Sport
student_visiting_lectures
sid |vlid
---------
1 | 1
1 | 2
1 | 3
2 | 2
3 | 3
Creating the table and inserting values
CREATE TABLE student(
id INT NOT NULL,
name VARCHAR(30),
PRIMARY KEY(id)
)ENGINE= InnoDB;
CREATE TABLE lectures(
lid INT NOT NULL,
title VARCHAR(40),
PRIMARY KEY(lid)
)ENGINE = InnoDB;
CREATE TABLE svl(
sid INT NOT NULL,
vlid INT NOT NULL,
PRIMARY KEY(sid,vlid),
FOREIGN KEY (sid) REFERENCES student(id),
FOREIGN KEY (vlid) REFERENCES lectures(lid)
) ENGINE = InnoDB;
INSERT INTO student VALUES(
1,'Jack'),
(2,'Rick');
INSERT INTO lectures VALUES(
1,'Math'),
(2,'English'),
(3,'Sport');
INSERT INTO svl VALUES(
1,1),
(1,2),
(1,3),
(2,1);
And this is the query
SELECT name, title FROM student
INNER JOIN svl ON id = sid
INNER JOIN lectures ON sid = vlid;
Since you want all students that have done all lectures, you can count how many lectures there are:
SELECT COUNT(*) as n FROM lectures;
Then, per student you can count how many lectures they follow:
SELECT student_id, COUNT(*) as n
FROM student_visits_lectures
GROUP BY student_id;
And you can filter the students that have followed all lectures:
SELECT s.*
FROM student_visits_lectures AS ls LEFT JOIN student AS s ON s.id=ls.student_id
GROUP BY student_id
HAVING COUNT(DISTINCT lecture_id) = (SELECT COUNT(*) FROM lectures);
See the fiddle.
This are the tables I have used:
CREATE TABLE student (
id INT NOT NULL,
name VARCHAR(64),
PRIMARY KEY (id)
);
CREATE TABLE lectures (
id INT NOT NULL,
title VARCHAR(100),
PRIMARY KEY(id)
);
CREATE TABLE student_visits_lectures (
student_id INT NOT NULL,
lecture_id INT NOT NULL
);
I've used the following commands for creating the tables.
CREATE TABLE Customer(
custid int NOT NULL AUTO_INCREMENT,
fname varchar(30) NOT NULL,
lname varchar(30) NOT NULL,
mno varchar(10),
password varchar(30),
PRIMARY KEY (custid)
);
CREATE TABLE Employee(
empid int NOT NULL,
fname varchar(30) NOT NULL,
lname varchar(30) NOT NULL,
mno varchar(10),
password varchar(30),
PRIMARY KEY (empid)
);
CREATE TABLE Address(
id int NOT NULL,
street varchar(30),
doorno varchar(30),
city varchar(30),
statee varchar(30),
zip varchar(5),
county varchar(30) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (id) REFERENCES Customer (custid)
);
CREATE TABLE EmpAddress(
id int NOT NULL,
street varchar(30),
doorno varchar(30),
city varchar(30),
statee varchar(30),
zip varchar(5),
county varchar(30) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (id) REFERENCES Employee (empid)
);
CREATE TABLE Service(
serviceid int NOT NULL,
serviceType varchar(30),
amount int,
PRIMARY KEY (serviceid)
);
CREATE TABLE Booking(
bookingid int NOT NULL AUTO_INCREMENT,
empid int NOT NULL,
custid int NOT NULL,
serviceid int NOT NULL,
PRIMARY KEY (bookingid),
FOREIGN KEY (empid) REFERENCES Employee (empid),
FOREIGN KEY (custid) REFERENCES Customer (custid),
FOREIGN KEY (serviceid) REFERENCES Service (serviceid)
);
CREATE TABLE Availability(
empid int NOT NULL,
datee date NOT NULL,
startTime int NOT NULL,
PRIMARY KEY (empid, datee, startTime),
FOREIGN KEY (empid) REFERENCES Employee (empid)
);
CREATE TABLE Transactions(
bookingid int NOT NULL,
paymentMethod varchar(20),
serviceid int,
amount int,
PRIMARY KEY (bookingid),
FOREIGN KEY (bookingid) REFERENCES Booking (bookingid),
FOREIGN KEY (serviceid) REFERENCES Service (serviceid)
);
I am trying to write a query that returns the bookingid, firstName, lastName, street, door no, zip code, serviceType, date and startTime GIVEN empid.
It is essentially a join of 5 tables and I'd implemented the query as:
SELECT B.bookingid, C.fname, C.lname, AD.street,
AD.doorno, AD.zip,S.serviceType, A.datee, A.startTime
FROM booking as B, availability as A, customer as C,
address as AD, Service as S
WHERE
B.empid=501 AND B.custid=C.custid
AND C.custid=AD.id
AND B.serviceid=S.serviceid AND B.empid=A.empid;
The REQUIRED results should have been:
BookingID fname lname street doorno zipcode serviceType date starttime
1 X Y ABC 33 5335 Clean 2015-05-20 9
2 P Q NMO 55 8294 Shift 2015-06-11 11
But the results give me the cross product of tables:
BookingID fname lname street doorno zipcode serviceType date starttime
1 X Y ABC 33 5335 Clean 2015-05-20 9
1 X Y ABC 33 5335 Shift 2015-06-11 11
2 P Q NMO 55 8294 Clean 2015-05-20 9
2 P Q NMO 55 8294 Shift 2015-06-11 11
Please let me know what is wrong with my query.
The primary key for Availability is currently (empid, datee, startTime), yet the JOIN is done on just on Booking.empid - it is possible there is more than one availability row per Employee.
I believe you will need to add a timestamp to Booking and interpolate on date during the join to Availability:
CREATE TABLE Booking(
-- ...
bookingDate datetime NOT NULL,
-- ...
);
I would also suggest that you add and end datetime bounds to the Availability, and store Date and Time as one (otherwise you will need to continually add the time back in):
CREATE TABLE Availability(
-- ...
startDateTime datetime NOT NULL,
endDateTime datetime NOT NULL,
PRIMARY KEY (empid, startDateTime), -- Put some rules to prevent overlap
);
The query then interpolates Booking to Availability on Date and Time:
SELECT B.bookingid, C.fname, C.lname, AD.street, AD.doorno, AD.zip,
S.serviceType, A.startDateTime
FROM
booking as B
INNER JOIN customer as C
ON B.custid=C.custid
INNER JOIN availability as A
ON B.empid=A.empid AND b.bookingDate BETWEEN A.startDateTime AND A.endDateTime
INNER JOIN address as AD
ON C.custid=AD.id
INNER JOIN Service as S
ON B.serviceid=S.serviceid
WHERE
B.empid=501;
I've also adjusted the join to use JOIN ON rather than doing the join in the WHERE.
This would address the duplicated availability data. However, I can't see how ServiceType would be different for the same booking.
You can use DISTINCT to eliminate duplicate records. Also always try to use explicit joins.
SELECT DISTINCT B.bookingid, C.fname, C.lname, AD.street,
AD.doorno, AD.zip,S.serviceType, A.datee, A.startTime
FROM booking as B
INNER JOIN availability as A ON B.empid = A.empid
INNER JOIN customer as C ON B.custid = C.custid
INNER JOIN address as AD ON C.custid = AD.id
INNER JOIN Service as S ON B.serviceid = S.serviceid
WHERE B.empid = 501
I created a database with following tables :
CREATE SCHEMA IF NOT EXISTS `facturatiedatabase` ;
USE `facturatiedatabase` ;
DROP TABLE IF EXISTS tblAddress ;
DROP TABLE IF EXISTS tblContact ;
DROP TABLE IF EXISTS tblCustomers ;
CREATE TABLE tblCustomers (
customerID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
vat VARCHAR(30) NOT NULL,
customerVisible varchar(1) NOT NULL DEFAULT 'T'
) ENGINE=InnoDB;
CREATE TABLE tblContact (
contactID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(100),
phone VARCHAR(100),
customerID int,
CONSTRAINT FK_customerID_Contact FOREIGN KEY (customerID) REFERENCES tblCustomers(customerID)
) ENGINE=InnoDB;
CREATE TABLE tblAddress (
addressID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
street VARCHAR(100),
houseNumber VARCHAR(15),
city VARCHAR (100),
country VARCHAR (100),
customerID int,
CONSTRAINT FK_customerID_Adress FOREIGN KEY (customerID) REFERENCES tblCustomers(customerID)
) ENGINE=InnoDB;
INSERT INTO tblCustomers (firstname, lastname,vat)
VALUES ("John","Doe","UV45856855");
INSERT INTO tblContact (customerID,phone, email)
VALUES ((SELECT DISTINCT LAST_INSERT_ID() FROM tblCustomers), "0000001","Johndoe#gmail.com");
INSERT INTO tblAddress (customerID,street,housenumber,city,country)
VALUES ((SELECT DISTINCT LAST_INSERT_ID() FROM tblCustomers), "berkenlaan","1a","Harelbeke","Belgie");
But when i try following inner join it gives me the following error :
LIMIT 0, 1000 Error Code: 1052. Column 'customerID' in field list is ambiguous 0.000 sec.
SELECT customerID, firstname, lastname, vat,email
FROM tblCustomers
INNER JOIN tblContact on tblCustomers.customerID = tblContact.contactID
The error message says it all: the column name customerID is contained in both tables. So which value should mysql select? That is ambiguous, therefore the error.
Have a try with this variant:
SELECT tblCustomers.customerID AS customerID, firstname, lastname, vat,email
FROM tblCustomers
INNER JOIN tblContact on tblCustomers.customerID = tblContact.contactID
(or pick that other tables's column with the same if you need that one...)
And, frankly, I doubt your ON clause is the one you want to use. Shouldn't that be ON tblCustomers.customerID = tblContact.customerID instead?