When execute my query i just get 1 item back that i attached to the sellerId instead of 2. Does anyone know how i can say?
select the name of item and re seller for each item that belongs to the re seller. With a rating higher than 4?
Current Query:
SELECT items.name, sellers.name
FROM items
inner JOIN sellers
on items.id=sellers.id
WHERE rating > 4
ORDER BY sellerId
The query for tables inc. data:
CREATE TABLE sellers (
id INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(30) NOT NULL,
rating INTEGER NOT NULL
);
CREATE TABLE items (
id INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(30) NOT NULL,
sellerId INTEGER REFERENCES sellers(id)
);
INSERT INTO sellers(id, name, rating) values(1, 'Roger', 3);
INSERT INTO sellers(id, name, rating) values(2, 'Penny', 5);
INSERT INTO items(id, name, sellerId) values(1, 'Notebook', 2);
INSERT INTO items(id, name, sellerId) values(2, 'Stapler', 1);
INSERT INTO items(id, name, sellerId) values(3, 'Pencil', 2);
You've got the wrong join, here's a corrected query;
SELECT items.name, sellers.name
FROM items
inner JOIN sellers
on items.sellerId=sellers.id
WHERE rating > 4
ORDER BY sellerId
You're joining on id = id, you want sellerid = id
Notice in your table definition that item.sellerId is the field that joins to seller.id
CREATE TABLE items (
id INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(30) NOT NULL,
sellerId INTEGER REFERENCES sellers(id)
);
You need to join on the correct column:
SELECT i.name, s.name
FROM items i INNER JOIN
sellers s
ON i.sellerid = s.id
----------^
WHERE rating > 4
ORDER BY i.sellerId
Note that I also introduced table aliases and qualified column names. These make a query easier to write and to read.
SELECT items.name, sellers.name
FROM items, sellers
WHERE items.sellerId = sellers.id and sellers.rating>4;
Here is the right query:
SELECT items.name as items, sellers.name as sellers
FROM sellers
INNER JOIN items
ON (sellers.id = items.sellerid)
WHERE sellers.rating > 4
Related
Two tables
Customer_Fixed_Deposit(
ID int primary key,
name varchar(20),
Fixed_Deposit int
);
Customer_Loan(
ID int primary key,
name varchar(20),
Loan int
);
I want the ID of all the customers and with names in both the tables without using set operations
I tried to insert all the values of id and name in 1 table into another, because there were duplicates and ID is the primary key it did not work
You can get all customers with the same name, assuming names are unique.
SELECT fd.id, fd.name, l.id, l.name
FROM Customer_Fixed_Deposit fd
JOIN Customer_Loan l
ON fd.name = l.name;
Now, if you want to insert only those customers to Customer_Loan table who are not already present in it.
INSERT INTO Customer_Loan (name)
SELECT name
FROM Customer_Fixed_Deposit
WHERE NOT EXISTS (
SELECT fd.id
FROM Customer_Fixed_Deposit fd
JOIN Customer_Loan l
ON fd.name = l.name;
);
If I understand you correctly, you have two tables with two different sets of people and IDs? If so, then I think a UNION would allow you to select all the IDs and Names from each table into one result. Try this:
SELECT
ID, name
FROM
Customer_Fixed_Deposit
UNION
SELECT
ID, name
FROM
Customer_Loan;
Question: Write a SQL query to find and display a customer who made 2 consecutive orders in the same category?
I am struggling with the answer. Any help would be appreciated.
Queries:
CREATE TABLE customers (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
name TEXT,
email TEXT);
CREATE TABLE orders (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
customer_id INTEGER,
item TEXT,
price REAL,
ORDER_DATE DATETIME,
category TEXT);
INSERT INTO customers (name, email) VALUES ("Doctor Who", "doctorwho#timelords.com");
INSERT INTO customers (name, email) VALUES ("Harry Potter", "harry#potter.com");
INSERT INTO customers (name, email) VALUES ("Captain Awesome", "captain#awesome.com");
INSERT INTO orders (customer_id, item, price,ORDER_DATE,category)
VALUES (1, "Sonic Screwdriver", 1000.00,'21-04-15 09.00.00','tools');
INSERT INTO orders (customer_id, item, price,ORDER_DATE,category)
VALUES (1, "Light", 1000.00,'21-10-15 09.00.00','tools');
INSERT INTO orders (customer_id, item, price,ORDER_DATE,category)
VALUES (2, "High Quality Broomstick", 40.00,'20-12-20 09.00.00','cleaner');
INSERT INTO orders (customer_id, item, price,ORDER_DATE,category)
VALUES (3, "TARDIS", 1000000.00,'21-01-20 09.00.00','other');
Step: 1
First of all, you add a foreign key in the column containing the customer id of the order table, then after that add the customers and orders tables together.
Step: 2
After adding both tables together run this query and you will get your result.
SELECT DISTINCT orders.category , customers.id,customers.name,customers.email FROM customers JOIN orders ON customers.id= orders.customer_id WHERE orders.category in ( select category from orders group by category having count(*) >= 2 )
You can also solve it by using LEAD. Get lead_category and lead_customers_id and filter with category, customers_id
select * from
(SELECT orders.category , orders.item, customers.id,customers.name,customers.email,
LEAD(category) OVER (ORDER BY customers.id ASC) AS lead_category,
LEAD(customers.id) OVER (ORDER BY customers.id ASC) AS lead_customers_id
FROM orders
JOIN
customers ON
orders.customer_id = customers.id) AS T
where category = lead_category and id = lead_customers_id
SELECT DISTINCT t1.customer_id
FROM orders t1
JOIN orders t2 USING (customer_id, category)
WHERE t1.ORDER_DATE < t2.ORDER_DATE
AND NOT EXISTS ( SELECT NULL
FROM orders t3
WHERE t1.customer_id = t3.customer_id
AND t1.category != t3.category
AND t1.ORDER_DATE < t3.ORDER_DATE
AND t3.ORDER_DATE < t2.ORDER_DATE )
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=a26be6164e027b1a4b0aa9a736764da3
I.e. we simply search for a pair of orders for the same customer and category where an order with the same customer but another category not exists between these orders.
Join customers table if needed.
I wanna a query to get first_name of students and first_name of teachers which have the most courses with each other with the number of these courses.
Table Student:
CREATE TABLE Student(
id INT AUTO_INCREMENT,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255),
email VARCHAR(255) UNIQUE,
PRIMARY KEY (id)
);
Table Teacher:
CREATE TABLE Teacher(
id INT AUTO_INCREMENT,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255),
email VARCHAR(255) UNIQUE,
degree VARCHAR(10) NUT NULL,
PRIMARY KEY (id)
);
Table Course:
CREATE TABLE Course(
id INT AUTO_INCREMENT,
code INT NOT NULL UNIQUE,
name VARCHAR(255) NOT NULL,
st_id INT,
teach_id INT,
PRIMARY KEY (id),
FOREIGN KEY st_id REFERENCES Student (id),
FOREIGN KEY teach_id REFERENCES Teacher (id)
);
Is the below query correct? i.e. Can I use 3 SELECT in a query?
query1:
SELECT S.first_name
FROM Student AS S
INNER JOIN Course AS C
ON C.st_id = S.id
SELECT T.first_name
FROM Teacher AS T
INNER JOIN Course AS CC
ON CC.teach_id = T.id
SELECT COUNT(*)
FROM Course
WHERE Course.st_id = S.id
AND Course.teach_id = T.id
GROUP BY COUNT(*)
ORDER BY DESC;
query2:
SELECT S.first_name, T.first_name, COUNT(*)
FROM Student AS S, Teacher AS T, Course
WHERE Course.st_id = S.id
AND Course.teach_id = T.id
GROUP BY COUNT(*)
ORDER BY DESC;
If the above queries are not correct(probably the first one is wrong) guide me to correct answer, please.
NOTE: If the ordering isn't unique, order by the name of teachers first, then order by the name of the students(for clarity but not important so much to me).
Your second query is closer to being right but it has some issues. I would recommend using JOIN statements rather than implied joins. This makes the query easier to read.
Something like this should work:
SELECT t.first_name,
t.id,
s.first_name,
s.id,
COUNT(*) AS course_count
FROM Course c
JOIN Student s ON c.st_id = s.id
JOIN Teacher t ON c.teach_id = t.id
GROUP BY t.id, s.id
ORDER BY course_count DESC, t.first_name, s.first_name;
You need to add a group by in order to get your count on a per student basis. Putting the group by on the id columns rather than the name makes sure you get counts on unique students and teachers in case you have multiple records in your table with the same first name. I am also adding the id columns to the select for the same reason, but these are not necessary and can be removed without affecting the accuracy of the query.
SELECT t.first_name, t.id, s.first_name, s.id, COUNT(c.id) AS course_count
FROM course c
JOIN student s ON c.st_id = s.id
JOIN teacher t ON c.teach_id = t.id
GROUP BY t.id, s.id
ORDER BY t.first_name, s.first_name
The essential data is contained in the Courses table, with the Student and Teacher tables only required for gathering the names. This query joins the 3 tables in question, computing the count of courses shared by teachers and students.
I created the following tables:
create table people (
ID varchar(9),
name varchar(20),
CONSTRAINT pk_ID PRIMARY KEY (ID)
);
create table cars (
license_plate varchar(9),
ID varchar(9),
CONSTRAINT pk_ID PRIMARY KEY (license_plate)
);
create table accidents (
code varchar(9),
license_plate varchar(9),
CONSTRAINT pk_ID PRIMARY KEY (code)
);
I inserted the following data:
insert into people(ID, name) values('0x1','Louis');
insert into people(ID, name) values('0x2','Alice');
insert into people(ID, name) values('0x3','Peter');
insert into cars(license_plate, ID) values('001','0x1');
insert into cars(license_plate, ID) values('002','0x2');
insert into cars(license_plate, ID) values('003','0x1');
insert into cars(license_plate, ID) values('004','0x3');
insert into accidents(code, license_plate) values('fd1','001');
insert into accidents(code, license_plate) values('fd2','004');
insert into accidents(code, license_plate) values('fd3','002');
The question is: How to select people who don't have had accidents in any of their cars?
My problem is that when I was trying to use not in. Having "Louis" at least one car in the table accidents, the query show me "Louis"and should not show "Louis".
My query:
select ID from people where ID in (select ID from cars where license_plate not in (select license_plate from accidents));
Result:
+-----+
| ID |
+-----+
| 0x1 |
+-----+
select name from people where ID not in (
select distinct c.ID from
accidents as a inner join cars as c
on a.license_plate = c.license_plate
)
Explanation = the sub query will join the cars and accidents, will give you the ID's of all cars who had accidents. On this you can run not in query on the people table
I need two subquery
select id from people
where id not it
(select id form cars where licens_plate not in
(select distintc license_plate from accidents))
This should be quite fast:
SELECT people.* FROM people
LEFT JOIN cars ON cars.ID = people.ID
LEFT JOIN accidents ON accidents.license_plate = cars.license_plate
WHERE accidents.code IS NULL
GROUP BY people.ID
im trying to create a sql query, that will detect (possible) duplicate customers in my database:
I have two tables:
Customer with the columns: cid, firstname, lastname, zip. Note that cid is the unique customer id and primary key for this table.
IgnoreForDuplicateCustomer with the columns: cid1, cid2. Both columns are foreign keys, which references to Customer(cid). This table is used to say, that the customer with cid1 is not the same as the customer with the cid2.
So for example, if i have
a Customer entry with cid = 1, firstname="foo", lastname="anonymous" and zip="11231"
and another Customer entry with cid=2, firstname="foo", lastname="anonymous" and zip="11231".
So my sql query should search for customers, that have the same firstname, lastname and zip and the detect that customer with cid = 1 is the same as customer with cid = 2.
However, it should be possible to say, that customer cid = 1 and cid=2 are not the same, by storing a new entry in the IgnoreForDuplicateCustomer table by setting cid1 = 1 and cid2 = 2.
So detecting the duplicate customers work well with this sql query script:
SELECT cid, firstname, lastname, zip, COUNT(*) AS NumOccurrences
FROM Customer
GROUP BY fistname, lastname,zip
HAVING ( COUNT(*) > 1 )
My problem is, that i am not able, to integrate the IgnoreForDuplicateCustomer table, to that
like in my previous example the customer with cid = 1 and cid=2 will not be marked / queried as the same, since there is an entry/rule in the IgnoreForDuplicateCustomer table.
So i tried to extend my previous query by adding a where clause:
SELECT cid, firstname, lastname, COUNT(*) AS NumOccurrences
FROM Customer
WHERE cid NOT IN (
SELECT cid1 FROM IgnoreForDuplicateCustomer WHERE cid2=cid
UNION
SELECT cid2 FROM IgnoreForDuplicateCustomer WHERE cid1=cid
)
GROUP BY firstname, lastname, zip
HAVING ( COUNT(*) > 1 )
Unfortunately this additional WHERE clause has absolutely no impact on my result.
Any suggestions?
Here you are:
Select a.*
From (
select c1.cid 'CID1', c2.cid 'CID2'
from Customer c1
join Customer c2 on c1.firstname=c2.firstname
and c1.lastname=c2.lastname and c1.zip=c2.zip
and c1.cid < c2.cid) a
Left Join (
Select cid1 'CID1', cid2 'CID2'
From ignoreforduplicatecustomer one
Union
Select cid2 'CID1', cid1 'CID2'
From ignoreforduplicatecustomer two) b on a.cid1 = b.cid1 and a.cid2 = b.cid2
where b.cid1 is null
This will get you the IDs of duplicate records from customer table, which are not in table ignoreforduplicatecustomer.
Tested with:
CREATE TABLE IF NOT EXISTS `customer` (
`CID` int(11) NOT NULL AUTO_INCREMENT,
`Firstname` varchar(50) NOT NULL,
`Lastname` varchar(50) NOT NULL,
`ZIP` varchar(10) NOT NULL,
PRIMARY KEY (`CID`))
ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=100 ;
INSERT INTO `customer` (`CID`, `Firstname`, `Lastname`, `ZIP`) VALUES
(1, 'John', 'Smith', '1234'),
(2, 'John', 'Smith', '1234'),
(3, 'John', 'Smith', '1234'),
(4, 'Jane', 'Doe', '1234');
And:
CREATE TABLE IF NOT EXISTS `ignoreforduplicatecustomer` (
`CID1` int(11) NOT NULL,
`CID2` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `ignoreforduplicatecustomer` (`CID1`, `CID2`) VALUES
(1, 2);
Results for my test setup are:
CID1 CID2
1 3
2 3
Edit as per TPete's comment (dind't try it):
SELECT
C1.cid, C1.firstname, C1.lastname
FROM
Customer C1,
Customer C2
WHERE
C1.cid < C2.cid AND
C1.firstname = C2.firstname AND
C1.lastname = C2.lastname AND
C1.zip = C2.zip AND
CAST(C1.cid AS VARCHAR)+' ' +CAST(C2.cid AS VARCHAR) <>
(SELECT CAST(cid1 AS VARCHAR)+' '+CAST(cid2 AS VARCHAR) FROM IgnoreForDuplicateCustomer I WHERE I.cid1 = C1.cid AND I.cid2 = C2.cid);
Initially I thought that IgnoreForDuplicateCustomer was a field in the customer table.
crazy but I think it works :)
first I join the customer tables with itself on the names to get the duplicates
then I exclud the keys on the IgnoreForDuplicateCustomer table (the union is because the first query returns cid1, cid2 and cid2,cid1
the result will be duplicated but I think you can get the info you need
select c1.cid, c2.cid
from Customer c1
join Customer c2 on c1.firstname=c2.firstname
and c1.lastname=c2.lastname and c1.zip=c2.zip
and c1.cid!=c2.cid
except
(
select cid1,cid2 from IgnoreForDuplicateCustomer
UNION
select cid2,cid1 from IgnoreForDuplicateCustomer
)
second shot:
select firstname,lastname,zip from Customer
group by firstname,lastname,zip
having (count(*)>1)
except
select c1.firstname, c1.lastname, c1.zip
from Customer c1 join IgnoreForDuplicateCustomer IG on c1.cid=ig.cid1 join Customer c2 on ig.cid2=c2.cid
third:
select firstname,lastname,zip from (
select firstname,lastname,zip from Customer
group by firstname,lastname,zip
having (count(*)>1)
) X
where firstname not in (
select c1.firstname
from Customer c1 join IgnoreForDuplicateCustomer IG on c1.cid=ig.cid1 join Customer c2 on ig.cid2=c2.cid
)