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
)
Related
Im currently learning about sub querys in mysql and just want to clarify if im on the right track. The below code does bring a result but im unsure if im doing it correctly. The question is
"Find a code and company name of all customers who submitted at least one order in April 1997 using an IN statement ."
SELECT CUSTOMER_CODE, COMPANY_NAME
FROM CUSTOMER
WHERE CUSTOMER_CODE IN (SELECT CUSTOMER_CODE
FROM ORDERS
WHERE ORDER_DATE BETWEEN '1997-04-01' AND '1997-04-30'
GROUP BY CUSTOMER_CODE )
I went through the values that are inserted into the tables and it just doesnt seem to be correct even though a result is produced.
(Side note, is using a EXIST clause the same as a IN clause, but instead of WHERE CUSTOMER_CODE IN it is WHERE EXISTS ?
I tried this
SELECT CUSTOMER_CODE, COMPANY_NAME
FROM CUSTOMER
WHERE NOT EXISTS (SELECT CUSTOMER_CODE
FROM ORDERS
WHERE ORDER_DATE BETWEEN '1997-04-01' AND '1997-04-30'
GROUP BY CUSTOMER_CODE );
these are the two talbes im using
CREATE TABLE CUSTOMER
(
CUSTOMER_CODE VARCHAR(5) NOT NULL,
COMPANY_NAME VARCHAR(40) NOT NULL,
CONTACT_NAME VARCHAR(30),
CONTACT_TITLE VARCHAR(30),
ADDRESS VARCHAR(60),
CITY VARCHAR(15),
REGION VARCHAR(15),
POSTAL_CODE VARCHAR(10),
COUNTRY VARCHAR(15),
PHONE VARCHAR(24),
FAX VARCHAR(24),
CONSTRAINT PK_CUSTOMER PRIMARY KEY (CUSTOMER_CODE)
);
CREATE TABLE ORDERS
(
ORDER_ID DECIMAL(9) NOT NULL,
CUSTOMER_CODE VARCHAR(5) NOT NULL,
EMPLOYEE_ID DECIMAL(9) NOT NULL,
ORDER_DATE DATE NOT NULL,
REQUIRED_DATE DATE,
SHIPPED_DATE DATE,
SHIP_VIA VARCHAR(40),
FREIGHT DECIMAL(10,2) DEFAULT 0,
SHIP_NAME VARCHAR(40),
SHIP_ADDRESS VARCHAR(60),
SHIP_CITY VARCHAR(15),
SHIP_REGION VARCHAR(15),
SHIP_POSTAL_CODE VARCHAR(10),
SHIP_COUNTRY VARCHAR(15),
CONSTRAINT PK_ORDERS PRIMARY KEY (ORDER_ID),
CONSTRAINT FK_CUSTOMER_CODE FOREIGN KEY (CUSTOMER_CODE) REFERENCES CUSTOMER(CUSTOMER_CODE),
CONSTRAINT FK_EMPLOYEE_ID FOREIGN KEY (EMPLOYEE_ID) REFERENCES EMPLOYEE(EMPLOYEE_ID),
CONSTRAINT FK_SHIP_VIA FOREIGN KEY (SHIP_VIA) REFERENCES SHIPPER(COMPANY_NAME)
);
but i recieve an empty set
Thankyou all for your time
instead of a IN clause you could use a INNER JOIN based on the same subquery ..
usually this perform better that a In clause
SELECT CUSTOMER_CODE, COMPANY_NAME
FROM CUSTOMER
INNER JOIN (
SELECT DISTINCT CUSTOMER_CODE
FROM ORDERS
WHERE ORDER_DATE BETWEEN '1997-04-01' AND '1997-04-30'
) t on t.CUSTOMER_CODE = CUSTOMER.CUSTOMER_CODE
You should not use group by for when you don't use aggregation function (this don't work by default in most recent version of mysql)
use DISTINCT if you need only distinct result
You must use EXISTS instead of NOT EXISTS:
SELECT c.CUSTOMER_CODE, c.COMPANY_NAME
FROM CUSTOMER c
WHERE EXISTS (
SELECT CUSTOMER_CODE FROM ORDERS
WHERE
CUSTOMER_CODE = c.CUSTOMER_CODE
AND
ORDER_DATE BETWEEN '1997-04-01' AND '1997-04-30'
);
You can also check about the ORDER_DATE with this:
YEAR(ORDER_DATE) = 1997 AND MONTH(ORDER_DATE) = 4
You can also do it with IN:
SELECT CUSTOMER_CODE, COMPANY_NAME
FROM CUSTOMER
WHERE CUSTOMER_CODE IN (
SELECT CUSTOMER_CODE FROM ORDERS
WHERE YEAR(ORDER_DATE) = 1997 AND MONTH(ORDER_DATE) = 4
);
If you want to find the total number of all customers who submitted no orders:
SELECT COUNT(DISTINCT c.CUSTOMER_CODE) AS COUNTER
FROM CUSTOMER c
WHERE NOT EXISTS (
SELECT CUSTOMER_CODE FROM ORDERS
WHERE CUSTOMER_CODE = c.CUSTOMER_CODE
)
I was working in mySQL and made a fake database for reviews, reviewers and tv series. So I made 3 different tables, one for reviewers, one for reviews and one for the series.
CREATE TABLE reviewers
(
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(150) NOT NULL
);
CREATE TABLE series
(
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(100) NOT NULL,
released_year YEAR(4),
genre VARCHAR(50)
);
CREATE TABLE reviews(
id INT AUTO_INCREMENT PRIMARY KEY,
rating DECIMAL(2,1),
series_id INT,
reviewer_id INT,
FOREIGN KEY(series_id) REFERENCES series(id),
FOREIGN KEY(reviewer_id) REFERENCES reviewers(id)
);
The thing that I wanted to ask is, how can I get the highest rating from each reviewer and in which show they gave it?
UPDATE
I came up with this code
SELECT first_name,last_name,title, a.series_id,a.rating FROM
( SELECT series_id,MAX(rating) AS max FROM reviews
GROUP BY series_id ) AS b
INNER JOIN reviews AS a
ON a.series_id=b.series_id AND a.rating=b.max
INNER JOIN reviewers
ON reviewers.id=a.reviewer_id
INNER JOIN series
ON series.id=a.series_id
GROUP BY series_id;
which gives me the max rating in each series and who gave that rating
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;
Create Table Doctor(
doctorID varchar(50) Primary key,
doctorFName varchar(50),
);
Create Table Appointment(
appID varchar(50) Primary Key,
doctorID varchar(50) Foreign Key References Doctor(doctorID),
);
Create Table Payment(
paymentID varchar(50) Primary Key,
paymentAmount int,
appID varchar(50) Foreign Key References Appointment(appID),
);
paymentAmount is also known as payment for each appointment
How can I get the average payment amount of each doctor?
I tried:
SELECT d.doctorID, d.doctorFName, SUM(p.paymentAmount) as AverageDailySalary
FROM Payment p JOIN Appointment a ON p.appID = a.appID JOIN Doctor d ON a.doctorID = d.doctorID
ORDER BY d.doctorID
That's a simple JOIN..GROUP BY query :
SELECT d.doctorID,d.doctorFName,AVG(p.paymentAmount) as avg_pay
FROM Doctor d
JOIN Appoitment a
ON(d.doctorID = a.doctorID)
JOIN payment p
ON(a.appID = p.appID)
GROUP BY d.doctorID,d.doctorFName
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?