SQL Server 2005 - присоединение на основе критериев в столбце таблицы - PullRequest
4 голосов
/ 06 апреля 2011

В SQL Server 2005 какой наиболее эффективный способ объединения двух таблиц в следующем сценарии?

Количество записей в каждой таблице может быть довольно большим, скажем, около 200000

.

В настоящее время я могу думать об этом только с помощью курсоров и некоторого динамического SQL для каждого элемента, что, безусловно, будет очень неэффективным.

У меня есть две таблицы - таблица PERSON и таблица SEARCHITEMS. Таблица SEARCHITEMS содержит столбец с некоторыми простыми критериями, который должен использоваться при сопоставлении записей с таблицей PERSON. Критерии могут ссылаться на любой столбец в таблице PERSON.

Например, с учетом следующих таблиц:

PERSON таблица

PERSONID   FIRSTNAME LASTNAME GENDER AGE ... VARIOUS OTHER COLUMNS
1          Fred      Bloggs   M      16
....
200000     Steve     Smith    M      18

SEARCHITEMS стол

ITEMID         DESCRIPTION      SEARCHCRITERIA 
1              Males            GENDER = 'M'
2              Aged 16          AGE=16
3              Some Statistic   {OTHERCOLUMN >= SOMEVALUE AND OTHERCOLUMN < SOMEVALUE}
....
200000         Males Aged 16    GENDER = 'M' AND AGE = 16

RESULTS таблица должна содержать что-то вроде этого:

ITEMID         DESCRIPTION       PERSONID    LASTNAME

1              Males             1           Bloggs
1              Males             200000      Smith
2              Aged 16           1           Bloggs
....
200000         Males Aged 16     1           Bloggs

Было бы неплохо иметь возможность просто сделать что-то вроде

INSERT INTO RESULTSTABLE
  SELECT * 
  FROM PERSON P
  LEFT JOIN SEARCHITEMS SI ON (APPLY SI.SEARCHCRITERIA TO P)

Но я не вижу способа сделать эту работу. Любая помощь или идеи приветствуются.

Ответы [ 2 ]

5 голосов
/ 06 апреля 2011

Видя, что таблица SEARCHITEMS нереляционная по своей природе, кажется, что курсор и динамическое решение SQL - единственное работоспособное решение.Конечно, это будет довольно медленно, и я бы «предварительно рассчитал» результаты, чтобы сделать его несколько сносным.

Для этого создайте следующую таблицу:

CREATE TABLE MATCHEDITEMS(
    ITEMID int NOT NULL
       CONSTRAINT fkMatchedSearchItem 
       FOREIGN KEY 
       REFERENCES SEARCHITEMS(ITEMID), 
    PERSONID int 
       CONSTRAINT fkMatchedPerson 
       FOREIGN KEY 
       REFERENCES PERSON(PERSONID)
       CONSTRAINT pkMatchedItems 
       PRIMARY KEY (ITEMID, PERSONID)
       )

Таблица будет содержатьданных много, но учитывая, что в нем хранятся только 2 int столбца, занимаемая площадь на диске будет небольшой.

Чтобы обновить эту таблицу, вы создаете следующие триггеры:

  • триггер в таблице SEARCHITEMS, который будет заполнять таблицу MATCHEDITEMS при каждом изменении или добавлении правила.
  • триггер в таблице PERSON, который будет запускать правила для обновленных или добавленных записей PERSON.

Результаты можно просто представить, присоединив 3 таблицы.

SELECT m.ITEMID, m.DESCRIPTION, m.PERSONID, p.LASTNAME
FROM MATCHEDITEMS m
JOIN PERSON p
  ON m.PERSONID = p.PERSONID
JOIN SEARCHITEMS s
  ON m.ITEMID = s.ITEMID 
0 голосов
/ 06 апреля 2011

Вы можете построить свой TSQL динамически, а затем выполнить его с помощью sp_executesql .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...