Use where clause in count function - sql

I'm looking to create a table with 2 columns. 1 column contains the amount paid each month while the other column contains the number of customer who ordered that month and paid that month.
select sum(paid), count(distinct customer where Order_Month = Paid_Month)
from DataTable
group by Paid_Month
Is there an easy way of doing so?

Use a case expression:
select sum(paid),
count(distinct case when Order_Month = Paid_Month then customer end)
from DataTable
group by Paid_Month;

Related

Best approach to display all the users who have more than 1 purchases in a month in SQL

I have two tables in an Oracle Database, one of which is all the purchases done by all the customers over many years (purchase_logs). It has a unique purchase_id that is paired with a customer_id.The other table contains the user info of all the customers. Both have a common key of customer_id.
I want to display the user info of customers who have more than 1 unique item (NOT the item quantity) purchased in any month (i.e if A customer bought 4 unique items in february 2020 they would be valid as well as someone who bought 2 items in june). I was wondering what should my correct approach be and also how to correct execute that approach.
The two approaches that I can see are
Approach 1
Count the overall number of purchases done by all customers, filter the ones that are greater than 1 and then check if they any of them were done within a month.
Use this as a subquery in the where clause of the main query for retrieving the customer info for all the customer_id which match this condition.
This is what i've done so far,this retrieves the customer ids of all the customers who have more than 1 purchases in total. But I do not understand how to filter out all the purchases that did not occur in a single arbitrary month.
SELECT * FROM customer_details
WHERE customer_id IN (
SELECT cust_id from purchase_logs
group by cust_id
having count(*) >= 2);
Approach 2
Create a temporary table to Count the number of monthly purchases of a specific user_id then find the MAX() of the whole table and check if that MAX value is bigger than 1 or not. Then if it is provide it as true for the main query's where clause for the customer_info.
Approach 2 feels like the more logical option but I cannot seem to understand how to write the proper subquery for it as the command MAX(COUNT(customer_id)) from purchase_logs does not seem to be a valid query.
This is the DDL diagram.
This is the Sample Data of Purchase_logs
Customer_info
and Item_info
and the expected output for this sample data would be
It is certainly possible that there is a simpler approach that I am not seeing right now.
Would appreciate any suggestions and tips on this.
You need this query:
SELECT DISTINCT cust_id
FROM purchase_logs
GROUP BY cust_id, TO_CHAR(purchase_date, 'YYYY-MON')
HAVING COUNT(DISTINCT item_id) > 1;
to get all the cust_ids of the customers who have more than 1 unique item purchased in any month and you can use with the operator IN:
SELECT *
FROM customer_details
WHERE customer_id IN (
SELECT DISTINCT cust_id -- here DISTINCT may be removed as it does not make any difference when the result is used with IN
FROM purchase_logs
GROUP BY cust_id, TO_CHAR(purchase_date, 'YYYY-MON')
HAVING COUNT(DISTINCT item_id) > 1
);
One approach might be to try
with multiplepurchase as (
select customer_id,month(purchasedate),count(*) as order_count
from purchase_logs
group by customer_id,month(purchasedate)
having count(*)>=2)
select customer_id,username,usercategory
from mutiplepurchase a
left join userinfo b
on a.customer_id=b.customer_id
Expanding on #MT0 answer:
SELECT *
FROM customer_details CD
WHERE exists (
SELECT cust_id
FROM purchase_logs PL
where CD.customer_id = PL.customer_id
GROUP BY cust_id, item_id, to_char(purchase_date,'YYYYMM')
HAVING count(*) >= 2
);
I want to display the user info of customers who have more than 1 purchases in a single arbitrary month.
Just add a WHERE filter to your sub-query.
So assuming that you wanted the month of July 2021 and you had a purchase_date column (with a DATE or TIMESTAMP data type) in your purchase_logs table then you can use:
SELECT *
FROM customer_details
WHERE customer_id IN (
SELECT cust_id
FROM purchase_logs
WHERE DATE '2021-07-01' <= purchase_date
AND purchase_date < DATE '2021-08-01'
GROUP BY cust_id
HAVING count(*) >= 2
);
If you want the users where they have bought two-or-more items in any single calendar month then:
SELECT *
FROM customer_details c
WHERE EXISTS (
SELECT 1
FROM purchase_logs p
WHERE c.customer_id = p.cust_id
GROUP BY cust_id, TRUNC(purchase_date, 'MM')
HAVING count(*) >= 2
);

How to aggregate in SQL by having clause

The below is the query I'm using, I would like to add two more columns in the select statement which I have and noted them in the group by clause but the total results are different. The below script gives me the correct total count but I want to see the totals also for a column called transaction, and a column called employee. The total count should still be the same.
SELECT SUB.YEAR, SUM(SUB.TOTAL_COUNT), SUM(SUB.TOTAL_SPENT)
FROM (
SELECT YEAR, COUNT(*) AS TOTAL_COUNT, SUM($SPENTX) AS TOTAL_SPENT, CUSTOMERID
FROM TABLE A
WHERE YEAR = 2017
GROUP BY YEAR, CUSTOMERID
HAVING SUM($SPENTX)<=1000
) SUB
GROUP BY SUB.YEAR

Adding values with condition in google bigquery

I need to add some values with a condition in GoogleBigQuery
NOTICE: I edited the original question since it was not accurate enough.
Thanks to the two participants who have tried to help me.
I tried to apply the solutions kindly suggested by you but I got the same result from the pct column as a result.
Something like this:
results
Here is the more detailed definition:
TABLE
Columns:
Shop: Shop location
brand: Brands of cars sold at shoplocation
sales: sales of each brand sold at each shop_location
rank: Rank of each brand per shop location (the biggest the greater)
total_sales_shop: SUM of all brand sales per shop location
pct: percentage of sales by brand in relationship with shop location
pct_acc:
What i need to calc is pct_acc which is the cumulative sum of the shops by rank (while it has no relation with brand)
PCT_ACC
My need is to reach something like PCT_ACC, and then save the results in another one like this:endtable
You can use following query to get the required data:
select values, rank,
sum(case when rank<2 then values else 0 end) condition1
from table
group by values, rank
Need to add/remove columns from select and group by as per requirement
To get the cumulative sum you can use following query:
select shop, brand, sales, rank, total_sales_shop, pct ,
sum(pct) over (partition by shop order by rank) as pct_act
from data
And to get the final table you can use combination of case statement and group by
e.g
select shop,
max(case when rank=1 then pct_act end) as rank_1,
max(case when rank=2 then pct_act end) as rank_2,
max(case when rank=3 then pct_act end) as rank_3,
max(case when rank=4 then pct_act end) as rank_4,
max(case when rank=5 then pct_act end) as rank_5
from cumulative_sum
group by shop
If you want only the final sum for the rows with that condition you can try:
SELECT
SUM (IF(Rank < 2, Values, 0) AS condition1
FROM table
If you want to get the rank and the sum only for the rows with that condition you can try doing
SELECT
Rank,
SUM (IF(Rank < 2, Values, 0) AS condition1
FROM table
WHERE
RANK < 2
GROUP BY
Rank
Finally, if you want to get the rank and the sum considering all the rows you can try doing:
SELECT
Rank,
SUM (IF(Rank < 2, Values, 0) AS condition1
FROM table
GROUP BY
Rank
I hope it helps

SQL - Pull distinct row based on max value

I am trying to pull the most recent sale amount for each salesperson. The salespeople have made a sale on multiple days, I only want the most recent one.
My attempt below:
SELECT salesperson, amount
FROM table
WHERE date = (SELECT MAX(date) FROM table);
Use correlated subquery :
SELECT t.salesperson, t.amount
FROM table t
WHERE t.date = (SELECT MAX(t1.date)
FROM table t1
WHERE t1.salesperson = t.salesperson -- for each salesperson
);
If you are using PostgreSQL, you can take advantage of DISTINCT ON:
SELECT DISTINCT ON (salesperson) salesperson, amount
FROM table t
ORDER BY salesperson, date DESC
This will return only one row for each salesperson. The ORDER BY clause says to return the one with the largest date for that salesperson.
Unfortunately, DISTINCT ON is not supported by other databases.

SQL grouping with multiple rows

There's a table that I use that lists invoice detail. So for instance let's say a customer checks out with 2 items, there are 2 rows for each item.
Right now my SQL Query looks like this:
Select date
,order_id
,count(distinct(item_name))
from Table_1
group by 1,2
Rather than grouping it by order_id. Is there anyway to modify this query to find the number of Orders that have X amount of items on a specific date. So on 1/1/1990 5 orders have 3 items, 6 orders have 2 items, etc.
Thanks for the help!
If I'm understanding your question correctly, you could use a subquery grouping by the item count:
select t.date, t.itemCount, t.count(order_id)
from (
Select date
,order_id
,count(distinct(item_name)) AS itemCount
from Table_1
group by 1,2
) AS t
group by date, itemCount