Trying to count # distinct values of a field based on value of a different field - sql

Looking for some help with my SQL query. I am trying to find a way to specify cases in which a customer purchases or sells at two different stores, but if they purchase at one store and sell at another, I don't care or want that to count.
I have tried this -
Select count(distinct store) OVER(Partition BY Customer)
but it doesn't like the distinct and causes an error. When I dont specify distinct, it will give me the count of all observations of that customer, instead of just the count of # of stores that they purchased from, or sold to.
Based on the data below, customer D is the type im looking to filter for.
My Raw Data:
Customer Type Qty Store
A Purchase 1 2
A Purchase 2 2
A Sale 3 1
B Sale 24 1
B Sale 12 1
C Purchase 4 2
D Sale 12 2
D Purchase 4 2
D Purchase 2 1
D Purchase 2 1
Any ideas?

select customer
from your_table
group by customer, type
having count(distinct store) > 1

Don't you just want to GROUP?
Select Count(store) FROM Blah GROUP BY Customer, Store
Edit: Ah I see what you want - you want a count of store over customer, sorry misread it!

Related

Inner join + group by - select common columns and aggregate functions

Let's say i have two tables
Customer
---
Id Name
1 Foo
2 Bar
and
CustomerPurchase
---
CustomerId, Amount, AmountVAT, Accountable(bit)
1 10 11 1
1 20 22 0
2 5 6 0
2 2 3 0
I need a single record for every joined and grouped Customer and CustomerPurchase group.
Every record would contain
columns from table Customer
some aggregation functions like SUM
a 'calculated' column. For example difference of other columns
result of subquery to CustomerPurchase table
An example of result i would like to get
CustomerPurchases
---
Name Total TotalVAT VAT TotalAccountable
Foo 30 33 3 10
Bar 7 9 2 0
I was able to get a single row only by grouping by all the common columns, which i dont think is the right way to do. Plus i have no idea how to do the 'VAT' column and 'TotalAccountable' column, which filters out only certain rows of CustomerPurchase, and then runs some kind of aggregate function on the result. Following example doesn't work ofc but i wanted to show what i would like to achieve
select C.Name,
SUM(CP.Amount) as 'Total',
SUM(CP.AmountVAT) as 'TotalVAT',
diff? as 'VAT',
subquery? as 'TotalAccountable'
from Customer C
inner join CustomerPurchase CR
on C.Id = CR.CustomerId
group by C.Id
I would suggest you just need the follow slight changes to your query. I would also consider for clarity, if you can, to use the terms net and gross which is typical for prices excluding and including VAT.
select c.[Name],
Sum(cp.Amount) as Total,
Sum(cp.AmountVAT) as TotalVAT,
Sum(cp.AmountVAT) - Sum(CP.Amount) as VAT,
Sum(case when cp.Accountable = 1 then cp.Amount end) as TotalAccountable
from Customer c
join CustomerPurchase cp on cp.CustomerId = c.Id
group by c.[Name];

How do I count how many emails each customer has received when there are multiple emails to count?

I am looking to count the number of emails each customer has received however am having trouble as there is more than one customer in the table that needs counting meaning a simple where clause isn't enough.
Here is an example of the Data:
CustomerID
EmailName
1
EmailA
1
EmailB
2
EmailA
2
EmailB
2
EmailC
3
EmailA
3
EmailB
I am able to count for a specific customer by using a where clause:
WHERE CustomerID = "1"
Which will return:
CustomerID
NumberOfEmailsSent
1
2
The issue I am having is I would like to get the following result:
CustomerID
NumberOfEmailsSent
1
2
2
3
3
2
The data set I am working with has thousands of email addresses so querying each email address separately is an unrealistic solution.
That is what GROUP BY is for.
SELECT CustomerID, COUNT(EmailName)
FROM YourTable
GROUP BY CustomerID
I think that you just need a GROUP BY clause:
SELECT CustomerID, COUNT(EmailName) as 'NumberOfEmailsSent'
FROM tbl
GROUP BY CustomerID
Output check here on DB<>FIDDLE

Postgresql : Check if the last number is the highest

I have large database and one field should be an incremental number, but it sometimes resets and I must detect them (the bold rows)
Table 1:
Shop #Sell DATE
EC1 56 1/10/2015
EC1 57 2/10/2015
**EC1 11 3/10/2015
EC1 12 4/10/2015**
AS2 20 1/10/2015
AS2 21 2/10/2015
AS2 22 3/10/2015
AS2 23 4/10/2015
To solve this problem I thought to find the highest number of each SHOP and check if it is the number with the highest DATE. Do you know another easier way to do it?
My concern is that it can be a problem to do the way I am thinking since I have a large database.
Do you know how I can do the query I am thinking of or do you have any others ideas?
The query you have in mind will give you all Shop values having a discontinuity in Sell number.
If you want to get the offending record you can use the following query:
SELECT Shop, Sell, DATE
FROM (
SELECT Shop, Sell, DATE,
LAG(Sell) OVER (PARTITION BY Shop ORDER BY DATE) AS prevSell
FROM Shops ) t
WHERE Sell < prevSell
ORDER BY DATE
LIMIT 1
The above query will return the first discontinuity found within each Shop partition.
Output:
Shop Sell DATE
---------------------
EC1 11 2015-03-10
Demo here
EDIT:
In case you cannot use windowed function and you only want the id of the shop having the discontinuity, then you can use the following query:
SELECT s.Shop
FROM Shops AS s
INNER JOIN (
SELECT Shop, MAX(Sell) AS Sell, MAX(DATE) AS DATE
FROM Shops
GROUP BY Shop ) t
ON s.Shop = t.Shop AND s.DATE = t.DATE
WHERE t.Sell <> s.Sell
The above will work provided that you have unique DATE values per Shop.
I think the following is the type of query you want:
select s.*
from (select shop, max(sell) as maxsell,
first_value(sell) over (partition by shop order by date desc) as lastsell
from shops s
group by shop
) s
where maxsell <> lastsell;

Using SQL to find the total number of customers with over X orders

I've been roasting my brain with my limited SQL knowledge while attempting to come up with a query to run a statistic on my orders database.
Table ORDERS is laid out like this:
CustomerID ProductID (etc)
1 10
1 10
1 11
2 10
4 9
Each purchase is recorded with the customer id and the product ID - there CAN be multiple records for the same customer, and even multiple records with the same customer and product.
I need to come up with a query that can return the amount of customers who bought between X and X distinct products - for example, 3 customers bought less then 5 different products, 10 bought from 5-10 different products, 1 bought over 10 different products.
I'm pretty sure this has something to do with derived tables, but advanced SQL is a new fairly craft to me. Any help would be appreciated!
Try this:
SELECT T1.products_bought, COUNT(T2.cnt) AS total
FROM (
SELECT '<5' AS products_bought, 0 AS a, 4 AS b
UNION ALL
SELECT '5-10', 5, 10
UNION ALL
SELECT '>10', 11, 999999
) T1
LEFT JOIN
(
SELECT COUNT(DISTINCT ProductID) AS cnt
FROM ORDERS
GROUP BY CustomerID
) T2
ON T2.cnt BETWEEN T1.a AND T1.b
GROUP BY a, b
Result:
products_bought total
<5 3
5-10 0
>10 0

MySQL - Finding out Balancing Figure From 2 Tables

I have 2 tables like this:
Stock Table
product_id bigint(20)
qty float
Sales Table
product_id bigint(20)
qty float
Sample Data
Stock Table
product_id---qty
1---10
2---11
3---20
4---50
1---10
3---10
Sales Table
product_id---qty
1---2
2---5
3---20
4---40
1---7
I want the following Output after running the Query
product_id---qty
1---11
2---6
3---10
4---10
Well, as spender ask I am trying to more clear the situation.
First of All, let's think that I store
10 quantity of product 1
11 quantity of product 2
20 quantity of product 3
50 quantity of product 4
10 quantity of product 1 (now I have total 20 of product 1)
10 quantity of product 3 (now I have total 30 of product 3)
Secondly, let's think that I sell
2 quantity of product 1
5 quantity of product 2
20 quantity of product 3
40 quantity of product 4
7 quantity of product 1 (now I have sold total 9 of product 1)
Thirdly, I want to know how much stock is now in my hand
11 quantity of product 1 (20-9 = 11)
6 quantity of product 2 (11-5 = 6)
10 quantity of product 3 (30-20 = 10)
10 quantity of product 4 (50-4 = 10)
My Question is: To find out this stock what is the Query?
Thanks in Advance for answering my question.
This answer works in Oracle - don't have MySql so can't test there
select product_id, sum(qty) from
(
select product_id, qty from stock
union all
select product_id, (-1 * qty) from sales
) as a
group by prod
You question is lacking detail and looks like it might even contain typos in the presented data. I'm going to make the assumption you are trying to calculate the diff between stock quantities and sales quantities, despite your data not actually supporting this (!!!). It looks like you require the following:
select
st.product_id,
sto.qty-st.qty
from
salesTable as st
join stockTable as sto on sto.product_id=st.product_id
Chris's answer is absolutely correct. But for the information I want to add this one which I found on NET.
SELECT tunion.product_id, (
(IFNULL((SELECT SUM(s.qty) FROM stock s WHERE s.product_id=tunion.product_id),0))-
(IFNULL((SELECT SUM(p.qty) FROM sales p WHERE p.product_id=tunion.product_id),0)))
AS quantity
FROM (SELECT DISTINCT s.product_id FROM stock s
UNION ALL SELECT DISTINCT p.product_id FROM sales p)
AS tunion GROUP BY tunion.product_id