开发者

SELECT categories FROM database using different languages

开发者 https://www.devze.com 2023-01-31 07:56 出处:网络
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:

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:

  1. Use categories_id as your link from users to categories instead of the actual string description.
  2. 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.
  3. 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
0

精彩评论

暂无评论...
验证码 换一张
取 消