【问题标题】:Efficient way for creating mapping创建映射的有效方法
【发布时间】:2021-04-25 14:04:34
【问题描述】:

我有 2 个如下表

CITY_A

ID CODE CITY
001 90 PARIS
002 90 PARIS
003 85 PARIS
004 60 SYDNEY
005 75 SYDNEY
006 75 SYDNEY

CITY_B

ID CODE CITY
001 IN PA
002 OUT PA
003 OUT PA
004 IN SYD
005 OUT SYD
006 IN SYD

两个表中的内容相同,但表示方式不同。我在这里为CITY 列和CODE 列有两个映射。

CITY_A 的映射

CODE CITY MEANING
90 PARIS ACTIVE
85 PARIS NOT_ACTIVE
60 SYDNEY ACTIVE
75 SYDNEY NOT_ACTIVE

CITY_B 的映射

CODE CITY MEANING
IN PA ACTIVE
OUT PA NOT_ACTIVE
IN SYD ACTIVE
OUT SYD NOT_ACTIVE

现在我必须根据映射比较两个表并找出不匹配的地方。所以我的预期输出是

ID CITY RESULT
001 PARIS MATCH
002 PARIS MISMATCH
003 PARIS MATCH
004 SYDNEY MATCH
005 SYDNEY MATCH
006 SYDNEY MISMATCH

目前我正在使用 CASE 和 Temp 表。太大了。

SELECT A.ID , CASE WHEN A.CODE = 90 AND A.CITY = 'PARIS' THEN 'ACTIVE' 
                   WHEN A.CODE = 85 AND A.CITY = 'PARIS' THEN 'NOT_ACTIVE' 
               -- FOR OTHER CITIES
               END AS A.CODE_MEANING,
               CITY
INTO #TEMP_CITY_A              
FROM CITY_A A

SELECT B.ID,CASE WHEN B.CODE = 'IN'  AND B.CITY='PA' THEN 'ACTIVE'
                   WHEN B.CODE = 'OUT'  AND B.CITY='PA' THEN 'NOT_ACTIVE' 
              -- FOR OTHER CITIES
            END AS B.CODE_MEANING,
            CASE WHEN B.CITY = 'PA' THEN 'PARIS' 
                 WHEN B.CITY = 'SYD' THEN 'SYDNEY'
             -- FOR OTHER CITIES
            END AS CITY
 INTO #TEMP_CITY_B              
 FROM CITY_B B

SELECT A.ID ,A.CITY, 
     CASE WHEN A.CODE_MEANING!=B.CODE_MEANING THEN 'MISMATCH' ELSE 'MATCH' END AS RESULT
FROM #TEMP_CITY_A A
JOIN #TEMP_CITY_B B ON A.ID = B.ID AND A.CITY = B.CITY

哪种方式最有效?

【问题讨论】:

  • 你为什么不直接JOIN CITY_AMapping for CITY_A 而不是硬编码值
  • 然后创建一个或使用VALUE构造函数
  • 目前还没有Mapping for CITY_A 表:) @Squirrel。那我应该单独创建一个映射表吗?实际上我没有创建表的权限。如果这是最好的方法,那么我会要求它。唯一的问题是所有的批准都需要很长时间
  • 如果映射表很大,行很多,最好创建一个表。如果只是几行,可以使用CTEVALUE 构造函数
  • 没那么大。我有大约 25 行。你能举一个VALUE的例子吗? @松鼠

标签: sql sql-server sql-server-2012


【解决方案1】:

这是一种使用 CTE 和映射表的表值构造函数来实现所需结果的可能方法:

WITH CITY_A_MAP AS (
  SELECT * FROM (
    VALUES(90, 'PARIS', 'Active'),(85, 'PARIS', 'Not_Active'),(60, 'SYDNEY', 'Active'),(75, 'SYDNEY', 'Not_Active')
  ) AS MAP(CODE, CITY, MEANING)
),
CITY_B_MAP AS (
  SELECT * FROM (
    VALUES ('IN', 'PA', 'Active'),('OUT', 'PA', 'Not_Active'),('IN', 'SYD', 'Active'),('OUT', 'SYD', 'Not_Active')
  ) AS MAP(CODE, CITY, MEANING)
)
SELECT A.ID, A.CITY,
       CASE WHEN MA.MEANING = MB.MEANING THEN 'MATCH' ELSE 'MISMATCH' END AS RESULT
FROM CITY_A A
JOIN CITY_A_MAP MA ON MA.CITY = A.CITY AND MA.CODE = A.CODE
JOIN CITY_B B ON B.ID = A.ID
JOIN CITY_B_MAP MB ON MB.CITY = B.CITY AND MB.CODE = B.CODE
ORDER BY A.ID

输出:

ID  CITY    RESULT
1   PARIS   MATCH
2   PARIS   MISMATCH
3   PARIS   MATCH
4   SYDNEY  MATCH
5   SYDNEY  MATCH
6   SYDNEY  MISMATCH

Demo on dbfiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-11
    • 1970-01-01
    • 1970-01-01
    • 2018-07-19
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    相关资源
    最近更新 更多