Using nested query instead of Join method - sql

I have 3 tables.
Car (PK: CarNo)
sales (FK:CarNo)
purchase (FK:CarNo)
A system like a car showroom. Cars are bought from customers and these cars are sold to customers. I want the SQL query that finds the cars whose sale price is less than the purchase price.
I created the following query using inner join, but I don't want to use join. How can I do it using nested query?
select DISTINCT * from car
left join sale on car.carNo=sale.carNo
left join purchase on sale.carNo=purchase.carNo
where sale.salePrice<purchase.purchasePrice;

Assuming a car can be sold or purchased only once, what you have is fine, though you shouldn't use DISTINCT and those should be inner joins.
select car.*
from car,
join sale on car.carNo = sale.CarNo
join purchase on sale.carNo = purchase.charNo
where sale.salePrice < purchase.purchasePrice
if you really wanted to use subqueries:
select car.*
from car
where (SELECT MAX(sale.salePrice)
FROM sale
WHERE sale.CarNo = car.CarNo) <
(SELECT MAX(purchase.purchasePrice)
FROM purchase
WHERE purchase.CarNo = car.CarNo)
Of course, if a car can be sold or purchased more than once, than you will need more than just CarNo, you'll need some date logic of some kind to make sure you are comparing the right sale with the right purchase.

Related

How can I find all monitor purchases (not with monitor ID value, instead should use the term 'Monitor')

I have two tables,
I need to find all monitor purchases (but not with monitor ID, instead I should use 'Monitor'). I have made code, but it takes the quantity for all products, not only for 'Monitor'.
The code I made:
select name, Price,sum(quantity)
from Products, Orders
where name='Monitor'
How can I fix this problem?
You need to link the rows of both tables. Right now you are creating the cartesian product, containing every row from the first table combined with every row from the second table. With your screenshot, that's going to be 9 rows in total.
SELECT name, Price, SUM(quantity)
FROM Products, Orders
WHERE name='Monitor'
AND Products.ProductId = Orders.ProductId
Or use JOIN directly to separate the filter condition from the join condition:
SELECT name, Price, SUM(quantity)
FROM Products
INNER JOIN Orders
ON Products.ProductId = Orders.ProductId
WHERE Products.name='Monitor'

Find item name along with the seller id and buyer id such that the seller has sold the item to the buyer

Hi IM trying to build a query for the following sentence for sql.
For each seller and each item sold by the seller, find the total amount sold.
I have 3 tables but not sure If i have to use them all. I have a feeling I need to use at least three tables to get this query but I keep getting an error. Also, I keep getting an error when I try to the following:
select selleruserid, itemid, sum(price) total
from sales_fact s
join items_dim i on i.itemid = s.itemid
join sellers_dim d on d.userid = s.selleruserid
group by selleruserid, itemid
I added a picture below of my tables.
All the information you want is in the fact table, so the other tables do not seem necessary:
select sf.selleruserid, sf.itemid, sum(sf.price) as total
from sales_fact s
group by sf.selleruserid, sf.itemid;
You would need to join in the other tables if you needed other information from the dimension, such as the name.

Multiple records joined Access SQL

I'm not sure if what I want to do is possible but if it is possible, it's probably a really easy solution that I just can't figure out. Once things get to a certain complexity though, my head starts spinning. Please forgive my ignorance.
I have a database running in MS Access 2007 for a school which has a plethora of tables joined to each other. I'm trying to create a query in which I get information from several tables. I'm looking up sales and payment information for different customers, pulling info from several different linked tables. Each sale is broken down into one of 4 categories, Course Fee, Registration Fee, Book Fee and Others. Because each customer will have multiple purchases, each one is a separate entry in the Sales table. The payment information is also in its own table.
My SQL currently looks like this:
SELECT StudentContracts.CustomerID, (Customers.CFirstName & " " & Customers.CLastName) AS Name, Customers.Nationality, Courses.CourseTitle, (StudentContracts.ClassesBought + StudentContracts.GiftClasses) AS Weeks, StudentContracts.StartDate, Sales.SaleAmount, SaleType.SaleType, Sales.DueDate, Payments.PaymentAmount
FROM (
(
(Customers INNER JOIN StudentContracts ON Customers.CustomerID = StudentContracts.CustomerID)
INNER JOIN Payments ON Customers.CustomerID = Payments.CustomerID)
INNER JOIN
(SaleType INNER JOIN Sales ON SaleType.SalesForID = Sales.SalesForID)
ON Customers.CustomerID = Sales.CustomerID)
INNER JOIN
(
(Courses INNER JOIN Classes ON Courses.CourseID = Classes.CourseID)
INNER JOIN StudentsClasses ON Classes.ClassID = StudentsClasses.ClassID)
ON Customers.CustomerID = StudentsClasses.CustomerID;
This works and brings up the information I need. However, I am getting one record for each sale as in:
CustomerID Name ... SaleAmount SaleType PaymentAmount
1 Bob $600 Course $1000
1 Bob $300 RgnFee $1000
1 Bob $100 Book $1000
What I need is one line for each customer but each sale type in it's own column in the row with the sale amount listed in its value field. As so:
CustomerID Name ... Course RgnFee Book Others PaymentAmount
1 Bob $600 $300 $100 $1000
Can anyone help and possibly explain what I should/need to be doing?
Thanks in advance!
You can create a cross tab from the query you have already created. Add the query to the Query Design Grid, choose Crosstab from query types, and select a Row or rows, Column and Value.
Say:
TRANSFORM Sum(t.SaleAmount) AS SumOfSaleAmount
SELECT t.ID, t.Name, Sum(t.SaleAmount) AS Total
FROM TableQuery t
GROUP BY t.ID, t.Name
PIVOT t.SaleType
If you want a certain order, you can edit the property sheet to include column headings, or you can add an In statement to the SQL. Note that if you add column headings, a column will be included for each column, whether or not data is available, and more importantly, a column will not be included that has data, if it is not listed.
TRANSFORM Sum(t.SaleAmount) AS SumOfSaleAmount
SELECT t.ID, t.Name, Sum(t.SaleAmount) AS Total
FROM TableQuery t
GROUP BY t.ID, t.Name
PIVOT t.SaleType In ("Course","RgnFee","Book","Others");

SQL Syntax for Complex Scenario (Deals)

i have a complex query to be written but cannot figure it out
here are my tables
Sales --one row for each sale made in the system
SaleProducts --one row for each line in the invoice (similar to OrderDetails in NW)
Deals --a list of possible deals/offers that a sale may be entitled to
DealProducts --a list of quantities of products that must be purchased in order to get a deal
now im trying to make a query which will tell me for each sale which deals he may get
the relevant fields are:
Sales: SaleID (PK)
SaleProducts: SaleID (FK), ProductID (FK)
Deals: DealID (PK)
DealProducts: DealID(FK), ProductID(FK), Mandatories (int) for required qty
i believe that i should be able to use some sort of cross join or outer join, but it aint working
here is one sample (of about 30 things i tried)
SELECT DealProducts.DealID, DealProducts.ProductID, DealProducts.Mandatories,
viwSaleProductCount.SaleID, viwSaleProductCount.ProductCount
FROM DealProducts
LEFT OUTER JOIN viwSaleProductCount
ON DealProducts.ProductID = viwSaleProductCount.ProductID
GROUP BY DealProducts.DealID, DealProducts.ProductID, DealProducts.Mandatories,
viwSaleProductCount.SaleID, viwSaleProductCount.ProductCount
The problem is that it doesn't show any product deals that are not fulfilled (probably because of the ProductID join). i need that also sales that don't have the requirements show up, then I can filter out any SaleID that exists in this query where AmountBought < Mandatories etc
Thank you for your help
I'm not sure how well I follow your question (where does viwSaleProductCount fit in?) but it sounds like you will want an outer join to a subquery that returns a list of deals along with their associated products. I think it would go something like this:
Select *
From Sales s Inner Join SaleProducts sp on s.SaleID = sp.SaleID
Left Join (
Select *
From Deals d Inner Join DealProducts dp on d.DealID = dp.DealId
) as sub on sp.ProductID = sub.ProductID
You may need to add logic to ensure that deals don't appear twice, and of course replace * with the specific column names you'd need in all cases.
edit: if you don't actually need any information from the sale or deal tables, something like this could be used:
Select sp.SaleID, sp.ProductID, sp.ProductCount, dp.DealID, dp.Mandatories
From SaleProducts sp
Left Join DealProducts as dp on sp.ProductID = dp.ProductID
If you need to do grouping/aggregation on this result you will need to be careful to ensure that deals aren't counted multiple times for a given sale (Count Distinct may be appropriate, depending on your grouping). Because it is a Left Join, you don't need to worry about excluding sales that don't have a match in DealProducts.

Creating an SQL query to list all clients, who spent over 1000$

So, I have three tables with the following rows: Customers (Customer_id and Name), Orders (Customer_id, Product_id, Quantity) and Products (Price).
How do I write a query which shows all customers who spent more than 1000$? Do I have to join the tables?
Because this is homework, I'm not going to give you the answer, just information on how to arrive at the answer.
You need to include the customers table, because that's what your looking for, customers. You'll need to join in aggregate with the orders table, so you can find out how many of each product they've ordered, and you'll need to join with the products table to find the prices of all those items in order to total them up to determine if they've spent more than $1000.
Go to it. Tell us how you get on.
SELECT * FROM customer c JOIN (
SELECT a.customer_id,SUM(a.quantity*b.price) spent FROM orders a
JOIN products b ON b.product_id=a.product_id GROUP BY a.customer_id
) d ON d.customer_id=c.customer_id WHERE d.spent>1000