2013-11-01 289 views
0

我有一個sql主表CHANNEL_PT 我想填寫基於其他兩個主表CHANNELPT需要幫助來優化SQL查詢

the CHANNEL_PT cosist of three colums CHANNEL_PT_CDCHANNEL_CD and 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