Я не уверен, как это сделать, но я просто даю вам некоторую идею, которая может быть полезна. У вас уже есть начальная таблица. Вы обрабатываете и создаете таблицу токенов:
+------------+---------+
| TokenValue | TokenId |
+------------+---------+
| A | 1 |
| B | 2 |
| C | 3 |
| E | 4 |
| D | 5 |
| G | 6 |
| R | 7 |
+------------+---------+
Это нормально для меня. Теперь я должен создать новую таблицу, в которой я бы сопоставлял исходную таблицу с токенами таблицы токенов (OrderedTokens
). Что-то вроде:
+-------+---------+---------+
| UrlID | TokenId | AnOrder |
+-------+---------+---------+
| 1 | 1 | 1 |
| 1 | 2 | 2 |
| 1 | 3 | 3 |
| 2 | 5 | 1 |
| 2 | 2 | 2 |
| 2 | 1 | 3 |
| 2 | 7 | 4 |
| 3 | 3 | 1 |
| 3 | 4 | 2 |
+-------+---------+---------+
Таким образом, вы даже можете воссоздать исходную таблицу, пока используете поле заказа. Например:
select string_agg(t.tokenValue, '/' order by ot.anOrder) as OriginalUrl
from OrderedTokens as ot
join tokens t on t.tokenId = ot.tokenId
group by ot.urlId
предыдущий запрос приведет:
+-------------+
| OriginalUrl |
+-------------+
| A/B/C |
| D/B/A/R |
| C/E |
+-------------+
Таким образом, вы даже не нуждаются в вашей исходной таблицы больше. Если вы хотите получить Urls, которые имеют какой-либо из предусмотренных лексем идентификаторов (в данном случае B
ИЛИ C
), вы sould использовать это:
select string_agg(t.tokenValue, '/' order by ot.anOrder) as OriginalUrl
from OrderedTokens as ot
join Tokens t on t.tokenId = ot.tokenId
group by urlid
having count(case when ot.tokenId in (2, 3) then 1 end) > 0
Это приводит к:
+-------------+
| OriginalUrl |
+-------------+
| A/B/C | => It has both B and C
| D/B/A/R | => It has only B
| C/E | => It has only C
+-------------+
Теперь, если вы хочу получить все Urls, которые имеют ОБА идентификаторов, то попробуйте следующее:
select string_agg(t.tokenValue, '/' order by ot.anOrder) as OriginalUrl
from OrderedTokens as ot
join Tokens t on t.tokenId = ot.tokenId
group by urlid
having count(distinct case when ot.tokenId in (2, 3) then ot.tokenId end) = 2
Добавить в count
всех идентификаторах вы хотите отфильтровать, а затем равно, что подсчитать количество добавленных вами идентификаторов. Предыдущий запрос приведет к:
+-------------+
| OriginalUrl |
+-------------+
| A/B/C | => It has both B and C
+-------------+
Забавно, что ни одно из предложенных нами решений не привело к ожидаемому результату. Итак, я неправильно понял ваши требования или ожидаемый результат, который вы указали неправильно?
Дайте мне знать, если это правильно.
Почему вы добавили 'ABC' и' DBAR'? Вы ищете записи, которые имеют BOTH ('B' и' C') или любой из них ('B' или' C')? Обратите внимание, что 'ABC' имеют оба и' DBAR'. Однако «CE» также имеет один и не отображается в наборе результатов: S –
моя ошибка. Я исправил пример – lbednaszynski