Displaying top-selling product pairs - mysql

I have a problem, I've spent a lot of time on. I have to display the pairs of items (Item1, Item2, How many) that appear on the invoices - and how many pairs have repeated. The table that connects invoices to goods is called "Transactions".
I Have 3 tables:
Items: IdItem, Name
Transactions: IdTransaction, IdInvoice, IdItem
Invoices: IdInvoice
Result of SQL Query must be:
Item1 | Item2 | Number

This sounds like a self-join and aggregation:
select t1.IdItem as IdItem1, t2.IdItem as IdItem2, count(*)
from transactions t1 join
transactions t2
on t1.IdInvoice = t2.IdInvoice and
t1.IdItem < t2.IdItem
group by t1.IdItem, t2.IdItem
order by count(*) desc;

Assuming your tables look like this:
CREATE TABLE Items (
IDItem INT,
Name VARCHAR,
PRIMARY KEY(IDItem)
);
CREATE TABLE Invoices (
IDInvoice INT,
PRIMARY KEY(IDInvoice)
);
CREATE TABLE Transactions (
IDTransaction INT,
IDInvoice INT,
IDItem INT,
PRIMARY KEY(IDTransaction),
FOREIGN KEY (IDItem) REFERENCES Items(IDItem),
FOREIGN KEY (IDInvoices) REFERENCES Invoices(IDInvoices)
)
If this is true then you need to query the results like this:
SELECT i.Name,in.IDInvoice FROM Transactions t
JOIN Items i ON i.IDItem = t.IDItem
JOIN Invoices in ON in.IDInvoice = t.IDInvoice
WHERE i.Name = item1

Related

How to get all the values of ID in two tables without using set operations

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;

Get all Items attached to sellerId - SQL

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

how to get the ID card in MYSQL?

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

For every customer select all the other customers that bought the same item

Database description
I have a simple database composed of three tables: customer, product and custumer_product.
customer: Contains the information about the customer. His ID and name
product: Contains informations about the products that are available in the store. ID and name
custumer_product: junction table
- customer (table)
id integer primary key not null
name TEXT
- custumer_product (table)
id_product integer
id_customer integer
primary key(id_product, id_customer)
FOREIGN KEY(Id_product) REFERENCES product(id)
FOREIGN KEY (ID_customer) REFERENCES customer(ID)
- product (table)
id integer primary key not null
name TEXT
The three tables have been initialized in sqlfiddle by using SQLITE. The following SQL queries are used to construct the database
create table if not exists customer (id integer primary key not null, name TEXT);
create table if not exists product (id integer primary key not null, name TEXT);
create table if not exists customer_product (id_product integer, id_customer
integer, primary key(id_product, id_customer), FOREIGN KEY(Id_product) REFERENCES product(id), FOREIGN KEY (ID_customer) REFERENCES customer(ID));
insert into customer(id,name) values(1,"john");
insert into customer(id,name) values(2,"Paul");
insert into customer(id,name) values(3,"Jenny");
insert into customer(id,name) values(4,"Fred");
insert into customer(id,name) values(5,"Lea");
insert into product(id,name) values(1,"Mouse");
insert into product(id,name) values(2,"screen");
insert into product(id,name) values(3,"pc");
insert into product(id,name) values(4,"CD");
insert into product(id,name) values(5,"Game");
insert into customer_product values(1,1);
insert into customer_product values(1,2);
insert into customer_product values(1,3);
insert into customer_product values(2,1);
insert into customer_product values(2,2);
insert into customer_product values(2,3);
insert into customer_product values(3,4);
insert into customer_product values(4,5);
insert into customer_product values(5,5);
Problem
For every customer I want to select all the other customers that bought at least one similar product.
John and Paul bought at least 1 similar product
No customer bought a similar product as jenny yet
Fred and lea bought a similar product
output
"John" "Paul"
"Jenny"
"Fred" "Lea"
This is basically a self-join and possibly an aggregation. For instance, the following gets all customers that have purchased a similar product as another, ordered by the number of similar products:
select cp.id_customer, cp2.id_customer, count(*)
from customer_product cp join
customer_product cp2
on cp.id_product = cp2.id_product
group by cp.id_customer, cp2.id_customer
order by cp.id_customer, count(*) desc;
You can bring in additional information such as customer names by doing additional joins.
While I'm not entirely sure I understand the conditions, there are three basic steps to this problem, which you can combine into one query (or not).
Get the products that the customer bought
Get the IDs of the customers that bought the same products
Get the customer details based on those IDs
So for 1, you do a simple select:
SELECT id_product FROM customer_product WHERE id_customer = 1
For 2, you can use the IN statement:
SELECT * FROM customer_product WHERE id_product IN
(SELECT id_product FROM customer_product WHERE id_customer = 1);
For 3 use a combination of JOIN and GROUP BY to get the relevant details from the customer table.
first find the list of product bought by at least 2 customers, second find the name of the custumers using the join table and third select the customer's name once. here is the query:
select distinct c.name from(select c.name, p.name,cp.id_customer, cp.id_product from customer_product cp join customer c on c.id=cp.id_customer join product p on p.id=cp.id_customer where cp.id_product in(select id_product, total from(select id_product,count(*) as total from customer_product group by id_product)p where total>=2)p1)p2)

How to get product which exists in multiple categories in sql server

I have 3 tables, namely product, category and productTocategoryNow my requirement is i want to check the products which exists in multiple categories. i am not getting proper formation of t-sql. Can anyone please help me build the query, below is my table structure.
Product table has all production information. (ProductId, Name, Description.. etc)Category table has category and product information (CategoryId, Name etc)
ProductToCategory has product and category information (ProductToCategoryID, CategoryID, ProductID)
You have to aggregate your many-to-many join table. Then you can use that in any number of ways to get the associate product info as needed.
For example:
CREATE TABLE Product (ProductId INT, Name VARCHAR(10))
CREATE TABLE Category(CategoryId INT, Name VARCHAR(10))
CREATE TABLE ProductToCategory (ProductToCategoryID INT, CategoryID INT, ProductID INT)
GO
INSERT INTO Product VALUES (1,'prod_1'),(2,'prod_2')
INSERT INTO Category VALUES (1,'cat_1'),(2,'cat_2')
INSERT INTO ProductToCategory VALUES (0,1,1),(1,2,1),(1,1,2)
GO
SELECT p.*
,a.CatCount
FROM Product p
INNER JOIN (
SELECT ProductID
,COUNT(CategoryId) CatCount
FROM ProductToCategory
GROUP BY ProductID
HAVING COUNT(*) > 1
) a ON p.ProductId = a.ProductId
GO
DROP TABLE Product
DROP TABLE Category
DROP TABLE ProductToCategory