如何按日期标识行并重复ID?

时间:2019-02-21 15:41:45

标签: sql sql-server sql-server-2008

我再次来到这里寻求至今仍无法实现的事情

我有几张表要填充来自excel的信息,然后从中提取信息,有些表是用excel列中的一行信息填充的,但现在让我们只关注特定的表

假设我在所有信息都放置在excel上,我想将几​​行移动到一个表中,该表的唯一数据是已经存在的ID(从1到1600),当前看起来像这样:

dbo_expedient

expedient_id|sheet_number|data_expedient_entry|expedient_address|
1           | NULL       | NULL               | NULL            |
2           | NULL       | NULL               | NULL            |
3           | NULL       | NULL               | NULL            |
4           | NULL       | NULL               | NULL            |
5           | NULL       | NULL               | NULL            |
6           | NULL       | NULL               | NULL            |
7           | NULL       | NULL               | NULL            |
8           | NULL       | NULL               | NULL            |

另一方面,我们有存储te信息的源表,它看起来像这样:

data_db

sheet_number|expedient_entry_data|name_expedient_owner|expedient_address|
1           | 01-01-2019         | you                | nowhere 123     |
2           | 01-01-2019         | me                 | somewhere 456   |
3           | 03-01-2019         | they               | anywhere 789    |
4           | 04-01-2019         | us                 | any place 1111  |
5           | 05-01-2019         | we                 | everywhere 2222 |
6           | 06-01-2019         | all                | right here 3333 |
7           | 07-01-2019         | he                 | right there 4444|
8           | 08-01-2019         | her                | over there 5555 |

所以,我面临的最大麻烦是我正在加入工作表编号字段,并且该字段只是有限的数量(有时不会超过800,并且从编号1开始),这是因为该数字每年都会重新开始,比方说我们在2017年有800张纸,在2018年有700张纸,但是如果我尝试插入2017年的800张纸,它只会插入那800张纸然后停下来,从2018年开始排掉700行,我问一个同事如何做到这一点,他告诉我要按年份和工作表编号来识别每一行,但是我不知道该怎么做,如果您能帮助我的话,这对我来说很重要,谢谢事先,我会随时注意任何问题。

E D I T

我正在尝试的当前查询是逐行的,而不是大量的,它看起来像这样:

UPDATE X
SET X.sheet_number= Z.sheet_number
FROM dbo_expedient X
JOIN data_db Z ON Z.sheet_number=X.expedient_id

我目前正在将工作表编号和权宜的ID合并在一起,但是由于工作表编号受到限制,并且由于某些位置再次开始,所以ID位置合适。

1 个答案:

答案 0 :(得分:0)

这是一种方法。

对于dbo_expedientdata_db表,我们需要一系列不断增长的唯一数字而没有间隙,以映射/匹配/连接它们的行。

我们可以使用ROW_NUMBER函数来生成这样的序列。

首先,看看简单的SELECT查询,这些查询演示了正在发生的事情。

SELECT
    expedient_id
    ,sheet_number
    ,data_expedient_entry
    ,expedient_address
    ,ROW_NUMBER() OVER (ORDER BY expedient_id) AS rn
FROM dbo_expedient
ORDER BY expedient_id
;

如果保证expedient_id中的dbo_expedient是从1开始的序列且没有间隔,那么您可以直接使用expedient_id,而无需使用ROW_NUMBER

SELECT
    sheet_number
    ,expedient_entry_data
    ,name_expedient_owner
    ,expedient_address
    ,ROW_NUMBER() OVER (ORDER BY YEAR(expedient_entry_data), sheet_number) AS rn
FROM data_db
ORDER BY YEAR(expedient_entry_data), sheet_number
;

现在将它们一起放在rn列上。最易读的方法是使用公用表表达式(CTE)。

WITH
CTE_Dst
AS
(
    SELECT
        expedient_id
        ,sheet_number
        ,data_expedient_entry
        ,expedient_address
        ,ROW_NUMBER() OVER (ORDER BY expedient_id) AS rn
    FROM dbo_expedient
)
,CTE_Src
AS
(
    SELECT
        sheet_number
        ,expedient_entry_data
        ,name_expedient_owner
        ,expedient_address
        ,ROW_NUMBER() OVER (ORDER BY YEAR(expedient_entry_data), sheet_number) AS rn
    FROM data_db
)
SELECT
     CTE_Src.sheet_number AS src_sheet_number
    ,CTE_Src.expedient_entry_data AS src_expedient_entry_data
    ,CTE_Src.name_expedient_owner AS src_name_expedient_owner
    ,CTE_Src.expedient_address AS src_expedient_address
    ,CTE_Dst.expedient_id AS dst_expedient_id
    ,CTE_Dst.sheet_number AS dst_sheet_number
    ,CTE_Dst.data_expedient_entry AS dst_data_expedient_entry
    ,CTE_Dst.expedient_address AS dst_expedient_address
FROM
    CTE_Src
    INNER JOIN CTE_Dst ON CTE_Dst.rn = CTE_Src.rn
;

在检查了此SELECT的结果并确认行已正确连接之后,您可以UPDATE的值

WITH
CTE_Dst
AS
(
    SELECT
        expedient_id
        ,sheet_number
        ,data_expedient_entry
        ,expedient_address
        ,ROW_NUMBER() OVER (ORDER BY expedient_id) AS rn
    FROM dbo_expedient
)
,CTE_Src
AS
(
    SELECT
        sheet_number
        ,expedient_entry_data
        ,name_expedient_owner
        ,expedient_address
        ,ROW_NUMBER() OVER (ORDER BY YEAR(expedient_entry_data), sheet_number) AS rn
    FROM data_db
)
,CTE_Update
AS
(
    SELECT
         CTE_Src.sheet_number AS src_sheet_number
        ,CTE_Src.expedient_entry_data AS src_expedient_entry_data
        ,CTE_Src.name_expedient_owner AS src_name_expedient_owner
        ,CTE_Src.expedient_address AS src_expedient_address
        ,CTE_Dst.expedient_id AS dst_expedient_id
        ,CTE_Dst.sheet_number AS dst_sheet_number
        ,CTE_Dst.data_expedient_entry AS dst_data_expedient_entry
        ,CTE_Dst.expedient_address AS dst_expedient_address
    FROM
        CTE_Src
        INNER JOIN CTE_Dst ON CTE_Dst.rn = CTE_Src.rn
)
UPDATE CTE_Update
SET dst_sheet_number = src_sheet_number
;