Count double occurrences in order list - sql

I have a list of orders, I need to find which ones occur with code 47 more than once with different users. For example:
ORDER_ID CODE USER
111 47 1
111 47 2
222 47 1
333 47 1
333 47 2
444 47 1
The expected result is 111 and 333.
How can I accomplish this?
Regards

I think you want aggregation and having:
select order_id
from orders o
where code = 47
group by order_id
having min(user) <> max(user);
You can also express the having as:
having count(distinct user) >= 2

You can try below -
select order_id from tablename
group by order_id
having count(distinct user)>=1

You can do it via row_number() as well
Select distinct order_id from
(select order_id, code, row_number()
over
( Partition by order_id, code
Order by order_id, code) rn
from
tablename
where user in (1,2)
) where rn>=1
But I guess you already have a user column hence i dont think you require extra manipulation
Select orderid, code from table
Group by orderid, code having
max(distinct user) >=1

Related

Get sum qty over specific range

I have the below table
substring(area,6,3)
qty
101
10
103
15
102
11
104
30
105
25
107
17
108
23
106
48
And I am looking to get a result as below without repeating the IIF ( as it's a cumulative of 4 sequences) in the area:
new_area(substring(area,6,3)
sum_qty
101-104
66
105-108
117
I don't know how to create the new area column to be able to get the sum qty
Looking forward to your help.
Please also add an explanation so I will understand how the query is running.
I think this is what you are looking for.
We just use the window function row_number() to create the Grp
NOTE: If you have repeating values in AREA use dense_rank() instead of row_number()
Example
Select new_area = concat(min(area),'-',max(area))
,qty = sum(qty)
From (
Select area=substring(area,6,3)
,qty
,Grp = (row_number() over (order by substring(area,6,3))-1) / 4
From YourTable
) A
Group By Grp
Results
new_area qty
101-104 66
105-108 113 -- get different results
If you were to run the subquery, you would see the following.
Then it becomes a small matter to aggregate the data grouped by the created column GRP

How to get the 2nd record for a customer purchase?

I'm working on a customers database and I want to get all data for their second purchase (for all of our customer weather they have 2 or more purchases).
For example:
Customer_ID Order_ID Order_Date
1 259 09/05/2020
1 644 03/11/2020
1 617 18/04/2022
4 834 22/09/2021
4 995 07/02/2022
I want to display the second order which is:
Customer_ID Order_ID Order_Date
1 644 03/11/2020
4 995 07/02/2022
I'm facing some difficulties in finding the right logic, any idea how I can achieve my end goal? :)
*Note: I'm using snowflake
You can use a ROW_NUMBER and filter using QUALIFY clause:
select * from table qualify row_number() over(partition by customer_id order by order_date) = 2;
You can use common table expression
with CTE_RS
AS (
SELECT Customer_ID,ORDER_ID,Order_Date,ROW_NUMBER() OVER(PARTITION BY Customer_ID ORDER BY Order_Date ) ORDRNUM FROM *TABLE NAME*
)
SELECT Customer_ID,ORDER_ID,Order_Date
FROM CTE_RS
WHERE ORDRNUM = 2 ;

Top 2 Months of Sales by Customer - Oracle

I am trying to develop a query to pull out the top 2 months of sales by customer id. Here is a sample table:
Customer_ID Sales Amount Period
144567 40 2
234567 50 5
234567 40 7
144567 80 10
144567 48 2
234567 23 7
desired output would be
Customer_ID Sales Sum Period
144567 80 10
144567 48 2
234567 50 5
234567 40 7
I've tried
select sum(net_sales_usd_spot), valid_period, customer_id
from sales_trans_price_output
where valid_period in (select valid_period, sum(net_sales_usd_spot)
from sales_trans_price_output
where rank<=2)
group by valid_period, customer_id
error is
too many values ORA-00913.
I see why, but not sure how to rework it.
Try:
SELECT *
FROM (
SELECT t.*,
row_number() over (partition by customer_id order by sales_amount desc ) rn
FROM sales_trans_price t
)
WHERE rn <= 2
ORDER BY 1,2 desc
Demo: http://sqlfiddle.com/#!4/882888/3
what if you change your where clause to:
where valid_period in
(
select p.valid_period from sales_trans_price_output p
join (select valid_period, sum(net_sales_usd_spot)
from sales_trans_price_output
where rank<=2) s on s.valid_period = p.valid_period
)
It might be ugly and need refactoring, but I think this is the logic you're after.
The error is because of this.
where valid_period in (select valid_period, sum(net_sales_usd_spot)
from sales_trans_price_output
where rank<=2)
The subquery can only contain one field.
You are on the right track using rank, but you might not be using it correctly. Google oracle rank to find the correct syntax.
Back to what you are looking to achieve, a derived table is the approach I would use. That's simply a subquery with an alias. Or, if you use the keyword with, it might be called a CTE - Computed Table Expression.
Try it
SELECT * FROM (
SELECT T.*,
RANK () OVER (PARTITION BY CUSTOMER_ID
ORDER BY VALID_PERIOD DESC) FN_RANK
FROM SALES_TRANS_PRICE_OUTPUT T
) A
WHERE A.FN_RANK <= 2
ORDER BY CUSTOMER_ID ASC, VALID_PERIOD DESC, FN_RANK DESC

Eliminate a duplicate result from a single column

Let's say I have a result from a query that looks like this:
ContactID LeadSalePrice
---------------------------
45 19.90
45 18.00
32 17.50
But, I want to eliminate duplicate ContactID's, always taking the higher price result. So what I want is:
ContactID LeadSalePrice
---------------------------
45 19.90
32 17.50
Here's (a simplified version of) the query:
SELECT
sc.ContactID
, c.LeadSalePrice
FROM
LeadSalesCampaignCriterias c
JOIN LeadSalesCampaigns sc ON c.LeadSalesCampaignID = sc.LeadSalesCampaignID
WHERE
...
ORDER BY
LeadSalePrice DESC
I've been playing around with DISTINCT and GROUP BY, but I'm not getting it.
Just use GROUP BY:
SELECT sc.ContactID, MAX(c.LeadSalePrice) as LeadSalePrice
FROM LeadSalesCampaignCriterias c JOIN
LeadSalesCampaigns sc
ON c.LeadSalesCampaignID = sc.LeadSalesCampaignID
WHERE ...
GROUP BY sc.ContactID;
Another option is the WITH TIES and Row_Number()
Select Top 1 with Ties *
From YourTable
Order By Row_Number() over (Partition By ContactID Order By LeadSalePrice Desc)
Returns
ContactID LeadSalePrice
32 17.50
45 19.90

How to sum in sql with a DISTINCT clause

In the following example SQL Fiddle
How should I proceed to obtain the cumulative price for each 'Phone' instead of obtaining the last value?
In the example given below, I would need the following table to be produced:
Phone Price Purchases
50 35 3
51 50 2
52 99 3
55 21 2
53 16 2
54 21 1
56 16 1
58 22 1
57 10 2
This is to be done in SQL-Server 2012
Thanks in advance.
You should be able to use the following:
select c1.phone,
c2.TotalPrice,
c1.purchases
from supportContacts c1
inner join
(
select
max(Fecha) maxFecha,
sum(price) TotalPrice,
phone
from supportContacts
group by phone
) c2
on c1.phone = c2.phone
and c1.Fecha = c2.maxFecha
order by c1.phone;
See SQL Fiddle with Demo.
The subquery gets the Total sum for each phone along with the the max fecha associated with the phone. You then use this and join back to your table on both the phone and the fecha to get the result.
I don't have a SQL Server 2012 handy, but give this a shot:
select
phone,
purchases,
price,
sum(price) over (partition by phone order by phone, price) as running_sum_purchases
FROM
supportContacts
Isn't it just...
SELECT Phone, Sum(Price), Count(Purchases)
FROM supportContacts
GROUP BY Phone
ORDER BY 1
.. or have I missed something?
http://sqlfiddle.com/#!6/7b36f/41
50 35 3
51 50 4
52 99 3
53 16 2
54 21 2
55 21 1
56 16 1
57 10 1
58 22 2
If you need more details per phone, you can add a subquery :
SELECT
Phone,
Sum(Price) as Total,
Count(Purchases) as Purchase_Count,
(SELECT TOP 1 Price
FROM supportContacts sc2
WHERE sc2.phone=sc1.phone
ORDER BY fecha DESC
) as Most_Recent
FROM supportContacts sc1
GROUP BY Phone
ORDER BY Phone
or, for the actual requirement which I've finally worked out :)
SELECT
Phone,
Sum(Price) as Total,
Count(Purchases) as Purchase_Count,
(SELECT Purchases
FROM supportContacts sc2
WHERE sc2.phone=sc1.phone
AND sc2.Fecha=
(SELECT Max(Fecha)
FROM supportContacts sc3
WHERE sc3.phone=sc1.phone
)
) as Last_Purchase
FROM supportContacts sc1
GROUP BY Phone
ORDER BY Phone
.. which is starting to get quite unwieldy, there's probably an optimisation possible, but I'm losing the will to play... LOL
But thanks for the cerebral exercise of trying to do it this way :)
EDIT
I would probably have done it like this, if it had been me...
http://sqlfiddle.com/#!6/7b36f/98
With PhoneGroup as
( SELECT
Phone,
Sum(Price) as Total_Price,
Max(Fecha) as Last_Fecha
FROM supportContacts
GROUP BY Phone
)
SELECT
Phone, Total_Price,
(SELECT Purchases
FROM supportContacts sc2
WHERE sc2.phone=PhoneGroup.phone
AND sc2.Fecha=PhoneGroup.Last_Fecha
) as Last_Purchase
FROM PhoneGroup
ORDER BY Phone