I hope someone will give me an idea how to proceed, because I'm losing my mind right now.
I just made two tables in my database. First one looks like this:
categories
categories_id
cat_group (categories group)
cat_name (category name)
cat_lang (category language)
Second one:
users
users_id
username
category
You'll probably ask yourself why am I using the "categories group". Well I need sometimes to pull all categories from the database for a certain group. Let's see an example:
cat_group = teacher
cat_name = teacher
cat_lang = 1 (en)
cat_group = teacher
cat_name = leraar
cat_lang = 2 (dutch)
cat_group = teacher
cat_name = professeur
cat_lang = 3 (french)
When I try to SELECT all teachers now from both tables, it works just fine. But sometimes the category names are the same in different languages.
For example:
Category name: student (english) category name: student (dutch) category name: étudiant (french)
When I try the same query:
SELECT users.username, users.categ开发者_如何学编程ory, categories.cat_group
FROM users
LEFT JOIN categories ON users.category = categories.category_name
WHERE categories.cat_group = 'student'
I end up with the following result:
student adam student
student chris student
étudiant brian student
student adam student
student chris student
I don't know what I'm doing wrong here. I just need something like: category_name: student username: adam category_group : student
Am I doing anything wrong in my query?
Thanks in advance.
I do not understand how any of the answers actually fixes your problem. For instance, how are you supposed to determine which language to use ?
I just need something like ... Am I doing anything wrong in my query?
We need to go back to first principles. The Data model is not ready for coding. When it is, the code will be easy.
Multiple language support requires a bit more work. The issue is worked around but not dealt with explicitly, and it needs to be. With those two serious issues not being resolved, it is no wonder that you are mentally stressed. And that's assuming you are reasonably qualified for the task, otherwise you have a third cause of stress.
You need something like this.
▶Normalised Data Model◀ (inline links do not work on some browsers/versions.)
Readers who are not familiar with the Relational Modelling Standard may find the ▶IDEF1X Notation◀ useful.
Your examples show a single category per User, so I have provided that; if an User can belong to multiple Categories, you need a different model, let me know.
Code
Now your queries are easy. I realise your query is an example, but there is no context, and in a language-specific environment, language is always fairly high up in the order, always part of the context. Here is a query), similar to your example, for all users with Category in their language:
SELECT FirstName,
LastName,
Name AS Category
FROM User U,
CategoryLanguage CL
WHERE U.CategoryId = CL.CategoryId
AND U.LanguageCode = CL.LanguageCode
Notice there is no need to join with Category
. This is because I have used the Identifiers that exist, and migrated them to the child tables, as per the Standard, and not stuck an Id
column on everything that moves (in the case of Id
columns all over the place, yes, you would have to join with Category
; that is eliminated). CategoryId
and LanguageCode
are exactly that, wherever they show up. No Nulls, no outer joins.
Here is the same query in your language (let's assume English):
SELECT FirstName,
LastName,
Name AS Category
FROM User U,
CategoryLanguage CL
WHERE U.CategoryId = CL.CategoryId
AND U.LanguageCode = "en" -- or ${language} from the app layer
AND U.CategoryId = ( SELECT CategoryId
FROM CategoryLanguage
WHERE LanguageCode = "en" -- or ${language} from the app layer
AND Name = "Student" -- or ${category} from the app layer
)
Joining on strings is expensive and risky. What happens when a category_name changes in Categories? You have to cascade the update to all of your Users records. A few suggestions:
- Use categories_id as your link from users to categories instead of the actual string description.
- Create a Categories_Group table with ID and Description columns. As above, use that ID as the link from Categories to Categories_Group instead of storing the descriptive group text in the Categories table.
- Finally, use the users.categories_id in your join condition and use the categories.cat_group_id in your where clause to eliminate the issues of duplicate names.
Despite the normalization, and natural key issues ... your query should be like
LEFT JOIN
categories ON users.category = categories.category_name and
categories.cat_name='student' <-- make sure cat_name is student (dutch,english)
and categories.cat_group='student'
and cat_lang=1 <-- if is english
精彩评论