使用没有PK的另一个表的值更新表

时间:2016-03-03 05:41:36

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

我有两张桌子

+-------+----+
| name  | id |
+-------+----+
| < -5  |  1 | 
| -2    |  5 |
| -1    |  6 |
| 0     |  7 |
| + 1   |  8 |
| + 3   |  9 |
| + 5   | 10 |
| > 60  | 17 |
+-------+----+
Table 2: 
+------------+------------+-------------------+-------------------+
| diff_date1 | diff_date2 | variance_id_date1 | variance_id_date2 |
+------------+------------+-------------------+-------------------+
|          0 |          0 |                 0 |                 0 |
|        -21 |        -21 |                 0 |                 0 |
|          5 |          5 |                 0 |                 0 |
|         58 |         58 |                 0 |                 0 |
|          4 |          4 |                 0 |                 0 |
+------------+------------+-------------------+-------------------+

更新variance_id_date1 表2中的variance_id_date2和表1中的ID

预期OutPut

+------------+------------+-------------------+-------------------+
| diff_date1 | diff_date2 | variance_id_date1 | variance_id_date2 |
+------------+------------+-------------------+-------------------+
|          0 |          0 |                 7 |                 7 |
|        -21 |        -21 |                 1 |                 1 |
|          5 |          5 |                10 |                10 |
|         58 |         58 |                10 |                10 |
|          4 |          4 |                 9 |                 9 |
+------------+------------+-------------------+-------------------+

我不想对这些值进行硬编码。

我的尝试

update @table1
 set variance_id_date1 = (select id from  @table where name =  cast(diff_date1 as varchar) )
 ,variance_id_date1 = (select id from  @table where name between  cast(diff_date1 as varchar) and  )

2 个答案:

答案 0 :(得分:3)

这是我的建议:

+-------+-------+----+
| start | end   | id |
+-------+-------+----+
| NULL  | -5    |  1 |
| -4    | -2    |  5 |
| -1    | -1    |  6 |
| 0     | 0     |  7 |
| 1     | 2     |  8 |
| 3     | 4     |  9 |
| 5     | 60    | 10 |
| 61    | NULL  | 17 |
+-------+-------+----+

然后简单地用适当的NULL处理

加入它

答案 1 :(得分:1)

带示例输出的选择脚本:

SELECT DISTINCT a.diff_date1
                ,CASE WHEN b.Equal IS NOT NULL THEN Equal 
                 WHEN c.Greater IS NOT NULL THEN c.Greater 
                 ELSE d.Less END as variance_id_date1_Up
FROM [mASter].[dbo].[tableName2] AS a LEFT OUTER JOIN 
 (SELECT [diff_date1]
 ,CASE WHEN ISNUMERIC(REPLACE(REPLACE(b.name  ,'+',''),' ','')) = 1 AND CAST([diff_date1] AS int) = CAST(REPLACE(REPLACE(b.name  ,'+',''),' ','') AS int) then b.id 
  ELSE NULL  END AS [Equal]
  FROM [mASter].[dbo].[tableName2] AS a CROSS JOIN [mASter].[dbo].[tableName] AS b) AS b
  on a.diff_date1 =b.diff_date1 AND b.Equal IS NOT NULL 
  LEFT OUTER JOIN 
  (SELECT [diff_date1]
  ,Max(CAST(CASE WHEN ISNUMERIC(REPLACE(REPLACE(REPLACE(b.name  ,'>',''),' ',''),'+','')) = 1 AND CAST([diff_date1] AS int) > REPLACE(REPLACE(REPLACE(b.name  ,'>',''),' ',''),'+','') then b.id ELSE NULL END AS int)) AS [Greater]
  FROM [mASter].[dbo].[tableName2] AS a CROSS JOIN [mASter].[dbo].[tableName] AS b GROUP BY [diff_date1]) AS c
  on a.diff_date1 = c.diff_date1 AND c.Greater IS NOT NULL AND b.diff_date1 IS NULL  
  LEFT OUTER JOIN 
  (SELECT [diff_date1]
  ,Min(CAST(CASE WHEN ISNUMERIC(REPLACE(REPLACE(b.name  ,'<',''),' ','')) = 1 AND CAST([diff_date1] AS int) < CAST(REPLACE(REPLACE(b.name  ,'<',''),' ','') AS int) then b.id ELSE NULL  END AS int) )AS [Less]
  FROM [mASter].[dbo].[tableName2] AS a CROSS JOIN [mASter].[dbo].[tableName] AS b GROUP BY [diff_date1]) AS d
  on a.diff_date1 =d.diff_date1 AND b.diff_date1 IS NULL AND c.diff_date1 IS NULL


示例输出:

   diff_date1   variance_id_date1
    0                 7
    -21               1
    4                 9
    5                 10
    58                10

更新脚本:

Update [tableName2] set variance_id_date1 = variance_id_date1_Up from(
SELECT DISTINCT a.diff_date1
                ,CASE WHEN b.Equal IS NOT NULL THEN Equal 
                 WHEN c.Greater IS NOT NULL THEN c.Greater 
                 ELSE d.Less END as variance_id_date1_Up
FROM [mASter].[dbo].[tableName2] AS a LEFT OUTER JOIN 
 (SELECT [diff_date1]
 ,CASE WHEN ISNUMERIC(REPLACE(REPLACE(b.name  ,'+',''),' ','')) = 1 AND CAST([diff_date1] AS int) = CAST(REPLACE(REPLACE(b.name  ,'+',''),' ','') AS int) then b.id 
  ELSE NULL  END AS [Equal]
  FROM [mASter].[dbo].[tableName2] AS a CROSS JOIN [mASter].[dbo].[tableName] AS b) AS b
  on a.diff_date1 =b.diff_date1 AND b.Equal IS NOT NULL 
  LEFT OUTER JOIN 
  (SELECT [diff_date1]
  ,Max(CAST(CASE WHEN ISNUMERIC(REPLACE(REPLACE(REPLACE(b.name  ,'>',''),' ',''),'+','')) = 1 AND CAST([diff_date1] AS int) > REPLACE(REPLACE(REPLACE(b.name  ,'>',''),' ',''),'+','') then b.id ELSE NULL END AS int)) AS [Greater]
  FROM [mASter].[dbo].[tableName2] AS a CROSS JOIN [mASter].[dbo].[tableName] AS b GROUP BY [diff_date1]) AS c
  on a.diff_date1 = c.diff_date1 AND c.Greater IS NOT NULL AND b.diff_date1 IS NULL  
  LEFT OUTER JOIN 
  (SELECT [diff_date1]
  ,Min(CAST(CASE WHEN ISNUMERIC(REPLACE(REPLACE(b.name  ,'<',''),' ','')) = 1 AND CAST([diff_date1] AS int) < CAST(REPLACE(REPLACE(b.name  ,'<',''),' ','') AS int) then b.id ELSE NULL  END AS int) )AS [Less]
  FROM [mASter].[dbo].[tableName2] AS a CROSS JOIN [mASter].[dbo].[tableName] AS b GROUP BY [diff_date1]) AS d
  on a.diff_date1 =d.diff_date1 AND b.diff_date1 IS NULL AND c.diff_date1 IS NULL) AS INPUT
  where [tableName2].diff_date1 = INPUT.diff_date1


请记住更改表名或列名。