SQL Query with count, sum and group by - sql

Quick question if anyone has time to answer. The current query works great, but I need to also get a total count of the orders and the total shipping. I know the numbers are getting thrown off because of the joins.
I know that my count and sum will be:
count(DISTINCT orders.id) AS num_orders,
SUM(orders.shipping_cost_ex_tax) AS shipping
I think I need to use the count and sum in the original select and handle the rest in the join, but for the life of me I can't get this right.
Any help would be appreciated, even if it's "run a separate query". Thanks everyone.
Current query:
SELECT
IF(products.categories LIKE '68', 'Shirts', 'Books') AS group_key,
CONCAT(order_products.name) AS product_name,
brands.name AS author,
SUM(order_products.quantity) AS num_units,
CASE WHEN products.sku LIKE '%-WB' THEN 'Combo'
WHEN products.sku LIKE '%-BO' THEN 'Box'
ELSE ''
END AS item_type,
SUM(IF(order_products.discount IS NULL, order_products.price_ex_tax, (order_products.price_ex_tax - order_products.discount))) AS income
FROM orders
INNER JOIN order_products ON order_products.bc_order_id = orders.bc_id
INNER JOIN products ON order_products.bc_product_id = products.bc_id
INNER JOIN brands ON products.brand_id = brands.bc_id
WHERE (orders.created_at BETWEEN '2012-01-28 00:00:00' and '2012-02-21 23:00:00')
GROUP BY group_key,
case when products.brand_id = '68'
then products.name
else products.sku
end

Looking at the comment provided and not having your full schema in front of me. Would something like this work:
Table Report
(
id,
countOrders,
countSales,
countShipping,
countTax,
datePublished
)
Table SoldProducts
(
id,
price,
tax,
shippingPrice,
datePurchased
)
So what you would do in this instance is generate a report by querying from SoldProducts then you would persist the report that was generated.

Related

SQL Server : create a view with Union with data from first query

My SQL is quite rusty, so much that I have not created a view before and I am not entirely sure how to do what I need. Perhaps I need a stored procedure. Here is the deal.
We have a a database of ticket history (purchases). We want to filter on a certain SKU, but we want all line items from each ticket that has that SKU. For isntance, Someone buys a shirt and a hat. I want to filter on the shirt to find everyone who wants a shirt but display the entire ticket showing the shirt and the hat.
I thought my query would be something like this but I don't think it would work.
select
ticket_id, post_date, qty_sold, total_price, sales_total
from
ticket_history
where
sku = 'xxxx'
Union
select
sku as trans_sku, qty_sold as trans_qty_sold, desc as trans_desc, total_price as trans_total_price
from
ticket_history
where
ticket_id = <the ticket id in first query>
Perhaps a sub-select is what is needed but I'm not too understanding of how to do that either.
Any suggestions would be great.
I am not sure what you are trying to do here and whether UNION is what you are looking for or not.
In your query the columns are different and doesn't matched between the two queries. Any way, you can use a Common table Expression so that you can reuse the subquery, this should solve your problem:
WITH FirstQuery
AS
(
select
ticket_id,
post_date,
qty_sold,
total_price,
sales_total
from ticket_history
where sku = 'xxxx'
)
SELECT *
FROM FirstQuery
UNION
SELECT
... -- You should select the same number of columns
... -- and with the same data types to match the first columns
from ticket_history
where ticket_id IN(SELECT ticket_id FROM FirstQuery);
Here the FirstQuery acts like a subquery, but here you can reuse it later like what we did and use it in the where clause.
But, again the columns you selected in the first query:
ticket_id,
post_date,
qty_sold,
total_price,
sales_total
are different than the columns you selected in the second query:
sku as trans_sku,
qty_sold as trans_qty_sold,
desc as trans_desc,
total_price as trans_total_price
These columns should be matched (the count of them and data types). Otherwise you will got an error.
Things to note about UNION:
the columns count should be the same between the two queries.
The columns' names are driven from the first query.
When doing a UNION, the selected columns must match between the two select's. (Same number of columns, and matching data types.)
Maybe you want a self join instead?
select th1.ticket_id, th1.post_date, th1.qty_sold, th1.total_price, th1.sales_total,
th2.sku as trans_sku, th2.qty_sold as trans_qty_sold,
th2.desc as trans_desc, th2.total_price as trans_total_price
from ticket_history th1
left join ticket_history th2 on th2.ticket_id = th1.ticket_id
where th1.sku = 'xxxx'
LEFT JOIN to get th1 rows even if there are no matching th2 row.

MS Access Error: 'At most one record can be returned by this subquery'

am try to connect 3 tables but am getting error At most one record can be returned by this subquery
My code is
SELECT InvoiceNumber,
Terms(SELECT PaymentTerms
FROM PSD_customerPaymentTerms
WHERE PSD_customerPaymentTerms.PTId = NewInvoice_1.Terms
) AS Terms,
InvoiceDate,
OurQuote,
SalesPerson(SELECT FirstName
FROM Employee
WHERE Employee.EmployeeId = NewInvoice_1.SalesPerson
) AS SalesPerson,
CustomerName(SELECT CustomerName
FROM Customer
WHERE Customer.CustomerId = NewInvoice_1.CustomerName
) AS CustomerName,
OrderNumber,
GrandTotal,
(SELECT SUM(PaymentAmount)
FROM Payment_Receipt
WHERE Payment_Receipt.InvoiceNumber=NewInvoice_1.InvoiceNumber
) AS AmountPaid,
GrandTotal-IIf(AmountPaid Is Null,0,AmountPaid) AS AmountDue,
(SELECT InvoiceStatus
FROM Payment_Receipt
WHERE Payment_Receipt.InvoiceNumber=NewInvoice_1.InvoiceNumber
) AS Status -- Error getting after adding this line.
FROM NewInvoice_1;
Payment_Receipt Table contain Id, Invoice No, Customer name, Total Paid, Balance Amount, Payment Date, Payment Amount, Payment Type,Payment Remarks, InvoiceStatus.
This is my table
How to get InvoiceStatus from this table ??
One general way to solve this problem is to force the subquery to return one row by using max() on the column:
select max(someColumn)
from someTable
where ...
In case your data has multiple rows for the where clause.
While this approach will get your query working, it may not give the results you want. More likely the where clause needs work. That said, it can be very useful when diagnosing the problem, especially if you aren't sure which subquery is causing the problem you can remove the change one subquery at a time.

microsoft access query grand total

I have a microsoft access query which is working fine and giving the required result but i want to add a grand total row at the bottom
my query is
SELECT Product.Description
, Count(Product.PID) AS CountOfPID
, Sum(SalesOrderProduct.NbrItemsDispatched) AS SumOfNbrItemsDispatched
, Sum(SalesOrderProduct.ExtendedPrice)
FROM Product
LEFT JOIN
(
SalesOrder
RIGHT JOIN SalesOrderProduct
ON SalesOrder.SOID = SalesOrderProduct.SOID
)
ON Product.PID = SalesOrderProduct.PID
GROUP BY Product.Description, SalesOrder.Status
HAVING SalesOrder.Status <> 'Open' or SalesOrder.Status is null;
and also where there is no data then 0 must be displayed and $ sign should not be displayed
I strongly suggest that you do not do this. There have been several questions recently where it ended in a problem. The grand total is a display issue and belongs in another query or in a report.
If you still feel the need to do this, you can use a UNION in your query.
A union query might look like:
SELECT 0 As srt, AText, Count(ID) FROM Table1
GROUP BY Srt, AText
UNION
SELECT 1 As Srt, "Total" As AText ,Count(ID) FROM Table1

SQL: Using UNION

Here is the question and database info.
Use the UNION command to prepare a full statement for customer 'C001' - it should be laid out as follows. (Note that the values shown below are not correct.) You may be able to use '' or NULL for blank values - if necessary use 0.
Here is a link to the webpage with the database info. http://sqlzoo.net/5_0.htm or see the image below.
Here is what I have tried:
SELECT sdate AS LineDate, "delivery" AS LEGEND, price*quantity AS Total,"" AS Amount
FROM shipped
JOIN product ON (shipped.product=product.id)
WHERE badguy='C001'
UNION
SELECT rdate,notes, "",receipt.amount
FROM receipt
WHERE badguy='C001'
Here is what I get back:
Wrong Answer. The correct answer has 5 row(s).
The amounts don't seem right in the amount column and I can't figure out how to order the data by the date since it is using two different date columns (sdate and rdate which are UNIONED).
Looks like the data in the example is being aggregated by date and charge type using group by, that's why you are getting too many rows.
Also, you can sort by the alias of the column (LineDate) and the order by clause will apply to all the rows in the union.
SELECT sdate AS LineDate, "delivery" AS LEGEND, SUM(price*quantity) AS Total,"" AS Amount
FROM shipped
JOIN product ON (shipped.product=product.id)
WHERE badguy='C001'
GROUP BY sdate
UNION
SELECT rdate, notes, "",receipt.amount
FROM receipt
WHERE badguy='C001'
ORDER BY LineDate
It's usually easiest to develop each part of the union separately. Pay attention to the use of "null" to separate the monetary columns. The first select gets to name the columns.
select s.sdate as tr_date, 'Delivery' as type, sum((s.quantity * p.price)) as extended_price, null as amount
from shipped s
inner join product p on p.id = s.product
where badguy = 'C001'
group by s.sdate
union all
select rdate, notes, null, sum(amount)
from receipt
where badguy = 'C001'
group by rdate, notes
order by tr_date

sql select sum off of two where clauses

SELECT Projects.Projectid, Projects.ProjectNumber, Projects.ProjectName,
Projects.ProjectBudgetedIS, Projects.ProjectSpentIS,
Projects.ProjectBudgetedBusiness, Projects.PorjectSpentBusiness, Project.Status,
ProjectStatus.Status AS Expr1
FROM Projects
INNER JOIN ProjectStatus ON Projects.Status = ProjectStatus.StatusID
WHERE Projects.Status = #Status
So what I want to do is take the sum of a table called invoices which has a field called ISorBusiness and a field called totalspent and store that data into the projects tabel in the appropriate field. So that when I get an invoice that is charged to the IS it takes that amount and rolls it into the Projects.ProjectSpentIS and if I get a invoice that is to the business it rolls it into the Projects.ProjectBudgetedBusiness.
I know this should be easy and sorry for the noobish question. Thanks in advance!
I would do something like:
SELECT SUM(CASE WHEN (IsOrBusiness = 'IS') THEN totalSpent ELSE 0 END) AS IsSpent,
SUM(CASE WHEN (IsOrBusiness = 'Business') THEN totalSpent ELSE 0 END) AS BusinessSpent
FROM Invoices
Obviously the usage depends on whether you are trying to write an insert query or select this data as part of the select query you have posted.