Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
需要帮助来优化SQL查询吗_Sql_Sql Server_Sql Server 2008 - Fatal编程技术网

需要帮助来优化SQL查询吗

需要帮助来优化SQL查询吗,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我有一个sql主表CHANNEL\u PT 我想根据另外两个主表CHANNEL和PT来填充它 三个列的CHANNEL\u PT余弦CHANNEL\u PT\u CD,CHANNEL\u CD和PT\u CD 将记录插入频道的场景如下:, 如果我在频道中有两个条目表 以及PT表中的两个条目,如下所示 然后,频道\u PT表如下所示 我知道这可以通过游标来完成,但出于性能考虑,我不使用它 为了获得预期结果,我编写了如下查询,但我想知道其他更有效的方法或优化查询。 BEGIN TRANSACTI

我有一个sql主表
CHANNEL\u PT
我想根据另外两个主表
CHANNEL
PT
来填充它

三个列的
CHANNEL\u PT
余弦
CHANNEL\u PT\u CD
CHANNEL\u CD
PT\u CD

将记录插入
频道的场景如下:,
如果我在
频道中有两个条目

以及
PT
表中的两个条目,如下所示

然后,
频道\u PT
表如下所示

我知道这可以通过
游标来完成,但出于性能考虑,我不使用它

为了获得预期结果,我编写了如下查询,但我想知道其他更有效的方法或优化查询。

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 <=@PT_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 CHANNEL_CD=@CH and PT_CD=@PT)
                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;
开始交易
声明@CH INT;
声明@CHU CNT INT;
声明@CH_MAX INT;
从频道中选择@CH_MAX=MAX(频道CD);
从CHANNEL\u CD>-1所在的频道中选择@CH=ISNULL(最小值(频道CD),0),@CH\u CNT=COUNT(频道CD)
而@CH-1
而@PT@PT
结束
从CHANNEL\u CD>@CH所在的频道中选择@CH=MIN(CHANNEL\u CD)
结束
犯罪
请尝试:

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

听起来像是在描述交叉连接。列通道\u PT\u CD是否定义为标识列?这样就不需要您分配该值,因为服务器将为您分配该值

然后,您可以进行简单的插入/选择

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

CHANNEL_PT_CD不是标识列游标在大多数情况下都比基于集合的操作慢。但是,您将光标替换为更慢的while循环。