В настоящее время я использую MS SQL Server 2016. У меня есть две таблицы, которые используются для сбора запросов в течение дня для поиска деталей, которые соответствуют ВСЕМ или ЛЮБОМУ из запрошенных атрибутов детали:
CREATE TABLE requests (
r1_request_id int NOT NULL,
r1_match_type int NOT NULL,
CONSTRAINT PK_requests PRIMARY KEY CLUSTERED
(
r1_request_id ASC
)
);
CREATE TABLE request_attributes (
r2_request_id int NOT NULL,
r2_part_attribute int NOT NULL,
CONSTRAINT PK_request_attributes PRIMARY KEY CLUSTERED
(
r2_request_id ASC,
r2_part_attribute ASC
)
);
Столбец r1_match_type содержит 1 или 2, где:
1 = ВСЕ request_attributes должны присутствовать в части
2 = ЛЮБЫЕ request_attributes могут присутствовать в части
Третья таблица - это таблица деталей:
CREATE TABLE parts (
p1_part_id int NOT NULL,
p1_attribute int NOT NULL,
CONSTRAINT PK_parts PRIMARY KEY CLUSTERED
(
p1_part_id ASC,
p1_attribute ASC
)
);
В конце дня выполняется запрос, чтобы найти все запросы и детали, содержащие атрибуты ANY или ALL для этого запроса.Например, с учетом следующих данных:
Table: parts
p1_part_id p1_attribute
10 1
10 2
10 3
10 4
20 1
20 2
20 3
20 4
30 2
30 4
Table: requests
r1_request_id r1_match_type
1 1
2 2
Table: request_attributes
r2_request_id r2_part_attribute
1 1
1 2
1 3
1 4
2 2
2 4
С учетом данных выше, запрос 1 имеет 4 атрибута части;ВСЕ эти атрибуты должны присутствовать в любых частях.Запрос 2 имеет 2 атрибута части;ЛЮБОЙ из которых может присутствовать в части.
Следующий запрос сопоставляет запросы с частями, но не использует флаг (r1_match_type), используемый для указания того, должны ли атрибуты части запроса соответствовать ВСЕ или ЛЮБОЙ частиАтрибуты:
SELECT r1_request_id, p1_part_id, COUNT(*) AS attribute_count
FROM requests
JOIN request_attributes ON ( r2_request_id = r1_request_id )
JOIN parts ON ( p1_attribute = r2_part_attribute )
GROUP BY r1_request_id, p1_part_id
ORDER BY r1_request_id, p1_part_id
r1_request_id p1_part_id attribute_count
------------- ----------- ---------------
1 10 4
1 20 4
1 30 2
2 10 2
2 20 2
2 30 2
Для правильного вывода необходимо учитывать флаг r1_match_type и выводить результат, показанный ниже, поскольку запрос 1 имеет 4 атрибута части, а ВСЕ 4 атрибута должны присутствовать в части (только части 10).и 20 имеют все 4 атрибута).
r1_request_id p1_part_id
------------- -----------
1 10
1 20
2 10
2 20
2 30
Как правило, в течение дня происходит около 50 000 запросов и около 1,3 млн. частей в БД.
Любопытно, как другие решат эту проблемуконкретная проблема?Использование одного запроса или двух запросов (один для поиска ВСЕХ, другой для поиска ЛЮБЫХ)?