Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.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 2005_Join - Fatal编程技术网

Sql 加入优先标准?

Sql 加入优先标准?,sql,sql-server-2005,join,Sql,Sql Server 2005,Join,我必须将表1中的每条记录与表2中最多一条记录进行匹配。 有一种更好的匹配方法(代码相等)和一种较差的匹配方法(在没有代码相等的情况下,让我们按代码排序并按索引匹配) 作为第一个近似值,我们假设执行此操作的代码可能如下所示: SELECT TABLE1.CODE AS CODE1, TABLE2.CODE AS CODE2 FROM (SELECT ROW_NUMBER() OVER(ORDER BY CODE) INDEX, CODE FROM TABLE1) T1 LEFT JOIN (SE

我必须将表1中的每条记录与表2中最多一条记录进行匹配。 有一种更好的匹配方法(代码相等)和一种较差的匹配方法(在没有代码相等的情况下,让我们按代码排序并按索引匹配)

作为第一个近似值,我们假设执行此操作的代码可能如下所示:

SELECT
TABLE1.CODE AS CODE1,
TABLE2.CODE AS CODE2
FROM 
(SELECT ROW_NUMBER() OVER(ORDER BY CODE) INDEX, CODE FROM TABLE1) T1
LEFT JOIN
(SELECT ROW_NUMBER() OVER(ORDER BY CODE) INDEX, CODE FROM TABLE2) T2
ON
(T1.CODE=T2.CODE) --CODE equality
OR
(T1.INDEX=T2.INDEX) --CODE equality

让我们考虑这些表:

 TABLE1   TABLE2
+------+ +------+
| CODE | | CODE |
+------+ +------+
| AAA  | | BBB  |
| BBB  | | CCC  |
| CCC  | | DDD  |
+------+ +------+
结果将是:

CODE1 CODE2
----- -----
AAA   BBB    -> matched because of INDEX equality
BBB   BBB    -> matched because of CODE equality
BBB   CCC    -> matched because of INDEX equality
CCC   CCC    -> matched because of CODE equality
CCC   DDD    -> matched because of INDEX equality
困难来了:我想表达这样一种观点,即尽管有两个匹配条件不是相互排斥的,但如果可能,第一个条件必须优先于第二个条件,并且只有当第一个条件失败时,才能对第二个条件进行评估

结果是:

CODE1 CODE2
----- -----
AAA   DDD    -> matched because of INDEX equality between the cast-off records not able to match better
                (corrected from the previous version where AAA was said to match expectedly with BBB)
BBB   BBB    -> matched thanks to CODE equality, no need to match on INDEX
CCC   CCC    -> matched thanks to CODE equality, no need to match on INDEX
当然,我最好在一个查询中获得此行为,以避免使用多步骤脚本,因为:

  • 你可以随意提出一个完全不同的问题:上面的问题只是为了说明总体思路,但显然不符合需要。因此,没有必要试图保留其结构

  • 与希望执行多功能查询匹配相比,我并不真正关心性能。如果需要子查询,那就开始吧!;-)

渴望阅读您的建议!:-)

编辑:

我在我的OP中犯了一个严重的错误,现在被纠正了,并且深刻地改变了可以被认为是准确答案的东西。预期的结果并不正确。我最谦虚的道歉-(


思想是:尽可能多地匹配代码相等性,然后只考虑那些由第一匹配算法留下的与索引匹配的那些。这就是为什么AAA错误地期望与BBB(已经与另一个BBB匹配)匹配索引的原因。实际上,索引必须与另一个非代码匹配项(在这种情况下为DDD)匹配。

鉴于您的测试数据和预期结果,这将给出正确的结果

;WITH T1 (row_id, code) AS (SELECT ROW_NUMBER() OVER (ORDER BY code) AS row_id, code FROM My_Table_1),
     T2 (row_id, code) AS (SELECT ROW_NUMBER() OVER (ORDER BY code) AS row_id, code FROM My_Table_2)
SELECT
    T1.code,
    COALESCE(T2.code, T3.code)
FROM
    T1
LEFT OUTER JOIN T2 ON T2.code = T1.code
LEFT OUTER JOIN T2 AS T3 ON T2.row_id IS NULL AND T3.row_id = T1.row_id

根据您的测试数据和预期结果,这将给出正确的结果

;WITH T1 (row_id, code) AS (SELECT ROW_NUMBER() OVER (ORDER BY code) AS row_id, code FROM My_Table_1),
     T2 (row_id, code) AS (SELECT ROW_NUMBER() OVER (ORDER BY code) AS row_id, code FROM My_Table_2)
SELECT
    T1.code,
    COALESCE(T2.code, T3.code)
FROM
    T1
LEFT OUTER JOIN T2 ON T2.code = T1.code
LEFT OUTER JOIN T2 AS T3 ON T2.row_id IS NULL AND T3.row_id = T1.row_id

我尝试了Oracle,但想法如下:

with t1 as (select 1 id,'AAA' col from dual union all
            select 2,   'BBB'     from dual union all
            select 3,   'CCC'     from dual ),
     t2 as (select 1 id,'BBB' col from dual union all
            select 2,   'CCC'     from dual union all
            select 3,   'DDD'     from dual )
---
SELECT t1.col col1, t2.col col2
  FROM t1, t2
 WHERE (t1.id = t2.id OR t1.col = t2.col)
   AND (t2.id = 1 OR t1.col = t2.col)
结果:

COL1 COL2
---  ---
AAA  BBB
BBB  BBB
CCC  CCC

我尝试了Oracle,但想法如下:

with t1 as (select 1 id,'AAA' col from dual union all
            select 2,   'BBB'     from dual union all
            select 3,   'CCC'     from dual ),
     t2 as (select 1 id,'BBB' col from dual union all
            select 2,   'CCC'     from dual union all
            select 3,   'DDD'     from dual )
---
SELECT t1.col col1, t2.col col2
  FROM t1, t2
 WHERE (t1.id = t2.id OR t1.col = t2.col)
   AND (t2.id = 1 OR t1.col = t2.col)
结果:

COL1 COL2
---  ---
AAA  BBB
BBB  BBB
CCC  CCC
好的,我知道了。 我把答案贴出来,以防有人对它感兴趣。 它可以根据最终的需要进行调整,但想法是存在的(我稍微更改了字段/常量的名称:它更接近真实的名称,并帮助我找到了解决方案,否则就太理论化了)

结果:

cod_uc cod_cnt matched_with
------ ------- ------------
A      NULL    D
B      B       B
C      C       C
NULL   D       A
NULL   E       NULL
好的,我知道了。 我把答案贴出来,以防有人对它感兴趣。 它可以根据最终的需要进行调整,但想法是存在的(我稍微更改了字段/常量的名称:它更接近真实的名称,并帮助我找到了解决方案,否则就太理论化了)

结果:

cod_uc cod_cnt matched_with
------ ------- ------------
A      NULL    D
B      B       B
C      C       C
NULL   D       A
NULL   E       NULL
初始数据:

; WITH 

  T1 (CODE) AS
  ( SELECT 'AAA' CODE UNION
    SELECT 'BBB'      UNION 
    SELECT 'CCC'
  )
, T2 (CODE) AS
  ( SELECT 'BBB' CODE UNION 
    SELECT 'CCC'      UNION 
    SELECT 'DDD' 
  )
帮助表:

 , FULLT (code1, code2) AS
   ( SELECT T1.CODE AS code1
          , T2.CODE AS code2
     FROM T1
       FULL OUTER JOIN T2
         ON T1.CODE = T2.CODE 
   )
 , INNERT (code1, code2) AS
   ( SELECT code1
          , code2
     FROM FULLT
     WHERE code1 = code2 
   )
 , LEFTT (code1, rn) AS
   ( SELECT code1
          , ROW_NUMBER() OVER(ORDER BY code1) AS rn
     FROM FULLT
     WHERE code2 IS NULL
   )
 , RIGHTT (code2, rn) AS
   ( SELECT code2
          , ROW_NUMBER() OVER(ORDER BY code2) AS rn
     FROM FULLT
     WHERE code1 IS NULL
   ) 
最后查询:

   SELECT code1             
        , code2
   FROM INNERT 

 UNION ALL

   SELECT code1
        , code2
   FROM LEFTT
     JOIN RIGHTT
       ON LEFTT.rn = RIGHTT.rn 

 ORDER BY code1
        , code2 
初始数据:

; WITH 

  T1 (CODE) AS
  ( SELECT 'AAA' CODE UNION
    SELECT 'BBB'      UNION 
    SELECT 'CCC'
  )
, T2 (CODE) AS
  ( SELECT 'BBB' CODE UNION 
    SELECT 'CCC'      UNION 
    SELECT 'DDD' 
  )
帮助表:

 , FULLT (code1, code2) AS
   ( SELECT T1.CODE AS code1
          , T2.CODE AS code2
     FROM T1
       FULL OUTER JOIN T2
         ON T1.CODE = T2.CODE 
   )
 , INNERT (code1, code2) AS
   ( SELECT code1
          , code2
     FROM FULLT
     WHERE code1 = code2 
   )
 , LEFTT (code1, rn) AS
   ( SELECT code1
          , ROW_NUMBER() OVER(ORDER BY code1) AS rn
     FROM FULLT
     WHERE code2 IS NULL
   )
 , RIGHTT (code2, rn) AS
   ( SELECT code2
          , ROW_NUMBER() OVER(ORDER BY code2) AS rn
     FROM FULLT
     WHERE code1 IS NULL
   ) 
最后查询:

   SELECT code1             
        , code2
   FROM INNERT 

 UNION ALL

   SELECT code1
        , code2
   FROM LEFTT
     JOIN RIGHTT
       ON LEFTT.rn = RIGHTT.rn 

 ORDER BY code1
        , code2 

您的第二个子查询是否应该针对表2而不是表1?抱歉,当然可以。我更正了操作。@SSITRA:这两个字段
code
是否具有唯一约束?您的第二个子查询是否应该针对表2而不是表1?抱歉,当然可以。我更正了操作。@SSITRA:这两个字段
code
是否具有唯一约束?