Sql Subquery Syntax - sql

I want to execute a subquery using the current customer ID as I try to describe below
SELECT DISTINCT Customer_Id,
(SELECT SUM (total) FROM Orders where Customer_Id = Customer_Id AND CAST(Date) > DayIspecify )
FROM Orders where shop_id= '1-9THT'
What I want is to calculate the SUM each customer spent over a specified time period on the specific shop.

SELECT Customer_Id, SUM(total) SumTotal
FROM Orders
where shop_id= '1-9THT'
group by Customer_id

Not require subquery
Try this:
SELECT Customer_Id,SUM(total)FROM Orders WHERE shop_id='1-9THT' GROUP BY Customer_Id

(Updated) Try:
select Customer_Id,
sum(case when o.shop_id = '1-9THT' and Date > DayIspecify
then total else 0 end) total
from Orders
group by Customer_Id
- to return all customers recorded on the Orders table, together with the values of any of their orders placed through shop 1-9THT after the date specified. (Change > to >= to make it on or after the date specified.)

Use SQL GroupBy
SELECT DISTINCT Customer_Id, SUM (total) FROM Orders where shop_id= '1-9THT' group by customer_Id

Related

SQL: Difference between consecutive rows

Table with 3 columns: order id, member id, order date
Need to pull the distribution of orders broken down by No. of days b/w 2 consecutive orders by member id
What I have is this:
SELECT
a1.member_id,
count(distinct a1.order_id) as num_orders,
a1.order_date,
DATEDIFF(DAY, a1.order_date, a2.order_date) as days_since_last_order
from orders as a1
inner join orders as a2
on a2.member_id = a1.member_id+1;
It's not helping me completely as the output I need is:
You can use lag() to get the date of the previous order by the same customer:
select o.*,
datediff(
order_date,
lag(order_date) over(partition by member_id order by order_date, order_id)
) days_diff
from orders o
When there are two rows for the same date, the smallest order_id is considered first. Also note that I fixed your datediff() syntax: in Hive, the function just takes two dates, and no unit.
I just don't get the logic you want to compute num_orders.
May be something like this:
SELECT
a1.member_id,
count(distinct a1.order_id) as num_orders,
a1.order_date,
DATEDIFF(DAY, a1.order_date, a2.order_date) as days_since_last_order
from orders as a1
inner join orders as a2
on a2.member_id = a1.member_id
where not exists (
select intermediate_order
from orders as intermedite_order
where intermediate_order.order_date < a1.order_date and intermediate_order.order_date > a2.order_date) ;

How to write a SQL query to find out customers who have purchased at least two times every month of the year

I have a table with columns order_id, customer_id, order_date and Amount.
How to find the customers who have ordered at least 2 times each month of the year in SQL (from Jan to Dec)?
I think you are looking for something like this
select
order_date_year,
customer_id
from
(
select
year(order_date) as order_date_year,
month(order_date) as order_date_month,
customer_id,
count(*) as number_of_orders
from
tableName
group by
year(order_date),
month(order_date),
customer_id
having
count(*) >= 2
) as t
group by
order_date_year,
customer_id
having
count(*) = 12

Grouping or Counting after a Sum

Using Oracle/SQL, I am looking for a way to count the number distinct IDs above or below a specified value following a sum. For example, I need to find how many customers have ordered $1,000 or more in goods last year, regardless of whether it was in one large order or several smaller orders. I don't need to identify each customer specifically, just find the total number of customers over this amount.
So far I am able to find the total of orders with:
select sum (Order_Amount), Customer_ID
from table.orders_placed
where year = 2013
group by Customer_ID
order by Customer_ID
I can also expand it doing this:
select count (dinstinct Customer_ID)
from(
select sum (Order_Amount), Customer_ID
from table.orders_placed
where year = 2013
group by Customer_ID
order by Customer_ID
)
but this just gives me the total number of distinct Customer_ID. Any other argument that I add to try to narrow what the "count" gives me results in an error. How can I specify that I want the total Order_Amount of $1,000 or more?
Try (no need to order by in inner query)
select count (dinstinct Customer_ID)
from(
select sum (Order_Amount) total_order_amount, Customer_ID
from table.orders_placed
where year = 2013
group by Customer_ID
) where total_order_amount > 1000
OR with Having
select sum (Order_Amount) total_order_amount, Customer_ID
from table.orders_placed
where year = 2013
group by Customer_ID
having sum(order_amount) > 1000
Use a HAVING clause to restrict the results of the grouping:
select sum (Order_Amount) as Total, Customer_ID
from table.orders_placed
where year = 2013
group by Customer_ID
having sum (Order_Amount) >= 1000
Then you can use this as a subquery to perform your aggregation and filtering.

T SQL select last sale of each customer

I'm trying to retrieve the last sale date for each customer as follows but it is just returning the last entry in the table:
Select top 1 InvoiceDate
,Customer
from salestable a
order by InvoiceDate desc
Help will be greatly appreciated.
Don't use TOP 1 - that's why you're returning only 1 result.
Try using MAX and GroupBy Customer
SELECT Customer, MAX(InvoiceDate)
FROM SalesTable
GROUP By Customer
ORDER By MAX(InvoiceDate) DESC

Can I limit the amount of rows to be used for a group in a GROUP BY statement

I'm having an odd problem
I have a table with the columns product_id, sales and day
Not all products have sales every day. I'd like to get the average number of sales that each product had in the last 10 days where it had sales
Usually I'd get the average like this
SELECT product_id, AVG(sales)
FROM table
GROUP BY product_id
Is there a way to limit the amount of rows to be taken into consideration for each product?
I'm afraid it's not possible but I wanted to check if someone has an idea
Update to clarify:
Product may be sold on days 1,3,5,10,15,17,20.
Since I don't want to get an the average of all days but only the average of the days where the product did actually get sold doing something like
SELECT product_id, AVG(sales)
FROM table
WHERE day > '01/01/2009'
GROUP BY product_id
won't work
If you want the last 10 calendar day since products had a sale:
SELECT product_id, AVG(sales)
FROM table t
JOIN (
SELECT product_id, MAX(sales_date) as max_sales_date
FROM table
GROUP BY product_id
) t_max ON t.product_id = t_max.product_id
AND DATEDIFF(day, t.sales_date, t_max.max_sales_date) < 10
GROUP BY product_id;
The date difference is SQL server specific, you'd have to replace it with your server syntax for date difference functions.
To get the last 10 days when the product had any sale:
SELECT product_id, AVG(sales)
FROM (
SELECT product_id, sales, DENSE_RANK() OVER
(PARTITION BY product_id ORDER BY sales_date DESC) AS rn
FROM Table
) As t_rn
WHERE rn <= 10
GROUP BY product_id;
This asumes sales_date is a date, not a datetime. You'd have to extract the date part if the field is datetime.
And finaly a windowing function free version:
SELECT product_id, AVG(sales)
FROM Table t
WHERE sales_date IN (
SELECT TOP(10) sales_date
FROM Table s
WHERE t.product_id = s.product_id
ORDER BY sales_date DESC)
GROUP BY product_id;
Again, sales_date is asumed to be date, not datetime. Use other limiting syntax if TOP is not suported by your server.
Give this a whirl. The sub-query selects the last ten days of a product where there was a sale, the outer query does the aggregation.
SELECT t1.product_id, SUM(t1.sales) / COUNT(t1.*)
FROM table t1
INNER JOIN (
SELECT TOP 10 day, Product_ID
FROM table t2
WHERE (t2.product_ID=t1.Product_ID)
ORDER BY DAY DESC
)
ON (t2.day=t1.day)
GROUP BY t1.product_id
BTW: This approach uses a correlated subquery, which may not be very performant, but it should work in theory.
I'm not sure if I get it right but If you'd like to get the average of sales for last 10 days for you products you can do as follows :
SELECT Product_Id,Sum(Sales)/Count(*) FROM (SELECT ProductId,Sales FROM Table WHERE SaleDAte>=#Date) table GROUP BY Product_id HAVING Count(*)>0
OR You can use AVG Aggregate function which is easier :
SELECT Product_Id,AVG(Sales) FROM (SELECT ProductId,Sales FROM Table WHERE SaleDAte>=#Date) table GROUP BY Product_id
Updated
Now I got what you meant ,As far as I know it is not possible to do this in one query.It could be possible if we could do something like this(Northwind database):
select a.CustomerId,count(a.OrderId)
from Orders a INNER JOIN(SELECT CustomerId,OrderDate FROM Orders Order By OrderDate) AS b ON a.CustomerId=b.CustomerId GROUP BY a.CustomerId Having count(a.OrderId)<10
but you can't use order by in subqueries unless you use TOP which is not suitable for this case.But maybe you can do it as follows:
SELECT PorductId,Sales INTO #temp FROM table Order By Day
select a.ProductId,Sum(a.Sales) /Count(a.Sales)
from table a INNER JOIN #temp AS b ON a.ProductId=b.ProductId GROUP BY a.ProductId Having count(a.Sales)<=10
If this is a table of sales transactions, then there should not be any rows in there for days on which there were no Sales. I.e., If ProductId 21 had no sales on 1 June, then this table should not have any rows with productId = 21 and day = '1 June'... Therefore you should not have to filter anything out - there should not be anything to filter out
Select ProductId, Avg(Sales) AvgSales
From Table
Group By ProductId
should work fine. So if it's not, then you have not explained the problem completely or accurately.
Also, in yr question, you show Avg(Sales) in the example SQL query but then in the text you mention "average number of sales that each product ... " Do you want the average sales amount, or the average count of sales transactions? And do you want this average by Product alone (i.e., one output value reported for each product) or do you want the average per product per day ?
If you want the average per product alone, for just thpse sales in the ten days prior to now? or the ten days prior to the date of the last sale for each product?
If the latter then
Select ProductId, Avg(Sales) AvgSales
From Table T
Where day > (Select Max(Day) - 10
From Table
Where ProductId = T.ProductID)
Group By ProductId
If you want the average per product alone, for just those sales in the ten days with sales prior to the date of the last sale for each product, then
Select ProductId, Avg(Sales) AvgSales
From Table T
Where (Select Count(Distinct day) From Table
Where ProductId = T.ProductID
And Day > T.Day) <= 10
Group By ProductId