Get random table rows whose column weight sum up to a value - mysql

I have a mysql table like this with about 100 rows
id | text | weight
---------------------
1 | textA | 2
2 | textB | 3
3 | textC | 8
...
and I am trying to create a query that would return a random set of rows (but at least 3) of this table, whose sum of weight would be equal to 10. So as a result I would get a number of rows X that sum up to 10.
Could you suggest a way to achieve this? Would it be some sort of plsql script or what?
Thanks!

Related

Sql query with mixed selected rows order

I have a table that looks like below:
| id | group_id | title |
-------------------------
| 1 | 1 | Hello |
| 2 | 1 | World |
| 3 | 2 | Foo |
| 4 | 2 | Bar |
My query may look like below to return the results above:
SELECT * FROM my_table ORDER BY id
Question
How can I order this table so that the group ids appears to be random, but still the same every time the query is executed.
Possible result example
This result looks to be in a random order. If I run the same query a week later, I want to see the exact same order which means it's not really random.
| id | group_id | title |
-------------------------
| 2 | 1 | World |
| 4 | 2 | Bar |
| 1 | 1 | Hello |
| 3 | 2 | Foo |
Appears to be random from a group_id perspective. It's no longer ordered by group_id like 1 1 2 2, but 1 2 1 2. It could also have been 2 1 1 2 or something that does not increase.
Should return the same results every time, not random each time.
I could order by title but if a title should change that row will be reordered. So the order needs to be made with the id I guess.
I want to avoid file or database caching if possible.
Is it possible?
How about taking the modulo function for your advantage.
SELECT * FROM my_table ORDER BY id % 3,id
Define a value to use with the modulo function (in my example 3) and order your table by the modulo of the id.
This should return the same order everytime you run the query and return some order that is pseudo random.
Since the modulo function can return the same value for different ids you also need to order by the original id to have a defined, reproducable order.
order this table so that the group ids appears to be random
Only ORDER BY RAND() may provide really random ordering.
but still the same every time the query is executed
Create separate static ordering table, fill it randomly with source table's ids, join it and order by it.
I did not solve the problem with the solution from #Kylro, but I found another way which works great.
SELECT * FROM my_table ORDER BY COS(id), id
Cos is sometimes a positive value and sometimes a negative value, almost random like. It works perfecty for this problem.

How to select random rows whose column sum meets the condition in MySQL

Is it possible to select random rows from a table whose particular column total (sum) should be less than my condition value ?
My table structure is like -
id | question | answerInSec
1 | Quest1 | 15
2 | Quest2 | 20
3 | Quest3 | 10
4 | Quest4 | 15
5 | Quest5 | 10
6 | Quest6 | 15
7 | Quest7 | 20
I want to get those random questions whose total sum of 'answerInSec' column is less than (nearest total) or equal to 60.
So random combination can be [1,2,3,4] OR [2,3,5,7] OR [4,5,6,7] etc.
Is this possible in single MySQL query ?
Are you look for this :
SELECT * FROM tbl_name ORDER BY RAND() WHERE [condition] LIMIT 10

mySQL get all possible combinations of certain rows

I have a strange request in mySQL. I found many ways to do this for pairs of combinations or a certain other number by adding more joins, but I am wondering if there is a dynamic way of doing it for any number of combinations.
To explain if I have a table table has 1 column (column_id) and (column_text)
Id | Text
--------
1 | A
2 | B
3 | B
4 | B
5 | A
Then by running a procedure GetCombinations with parameter A should yield:
CombinationId | Combinations
---------------------------
1 | 1
2 | 5
3 | 1,5
by running a procedure GetCombinations with parameter B should yield:
CombinationId | Combinations
---------------------------
1 | 2
2 | 3
3 | 4
4 | 2,3
5 | 2,4
6 | 3,4
7 | 2,3,4
Obviously the larger the number, then I expect an exponential increase of results.
Is such a query even possible? All I could find was results using Joins limiting the length of each result to the number of Joins.
Thank you
UPDATE
I have found an article here but the maximum number of combinations should be small (max 20 or so). In my case with a 100 combinations I calculated that it would produce: 9426890448883247745626185743057242473809693764078951663494238777294707070023223798882976159207729119823605850588608460429412647567360000000000000000000099 rows (lol)
So I will classify my answer as infeasible
However is there a way to get this result with max 2 combinations?
CombinationId | Combinations
---------------------------
1 | 2
2 | 3
3 | 4
4 | 2,3
5 | 2,4
6 | 3,4
I have found a query to get all combinations using JOIN but I am not sure how to produce the combination id and also how to get the individual rows.
UPDATE 2
Solved it using
SELECT #rownum := #rownum + 1 AS 'CombinationId'
cross join (select #rownum := 0) r
And I did the query with UNION ALL
What you are trying to do is to generate the Power Set of the set of all elements with field Text == <parameter>. As you already found out, this number grows exponentially with the length of the input array.
If you can solve it in other language (say, php), take a look at this:
Finding the subsets of an array in PHP

MySQL select N rows under different conditions

Suppose there is a table as
| id | value |
| 1 | xyz |
| 4 | abc |
| 5 | test |
I want to select N rows where id is smaller than a number X, but if this result set is less than N rows, I want following rows added to ensure there are N rows selected (unless there is no sufficient rows in this table).
For example, I want to get N=2 rows where id is no larger than X=4, so I get 1st and 2nd rows. But If I want to get N=3 rows for X=4, I want all the three rows.
Can I do this in one statement and try to be efficient?
You want to prioritize the rows. You can do this using order by and limit. Here is an example:
select t.*
from table t
order by (x <= #X) desc, x
limit 2;

Average values in a column across several rows for each unique value in another column in MS Access

I have query which produces a result like this:
ID | Area | Price
1 | A | 10
2 | A | 15
3 | A | 10
4 | B | 20
5 | B | 15
The query linked two tables one with ID and Area, another with ID and Price. I want change my query to average the price field for each area so I would end up with:
Area | Price
A | 11.6
B | 17.5
I have multiple price fields which I would like to average in the same format.
I'm using MS Access 2010.
You can achieve your desired result by simply basing your "averaging query" on your existing query. Say your existing query was saved as AreaAndPriceByID. Just create a new query like this:
SELECT Area, AVG(Price) AS AvgPrice
FROM AreaAndPriceByID
GROUP BY Area
If you want to round the averages to one decimal place you can use Round(AVG(Price), 1) instead.