How to group my query by name? P_Name - sql

select ID_Sale,SaleDate,Branch_Name,P_Name,P_UnitPrice,QuantitySold,
sum (QuantitySold*P_UnitPrice) over (order by ID_Sale asc) AS RunningTotal
from tblP_Sales
INNER JOIN tblProduct_With_Img
ON tblP_Sales.P_ID_Sales = tblProduct_With_Img.P_ID
INNER JOIN tblBranches
ON tblP_Sales.BranchID = tblBranches.BranchID
--this group is not working ? how to work this ?
group by P_Name
This is the result without the GROUP BY clause:
Sale_ID Sale_Date Branch Item Name Pric/unit qty RUNTotal
1056 2016-11-10 Ajman Afghani Pulaw With Meat 26 1 26
1057 2016-11-10 Ajman Sada Rice With Chicken Boti 24 2 74
1058 2016-11-11 Ajman Afghani Pulaw With Meat 26 1 100

I think you're looking to add "PARTITION BY "
select ID_Sale,SaleDate,Branch_Name,P_Name,P_UnitPrice,QuantitySold,
sum (QuantitySold*P_UnitPrice) over (PARTITION BY P_Name order by ID_Sale asc) AS RunningTotal
from tblP_Sales
INNER JOIN tblProduct_With_Img
ON tblP_Sales.P_ID_Sales = tblProduct_With_Img.P_ID
INNER JOIN tblBranches
ON tblP_Sales.BranchID = tblBranches.BranchID

Related

multiple two column values with grouping by a column

I've two tables tblOrder and tblOrderDetails. I want to get order no, total price per order (Quantity*UnitCost) and OrderDate as given below.
Order No
Total
OrderDate
ORD 1
3000
01/01/2021
ORD 2
2750
01/03/2021
What I've tried is giving me quantity is not a part of aggregate function.
SELECT tblOrder.OrderNo, tblOrderDetails.UnitCost*tblOrderDetails.Quantity AS Total, OrderDate
FROM tblOrderDetails INNER JOIN tblOrder ON tblOrderDetails.OrderId = tblOrder .OrderId
GROUP BY tblOrder.OrderNo;
Table structures and data
Table tblOrder:
OrderId
OrderNo
OrderDate
1
ORD 1
01/01/2021
2
ORD 2
01/03/2021
Table tblOrderDetails:
OrderDetailId
Quantity
UnitCost
OrderId
1
100
30
1
2
50
40
2
2
10
15
2
2
20
30
2
select o.OrderNo
,od.total
,o.OrderDate
from
(
select OrderId
,sum(Quantity*UnitCost) as total
from tblOrderDetails
group by OrderId
) od join tblOrder o on o.OrderId = od.OrderId
OrderNo
total
OrderDate
ORD 1
3000
2021-01-01
ORD 2
2750
2021-01-03
Fiddle
Your requirements are not 100% clear, but maybe, you can just do this, without any subquery:
SELECT tblOrder.OrderNo,
SUM(tblOrderDetails.UnitCost*tblOrderDetails.Quantity) AS Total,
OrderDate
FROM tblOrderDetails
INNER JOIN tblOrder ON tblOrderDetails.OrderId = tblOrder.OrderId
GROUP BY tblOrder.OrderNo,OrderDate;
To see the difference to Danny's answer - which might also be fine - have a look here: db<>fiddle

How to find out first product item client purchased whose bought specific products?

I want to write a query to locate a group of clients whose purchased specific 2 product categories, at the same time, getting the information of first transaction date and first item they purchased. Since I used group by function, I could only get customer id but not first item purchase due to the nature of group by. Any thoughts to solve this problem?
What I have are transaction tables(t), customer_id tables(c) and product tables(p). Mine is SQL server 2008.
Update
SELECT t.customer_id
,t.product_category
,MIN(t.transaction_date) AS FIRST_TRANSACTION_DATE
,SUM(t.quantity) AS TOTAL_QTY
,SUM(t.sales) AS TOTAL_SALES
FROM transaction t
WHERE t.product_category IN ('VEGETABLES', 'FRUITS')
AND t.transaction_date BETWEEN '2020/01/01' AND '2022/09/30'
GROUP BY t.customer_id
HAVING COUNT(DISTINCT t.product_category) = 2
**Customer_id** **transaction_date** **product_category** **quantity** **sales**
1 2022-05-30 VEGETABLES 1 100
1 2022-08-30 VEGETABLES 1 100
2 2022-07-30 VEGETABLES 1 100
2 2022-07-30 FRUITS 1 50
2 2022-07-30 VEGETABLES 2 200
3 2022-07-30 VEGETABLES 3 300
3 2022-08-01 FRUITS 1 50
3 2022-08-05 FRUITS 1 50
4 2022-08-07 FRUITS 1 50
4 2022-09-05 FRUITS 2 100
In the above, what I want to show after executing the SQL query is
**Customer_id** **FIRST_TRANSACTION_DATE** **first_product_category** **TOTAL_QUANTITY** **TOTAL_SALES**
2 2022-07-30 VEGETABLES, FRUITS 4 350
3 2022-07-30 VEGETABLES 5 400
Customer_id 1 and 4 will not be shown as they only purchased either vegetables or fruits but not both
Check now, BTW need find logic with product_category
select CustomerId, transaction_date, product_category, quantity, sales
from(
select CustomerId, transaction_date, product_category , sum(quantity) over(partition by CustomerId ) as quantity , sum(sales) over(partition by CustomerId ) as sales, row_number() over(partition by CustomerId order by transaction_date ASC) rn
from(
select CustomerId, transaction_date, product_category, quantity, sales
from tablee t
where (product_category = 'FRUITS' and
EXISTS (select CustomerId
from tablee tt
where product_category = 'VEGETABLES'
and t.CustomerId = tt.CustomerId)) OR
(product_category = 'VEGETABLES' and
EXISTS (select CustomerId
from tablee tt
where product_category = 'FRUITS'
and t.CustomerId = tt.CustomerId)))x)over_all
where rn = 1;
HERE is FIDDLE

Joining multiple tables and getting MAX value in subquery PostgreSQL

I have 4 Tables in PostgreSQL with the following structure as you can see below:
"Customers"
ID | NAME
101 Max
102 Peter
103 Alex
"orders"
ID | customer_id | CREATED_AT
1 101 2022-05-12
2 101 2022-06-14
3 101 2022-07-9
4 102 2022-02-14
5 102 2022-06-18
6 103 2022-05-22
"orderEntry"
ID | order_id | product_id |
1 3 10
2 3 20
3 3 30
4 5 20
5 5 40
6 6 20
"product"
ID | min_duration
10 P10D
20 P20D
30 P30D
40 P40D
50 P50D
Firstly I need to select "orders" with the max(created_at) date for each customer this is done with the query (it works!):
SELECT c.id as customerId,
o.id as orderId,
o.created_at
FROM Customer c
INNER JOIN Orders o
ON c.id = o.customer_id
INNER JOIN
(
SELECT customer_id, MAX(created_at) Max_Date
FROM Orders
GROUP BY customer_id
) res ON o.customer_id = res.customer_id AND
o.created_at = res.Max_date
the result will look like this:
customer_id | order_id | CREATED_AT
101 3 2022-07-9
102 5 2022-06-18
103 6 2022-05-22
Secondly I need to select for each order_id from "orderEntry" Table, "products" with the max(min_duration) the result should be:
order_id | max(min_duration)
3 P30D
5 P40D
6 P20D
and then join results from 1) and 2) queries by "order_id" and the total result which I'm trying to get should look like this:
customer_name | customer_id | Order_ID | Order_CREATED_AT | Max_Duration
Max 101 3 2022-07-9 P30D
Peter 102 5 2022-06-18 P40D
Alex 103 6 2022-05-22 P20D
I'm struggling to get query for 2) and then join everything with query from 1) to get the result. Any help I would appreciate!
You could make the first query to an CTE and use that to join the rest of the queries.
Like this.
WITH CTE AS ( SELECT c.id as customerId,
o.id as orderId,
o.created_at
FROM Customer c
INNER JOIN Orders o
ON c.id = o.customer_id
INNER JOIN
(
SELECT customer_id, MAX(created_at) Max_Date
FROM Orders
GROUP BY customer_id
) res ON o.customer_id = res.customer_id AND
o.created_at = res.Max_date)
SELECT customerId,orderId,created_at,p.min_duration
FROM CTE
JOIN (SELECT "orderId", MAX("product_id") as product_id FROM "orderEntry" GROUP BY orderId) oe ON CTE.orderId = oe.orderId
JOIN "product" pr ON oe.product_id = pr."ID"

How get data from 3 tables?

I have 3 tables
collecton, paymentdata, payment
Payment table is computed table and it has only one product data
So, rcvamt and restamt get from payment table
I have following data
Collection:
id(PK) clientid company Client product total note
1 2001 Company1 Client1 Product1 50000 note1
2 2002 Company2 Client2 Product2 60000 note2
3 2003 Company3 Client3 Product3 70000 note3
PaymentData:
wid(PK)wcid(FK) clientid product rcvamt restamt rcvdate nxtdate Note
1 1 2001 Product1 500 49500 10-1-2015 11-2-2015 abc1
2 1 2001 Product1 800 48700 11-2-2015 12-3-2015 xyz1
3 2 2002 Product2 1500 58500 5-3-2015 6-4-2015 qwe1
Payment
id(PK) wid(FK) clientid product rcvamt restamt
1 2 2001 Product1 1300 48700
2 3 2002 Product2 1500 58500
I want to show a report like
clientid company procudt total rcvamt restamt rcvdate nxtdate note
2001 Company1 Product1 50000 1300 48700 11-2-2015 12-3-2015 xyz1
2002 Company2 Product2 60000 1500 58500 5-3-2015 6-4-2015 qwe1
2003 Company3 Product3 70000 - - - - -
I tried to make it simple:
SELECT DISTINCT
C.clientid
, C.company
, C.product
, C.total
, P.rcvamt
, P.restamt
, ( SELECT TOP 1 rcvdate FROM PaymentData AS PD1 WHERE PD1.ClientID=PD.ClientID AND PD1.Product=PD.Product ORDER BY rcvdate DESC)
, ( SELECT TOP 1 nxtdate FROM PaymentData AS PD1 WHERE PD1.ClientID=PD.ClientID AND PD1.Product=PD.Product ORDER BY rcvdate DESC)
, ( SELECT TOP 1 Note FROM PaymentData AS PD1 WHERE PD1.ClientID=PD.ClientID AND PD1.Product=PD.Product ORDER BY rcvdate DESC)
FROM
Collection C
LEFT OUTER JOIN Payment P
ON C.clientid = P.clientid
LEFT OUTER JOIN PaymentData PD
ON P.clientid = PD.clientid
But I don't know all the relationships between the tables.
The Answer to your Question could look like this
Select Collection.clientid
,Collection.company
,Collection.product
,Collection.total
,Payment.rcvamt
,Payment.restamt
,PaymentData.rcvdate
,PaymentData.nxtdate
,PaymentData.Note
From PaymentData
Inner Join (Select wcid
,Max(PaymentData.rcvdate) as rcvdate
,Max(PaymentData.nxtdate) as nxtdate
FROM PaymentData
GROUP BY wcid) AS SubSelect ON PaymentData.wcid = SubSelect.wcid
AND PaymentData.rcvdate = SubSelect.rcvdate
AND PaymentData.nxtdate = SubSelect.nxtdate
Inner Join Payment on PaymentData.wcid = Payment.id
RIGHT OUTER JOIN Collection ON PaymentData.clientid = Collection.clientid
Here the sqlfiddle to prove my Answer.
Something like this should work. It appears you want an aggregation on the restamt, both other fields are the last payment received. I also assume this is SQL Server due to your name. If it's a different db, please provide the
UPDATE: Changed to LEFT JOIN to handle client 3 without products, fixed typo in product. SQL Fiddle: http://sqlfiddle.com/#!3/8ad566/19/0
SELECT
c.clientid,
c.company,
c.product,
c.total,
SUM(pd.rcvamt) AS rcvamt,
LastPayment.restamt,
LastPayment.rcvdate,
LastPayment.nxtDate,
LastPayment.note
FROM Collection c
LEFT OUTER JOIN PaymentData pd
ON pd.wcid = c.id
LEFT OUTER JOIN (
SELECT
wcid,
restamt,
rcvdate,
nxtdate,
Note,
ROW_NUMBER() OVER (PARTITION BY wcid ORDER BY rcvdate DESC) AS RowNum
FROM PaymentData
) LastPayment
ON LastPayment.wcid = c.id
AND LastPayment.RowNum = 1 -- Get last payment info
GROUP BY
c.clientid,
c.company,
c.product,
c.total,
LastPayment.restamt,
LastPayment.rcvdate,
LastPayment.nxtDate,
LastPayment.note
ORDER BY
c.clientid

How to Retrieve Maximum Value of Each Group? - SQL

There is a table tbl_products that contains data as shown below:
Id Name
----------
1 P1
2 P2
3 P3
4 P4
5 P5
6 P6
And another table tbl_inputs that contains data as shown below:
Id Product_Id Price Register_Date
----------------------------------------
1 1 10 2010-01-01
2 1 20 2010-10-11
3 1 30 2011-01-01
4 2 100 2010-01-01
5 2 200 2009-01-01
6 3 500 2011-01-01
7 3 270 2010-10-15
8 4 80 2010-01-01
9 4 50 2010-02-02
10 4 92 2011-01-01
I want to select all products(id, name, price, register_date) with maximum date in each group.
For Example:
Id Name Price Register_Date
----------------------------------------
3 P1 30 2011-01-01
4 P2 100 2010-01-01
6 P3 500 2011-01-01
10 P4 92 2011-01-01
select
id
,name
,code
,price
from tbl_products tp
cross apply (
select top 1 price
from tbl_inputs ti
where ti.product_id = tp.id
order by register_date desc
) tii
Although is not the optimum way you can do it like:
;with gb as (
select
distinct
product_id
,max(register_date) As max_register_date
from tbl_inputs
group by product_id
)
select
id
,product_id
,price
,register_date
from tbl_inputs ti
join gb
on ti.product_id=gb.product_id
and ti.register_date = gb.max_register_date
But as I said earlier .. this is not the way to go in this case.
;with cte as
(
select t1.id, t1.name, t1.code, t2.price, t2.register_date,
row_number() over (partition by product_id order by register_date desc) rn
from tbl_products t1
join tbl_inputs t2
on t1.id = t2.product_id
)
select id, name, code, price, register_date
from cte
where rn = 1
Something like this..
select id, product_id, price, max(register_date)
from tbl_inputs
group by id, product_id, price
you can use the max function and the group by clause. if you only need results from the table tbl_inputs you even don't need a join
select product_id, max(register_date), price
from tbl_inputs
group by product_id, price
if you need field from the tbl_prducts you have to use a join.
select p.name, p. code, i.id, i.price, max(i.register_date)
from tbl_products p join tbl_inputs i on p.id=i.product_id
grooup by p.name, p. code, i.id, i.price
Try this:
SELECT id, product_id, price, register_date
FROM tbl_inputs T1 INNER JOIN
(
SELECT product_id, MAX(register_date) As Max_register_date
FROM tbl_inputs
GROUP BY product_id
) T2 ON(T1.product_id= T2.product_id AND T1.register_date= T2.Max_register_date)
This is, of course, assuming your dates are unique. if they are not, you need to add the DISTINCT Keyword to the outer SELECT statement.
edit
Sorry, I didn't explain it very well. Your dates can be duplicated, it's not a problem as long as they are unique per product id. if you can have duplicated dates per product id, then you will have more then one row per product in the outcome of the select statement I suggested, and you will have to find a way to reduce it to one row per product.
i.e:
If you have records like that (when the last date for a product appears more then once in your table with different prices)
id | product_Id | price | register_date
--------------------------------------------
1 | 1 | 10.00 | 01/01/2000
2 | 1 | 20.00 | 01/01/2000
it will result in having both of these records as outcome.
However, if the register_date is unique per product id, then you will get only one result for each product id.