MySQL design issue - mysql

I think the design is straightforward so no explanation is required.
Question: Is there a way to inditcate the language of the name column in courses table? Maybe to link it with the languages table?
Edit: Or maybe separate the name-language pare in another table with id and reference it in courses table?
Edit2: Course language and Name langauge may be different

Question: Is there a way to inditcate the language of the name column in courses table? Maybe to link it with the languages table?
There's no need. The following query will give you what you want:
SELECT c.name, COALESCE(l.name,'default') as language
FROM courses c
LEFT JOIN courses_has_languages cl ON (cl.courses_course_id = c.course_id)
LEFT JOIN languages l ON (l.language_id = cl.languages_language_id)
Of source it would be even better if you just rename your column names so the query can be rewritten to:
SELECT c.name, COALESCE(l.name,'default') as language
FROM courses c
LEFT JOIN courses_has_languages cl ON (cl.course_id = c.id)
LEFT JOIN languages l ON (l.id = cl.language_id)
But that's just my preference.

If I understand you it sounds like you're on the right track.
Make language_id a foreign key in the courses table that points back to languages.

Assuming that the diagram correctly models the data then no, you do not need any additional relationships.
Instead, you will retrieve the languages for a course by JOINing the tables in a SELECT statement. If this is an operation you will perform frequently, you can encapsulate that SELECT statement by CREATEing a VIEW.

Related

mysql - How to perform joining of of two junctional tables in case where one of them has foreign key of another?

I am new in the database design, so I am still learning, so sorry for maybe inappropriate terms using, so I will try to explain on common language what problem I have. I learned how to join two tables (getting result) over junction table which is in between, but I got into problem when I want to join one "regular" table and one junction table over another junction table.
I have a relational database which has tables and relations between them like this:
I know how to join hgs_transliterations, hgs_gardiners, hgs_meanings, hgs_word_types using hgs_translations, but what I don't know how to do is how to join those 4 tables and the hgs_references table.
This is my code for joining lower 4 tables:
SELECT hgs_transliterations.transliteration, hgs_gardiners.gardiners_code, hgs_meanings.meaning, hgs_word_types.word_type
FROM hgs_translations
JOIN hgs_transliterations ON hgs_translations.transliteration_id = hgs_transliterations.id
JOIN hgs_gardiners ON hgs_translations.gardiners_id = hgs_gardiners.id
JOIN hgs_meanings ON hgs_translations.meaning_id = hgs_meanings.id
JOIN hgs_word_types ON hgs_translations.word_type_id = hgs_word_types.id
I read some tutorials on this subject which mention AS, INNER JOIN, OUTER JOIN, but I didn't quite understand terminology and how I can use this to create what I need. Sorry for maybe basic questions, but as I say, I am just a beginner and I am trying to understand something deeply so I can use it appropriately. Thank you in advance.
P.S. If someone thinks that this is not good database design (design of relations between tables), I would like to hear that.
Just add two more joins:
SELECT hgs_transliterations.transliteration, hgs_gardiners.gardiners_code,
hgs_meanings.meaning, hgs_word_types.word_type,
hgs_references.reference
FROM hgs_translations
JOIN hgs_transliterations ON hgs_translations.transliteration_id = hgs_transliterations.id
JOIN hgs_gardiners ON hgs_translations.gardiners_id = hgs_gardiners.id
JOIN hgs_meanings ON hgs_translations.meaning_id = hgs_meanings.id
JOIN hgs_word_types ON hgs_translations.word_type_id = hgs_word_types.id
JOIN junc_translation_reference ON junc_translation_reference.translation_id = hgs_translations.id
JOIN hgs_references ON hgs_references.id = junc_translation_reference.reference_id

Correct way to join MYSQL Tables

I'm trying to advance my knowledge of mysql from "I can make it work" to "I can make it work correctly". I'm working with joins right now and I was wondering the best way of doing the following:
I have 2 tables "items" and "categories". Inside the "items" table I have a field called category which will be linked to the "categories" table primary key cid. What is the best way of doing this? This is how I've always done it but I feel it's not the best way by any means
SELECT C.something, C.soemthing 2 FROM categories C, items I WHERE C.cid=I.category AND C.categoryName='New'
Your query is already correct but I'll recommend to use ANSI SQL-92 format
SELECT C.something, C.soemthing2
FROM categories C INNER JOIN items I
on C.cid=I.category
WHERE C.categoryName='New'
question, what are you trying to achieve?
Your query would return the correct result set, however the following is more readable:
SELECT C.something, C.soemthing 2
FROM categories C
INNER JOIN items I ON C.cid = I.category
WHERE C.categoryName='New';

Join of tables returning incorrect results

There are 4 sql tables:
Listings(Amount, GroupKey, Key, MemberKey),
Loans(Amount, GroupKey, Key, ListingKey),
Members(City, GroupKey, Key)
Groups(GroupRank, Key, MemberKey)
Now, if one wants to find out the loans which are also listings and find the members city and GroupRank for the members in the loan table. Here, the group table contains information about grous of which members are a part of.
and also perform a select operation as given below:
select Listings.Amount, Members.City, Groups.GroupRank
from listings, loans, members, groups
where Listings.Key=Loans.ListingKey and
Members.Key=Listings.MemberKey and
Listings.GroupKey=Groups.Key
The above join is giving an incorrect result, please point out where I am going wrong.
Also I am new to SQL so please excuse the novice question.
Note: The following is just a guess what your problem is. Like others said, clearify your question.
You want to JOIN
( http://dev.mysql.com/doc/refman/5.1/de/join.html )
those tables. What you write is just another form of a join, meaning it has the same effect. But you "joined" a bit too much. To make things clearer a syntax has been invented to make things clearer and avoid such mistakes. Read more about it in the link given above.
What you want to achieve can be done like this:
SELECT
Listings.Amount, Members.City, Groups.GroupRank
FROM
Listings
INNER JOIN Groups ON Listings.GroupKey=Groups.Key
INNER JOIN Members ON Members.Key=Listings.MemberKey
You don't do a SELECT on the Loans table, you don't need it in this query.
This is the INNER JOIN which will give you a result where every row in table A has an according entry in table B. When this is not the case, you have to use the LEFT or RIGHT JOIN.
Maybe the problem is related to the join type (INNER). Try LEFT JOIN for example but Mark has right: you should clearify your question.
I would firstly change your query to use the more modern join syntax, which allows outer joins. Tr this:
select Listings.Amount, Members.City, Groups.GroupRank
from listings
left join loans on Listings.Key=Loans.ListingKey
left join members on Members.Key=Listings.MemberKey
left join groups on Listings.GroupKey=Groups.Key
and/or Loans.GroupKey=Groups.Key
and/or Members.Key=Groups.MemberKey
You may need to play with the criteria on the last join (maybe they should be "or" not "and" etc).

MySQL -- joining then joining then joining again

MySQL setup: step by step.
programs -> linked to --> speakers (by program_id)
At this point, it's easy for me to query all the data:
SELECT *
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
Nice and easy.
The trick for me is this. My speakers table is also linked to a third table, "books." So in the "speakers" table, I have "book_id" and in the "books" table, the book_id is linked to a name.
I've tried this (including a WHERE you'll notice):
SELECT *
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
JOIN books on speakers.book_id = books.book_id
WHERE programs.category_id = 1
LIMIT 5
No results.
My questions:
What am I doing wrong?
What's the most efficient way to make this query?
Basically, I want to get back all the programs data and the books data, but instead of the book_id, I need it to come back as the book name (from the 3rd table).
Thanks in advance for your help.
UPDATE:
(rather than opening a brand new question)
The left join worked for me. However, I have a new problem. Multiple books can be assigned to a single speaker.
Using the left join, returns two rows!! What do I need to add to return only a single row, but separate the two books.
is there any chance that the books table doesn't have any matching columns for speakers.book_id?
Try using a left join which will still return the program/speaker combinations, even if there are no matches in books.
SELECT *
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
LEFT JOIN books on speakers.book_id = books.book_id
WHERE programs.category_id = 1
LIMIT 5
Btw, could you post the table schemas for all tables involved, and exactly what output (or reasonable representation) you'd expect to get?
Edit: Response to op author comment
you can use group by and group_concat to put all the books on one row.
e.g.
SELECT speakers.speaker_id,
speakers.speaker_name,
programs.program_id,
programs.program_name,
group_concat(books.book_name)
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
LEFT JOIN books on speakers.book_id = books.book_id
WHERE programs.category_id = 1
GROUP BY speakers.id
LIMIT 5
Note: since I don't know the exact column names, these may be off
That's typically efficient. There is some kind of assumption you are making that isn't true. Do your speakers have books assigned? If they don't that last JOIN should be a LEFT JOIN.
This kind of query is typically pretty efficient, since you almost certainly have primary keys as indexes. The main issue would be whether your indexes are covering (which is more likely to occur if you don't use SELECT *, but instead select only the columns you need).

Entity Framework query with grouping (many to many)

I have a classical many to many scenario with three tables (students, courses, and third StudentsCourses assignment table).
I'm using EF in my new project and EF designer doesn't create third table.
I need to select all cources along with number of students assigned to it.
Using plain SQL is very straightforward:
select c.Id, c.Name, Count(sc.*) as StudentCount
from Courses c left join StudentCourses sc on(c.Id=sc.CourseId)
group by c.Id, c.Name
But I can't figure out how to translate this query to Linq to SQL.
Please advice.
Thank you.
The EF designer hides the table. It's still there, but it just creates the assocation for you, so you can just reference students from courses or vice versa.
You could do something like this:
var list = from c in context.Courses
from s in c.Students
select new
{
StudentName=s.Name,
Class=s.Class,
};
for more information look at this page