Answer the question
In order to leave comments, you need to log in
Redundant data or complex query logic?
Hello, there are 2 tables, I will simplify for example:
1. setting: id | name
2. setting_value: id | setting_id | domain_id | language_id | value
domain_id (if null - then the setting is common for all sites)
language_id (if null - then the setting is for all languages) It is
necessary that for each domain and language there should be setting, and if it was not filled, then "standard" was returned.
And here is the problem and the big question, how best to do it:
1 (as it is done now):
I get a difficult question in my opinion, with the following logic:
Получаем данные для текущего домена (32) и языка (15).
UNION
Получаем данные для текущего домена (32) стандартного языка (1), исключая setting_id полученные из прошлого запроса.
UNION
Получаем данные для текущего домена (32) и общего языка (null), исключая прошлые запросы
UNION
Получаем данные для стандартного домена (1) и текущего языка (15), исключая прошлые запросы
И т.д пока не переберем все варианты
SELECT * FROM `setting_value` WHERE `domain_id` = 32 AND `language_id` = 15
Answer the question
In order to leave comments, you need to log in
Same questions from different accounts??
I understand that this is the same or the essence is similar: Get the string with the maximum match? ??
instead of `movie_desc` - `setting_value` (see the query and examples below)
through window functions, you need to do it if on MySQL 8 (you did NOT specify a DBMS ...), the ranking function is row_number()
-- здесь я вынес параметры (домены, языки) в отдельное представление param,
-- которое определяется перед SELECT
-- это сделано, для того чтобы по всему запросу не искать и вписывать их
-- меняется все в одном месте:
WITH param AS (
SELECT
2 AS primary_domain_id, -- id первичного домена
1 AS secondary_domain_id, -- id вторичного домена
2 AS primary_language_id, -- id первичного языка
1 AS secondary_language_id -- id вторичного языка
FROM dual
)
SELECT *
FROM (
SELECT m.*,
row_number() over (
partition by m.movie_id
order by
case
when m.domain_id = p.primary_domain_id then 100
when m.domain_id = p.secondary_domain_id then 50
else 1
end DESC,
case
when m.language_id = p.primary_language_id then 100
when m.language_id = p.secondary_language_id then 50
else 1
end DESC
) rn
FROM `movie_desc` m, param p
WHERE (m.domain_id = p.primary_domain_id
OR m.domain_id = p.secondary_domain_id
OR m.domain_id IS NULL)
AND (m.language_id = p.primary_language_id
OR m.language_id = p.secondary_language_id
OR m.language_id IS NULL)
) t
WHERE t.rn = 1
;
how very difficult
...
WHERE `domain_id` IS NULL OR `domain_id` = <value>
ORDER BY `domain_id` IS NOT NULL DESC
LIMIT 1
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question