2013-11-01 3 views
0

У меня есть главная таблица sql CHANNEL_PT , которую я хочу заполнить на основе двух других основных таблиц CHANNEL и PT.Нужна помощь для оптимизации SQL-запроса

CHANNEL_PT cosist из трех колоний CHANNEL_PT_CD, CHANNEL_CD и PT_CD.

сценарий для вставки записей в CHANNEL_PT таков, что, если я имею две записи в CHANNEL таблицы,

enter image description here

и две записи в PT таблицы, приведенной ниже,

enter image description here

тогда стол CHANNEL_PT будет таким, как показано ниже

enter image description here

я знал, что это может быть сделано с CURSOR, но я не использую его из-за проблемы с быстродействием.

Я написал запрос, как показано ниже, чтобы получить ожидаемый результат, но хочу знать любой другой более эффективный способ или оптимизированный запрос.

BEGIN TRANSACTION 
DECLARE @CH INT; 
DECLARE @CH_CNT INT; 
DECLARE @CH_MAX INT; 
SELECT @CH_MAX = MAX(CHANNEL_CD) FROM CHANNEL; 
SELECT @CH = ISNULL(MIN(CHANNEL_CD),0),@CH_CNT=COUNT(CHANNEL_CD) FROM CHANNEL WHERE CHANNEL_CD > -1 

WHILE @CH <= @CH_MAX 

BEGIN 
    DECLARE @PT INT; 
    DECLARE @PT_CNT INT; 
    DECLARE @PT_MAX INT; 
    SELECT @PT_MAX = MAX(PT_CD) FROM PT; 
    SELECT @PT = ISNULL(MIN(PT_CD),0),@PT_CNT=COUNT(PT_CD) FROM PT WHERE PT_CD > -1 
    WHILE @PT <[email protected]_MAX 
     BEGIN 
      DECLARE @CPT INT; 
      SELECT @CPT = ISNULL(MAX(CHANNEL_PT_CD),0) FROM CHANNEL_PT 
      IF NOT EXISTS(SELECT CHANNEL_CD,PT_CD FROM CHANNEL_PT WHERE [email protected] and [email protected]) 
       BEGIN 
        INSERT INTO CHANNEL_PT VALUES(@CPT+1,@CH,@PT) 
       END 
      SELECT @PT = MIN(PT_CD) FROM PT WHERE PT_CD > @PT 
     END 
    SELECT @CH=MIN(CHANNEL_CD) FROM CHANNEL WHERE CHANNEL_CD > @CH 
END 
COMMIT; 
+0

курсоров в большинстве случаев медленнее, чем операция устанавливается на основе. Но вы заменяете курсор на цикл while, который еще медленнее. – adrianm

ответ

0

Пожалуйста, попробуйте:

DECLARE @CPT INT=0; 
SELECT @CPT = ISNULL(MAX(CHANNEL_PT_CD),0) FROM CHANNEL_PT 

INSERT INTO CHANNEL_PT 
SELECT DISTINCT @CPT+ROW_NUMBER() OVER(ORDER BY b.CHANNEL_CD), 
    b.CHANNEL_CD, 
    c.PT 
FROM CHANNEL b, PT c 
WHERE (SELECT COUNT(*) FROM CHANNEL_PT a 
     WHERE a.CHANNEL_CD=b.CHANNEL_CD AND a.PT_CD=c.PT)=0 
1

Это звучит, как вы описываете перекрестное соединение. Столбец CHANNEL_PT_CD определен как столбец IDENTITY? Это избавляет вас от необходимости назначать это значение, поскольку сервер сделает это за вас.

Тогда вы можете сделать простой INSERT/SELECT

INSERT INTO CHANNEL_PT 
SELECT b.CHANNEL_CD, c.PT 
    FROM CHANNEL b 
cross join PT c 
+0

CHANNEL_PT_CD не является колонкой IDENTITY – Rohaan

Смежные вопросы