I've got a problem!
I've got a simple table which contains player_1, player_2, and played.
+---------+----------+----------+
| player1 | player2 | played |
+---------+----------+----------+
| 1 | 2 | 1 |
| 1 | 3 | 2 |
| 1 | 4 | 1 |
| 1 | 5 | 0 |
| 1 | 6 | 0 |
| 2 | 3 | 3 |
| 2 | 4 | 2 |
| 2 | 5 | 1 |
| 2 | 6 | 3 |
| 3 | 4 | 1 |
| 3 | 5 | 2 |
| 3 | 6 | 0 |
| 4 | 5 | 3 |
| 4 | 6 | 1 |
| 5 | 6 | 3 |
+---------+----------+----------+
and so on... There are 78 records, because there are 13 players in total.
I would like a result that shows me which 'matches' have been least played. So, e.g. a person was sick and couldn't play last time, the played games between that person and other players are lower. This game is more likely to be in the result.
But in each result, which shows me 6 matches (1 player has some time off), a player can be displayed only once! However, the least played games have to be in the result too. (well, the last part is easy, ORDER BY played ASC, LIMIT 6)...
How do I get each 13 players (well, without the one) to be in the result?
A nice result would be (well, now I'd like only 3 matches, because in this example are only 6 players)...
Every player plays a game in this round, and it is selected by ordening the least played games. The rest is just being filled in.
+---------+----------+----------+
| player1 | player2 | played |
+---------+----------+----------+
| 1 | 5 | 0 |
| 2 | 4 | 1 |
| 3 | 6 | 0 |
+---------+----------+----------+
You can think of this as a Graph Problem.
Let's say each player is a node, and every record in a table represents an arc, a weighted arc with weight of 'played', The number of games played between the 2 players connected with the arc.
Now, what you're looking for is an algorithm to find the 6 matches least played (if I understand correctly, the 6 matches to play in the next round) providing that every player plays only once a round.
I suggest using a greedy algorithm:
1. Sort arcs ascending.
2. While there are still arcs left.
2.1 Remove first arc and add to round_games.
2.2 Remove all arcs with any participating nodes in the previous arc.
Related
I'm working on a project where I list 5 problems with 2 solutions each. The users can vote on one solution per problem. Now I have to calculate the percentage of the highest value per problem.
For example in problem 1 I have 20 votes on solution 1 and 30 votes on solution 2, I want to get 60%. I know I will have to count the two vote values together per problem divide by 100 and then multiply by the value that is the highest.
How do I do this in my dao (with sql) ? Do I have to make another column in the table 'solutions'?
table: solutions
+----------+------------+---------+
| id | id_problem | vote |
+----------+------------+---------+
| 1 | 1 | 25 |
| 2 | 1 | 10 |
| 3 | 2 | 18 |
| 4 | 2 | 2 |
| 5 | 3 | 6 |
| 6 | 3 | 7 |
| 7 | 4 | 11 |
| 8 | 4 | 4 |
| 9 | 5 | 5 |
| 10 | 5 | 2 |
+----------+------------+---------+
Try this:
select
id_problem,
CONCAT(ROUND(MAX(vote) / SUM(vote), 2) * 100, '%') as Percentage
from solutions
group by id_problem;
Okay so I'm creating a task manager for my company. A user can assign assign a task to multiple other users. So I've though of 2 ways of implementing this.
This is my tasks table for option one (at least the columns that are important in this discussion ):
----------------------------------------------
| id | assigned_to | assigned_from |
---------------------------------------------
| 1 | 1,3,6 | 4 |
--------------------------------------------
| 2 | 1,4 | 2 |
---------------------------------------------
So here I pretty much just comma separate each user_id that is assigned to this particular task
Option 2:
----------------------------------------------------------
| id | task_id | assigned_to | assigned_from |
------------------------------------------------------------
| 1 | 335901 | 1 | 4 |
-----------------------------------------------------------
| 2 | 335901 | 3 | 4 |
-----------------------------------------------------------
| 3 | 335901 | 6 | 4 |
-----------------------------------------------------------
| 4 | 564520 | 1 | 2 |
-----------------------------------------------------------
| 4 | 564520 | 4 | 2 |
-----------------------------------------------------------
So as you can see here instead of putting the assiged_to is's here I just create a task id which is a random number and then I can groupBy 'task_id'. This is currently they way I have built it but for some reason it feels like it might screw me over in the future (not that option one doesn't give me the same feeling). So my question is which way do you guys recommend or is there maybe a different better way that I could be doing this?
Option 2 ist the better solution since you can acutally work with the table. You may e.g. create another table Tasks with
Task_id | Task_name | Budget | ...
Or a table with user-IDs for assigned_to and assigned_from. All these tables can be joined together if you use 2nd Option.
btw it is the correct normalization form
You can use Option 2 and normalize further if tasks are always assigned by/from the same person.
Tasks table:
task_id | assigned_from
1 | 4
2 | 2
The Assignees table then doesn't need to have the assigned_from since it's always the same for that task_id:
id | task_id | assigned_to
1 | 1 | 1
2 | 1 | 3
3 | 1 | 6
4 | 2 | 1
5 | 2 | 4
Okay, so lets say that we have 4 columns and 3 rows of data.
|user_id|pick_1|pick_2|pick_3|
-------------------------------
|fred |C++ |java | php |
------------------------------
|eric |java |C++ | php |
------------------------------
|sam | C++ | php | java |
------------------------------
So right now, users are entering their favorite languages. The first pick(pick_1) would be the favorite programming language and the second pick (pick_2) would be the 2nd favorite programming language and etc.
How can I organize this in a way so that I can give a point value according to what columns the programming languages are. So maybe pick_1 can give 3 points, pick_2 can give 2 points and pick_3 can give 1 point.
So when you tally up the scores, C++ will have 8 points, java will have 6 points, and php will have 4 points.
That way I can give an overall ranking of what tends to be the more favorable programming language. Like so
|rank|language|points|
----------------------
| 1 | C++ | 8 |
----------------------
| 2 | java | 6 |
----------------------
| 3 | php | 4 |
----------------------
It doesn't even need to have a point system, I just couldn't think of another way to rank the languages on a scale of liked to un-liked. So if there's another way to yield the same results than please let me know. Otherwise how would I be able to do this. Preferably in just MySql. I am currently using PHP.
Thank you for reading.
You need a simpler structure
User_ID | Pick | Points
Fred c++ 3
Fred php 2
Fred java 1
This way you can do a simple sum(points) group by pick
for a SQL only solution, I would normalize your structure, and put the picks in a different table:
users: user_id; user_name
picks: pick_id; user_id; language; points;
then you would have your data in 2 tables:
| user_id | user_name |
-----------------------
| 1 | Fred |
-----------------------
| 2 | Eric |
-----------------------
| 3 | Sam |
-----------------------
| pick_id | user_id | language | points |
---------------------------------------------
| 1 | 1 | C++ | 1 |
---------------------------------------------
| 2 | 1 | Java | 2 |
---------------------------------------------
| 3 | 1 | php | 3 |
---------------------------------------------
| 4 | 2 | Java | 1 |
---------------------------------------------
| 5 | 2 | C++ | 2 |
---------------------------------------------
| 6 | 2 | php | 3 |
---------------------------------------------
| 7 | 3 | C++ | 1 |
---------------------------------------------
| 8 | 3 | Java | 2 |
---------------------------------------------
| 9 | 3 | php | 3 |
---------------------------------------------
And then use the following query to fetch the desired result:
SELECT language, SUM(points) FROM users JOIN picks ON users.user_id=picks.user_id GROUP BY language
As seen in this fiddle
This way it's also easy to add constraints so people can not vote for a language more then once, or give the same amount of votes to 2 different languages.
i will create schema the database MySQL. There are username, password etc and rating system and available in month.
Standard it looks like this:
id | username | password | january | february | march | rating1 | rating2| rating3 |
1 | john | xxx | 1 | 0 | 1 | 3 | 3 | 6
2 | amy | xxx | 1 | 1 | 0 | 1 | 6 | 3
if a user buys article then must add a rating (1,2,3). if chose 2 in John then rating2 +1
id | username | password | january | february | march | rating1 | rating2| rating3 |
1 | john | xxx | 1 | 0 | 1 | 3 | 4 | 6
2 | amy | xxx | 1 | 1 | 0 | 1 | 6 | 3
january, february (1 - available, 0 - not available)etc set himself John or Amy.
this is good? Should I create separate tables for Januar/feb/march and rating1/2/3? Maybe only for rating?
im not a hard core database designer but at a glance this is schema is not normalized.
if you can create a separate table for month and rating would be better please find the below sample
d | username | password
1 | john | xxx
2 | amy | xxx
id | month | rating
1 | 1 | 3
MonthID | MonthName
1 | January
How ever this sujjestion may not be the ideal solution for your proposed database.
OK I know this is late but this is very serious!!!
First use bcrypt for encrypting passwords
Second NEVER store a password that is not encrypted properly. You need a "salt" to do this correctly.
See here: http://www.nathandavison.com/posts/view/13/php-bcrypt-hash-a-password-with-a-logical-salt
I'm not a php guy but it looks good.
As for the DB, Prabhakantha's answer looks OK but might not be complete suitable.
Users
id | username | password | salt
1 | john | xxx | blah
2 | amy | xxx | ughh
ratings
id | month_id | rating
1 | 1 | 3
Months
id | month | year
1 | January | 1990
I know in the ruby on rails world I would model this with a polymorphic association. Take a look how that works here: http://railscasts.com/episodes/154-polymorphic-association
Yes it is a video on rails but it applies here.
I am just puzzled here. Maybe because it's the end of the day, I dont know. Im using PHP to grab items from a MySQL db. I am just looking for some PHP help. I have the HTML and CSS done. Here is the basic structure of the db. Its a nested set btw. Imagine that my left and right values for the nested set have been sorted in MySQL already which leaves me with depth.
----------------------------------------
| id | title | sequence_number | depth |
----------------------------------------
| 1 | A | 1 | 1 |
| 2 | B | 2 | 1 |
| 3 | C | 1 | 2 |
| 4 | D | 3 | 1 |
| 5 | E | 4 | 1 |
| 6 | F | 2 | 2 |
| 7 | A | 1 | 3 |
| 8 | B | 5 | 1 |
| 9 | C | 3 | 2 |
| 10 | D | 2 | 3 |
| 11 | E | 6 | 1 |
| 12 | F | 4 | 2 |
----------------------------------------
Now if that's not enough to confuse you then keep reading. I am using a foreach loop to loop through each item and sort it manually like that. The problem is the menu eventually will go to 3 levels which gets me stuck as my loop is only for two levels. Can anybody help me sort this array?
you could use a recursive function
eg
loop through with depth set as 1 then re-call the function with depth set as depth + 1
does that help?
Josh