multi-calculation query - mysql

Product Table
id name description price
1 AAA AAAAAA 10.00
2 BBB BBBBBB 12.00
3 CCC CCCCCC 15.00
4 DDD DDDDDD 8.00
5 EEE EEEEEE 12.50
Sales Table
trackid productid affiliateid paymentstatus refundid
1 2 1 COMPLETED 1
2 2 0 DONE null
3 3 1 COMPLETED null
4 3 0 COMPLETED null
5 3 0 COMPLETED null
6 5 5 DONE null
7 5 0 COMPLETED 2
8 5 2 COMPLETED null
9 2 0 DONE null
10 3 1 COMPLETED 3
For Sales table
If there is no affiliate for a particular sale, then affiliateid would be 0 otherwise affiliateid (I have another table for user which lists vendors and affiliates)
If a particular sales is been refunded (for any reason), then refundid would be set to some value, otherwise it would be null
paymentstatus can have any 1 of 2 values, COMPLETED and DONE
Now I need query that list following data for each product in product table
productid name totalsales affsales refunds
1 AAA 0 0 0
2 BBB 1 1 1
3 CCC 4 2 1
4 DDD 0 0 0
5 EEE 2 1 1
totalsales: sales with paymentstatus as "COMPLETED"
affsales: sales with paymentstatus as "COMPLETED" and affiliateid NOT EQUAL TO 0
refunds: sales with paymentstatus as "COMPLETED" and refundid NOT null
How can I form this particular query?

select
p.name,
SalesSummary.productid,
COALESCE( SalesSummary.TotalSales, 0 ) TotalSales
COALESCE( SalesSummary.AffSales, 0 ) AffSales
COALESCE( SalesSummary.Refunds, 0 ) Refunds
from
product p
left join
( select s.productid,
count(*) TotalSales
sum( if( s.affiliateID > 0, 1, 0 )) affSales,
sum( if( ifnull( s.RefundID, 0 ) > 0, 1, 0 )) Refunds
from
sales s
where
s.PaymentStatus = 'COMPLETED'
group by
s.productid
) SalesSummary
on p.id = SalesSummary.productid

Related

Inner Selection, Sum of colunms with conditions order by Region

After selection I get my new clear table like
SELECT a.sta_name, a.product, a.product_id, a.date, a.active, a.region_id, a.brand, a.brand_id from
(SELECT DISTINCT sta_name, product, product_id, date, active, region_id, brand, brand_id FROM `sv_ziyaret`
WHERE brand_id=2 and date between "2021-07-00" and "2021-07-31" order by region_id) a
so I get my values DISTINCT
sta_name | product | product_id | active | region_id | brand | brand_id| date |
3M A 1 1 1 A1 1 2021-07-02
2M A 1 0 1 A1 1 2021-07-02
5M B 2 0 1 A1 1 2021-07-05
4M B 2 0 2 A1 1 2021-07-06
M A 2 1 2 A1 1 2021-07-10
2M C 3 1 4 A1 1 2021-07-12
3M B 2 1 4 A1 1 2021-07-15
sta_name never repeats with same region_id, products do. What I try to get is
product_id | product | active_on | active_off | region_id
1 A 12 2 1
1 A 7 9 2
2 B 6 10 1
2 B 16 5 2
3 C 10 5 4
My main purpose is to be able to calculate percentage of product's existance in each region. In instance A product has %80 on sale on shalves at region A.
Manualy I am able to get each products result as
SELECT
product, product_id, region_id,
SUM(CASE WHEN sv_ziyaret.active = 1 THEN 1 ELSE 0 END) var,
SUM(CASE WHEN sv_ziyaret.active = 0 THEN 1 ELSE 0 END) yok
FROM
`sv_ziyaret`
WHERE
product_id=37 and date between "2021-07-00" and "2021-07-31" and region_id=7 order by region_id
but this is not a good solution I need it to be able to get each product by giving its brand_id only.
Hope to get a hand realy would same my weak
You are very close to the general solution. You just need GROUP BY AND LAST_DAY().
SELECT
product, product_id, region_id, LAST_DAY(date) month_ending,
SUM(CASE WHEN sv_ziyaret.active = 1 THEN 1 ELSE 0 END) var,
SUM(CASE WHEN sv_ziyaret.active = 0 THEN 1 ELSE 0 END) yok
FROM
sv_ziyaret
WHERE
GROUP BY product, product_id, region_id, LAST_DAY(date)
ORDER BY region_id, LAST_DAY(date), product_id;

Merging Multiple Queries - Same Table

I have 1 table called itemmovement : It has Item Id , Quantity In , Quantity Out , Invoice Id, Date. I need to make in one query to show how many pieces are sold and beside the sold column there will be the current on hand quantity .
itemmovement
Id itemid qtyin qtyout invid purchasereturnid date
1 1 10 2019-01-04
2 2 8 2019-01-06
3 2 2 1 2019-01-08
4 1 3 2 2019-01-12
5 2 1 2019-02-04
6 3 4 2019-03-04
7 1 1 3 2019-04-04
8 1 1 1 2019-04-14
9 3 1 2 2019-04-24
I need the query to show this result
Id itemid Sold Quantity OnHandQty
1 1 4 5
2 2 2 7
3 3 0 3
I'm Trying to use this query but not working
SELECT *
FROM
(SELECT itmv.itemid,
sum(itmv.qtyout)-sum(itmv.qtyin)
FROM itemmovement itmv
WHERE (itmv.systemdate BETWEEN '2019-01-01' AND '2019-06-01')
AND invid>0
GROUP BY itmv.itemid) AS result1,
(SELECT sum(itmv2.qtyin)-sum(itmv2.qtyout)
FROM itemmovement itmv2
WHERE itmv.itemid=itmv2.itemid
GROUP BY itmv2.itemid) AS result2
ORDER BY sum(itmv.qtyin)-sum(itmv.qtyout)
I'm getting :
Unknown column 'itmv.itemid' in 'where clause it for this syntax :
where itmv.itemid = itmv2.itemid
Here's your query.
select itemid
, sum(case when COALESCE(invid,0) > 0 then qtyout else 0 end) as Sold_Qantity
, sum(qtyin)-sum(qtyout) as OnHandQty
from itemmovement
group by itemid

Rearrange MySQL table from each month

This is my target table
retail_id month tgt_volume product_type
1 2013-11-01 2 Bar
2 2013-10-01 1 Touch
3 2013-09-01 1 Bar
4 2013-10-01 5 Smart
5 2013-10-01 8 Bar
3 2013-08-01 2 Smart
2 2013-08-01 5 Bar
3 2013-07-01 7 Bar
3 2013-07-01 2 Smart
I need this format
retail_id bar smart touch total month
1 2 0 0 2 2013-11-01
2 0 0 1 1 2013-10-01
2 5 0 0 5 2013-08-01
3 1 0 0 1 2013-09-01
3 0 2 0 2 2013-08-01
3 7 2 0 9 2013-07-01
4 0 5 0 5 2013-08-01
5 8 0 0 8 2013-10-01
So I want to retrieve every months total target and each product type total for each retail_id. I was trying a query which count every product_type but not count each month. How can I do this to make above format.. my test query is(without month count)
SELECT DISTINCT t.retail_id,bar_vol.bar,smart_vol.smart,touch_vol.touch,total.total,t.month FROM targets t
LEFT JOIN
(SELECT SUM(tgt_volume) AS bar,retail_id FROM targets t1 WHERE t1.product_type='Bar' GROUP BY retail_id) AS bar_vol
ON t.retail_id=bar_vol.retail_id
LEFT JOIN
(SELECT SUM(tgt_volume) AS smart,retail_id FROM targets t2 WHERE t2.product_type='Smart' GROUP BY retail_id) AS smart_vol
ON t.retail_id=smart_vol.retail_id
LEFT JOIN
(SELECT SUM(tgt_volume) AS touch,retail_id FROM targets t3 WHERE t3.product_type='Touch' GROUP BY retail_id) AS touch_vol
ON t.retail_id=touch_vol.retail_id
LEFT JOIN
(SELECT SUM(tgt_volume) AS total,retail_id FROM targets t4 GROUP BY retail_id) AS total
ON t.retail_id=total.retail_id
You can use a CASE statement inside an aggregate function to achieve this:
SELECT Retail_ID,
SUM(CASE WHEN product_Type = 'Bar' THEN tgt_Volume ELSE 0 END) AS Bar,
SUM(CASE WHEN product_Type = 'smart' THEN tgt_Volume ELSE 0 END) AS Smart,
SUM(CASE WHEN product_Type = 'Touch' THEN tgt_Volume ELSE 0 END) AS Touch,
SUM(tgt_Volume) AS Total,
Month
FROM targets
GROUP BY RetailId, Month;
Example on SQL Fiddle

Increment Group Number based on row value SQL Server 2008

I have two tables that aren't really associated, but need to be combined. So I'm using union all on the two tables. The unioned tables are ordered by date, so rows from one table are dispersed among rows from the other table. What I need to do is get a running count of a column so I can group elements.
To explain further, table A holds dates of when a container is emptied, while table B holds daily entries for content of the container. I need to union the two tables so I have one table where I can get the sum of the information for a container before the container is emptied.
So I need something like this:
Table A:
Location_ID Empty Date
123 3/2/13
123 3/10/13
123 4/1/13
Table B:
PSI Entry Date Location_ID
120 2/28/13 123 (same for all)
130 3/1/13
100 3/8/13
110 3/9/13
200 3/18/13
180 3/20/13
So the unioned table after some magic would look like:
Table C...:
Location_ID Date PSI Emptied
123 2/28/13 120 0
123 3/1/13 130 0
123 3/2/13 null 1
123 3/8/13 100 0
123 3/9/13 110 0
123 3/10/13 null 1
123 3/18/13 200 0
123 3/20/13 180 0
123 4/1/13 null 1
What I need to do is have a grouping such that I can have a table like this
Table C_b
Location_ID Date PSI Emptied Group
123 2/28/13 120 0 1
123 3/1/13 130 0 1
123 3/2/13 null 1 1
123 3/8/13 100 0 2
123 3/9/13 110 0 2
123 3/10/13 null 1 2
123 3/18/13 200 0 3
123 3/20/13 180 0 3
123 4/1/13 null 1 3
How can I get that grouping in that way? I have to make it work in SQL Server 2008. I have tried using Count, and Rank, and Row_Number. But the problem with those is that it won't do a running count, it will just say the total count in each row.
Try this query:
DECLARE #MyTable TABLE(
EntryDate DATE NOT NULL,
Emptied BIT NOT NULL
);
INSERT INTO #MyTable (EntryDate,Emptied)
VALUES
('2013-01-01',0),
('2013-01-02',0),
('2013-01-03',1),
('2013-01-04',0),
('2013-01-05',0),
('2013-01-06',1),
('2013-01-07',0),
('2013-01-08',0),
('2013-01-09',1);
DECLARE #TableWithRowNum TABLE(
EntryDate DATE NOT NULL,
Emptied BIT NOT NULL,
RowNum INT PRIMARY KEY
);
INSERT INTO #TableWithRowNum (EntryDate,Emptied,RowNum)
SELECT crt.*,ROW_NUMBER() OVER(ORDER BY crt.EntryDate) AS RowNum
FROM #MyTable crt;
WITH RecCTE
AS(
SELECT
crt.EntryDate,
crt.Emptied,
crt.RowNum,
1 AS Grp
FROM #TableWithRowNum crt
WHERE crt.RowNum=1
UNION ALL
SELECT
crt.EntryDate,
crt.Emptied,
crt.RowNum,
CASE WHEN prev.Emptied=1 THEN prev.Grp+1 ELSE prev.Grp END
FROM #TableWithRowNum crt INNER JOIN RecCTE prev ON crt.RowNum=prev.RowNum+1
)
SELECT * FROM RecCTE
OPTION(MAXRECURSION 0); -- Default value for MAXRECURSION is 100
GO
Results:
EntryDate Emptied RowNum Grp
---------- ------- ------ ---
2013-01-01 0 1 1
2013-01-02 0 2 1
2013-01-03 1 3 1
2013-01-04 0 4 2
2013-01-05 0 5 2
2013-01-06 1 6 2
2013-01-07 0 7 3
2013-01-08 0 8 3
2013-01-09 1 9 3

MySQL Group By not producing expected result

This is my table structure:
rec_id product_id quantity quantity_in quantity_out balance stock_date status
1 2 342 NULL 17 325 2009-10-23 1
2 2 325 NULL 124 201 2009-10-23 1
3 1 156 NULL 45 111 2009-10-23 1
4 2 201 NULL 200 1 2009-10-23 1
5 2 1 NULL 1 0 2009-10-23 1
6 1 111 NULL 35 76 2009-10-23 1
All I want is the last transaction done for a given product: product_id, quantity, quantity_out and balance from this table.
Example, there are 2 transaction done for product 2 (ids 1 & 2):
final balance for product_id 2 is 0 -> stored in rec_id 5
final balance for product_id 1 is 76 -> stored in rec_id 6
Final result/output should be like this:
recid productid quantity quantityin quantityout balance stock_date status
5 2 1 NULL 1 0 2009-10-23 1
6 1 111 NULL 35 76 2009-10-23 1
You can find the latest record for each product like:
select max(rec_id) as MaxRec
from YourTable
group by product_id
Using a subquery, you can retrieve the latest rows for their product:
select *
from YourTable
where rec_id in (
select max(rec_id) as MaxRec
from YourTable
group by product_id
)
Here's a single query with no subqueries:
SELECT main.*
FROM YourTable main
LEFT JOIN YourTable newer
ON newer.product_id = main.product_id AND newer.rec_id > main.rec_id
WHERE newer.rec_id IS NULL;
You can tweak the field list however you want--make sure you select fields from main, not newer, which should be all null.