so in my database i have two rows: Barcode, Profit ;
They are in an descending order according to profit, eg:
Barcode , Profit:
101 , 10000
106 , 9999
107 , 8888
108 , 222
i need to sql query which will do the following:
I need to sum all the profit then look at its %80 value and then start summing barcode values until %80 is met, eg:
Barcode , Profit:
101 , 10000
106 , 9999
107 , 8888
108 , 222
10000+9999+8888+222= 29109
29109 is the total sum and its %80 is = 23 287,2
since 10000+9999+8888 does contain the %80the result should return:
Barcode
101
106
107
You can do this using variables:
select t.*
from (select t.*, (#sump := #sump + profit) as running_profit
from t cross join
(select #sump := 0) params
order by profit desc
) t
where running_profit < 0.8 * #sump;
The inner query calculates the cumulative profit. As a side effect, it also calculates the total sum of the profit.
The outer where select all rows up to the first row that exceeds the 80% threshold.
Related
I have one table and trying to subtract the total where a condition is True from the full total.
Ticket
Amount
Code
11
5.00
12
3.00
X
13
10.00
14
2.00
X
My query was
SELECT SUM(AMOUNT)
FROM Table
MINUS
SELECT SUM(Amount)
FROM Table
WHERE Code = 'X'
So the answer should be 20 - 5= 15
Below two possible queries:
-- Use IF operator
SELECT SUM(amount) - SUM(IF(code = 'X', amount, 0)) FROM tbl;
-- Use implicit MySQL conversion boolean to int (true => 1)
SELECT SUM(amount) - SUM(amount * (code = 'X')) FROM tbl;
SQL editor online
I am new with mysql and working to change a store application to make it have two stock. I created a table to store stock quantity:
Then I plan to create a view with stock quantity, per store, per SKU. I using the following query:
SELECT
`stockList`.`sku`,
SUM(A.`stockQty`) AS 'store1',
SUM(B.`stockQty`) AS 'store2',
SUM(`stockList`.`stockQty`) AS 'total'
FROM `stockList`
LEFT JOIN (
SELECT * FROM `stockList` WHERE `idStock`=1
) AS A
ON `stockList`.`sku`=A.`sku`
LEFT JOIN (
SELECT * FROM `stockList` WHERE `idStock`=2
) AS B
ON `stockList`.`sku`=B.`sku`
GROUP BY `stockList`.`sku`
Per resulting table, calculation is not proper and I could not identify the logic:
SKU 43 should show for store1 = 9 and for store2 = 10, total = 19. This is what they show if I execute the select queries alone. Please, let me know if I misunderstood how this sum logic works.
You might to use SUM on subquery to calculate Totle price by sku
LEFT JOIN may make some fields not match causing NULL so use IFNULL to preset value 0
You can try this.
SELECT
T.sku,
SUM(T.stockQty) as totle,
IFNULL(A.`store1`,0) AS `store1`,
IFNULL(B.`store2`,0) AS `store2`
FROM `stockList` AS T
LEFT JOIN
(
SELECT sku,SUM(`stockQty`) as `store1`
FROM `stockList`
WHERE `idStock`=1
GROUP BY sku
) as A ON A.sku = T.sku
LEFT JOIN
(
SELECT sku,SUM(`stockQty`) as `store2`
FROM `stockList`
WHERE `idStock`=2
GROUP BY sku
) AS B ON T.sku =B.sku
GROUP BY T.sku
sqlfiddle
Your query is much more complicated than it needs to be. You can just do this:
SELECT
sku,
SUM(stockQty) as total,
SUM(IF(idStock=1,stockQty,0)) AS `store1`,
SUM(IF(idStock=2,stockQty,0)) AS `store2`
FROM `stockList`
GROUP BY sku
Output:
sku total store1 store2
36 10 10 0
37 3 3 0
38 4 4 0
39 3 3 0
40 10 10 0
41 12 12 0
42 12 12 0
43 19 9 10
I have the following data
user_id days date
88 2 2013-08-25
88 4 2013-08-23
88 18 2013-08-5
88 1 2013-08-4
88 2 2013-08-2
73 11 2013-08-2
299 4 2013-08-2
12 983 2013-08-2
I'm trying to get all recent rows (order by DATE desc) for a specific user_id , until the SUM of days column is bigger than X. For example in this case if X=7 I would get the three first rows with SUM(days)=24.
Try this. Here you will use a local variable that will count the sums in the subquery.
select
user_id,
days,
date
from
(
select
user_id,
days,
date,
#sum_days := #sum_days + days as sum_days
from
myTable
order by
date desc
) t
cross join (select #sum_days := 0) const -- resetting your #sum_days var.
where
sum_days < X -- fill a number in for X here.
I am developing an SSRS report with the following dataset (Table-1). I am grouping by Account and Period. My goal is to get the Total Expense and the Budget within a group. Because the Budget data is duplicated per group, I cannot use SUM() function for Budget. How do I remove the duplicates so the new dataset looks like this? (Table-2) Please advice. Thank you for your time.
Table-1
ID Account Period Expense Budget
1 100 201301 20 100
2 100 201301 30 100
3 100 201302 10 150
4 100 201302 40 150
5 200 ...................
Table-2
ID Account Period Expense Budget
1 100 201301 20 100
2 100 201301 30 NULL
3 100 201302 10 150
4 100 201302 40 NULL
5 200 ...................
If you really want to make duplicate budgets null try this update command
please check sqlfiddle http://sqlfiddle.com/#!3/1e619/11
Update table1
set budget = null
where id in
(
select aa.id from
(
select id,row_number()
over(partition by Budget order by Period) as rno
from table1
) aa
where rno > 1
);
select * from table1;
good luck.
I would use a windowed function if you have to do that grouping in SQL. If you can do it in SSRS just add a 'Row Grouping Parent' it would be better.
For SQL I would do this:
declare #Temp table ( ID int identity, Account int, period int, expense int, budget int);
insert into #Temp values (100, 201301, 20, 100),(100, 201301, 30, 100),(100, 201302, 10, 150),(100, 201302, 40, 150)
select *
from #Temp
select
ID
, Account
, Period
, Expense
, case when (row_number() over(partition by Budget order by Period) = 1) then Budget end as Budget-- only shows first occurrence of an order amount ordering by person
from #Temp
i have a table in my database named subscriber which contains two rows one for the subscriber id and another one for points earned by each subscriber .
My Select query :
SELECT 1000 * ( LOYALTY_POINTS DIV 1000 ) AS 'from', 1000 * ( LOYALTY_POINTS DIV 1000 ) +1000 AS 'to', COUNT( * ) AS NUMBER FROM SUBSCRIBER GROUP BY LOYALTY_POINTS DIV 1000
should return for each range of points the number of subscribers but unfortunately it only returns the number of subscribers different than zero.
My result is:
from to NUMBER
0 1000 8
1000 2000 2
3000 4000 1
I want the query to return records with zero coun also.
The result should be:
from to NUMBER
0 1000 8
1000 2000 2
2000 3000 0
3000 4000 1
How to do it? Thank you in advance.
You need to generate some numbers to indicate your range
SELECT 0 as RangeStart UNION Select 1000 UNION Select 2000 UNION Select 3000
and LEFT JOIN this to your results.
SELECT
RangeStart, RangeStart + 999 as RangeEnd, RangeCount
FROM
(SELECT 0 as RangeStart UNION Select 1000 UNION Select 2000 UNION Select 3000) range
LEFT JOIN
(Select LoyaltyPoints DIV 1000 as loyaltypoints, count(*) as RangeCount group by LoyaltyPoints DIV 1000 ) counts
ON range.rangestart = counts.loyaltypoints