Selecting products sold to a given set of customers - sql

I have two tables, product and sold_record. product contains my list of products, while sold_record contains all of my transactions. How can I select a distinct list of products that both customer A and customer B bought?

If your sold_record table has a product id and customer id, then the query would be:
select distinct s1.product_id
from sold_record as s1, sold_record as s2
where s1.customer_id = "Customer A"
and s2.customer_id = "Customer B"
and s1.product_id = s2.product_id;
There may be a simpler way to do this using a join, but this should work.

Let's suppose table Product has a primary key ProdID, and table Sold a foreign key into Product by the same name as well as a Customer field (probably another foreign key into a third table Customer, but since you say there must be only two tables we'll assume a string that's the customer name, instead). Then:
Select DISTINCT Product.ProdID
From Product
Inner Join Sold SA On (Product.ProdID=SA.ProdID
AND SA.Customer='A')
Inner Join Sold SB On (Product.ProdID=SB.ProdID
AND SB.Customer='B')
will give you the ProdID in question (of course, you can get other columns from that table, too, we just have no idea what those columns might be;-).

Related

getting the sum of products between two columns in SQL

My situation is this: I have an order_details table containing entities representing the
"content" of an orders, each row has
a product_id column ---> foreign key referencing the type of product
an order_id column ----> foreign key represents which order the product belongs to
a qty column ----------> representing the quantity of the product present in the order
each product row instead has:
a product name column ----> representing the product name
a co2_value --------------> representing the value of co2 removed buying that product
each table (orders table too) has his own id column as primary key for the rows.
the problem is the following:
I need a sql query to find the total co2_value of an order adding all the co2_values of the products belonging to a specific order, multiplied by their quantity.
I tried this query first:
SELECT SUM(co2_value) FROM products
INNER JOIN order_details
ON products.id = order_details.product_id AND order_details.order_id = ". $this->id;
the problem with this is that i'am getting only the sum of the co2_values of the product without multiplying them by the quantity, is there a way to do that in a single query?
I'll leave the link to migration here
select
sum(co2_value * qty)
from
products
inner join order_details on
products.id = order_details.product_id
and order_details.order_id = ". $this->id;
You can simply select the co2_value with respect to its quantity by multiplying it using the above query

SQL Joining on 5 Tables - Inclusion & Exclusion

I want to join 5 tables to come up with 3 different result sets.
My tables are:
Customers - contains email address (unique id), email address domain name, account name, demographic info, etc (Customers)
Product 1 customer account names (Product1Accounts)
Product 1 customer email address domain names (Product1Domains)
Product 2 customer account names (Product2Accounts)
Product 2 customer email address domain names (Product2Domains)
The 3 results I need are:
Product 1 customers excluding Product 2 customers
Product 2 customers excluding Product 1 customers
Customers of both Product 1 and 2
Side Note: a customer of each product could be identified by account OR domain name.
I can create the following to come up with matches on table 1,2,3 or 1,4,5 but I am getting hung up on how to incorporate the exclusions
SELECT *
FROM Customers
INNER JOIN Product1Accounts
ON Customers.Company=Product1Accounts.Account
UNION
SELECT *
FROM Customers
INNER JOIN Product1Domains
on Customers.Email_Address_Domain=Product1Domains.Domain
I'm also not sure how to obtain the 3rd result set I am looking for... any help or advice on how to write this code better would be appreciated.
For the third result you can just keep adding UNIONs to get the additional results for the Product2 tables (which really smells like the database needs to be normalized).
For the first two results the EXCEPT keyword should work. I don't work with SQL Express, so I'm not sure if it's available in that version of SQL Server, but check it out. Your code would look like:
(
SELECT C.Company
FROM Customers C
INNER JOIN Product1Accounts PA ON PA.Account = C.Company
UNION
SELECT C.Company
FROM Customers C
INNER JOIN Product1Domains PD ON PD.Domain = C.Email_Address_Domain
)
EXCEPT
(
SELECT C.Company
FROM Customers C
INNER JOIN Product2Accounts PA ON PA.Account = C.Company
UNION
SELECT C.Company
FROM Customers C
INNER JOIN Product2Domains PD ON PD.Domain = C.Email_Address_Domain
)
I think your database structure is not correct, you are having 2 different tables for the 2 products. Does it mean that if in future you have 5 more products, you will have 5 more tables?
I think its better to remove the product1 and product2 tables and create one product table, then you can have another table that can be called productType which have the information about the type of the product and with a Foreign Key its connected to your main product Table
Also does any of your product tables have a Foreign Key available in your customers table? from what I can see they name of the columns you are trying to do the join on are not really clear to be a foreign key.

How do I retrieve records from two tables that use the same PK while singling out records with a specific PK entry?

I have two tables joined by a primary key (coupon ID -as you can see in the attached picture below).
In the coupon table I have all of the existing coupons .
In the customer coupon table I have coupon id's that have been purchased by the customer id next to it.
Only coupons that have been purchased appear in the customer coupon table.
I would like to send a query in which I can retrieve all the coupons that have not been purchased by a certain customer ID.
the retrieved records can be coupons that have been purchased by other customer id's or new coupons which don't appear in the customer coupon table.
I'm currently using a derby DB which supports the following:
INNER JOIN
LEFT OUTER JOIN
RIGHT OUTER JOIN
The most straight forward approach, IMHO, would be to use the not exists operator:
SELECT *
FROM coupon c
WHERE NOTE EXISTS (SELECT *
FROM customer_coupon cc
WHERE c.id = cc.coupon_id AND
cc.customer_id = 123 /* Just an example */)

find the record that holds the foreign key

Let's say I have two tables, Product and Sale, Sale holds a foreign key to Product, so it's a one-to-many relationship with Product as one and Sale as many. How to write sql to get the Product of a Sale?
JOIN the two tables:
SELECT
*
FROM Product AS p
INNER JOIN Sale AS s ON s.ProductId = p.ProductId
WHERE s.SaleId = ...
Then you can specify a WHERE clause to filter on the Sale table, and SELECT whatever columns you want to select from the two tables.
You probably might need to have a look at the different types of JOINs:
A Visual Explanation of SQL Joins.

Ensure in many-to-many relationship at least one relationship is primary

Sorry for the bad title, if you can think of a better one, let me know.
Many-to-many relationship using tables.
Product
ProductCategory
Category
In the ProductCategory table i have boolean column primarycategory
Each product must have a primary category.
I want to find all products in my database which don't have a primarycategory.
Note: I have assumed field names in tables other than the one you specified.
This should return a distinct list of product IDs that have no primary category. Bit fields in SQL server are numeric, so you can give them to the max() function.
select
pc.product
from
ProductCategory pc
group by
pc.product
having
max(pc.primarycategory) = 0
The above query assumes that all products have at least one category. If not, try the following:
select
pc.product
from
Product p
left join
ProductCategory pc on p.id = pc.product
group by
pc.product
having
max(isnull(pc.primarycategory, 0)) = 0
Assuming true = value 1, try this:
Select Product From Product p
Where Not Exists (Select * From ProductCategory
Where Product = p.Product
And primarycategory = 1 )
but if you have control over this database, Move the PrimaryCategory column to the Products table, (and populate it with the category identifier itself, not a boolean), that is where this belongs in a properly normalized schema...