我不知道如何做到這一點,但我只是給你一些可能有用的想法。你已經有了你的初始表格。您處理的是並創建令牌表:
+------------+---------+
| 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 |
+-------------+
所以,你甚至不需要你的原始表了。如果你想有任何所提供的令牌IDS(在這種情況下B
OR C
)的網址,你前人的精力用這個:
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
+-------------+
現在,如果你想同時具有ID的所有網址,那就試試這個:
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
所有的IDS要篩選,然後等於該算的您添加的ID數量。將導致前面的查詢中:
+-------------+
| OriginalUrl |
+-------------+
| A/B/C | => It has both B and C
+-------------+
有趣的是,我沒有在提供您預期的結果的結果的解決方案。那麼,我誤解了您的要求還是您提供的預期結果是錯誤的?
讓我知道這是否正確。
爲什麼添加ABC和DBAR?你在尋找有BOTH('B'和'C')或其中任何一個('B'或'C')的記錄嗎?注意'ABC'有兩個和'DBAR'都有。但'CE'也有一個,它不會顯示在結果集中:S – 2012-03-11 17:24:36
我的錯誤。我已更正示例 – lbednaszynski 2012-03-11 19:24:25