Итак, у нас есть сайт Drupal с узлами, помеченными в 4 словарях. В терминах SQL это все просто объединения в базовой таблице. В упрощенном виде это выглядит примерно так:
SELECT a.name AS location, b.name AS sector, c.name AS tag, d.name AS status
FROM node n
LEFT JOIN a ON a.id = n.id
LEFT JOIN b ON b.id = n.id
LEFT JOIN c ON c.id = n.id
LEFT JOIN d ON d.id = n.id
WHERE n.type = 'X'
GROUP BY a.name, b.name, c.name, d.name
У нас есть страница со списком, где вы можете фильтровать по A, B, C и D; у каждого есть список всех значений и опция «Все».
Нам нужен список различных комбинаций A, B, C и D которые имеют результаты. Это делается для создания карты сайта, и, очевидно, мы не хотим, чтобы боты очищали страницы результатов.
Я попытался использовать WITH ROLLUP с частичным успехом. Это дает мне a/b/c/d
, a/b/c/*
, a/b/*/*
, a/*/*/*
а также */*/*/*
, Однако это не делает */*/*/d
, */b/*/*
или же */b/*/d
(вместе со всеми подобными комбинациями).
Любые предложения о том, если это возможно с использованием SQL с таким подходом? Я бы не стал использовать подзапросы.
Наша альтернативная теория состоит в том, чтобы перебрать все узлы и построить массив в PHP со всеми комбинациями, под которыми появляется узел. Например: если узел 1 был в a/b/c/d
тогда к нашему массиву будет добавлено следующее
[
'a/b/c/d',
'a/b/c/*',
'a/b/*/d',
'a/*/c/*',
'a/*/c/d',
'a/*/*/*',
'*/*/*/d',
'*/b/c/d',
'*/b/c/*',
'*/b/*/d',
'*/*/c/*',
'*/*/c/d',
'*/*/*/*',
'*/*/*/d',
'*/*/*/*',
]
(Я думаю, вот и все комбинации).
Уникальным набором из них в конце будут все доступные пути / опции без каких-либо пустых. Я думаю.
Это, очевидно, немного грубый подход. Такое ощущение, что это сработает, но это менее элегантно, чем делать это с SQL.
РЕДАКТИРОВАТЬ: Это не работает, я уверен, что это не все результаты
Хм … только что попробовал это, и похоже, что вы можете получить все возможные результаты, используя 2 запроса, группирующихся в каждом направлении:
т.е. GROUP BY a.name, b.name, c.name, d.name
затем GROUP BY d.name, c.name, b.name, a.name
Но затем я попытался добавить оба направления группировки в один запрос, и это выглядит довольно многообещающе:
т.е. GROUP BY a.name, b.name, c.name, d.name, c.name, b.name, a.name
Я думаю, что это работает, но мог бы быть лучший способ.
Я использую 4 запроса, чтобы получить все результаты, например:
SELECT a.name AS location, b.name AS sector, c.name AS tag, d.name AS status
FROM node n
LEFT JOIN a ON a.id = n.id
LEFT JOIN b ON b.id = n.id
LEFT JOIN c ON c.id = n.id
LEFT JOIN d ON d.id = n.id
WHERE n.type = 'X'
GROUP BY a.name, b.name, c.name, d.name
SELECT b.name AS sector, c.name AS tag, d.name AS status
FROM node n
LEFT JOIN b ON b.id = n.id
LEFT JOIN c ON c.id = n.id
LEFT JOIN d ON d.id = n.id
WHERE n.type = 'X'
GROUP BY b.name, c.name, d.name
SELECT c.name AS tag, d.name AS status
FROM node n
LEFT JOIN c ON c.id = n.id
LEFT JOIN d ON d.id = n.id
WHERE n.type = 'X'
GROUP BY c.name, d.name
SELECT d.name AS status
FROM node n
LEFT JOIN d ON d.id = n.id
WHERE n.type = 'X'
GROUP BY d.name
Таким образом, первый запрос возвращает все результаты, где все 4 категории имеют значение, то есть a / b / c / d, а сворачивание добавляет их для a / b / c / -, a / b / — / -, a / — / — / — (дефисы для всех значений фильтра, звездочки исчезают, когда я набираю их по какой-то причине)
Затем второй запрос возвращает все для * / b / c / d, а свертка добавляет — / b / c / -, — / b / — / —
Третье возвращает — / — / c / d, а сворачивание добавляет — / — / c / —
затем четвертый добавляет — / — / — / d и — / — / — / —
Что я думаю, это все
Других решений пока нет …