返回字段具有相同值和附加文本的所有记录

时间:2015-06-23 06:31:17

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

表包含特定字段的唯一记录(FILENAME)。虽然记录是唯一的,但实际上它们只是附加了一些文本的重复记录。如何返回和分组相似或类似的记录并更新空字段?

下表是典型的记录。每条记录都有一个文件名,但它不是一个关键字段。有一个带有元数据的数据库记录,我想填充这些记录以记录只能由前n个字符识别的元数据。

变量是原始文件名始终改变字符长度。 常量是前缀始终相同。

FILENAME     /    DWGNO       /    PROJECT
52349        /     52349      /     Ford
52349-1.dwg  /                / 
52349-2.DWG  /                / 
52349-3.dwg  /                / 
52351        /       52351    /      Toyota
52351_C01_REV-   /                / 
52351_C01_REV2-  /                / 
123          /        123     /       Nissan
123_rev1     /                /     
123_rev2     /                /     
123_rev3     /                /     

表格应如下所示。

FILENAME       /      DWGNO     /     PROJECT
52349          /      52349     /      Ford
52349-1.dwg    /      52349     /      Ford
52349-2.DWG    /      52349     /      Ford
52349-3.dwg    /      52349     /      Ford
52351          /      52351      /      Toyota
52351_C01_REV- /      52351      /      Toyota
52351_C01_REV2-/      52351      /      Toyota
123            /      123        /      Nissan
123_rev1       /      123        /      Nissan
123_rev2       /      123        /      Nissan
123_rev3       /      123        /      Nissan

我首先尝试加入表格并检查长度但是" LEFT(FILENAME,10)"没有返回所有结果。

USE MyDatabase
SELECT      x.DWGNO AS X_DWGNO,
    y.DWGNO AS Y_DWGNO,
    x.FILENAME AS X_FILENAME
    y.FILENAME AS Y_FILENAME
    x.DWGTITLE,
    x.REV,
    x.PROJECT
FROM        dbo.DocShare x
-- want all the files from the left table... I think
LEFT JOIN   dbo.DocShare y
 ON     LEFT(FILENAME LEN(CHARINDEX('.', FILENAME 1))) = LEFT(FILENAME, 10)

还尝试了基于类似帖子的其他内容,但它也不起作用。

USE MyDatabase
SELECT      X.E_DWGNO,
    y.DWGNO AS Y_DWGNO,
    x.FILENAME AS X_FILENAME
    y.FILENAME AS Y_FILENAME
    x.DWGTITLE,
    x.REV,
    x.PROJECT
FROM        dbo.DocShare x
WHERE EXISTS(SELECT x.FILENAME 
        FROM dbo.DocShare
        WHERE x.FILENAME = LEFT(y.FILENAME LEN(CHARINDEX('.', y.FILENAME, 0))))
ORDER BY y.FILENAME 

4 个答案:

答案 0 :(得分:2)

首先,您希望获取基本文件或DWGNO IS NOT NULL所在的行。然后,获取修订版本(DWGNO IS NULL)并对基本文件执行JOIN

SQL Fiddle

WITH CteBase AS (
    SELECT * FROM Tbl WHERE DWGNO IS NOT NULL
),
CteRev AS(
    SELECT
        t.FileName,
        DWGNO = cb.DWGNO,
        Project = cb.Project
    FROM Tbl t
    INNER JOIN CteBase cb
        ON t.FileName LIKE cb.FileName + '%'
    WHERE t.DWGNO IS NULL
)
SELECT * FROM CteBase
UNION ALL
SELECT * FROM CteRev
ORDER BY FileName

答案 1 :(得分:2)

试试这个

Sql Fiddle

select f2.Filename,f1.DWGNO,f1.Project
from File1 f2 left join File1 f1 on
f2.Filename like f1.Filename+'%'
where f1.DWGNO != '' 

答案 2 :(得分:0)

如果像523510这样的文件名,使用like%可能会导致数据不正确,因为它像52351%。试试下面的

USE MyDatabase
SELECT      x.DWGNO AS X_DWGNO,
    y.DWGNO AS Y_DWGNO,
    x.FILENAME AS X_FILENAME
    y.FILENAME AS Y_FILENAME
    x.DWGTITLE,
    x.REV,
    x.PROJECT
FROM        dbo.DocShare x
-- want all the files from the left table... I think
LEFT JOIN   dbo.DocShare y
 ON     left(y.[FileName],PATINDEX('%[^0-9]%', y.[FileName])-1) = x.[FILENAME]

答案 3 :(得分:0)

我假设内部查询是标量。

基本上它使用patindex()来查找非数字字符。 (我想我的函数调用正确。)我们真的不需要更新那些不包含其中一个的行。对于那些我们需要查找具有匹配前缀的行作为其完整文件名的行。该前缀是返回值patindex()之前的所有字符。

update dbo.DocShare
set DWGNO = (
        select DWGNO
        from dbo.DocShare as ds
        where ds.FILENAME =
            left(
                dbo.DocShare.FILENAME,
                patindex('%[^0-9]%', dbo.DocShare.FILENAME + '_') - 1
            )
    ),
    PROJECT
        select PROJECT 
        from dbo.DocShare as ds
        where ds.FILENAME =
            left(
                dbo.DocShare.FILENAME,
                patindex('%[^0-9]%', dbo.DocShare.FILENAME + '_') - 1
            )
)
where patindex('%[0-9]%', FILENAME + '_') > 0