2 tables
Product(maker, model)
PC(model, ..., price)
model is a foreign key between Product and PC
I need to select all rows in Product that have the same maker and average their price.
Therefore with these tables:
Product PC
------- -------
A 1 1 60
A 2 2 80
B 3 3 110
B 4 4 140
I should get:
maker avg(price)
---------------------
A 70
B 125
I have tried this, but have no idea how to combine the rows and average just those that get combined. This displays the average across the entire PC table for all maker.
select
Product.maker, Product.model, avg(PC.price)
from
Product, PC
group by
Product.maker, Product.model
order by
maker asc;
Don't use the old legacy implicit join syntax any more. Use explicit joins
select Product.maker, avg(PC.price)
from Product
left join PC on PC.model = Product.model
group by Product.maker
order by Product.maker asc
Related
I have 2 tables as show below.
Table1
Order ID
Item_code
Sales_Price
Qty_ordered
Total
Qty shipped
1000
111
10
5
$50
1
1000
222
20
10
$200
2
1000
333
30
15
$450
0
I have another table that stores only the details of how much was invoiced (i.e. how much we shipped)
Table2 (because we shipped only 10x1 and 20x2 = $50)
Order ID
Invoice_total
1000
$50
I wrote the following query,
select T1.Order_ID,
sum(T1.Qty_Ordered) as Qty_Ordered,
sum(T1.Total) as Total_Amt_ordered,
sum(T1.Qty_shipped) as Qty_Shipped,
sum(T2.Invoice_total)
from T1 join
T2 on T1.Order_ID = T2.Order_ID
This query gives me the following output, (It is adding $50 to all the rows of T1 Orders).
Order ID
Qty_ordered
Total
Qty shipped
Invoice_total
1000
30
$700
3
$150
Whereas now, I want my output to be as:
Order ID
Qty_ordered
Total
Qty shipped
Invoice_total
1000
30
$700
3
$50
(because we shipped only $50)
What changes should I make to my query?
I know I can just hard code it but my database has 1000's of orders and 1000's of Half shipped Orders. I want to keep track of Shipped $ (Invoiced $) for all the orders.
If I understand correctly, you want:
select T2.Order_ID, T2.Invoice_total,
sum(T1.Qty_Ordered) as Qty_Ordered,
sum(T1.Total) as Total_Amt_ordered,
sum(T1.Qty_shipped) as Qty_Shipped,
from T2 join
T1
on T1.Order_ID = T2.Order_ID
group by T2.Order_ID, T2.Invoice_total;
That is, you don't want to aggregate Invoice_total. You just want it to be a group by key.
I have two table "tbl_In_Details" and "tbl_Out_Details"
Sample data for tbl_In_Details
ID Item_Name Rate Quantity Source_company
1 wire 10 4 2020-04-21 22:47:29.083
2 Tea 4 20 2020-04-21 22:47:52.823
Sample data for tbl_Out_Details
ID Item_Name Quantity Created_Date
1 wire 1 2020-04-21 22:48:48.233
2 wire 2 2020-04-21 22:50:16.367
3 Tea 2 2020-04-21 23:48:39.943
Now i want to calculate SUM of price and price (RATE*QUANTITY) from out going table
i tried in such a way but not getting result
select o.Item_Name, SUM(o.quantity) as Total_quantity ,SUM(o.quantity * i.Rate) as Expenses
from tbl_In_Details i inner join tbl_Out_Details o
ON i.Item_Name = o.Item_Name group by o.Item_Name,o.quantity, i.Rate
My Output should be
Item_Name Total_quantity Expenses
Tea 2 8
wire 3 30
Your query is completely fine. The only thing you need to get the desired result is to delete grouping by 'quantity' and 'rate'.
select o.Item_Name, SUM(o.quantity) as Total_quantity ,SUM(o.quantity * i.Rate) as Expenses
from tbl_In_Details i inner join tbl_Out_Details o
ON i.Item_Name = o.Item_Name group by o.Item_Name;
One method uses union all and group by:
Aggregate before joining:
select i.item_name, o.quantity, i.expenses
from (select id, item_name, sum(rate*quantity) as expenses
from tbl_In_Details
group by id, item_name
) i join
(select id, item_name, sum(quantity) as quantity
from tbl_Out_Details
group by id, item_name
) o
on i.id = o.id
I am not sure why my brain can't process this right now but it seems like this would be an easy query to write.
I have 2 tables:
- Orders
(pk)orderID
customername
orderDate
- OrderDetails
(pk)detailsID
orderID
productName
So when a new order is placed, one row gets added to Orders with customer info and in the orderDetails table a row gets added for each product ordered.
So picture these 2 layouts:
ORDERS
orderID customerName orderDate
1 John Smith 2/21/2020
2 Bill Adams 2/21/2020
3 Susan Conrad 2/21/2020
4 Amy Fetcher 2/21/2020
ORDERDETAILS
detailsID orderID productName
1 1 pillow
2 1 mattress
3 2 pillow
4 3 sheets
5 3 headboard
6 3 mattress
7 4 pillow
8 4 framed art
9 4 decals
10 4 plant stand
In my query, I want to select all from orders where the date = today. I am joining the ORDERDETAILS table because I want to know anytime I sold a pillow in my results.
I only want 1 row per order to be displayed in the results so in orderID 1 for example, they ordered a pillow and mattress. In the results under productName for that row, I want it to display pillow.
If someone didn't order a pillow, I still need the row to show for their order today and under productName I dont care what it shows if it's not a pillow. It can show nothing or one of the other product names they ordered.
I know this doesn't work:
SELECT ORDERS.*, ORDERDETAILS.*
FROM ORDERS INNER JOIN ORDERDETAILS ON ORDERS.orderID = ORDERDETAILS.orderID
WHERE productName = "pillow"
I am not sure if I need subqueries or some sort of outer left join maybe both?
Any help is much appreciated, thank you!
You can do it this way
select detailsID, a.orderID, productName, customerName, orderDate from
(
select detailsID, orderID, productName from ORDERDETAILS where productName = 'pillow'
union
select detailsID, orderID, productName from
(
select detailsID, orderID, productName, rank()over(partition by orderID order by detailsID) as _Rank from ORDERDETAILS
)a where _Rank = 1
and orderID not in (select orderID from ORDERDETAILS where productName = 'pillow')
) a
inner join Orders b on a.orderID = b.orderID
Output:
detailsID orderID productName customerName orderDate
1 1 pillow John Smith 2/21/2020
3 2 pillow Bill Adams 2/21/2020
4 3 sheets Susan Conrad 2/21/2020
7 4 pillow Amy Fetcher 2/21/2020
Since you're only interested in some order details, but all headers, you want a LEFT JOIN. And since you only want to filter the results from ORDERDETAILS, you'll want your filtering criteria in the JOIN, rather than in a WHERE clause that also applies to the ORDERS table.
SELECT ORDERS.*, ORDERDETAILS.*
FROM
ORDERS
LEFT JOIN ORDERDETAILS
ON ORDERS.orderID = ORDERDETAILS.orderID
AND productName = "pillow"
That should get you most of the way there. If there's a possibility of more than one detail record per order that includes pillow, then you'll want to use a sub-query against the details table to skinny it down further to just the information you're interested in. And at that point, I'd move the filter into the sub-query.
I'm trying to do a INNER JOIN and count values with information from two tables. The problem is that the product category table have multiple rows with the same or similar value and my COUNT() is to high as a result.
My two tables
Sales table
Date prod_id
2016-01-01 81
2016-01-01 82
2016-01-01 81
2016-10-01 80
2016-01-01 80
2016-01-02 80
2016-01-02 80
2016-01-02 81
2016-01-02 81
.... ....
Product table
prodid Name
80 Banana
81 Apple
82 Orange
83 Ice Cream
80 BANANAS
81 APPLE
82
83 Ice Cream
.... ....
When I do an INNER JOIN and count the number of occurrences of e.g. prod_id I get an unreasonable high number, and my guess is that it's because there are more than one occurrence of prod_id 80 for example.
Do you have any idea for a solution? My first reaction was to redo the Procuct table, but there are many other systems depending on that table so I can't change it a foreseeable future.
My query so far:
SELECT
pt.Date AS "Date",
ft.Name AS "Product",
COUNT(ft.Name) Number
FROM SALES as pt
INNER JOIN PROD_TABLE AS ft ON pt.prod_id=ft.prodid
WHERE pt.Date BETWEEN '2016-01-01' AND '2016-01-30'
GROUP BY pt.Date, ft.Name
ORDER BY pt.Date DESC
Expected result:
Date Product Number
2016-01-01 Banana 2
2016-01-01 Apple 2
2016-01-01 Orange 1
First, you should fix the data. Having a product table with duplicates seems non-sensical. You shouldn't try to get around such issues by writing more complex queries.
That said, this is pretty easy to do in SQL Server. I think outer apply is appropriate:
select p.name, count(*)
from sales s outer apply (
(select top 1 p.*
from product p
where p.name is not null and
p.prodid = s.prod_id -- note: the columns should have the same name
) p;
I guess this simple query solves your requirement:
select
date,
name,
count(name)
from product p inner join sales s
on s.prod_id=p.prodid group by date,name
I'm having some difficulty with a query that I'm writing that is meant to display the "makers" that produce laptops with 3 or more DIFFERENT speeds.
SELECT DISTINCT Product.maker, Count(Laptop.speed) AS [3+ Different Speeds]
FROM Laptop INNER JOIN Product ON Laptop.model = Product.model
WHERE type = "laptop"
GROUP BY Product.maker
HAVING Count(*) >= 3;
This gives me the 2 correct "makers" that produce 3 or more laptop models, however, one "maker", A, produces two laptop models with the SAME speed, so that "maker" needs to be eliminated from the resulting table, which is below.
maker 3+ Different Speeds
A 3
E 3
Here's the Laptop table where the model and speed data is stored:
model speed
2001 2.00 E
2002 1.73 E
2003 1.80 E
2004 2.00 A
2005 2.16 A
2006 2.00 A
E produces the top 3, and A produces the bottom 3. I'm fairly certain that I need to make my Count function DISTINCT, however, I know that Access does not support DISTINCT Count. Any assistance/suggestions would be greatly appreciated!
The below query should solve your problem.
SELECT
maker,
COUNT(speed)
FROM(
SELECT
p.maker,
l.speed
FROM
Laptop l
INNER JOIN Product p
ON l.model = p.model
WHERE
type = "laptop"
GROUP BY 1,2
) foo
GROUP BY 1
HAVING COUNT(1) >= 3
First you aggregate all speeds for the same maker, so the inner query would produce:
maker | speed | count
-------+-------+-------
E | 1.73 | 1
E | 1.80 | 1
A | 2.16 | 1
E | 2.00 | 1
A | 2.00 | 2
Now you have distinct rows for each pair (maker, speed) so that you can simply run a COUNT() over speed.
Result
maker | count
-------+-------
E | 3
A | 2
Now eliminate A with HAVING clause.
Your query will work fine if you take out the distinct keyword. If you only group by the maker, then that query will bring you back only one record per maker, the distinct is actually redundant.
This is the WORKING query that I came up with, a slightly modified version of what you provided me with.
SELECT P.maker AS [Maker], Count(L.speed) AS [3+ Different Speeds]
FROM (SELECT P.maker, L.speed FROM Laptop AS L INNER JOIN Product AS P ON L.model = P.model
WHERE type = "laptop"
GROUP BY P.maker, L.speed)
GROUP BY [Maker]
HAVING Count(L.speed) >= 3;
Thanks again!