Лучший (простой и эффективный) способ запросить отдельный список тегов? - PullRequest
0 голосов
/ 13 декабря 2010

Существует большая таблица - Блог (предположим, записи больше 10 тысяч), структура выглядит так:

Blog_ID  Title  Tag
----------------------
1        AAA    T1|T2|T3
2        BBB    T2|T4
3        CCC    T3|T1|T2|T6|

..................

Теги блога разделены знаком '|' и, безусловно, МОГУТ дублировать, я хочу написать запрос, чтобы получить все отличные теги, а также тег внешний вид , результат как:

Tags   Appearance Count
------------------------
T1     14
T2     35
T3     88
T4     45

............

Тогда каков наилучший (простой и эффективный) способ добиться этого, пожалуйста?Еще одно ограничение - это возможность SQL Server 2000, так как мой поставщик хостов веб-приложений использует SQL Server 2000.

Благодарим за любую помощь !!

Ответы [ 2 ]

6 голосов
/ 13 декабря 2010

Вы должны нормализовать свои данные.Это означает, что в одном столбце не должно быть более одного значения - без разделителей.Для нормализации данных необходимо создать таблицу для хранения тегов:

TAGS

  • tag_id (первичный ключ)
  • tag_name

Затем вам нужна таблица, которая связывает запись BLOG с определенным тегом:

BLOG_TAGS

  • blog_id (первичный ключ)
  • tag_id (первичный ключ)

Самое интересное - извлечь данные из существующего формата с помощью разделителя каналов, чтобы правильно их сохранить.

Затем вы сможете получить желаемый результат.используя:

   SELECT t.tag_name, 
          COUNT(bt.blog_id) AS appearanceCount
     FROM TAGS t
LEFT JOIN BLOG_TAGS bt ON bt.tag_id = t.tag_id
1 голос
/ 13 декабря 2010

Вообще OMG Ponies определенно прав!Но если вам действительно нужно это сделать, посмотрите на этот пример кода (надеюсь, он действителен для SQL Server 2000):

create table #t (Blog_ID int, Title varchar(50), Tag varchar(4000));
insert into #t select 1, 'AAA', 'T1|T2|T3';
insert into #t select 2, 'BBB', 'T2|T4';
insert into #t select 3, 'CCC', 'T3|T1|T2|T6';

select Tag, count(*) as AppearanceCount from (
select substring(t.Tag,
        a.n+b.n+c.n+d.n+e.n+f.n+g.n+h.n+i.n+j.n+k.n+l.n,
        charindex('|',t.Tag+'|',a.n+b.n+c.n+d.n+e.n+f.n+g.n+h.n+i.n+j.n+k.n+l.n)
            - (a.n+b.n+c.n+d.n+e.n+f.n+g.n+h.n+i.n+j.n+k.n+l.n)) as Tag
from    (select 0 as n union select 1) a,
        (select 0 as n union select 2) b,
        (select 0 as n union select 4) c,
        (select 0 as n union select 8) d,
        (select 0 as n union select 16) e,
        (select 0 as n union select 32) f,
        (select 0 as n union select 64) g,
        (select 0 as n union select 128) h,
        (select 0 as n union select 256) i,
        (select 0 as n union select 512) j,
        (select 0 as n union select 1024) k,
        (select 0 as n union select 2048) l,
        #t t
where substring('|'+t.Tag,a.n+b.n+c.n+d.n+e.n+f.n+g.n+h.n+i.n+j.n+k.n+l.n,1)='|'
) x
group by Tag;

drop table #t;

Вы можете (и, возможно, должны) использовать UDF для генерации чисел.Читать намного легче:

seelct Tag, count(*) as AppearanceCount from (
select substring(t.Tag, n.n, charindex('|',t.Tag+'|',n.n) as Tag
from dbo.fn_Numbers(4000) n cross join #t t
where substring('|'+t.Tag,n.n,1)='|') x group by Tag;

(Спасибо Ицик Бен-Ган)

...