Custom select if sum>x - mysql

I have this table :
TICKETID | PRICE | NUMBER
So for each ticketid, the player can pay a price for each number on the ticketid.
So if the player wants to pay 1$, 3$ and 4$ for numbers 22,23 and 24 for ticketid 25, then the table will look like this :
TICKETID | PRICE | NUMBER
25 | 1 | 22
25 | 3 | 23
25 | 4 | 24
I want to select a random ticket that has TOTAL PRICE >50, to make it receive a prize.
I also want that the randomization to be fair, and that when doing this draw, each ticket would have only 1 apparition rate. If I don't use DISTINCT or GROUPBY, then a ticketid with 10 numbers will have more chances to get drawn than a ticket with 2 numbers.
I tried this but it's not working:
SELECT DISTINCT(ticketid),SUM(price) FROM table
WHERE SUM(price)>50 GROUP BY ticketid
I get the error message
invalid usage of GROUP BY function
Can anybody help?

What you want is the "HAVING" clause which is applied to any possible candidate records AFTER the group by aggregations have been processed. The Having is applied THEN and either included (or not) in the final result set.
SELECT
ticketid,
SUM(price) TotalPrice
FROM
table
group by
TicketID
HAVING
sum(price) > 50

Related

Need validation that interpretation for a Grouping Query is correct

I am running the following query and at first it appears to give the sub totals for customers and shows by date each customers payment amounts only if that total for all payments is greater than $90,000.
SELECT
Customername,
Date(paymentDate),
CONCAT('$', Round(SUM(amount),2)) AS 'High $ Paying Customers'
FROM Payments
JOIN Customers
On payments.customernumber = customers.customernumber
Group by customername, Date(paymentDate) WITH ROLLUP
having sum(amount)> 90000;
But upon looking at the records for Dragon Souveniers, Ltd. and Euro+ Shopping Channel is is actually showing the paydates that have amounts individually over $90000 as well as the subtotal for that customer as a rollup. For all other customers, their individual payment dates are not reported in the result set and only their sum is if it over $90000. For example Annna's Decorations as 4 payment records and none of them are over 90000 but her sum is reported as the value for the total payments in the query with the rollup. Is this the correct interpretation?
The HAVING clause work correct, It filters all records with a total no above 90000. It also does do this for totals.
When using GROUP BY .... WITH ROLLUP, you can detect the created ROLL UP lines by using the GROUPING() function.
You should add a condition in a way that the desired columns are not filtered.
Simple example:
select a, sum(a), grouping(a<3)
from (select 1 as a
union
select 2
union select 3) x
group by a<3 with rollup;
output:
+---+--------+---------------+
| a | sum(a) | grouping(a<3) |
+---+--------+---------------+
| 3 | 3 | 0 |
| 1 | 3 | 0 |
| 1 | 6 | 1 |
+---+--------+---------------+
this shows that the last line (with grouping(i<3) == 1) is a line containing totals for a<3.

Combine results from 3 sql queries to calculate running stock

I am trying to calculate the stock by product a warehouse had over time. I have the information about today's stock, and also the amount of products sold and purchased by day. So, the calculation for yesterday values would be:
Yesterday_stock=Stock-yesterday_sold_quantity+yesterday_purchased_quantity. My problem is that i should save somewhere the amount of everyday's stock in order to calculate the stock of the previous day. I found that in order to do that i could use over sql clause with order by. But unfortunately, i have sql server 2008 and this is not a choice.
The tables are:
Prdamount which holds the current stock per product (StuPrdID ) and if it is blocked for some reason.
|-------------- |------------------|---------------
| StuPrdID | StuQAmount |prdBlockingReason
|---------------|------------------|-------------
| 12345| 16 |
|---------------|------------------|--------------
| 08889| 12 | expired
|---------------|------------------|------------
Table Moves which holds information about inserts and outputs of products. If MoveCase field has value equal 1 it is an output move, if it is a 2 it is a purchased quantity. Moves table dummy data:
|-------------- |--------------------- -|--------|-------
|MoveItemCode | MoveDate |MoveCase|MoveRealQty
|---------------|---------------------- |--------|-------
| 12345 |2018-06-24 00:00:00.000| 1 |14
|---------------|-----------------------|--------|--------
| 08889 |2018-06-24 00:00:00.000| 2 |578
|---------------|-----------------------|--------|--------
and table Product with information related with data:
|-------------- |------------------|
| PrdCode | PrdDespription |
|---------------|------------------|
| 12345| Orange juice|
|---------------|------------------|
| 08889| Chocolate|
|---------------|------------------|
I want an output like this:
|------------|--------------------- -|--------|--------------|------------
|Prdcode | PrdDescription |Stock |Stock 18/07/03|Stock 18/7/02
|------------|---------------------- |--------|--------------|------------
| 12345 |Orange Juice | 80 |50 34
|----------- |-----------------------|--------|--------------|------------
| 08889 |Chocolate | 45 |82 17
|------------|-----------------------|--------|--------------|-------------
this query gives me the running stock:
select
product.PrdCode,
product.PrdDescr,
SUM(StuQAmount) as Stock
from prdamount
left join product on (product.PrdID=prdamount.StuPrdID)
where prdamount.prdBlockingReason=' '
group by product.PrdCode,product.PrdDescr
order by product.PrdCode asc
This query gives me the quantity sold by product per day:
select
moves.MoveItemCode,
prd.PrdDescr,
moves.MoveDate,
SUM(MoveRealQty) as 'sold_quantity'
from moves
left join prd on (moves.MoveItemCode=product.PrdCode)
where (moves.MoveDate>'2018-06-01' and and moves.MoveCase=1)
group by moves.MoveItemCode,product.PrdDescr,moves.MoveDate
order by moves.MoveItemCode asc,moves.MoveDate asc
And this query gives me the quantity purchases by product per day:
select
moves.MoveItemCode,
prd.PrdDescr,
moves.MoveDate,
SUM(MoveRealQty) as 'Purchased_Quantity'
from Moves
left join product on (moves.MoveItemCode=product.PrdCode)
where (moves.MoveDate>'2018-06-01' and moves.MoveCase=2)
group by moves.MoveItemCode,product.PrdDescr,moves.MoveDate
order by moves.MoveItemCode asc,moves.MoveDate asc
I tried to combine these 3 queries into one using subqueries, but it didn't work. So how can i accomplish the result that i want? Sorry if the question is silly, i am a beginner in sql
try this,
select
product.PrdCode,
moves.MoveItemCode,
product.PrdDescr,
moves.MoveDate,
SUM( case when moves.MoveCase=1 then MoveRealQty else 0 end) as 'sold_quantity',
SUM( case when moves.MoveCase=2 then MoveRealQty else 0 end) as 'Purchased_Quantity',
(select SUM(StuQAmount) from prdamount where StuPrdID = product.PrdID and prdBlockingReason=' ')
from moves
left join product on (moves.MoveItemCode=product.PrdCode)
where (moves.MoveDate>'2018-06-01')
group by moves.MoveItemCode,product.PrdDescr,moves.MoveDate, product.PrdCode
order by moves.MoveItemCode asc,moves.MoveDate asc

Mysql Agregate function to select maximum and then select minimum price within that group

I am trying to get the maximum value out of a aggregate function, and then also get the min value out of a Price column which comes back in results.
id | discount | price
1 | 60 | 656
2 | 60 | 454
3 | 60 | 222
4 | 30 | 335
5 | 30 | 333
6 | 10 | 232
So in above table, I would like to separate Minimum Price vs Highest Discount.
This is the result I should be seeing:
id | discount | price
3 | 60 | 222
5 | 30 | 333
6 | 10 | 232
As you can see, its taken discount=60 group and separated the lowest price - 222, and the same for all other discount groups.
Could someone give me the SQL for this please, something like this -
SELECT MAX(discount) AS Maxdisc
, MIN(price) as MinPrice
,
FROM mytable
GROUP
BY discount
However, this doesnt separate the minimum price for each group. I think i need to join this table to itself to achieve that. Also, the table contains milions of rows, so the sql needs to be fast. One flat table.
This question is asked and answered with tedious regularity in SO. If only the algorithm was better at spotting duplicates. Anyway...
SELECT x.*
FROM my_table x
JOIN
( SELECT discount,MIN(price) min_price FROM my_table GROUP BY discount) y
ON y.discount = x.discount
AND y.min_price = x.price;
In your query, you cannot group by discount and then maximize the discount value.
This should get you the result you are looking for..
SELECT Max(ID) AS ID, discount, MIN(price) as MinPrice, FROM mytable GROUP BY discount
If you do not need the id, yo would do:
select discount, min(price) as minprice
from table t
group by discount;
If you want other columns in the row, you can either join back to the original table or use the substring_index()/group_concat() trick:
select substring_index(group_concat(id order by price), ',', 1) as id,
discount, min(price)
from table t
group by discount;
This will not always work because the intermediate result for group_concat() can overflow if there are too many matches within a column. This is controlled by a system parameter, which could be made bigger if necessary.

how to sort 2 different column in sql

can you guys show me how to sort user define column and fixed column name in sql. i need to display the highest transaction and outletid, instead i only get the highest transaction but the oulet id is not in grouping.
pardon me, im very bad at english
here is the problem
outlet id | revenue code | total transaction | total amount
6837 | 014 | 326 | 39158.94
6821 | 408 | 291 | 48786.50
6814 | 014 | 285 | 74159.76
6837 | 452 | 282 | 8846.80
and here is my sql
SELECT
outletid,
revcode,
count(receiptnumbe) as Transactions,
sum(amount) as total
FROM
user_payment
WHERE
date = (SELECT MAX(date) FROM user_payment GROUP BY date desc LIMIT 0, 1)
GROUP BY
outletid, revcode
ORDER BY Transactions desc
i need it to be like this. sort by outlet id and highest transactions.
outlet id | revenue code | total transaction | total amount
6837 | 014 | 326 | 39158.94
6837 | 452 | 282 | 8846.80
6821 | 408 | 291 | 48786.50
6814 | 014 | 285 | 74159.76
Is this what you want?
ORDER BY OutletId, Transactions desc
EDIT:
If I understand correctly, you want it sorted by the outlet that has the most total transactions. Then by transactions within that group. To do that, you need to summarize again at the outlet level and join back the results:
select outor.*
from (SELECT up.outletid, up.revcode, count(up.receiptnumbe) as Transactions,
sum(up.amount) as total
FROM user_payment up
WHERE date = (SELECT MAX(date) FROM user_payment)
GROUP BY outletid, revcode
) outor join
(SELECT up.outletid, count(up.receiptnumbe) as Transactions,
sum(up.amount) as total
FROM user_payment up
WHERE date = (SELECT MAX(date) FROM user_payment)
GROUP BY outletid
) o
on outor.outletid = o.outletid
order by o.Transactions desc, outor.outletid, outor.Transactions desc;
1)The first thing to do is make sure that you are sorting the fields the way you want to. Do you want them sorted numerically or alphabetically?
See Sorting Lexical and Numeric
Count should be numerical, but you should check outletid.
If you have access to the tables, you could change the field to a number type for it to be sorted numerically or a string for it to be sorted alphabetically.
You might have to use cast or convert. See Oracle Cast Documentation.
2)If you want the whole table sorted by outlet id and amount of transactions you might consider removing the group by clause.
3)The third thing I would look at even if this did work is renaming column names that had reserved words to the tables that were reserved words. I noticed transaction highlighted in blue.
When these things are checked Melon's comment should work.
Good question. Feel free to comment so I can follow up.

Multiple SUM commands

I am trying to sum a column in my table, the problem being there are multiple sums that need to be done.
So for instance there may be 40 records with an ID of 1 and a point value of 20, And then it will change to a new person with an ID of 2 and a point value of 20. If that makes sense.
How I want to do the query, but it doesn't work is like this:
SELECT SUM(Value)
FROM Points WHERE RegNum IN('','','')
And then I would like it to show up just like a normal SUM command would, with the total summed up, but with a line for each ID. I have looked over other questions about SUM commands and just can't quite apply it to my situation.
Thank you for any help.
It seems like you need to use a GROUP BY in your case. Try
SELECT RegNum, SUM(Value) total
FROM Points
WHERE RegNum IN(1, 2, 3)
GROUP BY RegNum
Sample output:
| REGNUM | TOTAL |
------------------
| 1 | 17 |
| 2 | 9 |
| 3 | 1 |
Here is SQLFiddle demo
Try
SELECT RegNum, SUM(Value) as TotalRegNum
From Points
WHERE RegNum IN('1','2','3')
GROUP BY RegNum