unknown column in where clause in sql - mysql

SELECT *
FROM subjects
INNER JOIN entries ON entries.subject_id= subjects.subject_id
INNER JOIN students ON entries.student_id=students.student_id
WHERE subjects.exam_board LIKE ‘OCR’;
when i execute this the error unknown column 'OCR' in where clause
The following is my subject table
INSERT INTO subjects
(subject_id, subject_name, level_of_entry, exam_board)
VALUES
(1, 'chemistry', 'AS', 'OCR');
INSERT INTO subjects
(subject_id, subject_name, level_of_entry, exam_board)
VALUES
(2, 'biology', 'GCSE', 'AQA');
INSERT INTO subjects
(subject_id, subject_name, level_of_entry, exam_board)
VALUES
(3, 'music', 'GCSE', 'Edexcel');
the below is my students table
INSERT INTO students
(student_id,first_name,middle_name,last_name,email,password,reg_date)
VALUES
(NULL, 'Tom', 'Michael', 'ford', 'tom#yahoo.com','tom1234','2003/12/08');
INSERT INTO students
(student_id,first_name, middle_name, last_name, email, password, reg_date)
VALUES
(NULL, 'michael', 'scoffield', 'burrows', 'lincoln#yahoo.com', 'lincoln1234', '2001/12/16');

You have to use '(single quote) sign insted of ` in like clause hope below code will help you
SELECT *
FROM subjects
INNER JOIN entries ON entries.subject_id= subjects.subject_id
INNER JOIN students ON entries.student_id=students.student_id
WHERE subjects.exam_board LIKE 'OCR';

Related

Error code 1111: says invalid use of group function

Im trying to use
select Suppliers.sid
from Suppliers
left join Catalog on Suppliers.sid=Catalog.sid
where Catalog.cost>avg(Catalog.cost);
but im getting error code 1111:
Unsure what's going on with my database. Im very nice to sql and just having issues getting this to work.
CREATE DATABASE CSC123Lab2;
USE CSC123Lab2;
CREATE TABLE Suppliers (
sid CHAR(20),
sname CHAR(20),
address CHAR(20),
pid CHAR(20)
);
CREATE TABLE Parts (
pid CHAR(20),
pname CHAR(20),
color CHAR(20),
sid CHAR(20)
);
CREATE TABLE Catalog (
sid CHAR(20),
pid CHAR(20),
cost REAL
);
ALTER TABLE Suppliers ADD PRIMARY KEY (sid);
ALTER TABLE Parts ADD PRIMARY KEY (pid);
INSERT INTO Suppliers (sid, sname, address) VALUES (1, "carvel", "1234 Main Street");
INSERT INTO Suppliers (sid, sname, address) VALUES (2, "coldstone", "5678 Pine Street");
INSERT INTO Suppliers (sid, sname, address) VALUES (3, "ralphs", "9876 Oak Street");
INSERT INTO Suppliers (sid, sname, address) VALUES (4, "Acme Widget", "4321 Maple Street");
INSERT INTO Parts (pid, pname, color) VALUES (1, "hammer", "red");
INSERT INTO Parts (pid, pname, color) VALUES (2, "screwdriver", "pink");
INSERT INTO Parts (pid, pname, color) VALUES (3, "nails", "green");
INSERT INTO Parts (pid, pname, color) VALUES (4, "screws", "teal");
INSERT INTO Catalog (sid, pid, cost) VALUES (1, 3, 32);
INSERT INTO Catalog (sid, pid, cost) VALUES (4, 1, 10);
INSERT INTO Catalog (sid, pid, cost) VALUES (4, 3, 48);
INSERT INTO Catalog (sid, pid, cost) VALUES (2, 4, 24);
select Suppliers.sid
from Suppliers
left join Catalog on Suppliers.sid=Catalog.sid
where Catalog.cost>avg(Catalog.cost);
DROP TABLE Catalog;
DROP TABLE Parts;
DROP TABLE Suppliers;
DROP DATABASE CSC123Lab2;
use group by and do filter in next level
with cte as
(select Suppliers.sid,avg(Catalog.cost) as avg_val
from Suppliers
left join Catalog on Suppliers.sid=Catalog.sid
group by Suppliers.sid
) select a.sid
from Catalog a join cte on a.sid=cte.sid
where a.cost>avg_val
I think you just want a window function:
select s.sid
from Suppliers s join
(select c.*, avg(c.cost) over () as avg_cost
from Catalog c
) c
on s.sid = c.sid
where c.cost > c.avg_cost;
Note, though, that you don't really need the left join. The where clause turns the left join into an inner join.
Then, you don't need the join at all, because sid is in both tables:
select c.sid
from (select c.*, avg(c.cost) over () as avg_cost
from Catalog c
) c
where c.cost > c.avg_cost;
If you prefer, you could express this using a subquery:
select c.sid
from Catalog c
where c.cost > (select avg(c2.cost) from catalog c2);

Query to get the ID of authors who published papers in two consecutive years

I want to write a query that displays the ID of the Author who published papers in two consecutive years.
Here is the database schema:
CREATE TABLE Author (aid integer NOT NULL,
name varchar(50) NOT NULL,
affiliation varchar(50), primary key(aid));
CREATE TABLE Paper (pid integer NOT NULL,
title varchar(50) NOT NULL,
year integer NOT NULL, primary key(pid));
CREATE TABLE Authored (aid integer references Author,
pid integer references Paper,
primary key(aid, pid), foreign key(aid) references Author(aid), foreign key(pid) references Paper(pid));
insert into Author(aid, name, affiliation) values (1, "A", "DS");
insert into Author(aid, name, affiliation) values (2, "B", "PS");
insert into Author(aid, name, affiliation) values (3, "C", "CS");
insert into Paper(pid, title, year) values (100, "DS1", 2019);
insert into Paper(pid, title, year) values (101, "PS1", 2019);
insert into Paper(pid, title, year) values (102, "CS1", 2019);
insert into Paper(pid, title, year) values (103, "DS2", 2020);
insert into Paper(pid, title, year) values (104, "PS2", 2020);
insert into Paper(pid, title, year) values (105, "CS2", 2019);
Authored.aid is a foreign key to Author and Authored.pid is a foreign key to Paper. And this is what I have so far but this is not giving me the desired result and I don't know what's wrong:
select au1.aid, a1.name
from authored au1 inner join authored au2 on au1.aid=au2.aid
inner join author a1 on au1.aid=a1.aid
inner join paper p1 on au1.pid=p1.pid
inner join paper p2 on au2.pid=p2.pid
where p1.year = p2.year+1
order by au1.aid;
You need to GROUP BY au1.aid to get distinct authors:
SELECT au1.aid, a1.name
FROM authored au1 INNER JOIN authored au2 ON au1.aid=au2.aid
INNER JOIN author a1 ON au1.aid=a1.aid
INNER JOIN paper p1 ON au1.pid=p1.pid
INNER JOIN paper p2 ON au2.pid=p2.pid AND p1.year+1 = p2.year
GROUP BY au1.aid
ORDER BY au1.aid
Not sure about your query but an IN clause looks to be useful:
where paper.year IN ('2019', '2020')

MySQL find ids for which there is no existing row

I have three tables :
1. Person (person_id, name) : (1, "Test1"), (2, "Test2"), (3, "Test3")
2. Role (role_id, description) : (1, "Admin"), (2, "Designer"), (3, "Developer") ..
3. PersonRoles (person_id, role_id) : (1 , 1), (1, 2), (2, 3), (2, 1), (3, 1)
Is it possible in MySQL with a query to get the ids of the people for which there`s no row with exact role in the PersonRoles table. For Example if I want to check for "Designer" role the query should return ids: 2 and 3
Here is your solution:
select person_id from Person
where person_id not in
(select person_id from Role r
inner join PersonRoles pr on pr.role_id=r.role_id
where r.description='Designer')
You could use the not exists operator:
SELECT *
FROM Person p
WHERE NOT EXISTS (SELECT *
FROM Role r
JOIN PersonRoles pr ON r.role_id = pr.role_id
WHERE r.description = 'Designer' AND
pr.person_id = p.person_id)

PL/SQL SELECT on two tables

I've got two tables. One of these contains userData and the other one contains userGroups linked to users which are in a Group.
Means like a user can be in 0 or more Groups.
I'm trying to get this columns with a query used like this:
SELECT distinct(a.userID), a.userName, Count(b.userID_FID)
FORM userData a,
userGroup b
WHERE a.userID = b.userID_FID
But somehow the Count part returning me a wrong number.
SELECT max(a.userName), Count(distinct b.userID_FID)
FROM userData a
JOIN userGroup b
ON a.userID = b.userID_FID
GROUP BY a.userID
My suggestion is do not use many tables with from
This will get you the number of groups each user is in.
To build the test scenario, use this:
create table #groups
(userID_FID int
,groups int
);
create table #user
(userID int);
insert into #groups values (1, 5);
insert into #groups values (1, 2);
insert into #groups values (1, 3);
insert into #groups values (1, 4);
insert into #groups values (2, 3);
insert into #groups values (2, 4);
insert into #groups values (3, 1);
insert into #groups values (3, 5);
insert into #user values (1);
insert into #user values (2);
insert into #user values (3);
select * from #groups;
select * from #user;
This piece is the query you want, according to the test scenario above:
select userid, count(*) as NumberOfGroups
from #groups g
, #user u
where g.userID_FID = u.userID
group by userID;

SQL: Sort on number of row entries and join

How do I find duplicate entries in a column (like multiple rows in student_id column) and join those to another table with common id (like student_id from another table to get student_name)?
grades:
student_id,grade
6,A
1,B
1,F
7,C
6,A
students:
student_id,student_name
1,roy
6,bob
7,art
so that I can get a joined table of only duplicate student rows on student_id that resembles:
student_id,student_name,grade
6,bob,A
1,roy,B
1,roy,F
6,bob,A
It would be nice to then just return the names of the most recent data frame:
bob
roy
Try this:
select students.student_name
from grades
inner join students on grades.student_id = students.student_id
group by student_name
having count(*) > 1
Example:
create table grades (student_id int, grade char(1));
insert into grades values (6, 'A'), (1, 'B'), (1, 'F'), (7, 'C'), (6, 'A');
create table students (student_id int, student_name varchar(20));
insert into students values (1, 'roy'), (6,'bob'), (7,'art');
select students.student_name
from grades
inner join students on grades.student_id = students.student_id
group by student_name
having count(*) > 1
Result:
student_name
bob
roy
This should result in bob and roy.
Command line on Linux, assuming you have sqlite:
~$ sqlite
SQLite version 2.8.17
Enter ".help" for instructions
sqlite> create table grades (student_id int, grade char(1));
sqlite> insert into grades values (6, 'A');
sqlite> insert into grades values (1, 'B');
sqlite> insert into grades values (1, 'F');
sqlite> insert into grades values (7, 'C');
sqlite> insert into grades values (6, 'A');
sqlite>
sqlite> create table students (student_id int, student_name varchar(20));
sqlite> insert into students values (1, 'roy');
sqlite> insert into students values (6,'bob');
sqlite> insert into students values (7,'art');
sqlite>
sqlite> select students.student_name
...> from grades
...> inner join students on grades.student_id = students.student_id
...> group by student_name
...> having count(*) > 1;
roy
bob
sqlite>
Find duplicates and then join it back for more information:
SELECT s.student_id, s.student_name
FROM student s
INNER JOIN
(SELECT g.student_id
FROM grades g
GROUP BY g.student_id
HAVING COUNT(*) > 1) dups
ON s.student_id = dups.student_id