First of all, i want to apologize for my bad english.
I have a problem on mySQL and i didn't get the right idea to solve.
I have 3 Tables:
CREATE TABLE branch (name CHAR(30), city VARCHAR(30), assets NUMERIC(16,2), PRIMARY KEY (name));
CREATE TABLE account (accountNr CHAR(9), branch CHAR(30), balance NUMERIC(12,2), PRIMARY KEY (accountNr), FOREIGN KEY (branch) REFERENCES branch(name));
CREATE TABLE customer (customerId INT(5), accountNr CHAR(9), PRIMARY KEY (customerId, accountNr), FOREIGN KEY (accountNr) REFERENCES account(accountNr));
I should find a request to find the costumerId's of the customer who have an account in all branches where city = 'New York'. I must use the 'NOT EXISTS' condition.
So i know, i have two amounts:
A. the amount of branches where the customers have an account.
B. the amount of all branches in New York
Idea: Pick all customers where B is a subset of A
you can try this query:
select distinct customerId
from customer out_customer where
( select count(account.accountNr) from account inner join branch on account.branch = branch.name
INNER join customer ON customer.accountNr = account.accountNr
where city='New York' AND out_customer.customerId = customer.customerId ) = (select count(name) from branch where city='New York')
Related
I am trying to solve an SQL question about below question in MySQL
output the patient name who has taken treatment from all doctors at least once.
I am stuck with the "all doctors".
Is there a way to get this result with one query?
Where I have the table,
CREATE table patient (
pno VARCHAR(5) PRIMARY KEY,
name VARCHAR(15) NOT NULL,
);
CREATE table doctor (
dno VARCHAR(5) PRIMARY KEY,
name VARCHAR(15) NOT NULL,
);
CREATE table record (
id INT auto_increment PRIMARY KEY,
dno VARCHAR(5),
pno VARCHAR(5),
FOREIGN KEY(dno) REFERENCES doctor(dno)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY(pno) REFERENCES patient(pno)
ON UPDATE CASCADE
ON DELETE CASCADE
);
pno is the patient number, which is referenced by record,
dno is the doctor's number, which is referenced by record.
I think IN and EXSISTS doen't work in this situation.
Maybe using count(*) would work but, I tried using subquery below, and couldn't solve this.
SELECT count(*)
FROM doctor;
You can:
first select the cardinality of the doctors,
then select all patients whose distinct count of doctors is equal to the cardinality of doctors
hence get the patients' names.
The query should look like this:
SELECT p.name
FROM patient p
WHERE p.pno IN (
SELECT r.pno
FROM record r
GROUP BY r.pno
HAVING COUNT(DISTINCT r.dno) = (
SELECT COUNT(*)
FROM doctors
)
)
Note: I'll leave an SQL fiddle link here in case of question update with some sample data.
I am having some trouble getting a statement to run, I am looking for the total credits of each student and the student ID.
I have written:
select student.ID,sum (course.credits)
from (student natural join takes),course
where takes.course_id=course.course_id
group by student.ID
when I run this I get the following error:
column used in NATURAL join cannot have qualifier
my tables are
create table student
(ID varchar(5),
name varchar(20) not null,
dept_name varchar(20),
tot_cred numeric(3,0) check (tot_cred >= 0),
primary key (ID),
foreign key (dept_name) references department
on delete set null
create table takes
(ID varchar(5),
course_id varchar(8),
sec_id varchar(8),
semester varchar(6),
year numeric(4,0),
grade varchar(2),
primary key (ID, course_id, sec_id, semester, year),
foreign key (course_id,sec_id, semester, year) references section
on delete cascade,
foreign key (ID) references student
on delete cascade
I am not sure what the problem is. when I run this statement it works
select name, sum(course.credits)
from (student natural join takes),course
where ID=1000 and takes.course_id=course.course_id
group by name
if you can point me in the right direction I would appreciate it.. thank you
NATURAL JOIN is not recommended and can lead to subtle unintended bugs, particularly when tables are modified later. Use INNER JOIN instead:
select name, sum(c.credits)
from student s
inner join takes t
ON t.ID = s.ID
inner join course c
ON c.COURSE_ID = t.COURSE_ID
where s.ID = 1000
group by name
Best of luck.
The from clause is just wrong with regard to how you use your brackets. Just use an explicit join clause for all your joins and you should be OK:
SELECT student.ID, SUM(course.credits)
FROM student
NATURAL JOIN takes
NATURAL JOIN course
GROUP BY student.ID
I'm taking Database Management course this semester and I'm working on one of assigned problems we got. We are supposed to create a database and give mysql statements for actions described.
The action that issues me is described like this:
Get the numbers of students who have the same sex and live in the same town as student 20.
I tried using inner join but I got errors which confuse me. I also tried matching but since there is no data stated, that didn't work either.
Here is my code.
create table student (nr INTEGER PRIMARY KEY, town TEXT, birthdate
INTEGER, sex INTEGER, sname TEXT, ssurname TEXT);
create table lecturer (lnr INTEGER PRIMARY KEY, lname TEXT, lsurname TEXT);
create table course (cnr INTEGER PRIMARY KEY, cname TEXT, lnr INTEGER,
FOREIGN KEY fk_clnr (lnr)
REFERENCES lecturer (lnr) );
create table enrolledin (nr INTEGER, cnr INTEGER,
FOREIGN KEY fk_nr (nr)
REFERENCES student (nr),
FOREIGN KEY fk_cnr (cnr)
REFERENCES course (cnr) );
create table exam (lnr INTEGER, cnr INTEGER, nr INTEGER, note TEXT,
FOREIGN KEY fk_enr (nr)
REFERENCES student (nr),
FOREIGN KEY fk_ecnr (cnr)
REFERENCES course (cnr),
FOREIGN KEY fk_elnr (lnr)
REFERENCES lecturer (lnr) );
select nr, sex, town
FROM student
WHERE student AS S INNER JOIN matches M ON
S.sex = M.sex AND S.town = M.town WHEN nr = 20;
Get the numbers of students who have the same sex and live in the same town as student 20
You should resolve this by a subselect. I dont understand why you use a join. All information are in student aviable.
So lets start:
First you need sex of student with nr 20:
SELECT sex FROM student WHERE nr = 20;
Than you need town of student with nr 20:
SELECT town FROM student WHERE nr = 20;
Now you need the count of students:
SELECT COUNT(*) FROM student;
At least you put everything together:
SELECT COUNT(*) FROM student
WHERE sex = (
SELECT sex FROM student WHERE nr = 20
)
AND town LIKE (
SELECT town FROM student WHERE nr = 20
);
I have a small query to be answered.
There are 4 tables call it as
user : uid, uname
category: cid,canme
product : pid, pname
assemble : aid, uid,pid,cid;
I want to display a record from product table but the requirement is pid(from product) and uid (from user) should not be present in assemble table in the same row at a time.
I believe this is what you're looking for:
select * from user u, product p, assemble a where p.pid not in
(Select pid from assemble) and u.uid not in (select uid from assemble)
Check out this SQL Fiddle and the comments within. You're covering a lot of concepts here, and you'll want to think about your design and what you're trying to accomplish, but to address the goals you've set forth in your question:
You can use PRIMARY KEYS or UNIQUE CONSTRAINTS to ensure that duplicate values don't get inserted into your tables (e.g., you don't want pid and cid to be duplicated in the assemble table, so I made that the primary key). I'm being very literal with your statement:
the requirement is pid(from product) and uid (from user) should not be present in assemble table in the same row at a time. (emphasis mine)
You can use JOINS to relate items from different tables to one another. In fact, your assemble table is often referred to as a "join table". My example is using inner joins (meaning, values must exist in both tables).
You can use FOREIGN KEYS to ensure that columns you want to reference in another table exist there.
Below is the code in case SQL Fiddle misbehaves.
Create and populate the tables:
CREATE TABLE users (
uid serial,
uname text,
CONSTRAINT user_pkey PRIMARY KEY (uid)
);
CREATE TABLE categories (
cid serial,
cname text,
CONSTRAINT cat_pkey PRIMARY KEY (cid)
);
CREATE TABLE products (
pid serial,
pname text,
CONSTRAINT prod_pkey PRIMARY KEY (pid)
);
CREATE TABLE assemble (
join_id serial,
uid bigint,
pid bigint,
cid bigint,
CONSTRAINT assemble_pkey PRIMARY KEY (uid, pid),
CONSTRAINT assemble_user_fkey FOREIGN KEY (uid)
REFERENCES users (uid),
CONSTRAINT assemble_prod_fkey FOREIGN KEY (pid)
REFERENCES products (pid),
CONSTRAINT assemble_cat_fkey FOREIGN KEY (cid)
REFERENCES categories (cid)
);
INSERT INTO users (uname) VALUES ('Akshay');
INSERT INTO users (uname) VALUES ('Mom');
INSERT INTO users (uname) VALUES ('Dad');
INSERT INTO categories (cname) VALUES ('Shoes');
INSERT INTO categories (cname) VALUES ('Hats');
INSERT INTO categories (cname) VALUES ('Coats');
INSERT INTO products (pname) VALUES ('Blue Suede Nikes');
INSERT INTO products (pname) VALUES ('Fedora');
INSERT INTO products (pname) VALUES ('Flying Jacket');
-- Give Akshay a hat
INSERT INTO assemble (uid, cid, pid)
VALUES (
(SELECT uid FROM users WHERE uname='Akshay'),
(SELECT cid FROM categories WHERE cname='Hats'),
(SELECT pid FROM products WHERE pname='Fedora')
);
-- Give Mom a coat
INSERT INTO assemble (uid, cid, pid)
VALUES (
(SELECT uid FROM users WHERE uname='Mom'),
(SELECT cid FROM categories WHERE cname='Coats'),
(SELECT pid FROM products WHERE pname='Flying Jacket')
);
-- Give Dad some shoes
INSERT INTO assemble (uid, cid, pid)
VALUES (
(SELECT uid FROM users WHERE uname='Dad'),
(SELECT cid FROM categories WHERE cname='Shoes'),
(SELECT pid FROM products WHERE pname='Blue Suede Nikes')
);
Queries:
-- get the data out of your assemble table, with names from related tables
SELECT u.uname, c.cname, p.pname
FROM users u
INNER JOIN assemble j
ON u.uid = j.uid
INNER JOIN categories c
ON j.cid = c.cid
INNER JOIN products p
ON p.pid = j.pid;
-- Give Mom the same coat... this will fail due to the PRIMARY KEY, even with a different category
INSERT INTO assemble (uid, cid, pid)
VALUES (
(SELECT uid FROM users WHERE uname='Mom'),
(SELECT cid FROM categories WHERE cname='Hats'),
(SELECT pid FROM products WHERE pname='Flying Jacket')
);
I want to make a link between a table customer and a table product by an IdProduct.
Example:
Create table customer(
idcustomer INT not null,
name Varchar(20),
idproduct INT,
);
create table Product(
idproduct INT not null,
nameProduct varchar(40)
);
How can I link the two together like the foreign key system for, when I select a customer, I can get all his products? It's a question about the structure of the database.
You want to introduce a 3rd table to resolve the many-to-many relationship between customers and products. It should consist of idcustomer and idproduct.
Then, to get all the products for a given customer:
SELECT c.name, p.nameProduct
FROM Customer c
INNER JOIN CustomerProductXref cpx
ON c.idcustomer = cpx.idcustomer
INNER JOIN product p
ON cpx.idproduct = p.idproduct
WHERE c.idcustomer = 12345
In mysql a foreign key is a special type of constraint. It is preferably created with the table, but can also be added afterwards. In this case, you might define the constraint as:
ALTER TABLE customer
ADD FOREIGN KEY (idproduct)
REFERENCES Product (idproduct);
(Note that you have to use the InnoDB engine to take advantage of FK's in mysql. More here
However FK's aren't required to make a JOIN, which is how you would link the tables in a SELECT -
select c.idcustomer, c.name, p.nameproduct
from customer c
join Product p on p.idproduct=c.idproduct;
Here's how you'd make a foreign key constraint (ignoring the cardinality issues that Joe rightly suggests):
CREATE table Product(
idproduct INT not null,
nameProduct varchar(40),
PRIMARY KEY (idproduct )
);
CREATE table customer(
idcustomer INT not null,
name Varchar(20),
idproduct INT,
FOREIGN KEY (idproduct) REFERENCES Product(idproduct )
);
Get your data like this:
SELECT * FROM Product AS P
INNER JOIN Customer AS C ON C.idproduct = P.idproduct
WHERE C.idcustomer = 1