Resolving a many to many relationship in an RPG game - mysql

In an RPG game a character can choose from a list of skills, which in turn are stored in a unique skill list for that character.
The problem being that there is still a many to many relationship between skills and skill list that I would like to resolve.
I've read through the other articles and I am still none the wiser, can anyone shed some light on this problem.
Thanks in advance.

I don't understand why there would be a many to many relationship between skills and skill list. That sounds like a many to one relationship. But if you really mean you are trying to link the characters to the skills then:
You will need a third table that links the skills table to the characters table, something like the following:
Table: characterskills
characterid
skillsid
Then using SQL you can retrieve a master list of all characters and all of their skills:
SELECT c.charname, s.skillname FROM
characters AS c
INNER JOIN characterskills AS cs ON cs.characterid = c.id
INNER JOIN skills AS s ON cs.skillsid = s.id
Here is the SQL Fiddle demonstrating the above.

Related

Using sakila database to find a movie by language

I'm new to the site and new in sql.
I use a sample database of sakila, I downloaded it from mysql website.
https://dev.mysql.com/doc/index-other.html
I want to find a movie name by its language.
For example I want to find all the movies whose language is their original is English.
I have 2 tables that I use, the movie table and the language table, I JOIN this 2tables, and then return the names of the movies that are in English.
This is what I wrote down, but I can not understand why it does not work for me
Select title from film,language where original_language_id=language.language_id and language.name="ENGLISH";
I get an empty table, even though my movies are in English
Picture of the movie table, language table and query I wrote down:
language table
movie table
query i wrote
I do not understand where the problem is, I think the problem is very small, but I can not find it
It's odd that anything came back with your original query as the original_language_id data is NULL, meaning no data has ever been set. Here is a SQL query that should give you what you need:
SELECT f.`title`
FROM `film` f INNER JOIN `language` l ON f.`language_id` = l.`id`
WHERE l.`name` = 'English';
If you're new to SQL, welcome! Do try to use the proper JOIN style as the method you used has not been actively used for 20+ years.
Cheers,

How to count entries of a data\row in another table in MySql?

The database and entries are as in the figure below:
Teacher table
Course table
1) Show how many courses each teacher is teaching.
2) Give the name of the teacher who teaches more than two courses.
Is it necessary to use join(s) or can we perform the actions by any other means?
Thank you in advance.
Any help is appriciated.
A join is necessary, as you are trying to receive a result based on data from two tables. To even know what courses a teacher is teaching, you must join the tables.
Imagine you were at a hackathon, and you met a friendly coder there. You remember one very distinct thing about him - we'll say he had a very distinct hair style that no one else at the hackathon had. However, that's the only thing you can remember about him. You ask your friend that was with you if he remembers your new found friend, describing him by his distinct hair style. Lucky you, he remembers! Your friend then tells you all the other details about your new found hackathon companion (e.g. his name, where he was from, etc.). In this case, your friend is the join. You only knew one distinct thing about the hackathon man (like a foreign key in a database), but it was distinct enough to get you the rest of the information about the man.
Putting this in context of your situation, your tables will need to have a foreign key relationship. This will allow you to link the tables together so that you can see what courses each teacher is in charge of.

How to extract out all multiple ID's of the same person in MYSQL

Say that I am given a data-model with different entities connected to each other with one-many or many-one relationships. I am suppose to find the songs that were done by the artist AKON. How can we use the sequel query to find that. He has multiple ID's in the the entity which then is used to find the Song he did. How can we use the SQL to find those out.
Say we are given the ID's (1,10002,2908) but we do not know those, all we do know is the name 'AKON' which helps us to find the different ID's and all the songs connected with those ID's
Hm sounds like a simple Join query.
SELECT a.songid FROM db.songs a
INNER JOIN db.artists b on b.artistid=a.artistid
WHERE b.artistname='AKON'
Is that what you´re looking for?

Can I display one to many results in results table?

I have a table for person and a table for language. Each person can speak up to 4 languages. My client wants to search for people that can speak, for instance Spanish.
My problem is that the results table currently won't have a column called Language because they will speak more than one. I could display just the first one, but it will be misleading to hide the other languages that they speak.
The table could have a column for each language, and fill in NULL if they don't have all 4 languages, i.e.:
Language 1
Language 2
Language 3
Language 4
But this seems very sloppy.
I have considered listing all of the languages in a single column, using a comma separated list, but this is know good for sorting the column alphabetically.
Currently, I am having to tell my client that the results table can only show columns where the person has one of them (1 to 1), i.e. name, location, native language etc. Only when the client clicks on that person, can it reveal all of their languages.
Does anyone know if there is a common way to solve this? Hope this makes sense
I do have an association table. The problem is that my search will return
joe bloggs, gotham city, spanish
then
joe bloggs, gotham city, french
on the next row - but then the same person is listed twice in the table. When I restrict it to one entry per name, I just get "joe bloggs, gotham city, spanish". Now I don't know that he also speaks french. Is this clearer?
You should have a join table which contains two fields: person and language. There should be one row per person per language, so if one person speaks four languages, there would be four rows for this user.
The primary key for this table would comprise both fields.
Then to get a list of which people speak Spanish, you would need a query like
select people.name
from people inner join p2l
on people.id = p2l.person
inner join languages
on p2l.language = languages.id
where languages.name = 'Spanish'
And a list of all people who speak a language
select people.name, languages.name
from people inner join p2l
on people.id = p2l.person
inner join languages
on p2l.language = languages.id
And now a list of all people, whether they speak a language or not
select people.name, languages.name
from people left join p2l
on people.id = p2l.person
inner join languages
on p2l.language = languages.id
Having thought about this some more, it seems that you have the following options
Use the simple join/link/association table that both Christophe and I suggested, then massage the data in the program which calls the SQL. This is the simplest route to take.
Maintain a comma delimited list of languages along with the join table. The join table will allow you to answer queries such as 'who speaks Spanish', whereas the list will enable you to print out a list of languages per person. Maintaining this list will be a problem.
Use the 'dedicated field per language' approach of Ravindra; every time you need a new language, you will have to change the field structure, thus this approach is very much not recommended.
Use a cross tab query; this is quite hard to do and depends on which flavour of SQL you are using. Look at this article creating-cross-tab-queries-and-pivot-tables-in-sql.
In my option, option 1 is the best and easiest. SQL is great at what it does and terrible at what it doesn't do, so it's best to take the best parts of SQL and surround them with the best parts of a declarative language.
So the traditional way to solve this is to create something called an association table, which has foreign keys to both the person and language tables. This lets you add an arbitrary number of languages (including zero). Then you can join accross these tables to find all users speaking a specific language.
This may help with how to structure databases: http://en.wikipedia.org/wiki/First_normal_form
There's higher normal forms, but this will help you solve your current problem.
create two table
person having cloumns- person_id,person_name & more if u want.
create another table -Language having columns-person_id,lang1,lang2,lang3,lang4
make person_id as foreign key
now when u want to access languages, just fetch them by compairing person_id
SELECT p.person_id
FROM person p, language l
WHERE p.person_id = l.person_id;

SQL Multiple Inner Joins on the same field

I am currently working as a programmer in a small startup aiming on providing pay-per-view content online and I have been assigned to develop the metadata database for the movie catalogue
I have two main tables, movie and people, where *movie_ID* and *people_ID* are the primary keys respectively for each table. Both tables have a many-to-many relationship.
To represent different relations I am currently using link tables, for example, actor_movie would store the *movie_ID* and corresponding *people_ID* for each of the actors in the movie, while the director_movie table would store the *movie_ID* and the director(s) *people_ID*. Same goes for writer, composers and producers.
Now, my problem is that I need to craft out a query that returns all the actors, directors, producers, writers, composers, etc. etc. in one single table to be passed on the frontend Web UI as a list of all the persons involved in the movie.
I'm currently stumped as to how to create a multiple SELECT query that would JOIN all the link tables together based on the *movie_ID* and *people_ID* and then return the details of each of the person in the people table as well.
And example of what I have written so far is:
SELECT
movie.titleMovie,
people.namePeople,
FROM
movie movie
INNER JOIN actorlinkmovie acm ON acm.idMovie = movie.idMovie
INNER JOIN people people ON people.idPeople = acm.idPeople
What I would like to have happen is:
SELECT
movie.idMovie,
movie.titleMovie,
movie.descMovie,
movie.dateMovie,
movie.runtimeMovie,
movie.langMovie,
movie.ratingMovie,
people.namePeople
FROM
htv_movie movie
INNER JOIN htv_actorlinkmovie acm ON acm.idMovie = movie.idMovie
INNER JOIN htv_directorlinkmovie dcm ON dcm.idMovie = movie.idMovie
INNER JOIN htv_producerlinkmovie pcm ON pcm.idMovie = movie.idMovie
INNER JOIN htv_people people WHERE people.idPeople = dcm.idPeople AND people.idPeople = acm.idPeople AND people.idPeople = pcm.idPeople
And it should return the all the related people from a single movie.
Would like to get some input about the whole design since I'm a pretty new at designing a whole database (first time actually) and whether would this design be suitable if I need to scale up to about 5000 movies (the current company aim). This database will pretty much serve as the website's backend as well.
Thanks.
UPDATE: Temporarily worked out a dirty solution using PHP variables and a template SQL query. Looks like doing multiple inner joins wasn't that required after all. Thanks for the suggestions though.
You can achieve your goal like this:
SELECT MovieName,
dbo.GetDirector(MovieID),
dbo.GetActors(MovieID),
dbo.GetWriter(MovieID) FROM Movie
where
dbo.GetDirector(MovieID) is a
function that will return directors
in the movie.
dbo.GetActors(MovieID) is a function
that will return actors in the movie.
dbo.GetWriter(MovieID) is a function
that will return writers in the
movie.
If there are some other tables then you can make functions for those tables as well.
Hope this helps.