用于删除冗余数据的SQL查询

用于删除冗余数据的SQL查询,sql,sql-server,Sql,Sql Server,我的数据如下: 我的问题是: 我想创建查询以删除具有类似版本的冗余行示例13.0、13.0.0、13.0.0.0与SQL Server相同。因此,我想删除版本为13.0、13.0.0、13.0.0.0的行,只保留版本为13.0.0.275的行 是否有任何方法可以使用某些SQL查询执行相同的操作 请提供帮助。检查是否通过此选择获取要删除的行 SELECT * FROM my_table AS a INNER JOIN ( SELECT vendor ,title

我的数据如下:

我的问题是:

我想创建查询以删除具有类似版本的冗余行示例13.0、13.0.0、13.0.0.0与SQL Server相同。因此,我想删除版本为13.0、13.0.0、13.0.0.0的行,只保留版本为13.0.0.275的行

是否有任何方法可以使用某些SQL查询执行相同的操作


请提供帮助。

检查是否通过此选择获取要删除的行

    SELECT *
FROM my_table AS a
INNER JOIN (
    SELECT vendor
        ,title
        ,max(Version) AS version
    FROM my_table
    GROUP BY vendor
        ,title
    ) t ON t.vendor = a.vendor
    AND t.title = a.title
    AND t.version != a.version
然后

DELETE
FROM my_table AS a
INNER JOIN (
    SELECT vendor
        ,title
        ,max(Version) AS version
    FROM my_table
    GROUP BY vendor
        ,title
    ) t ON t.vendor = a.vendor
    AND t.title = a.title
    AND t.version != a.version
试试这个:

    SELECT b.productid
    ,a.Title
    ,a.`Language`
    ,a.Vendor
    ,a.max_ver
FROM (
    SELECT max(Version) AS max_ver
        ,Title
        ,`Language`
        ,Vendor
        ,version
    FROM tbl_product
    GROUP BY `Language`
        ,Vendor
        ,Title
    ORDER BY Title
    ) AS a
LEFT JOIN (
    SELECT productid
        ,Title
        ,`Language`
        ,Vendor
        ,version
    FROM tbl_product
    ) AS b ON a.max_ver = b.version
    AND a.Title = b.Title;

祝你好运。

有一些方法可以做到这一点。试试这个:

    DECLARE @t TABLE (
    productid INT
    ,title VARCHAR(15)
    ,versionNo VARCHAR(50)
    )

INSERT INTO @t
VALUES (
    1
    ,'SQL Server'
    ,'13'
    )
    ,(
    1
    ,'SQL Server'
    ,'13.0.0'
    )
    ,(
    1
    ,'SQL Server'
    ,'13.0.0.0'
    )
    ,(
    1
    ,'SQL Server'
    ,'13.0.0.275'
    )
    ,(
    2
    ,'Visual Studio'
    ,'13'
    )
    ,(
    2
    ,'Visual Studio'
    ,'13.0.0'
    )
    ,(
    2
    ,'Visual Studio'
    ,'13.0.0.0'
    )
    ,(
    2
    ,'Visual Studio'
    ,'13.0.0.275'
    )

SELECT *
FROM @t

--1. Approach First
--delete t from @t t join
--(
--  select productid,title, max(versionNo) versionno from @t 
--  group by productid, title 
--) temp on t.productid = temp.productid and t.title = temp.title and t.versionno <> temp.versionno
--2. Approach Second
DELETE t
FROM @t t
JOIN
    --select distinct t. *  from @t t join
    (
    SELECT DISTINCT productid
        ,title
        ,S.a.value('(/H/r)[4]', 'VARCHAR(100)') FourthPostionValue
    FROM (
        SELECT *
            ,CAST(N'<H><r>' + Replace(versionno, '.', '</r><r>') + '</r></H>' AS XML) AS [vals]
        FROM @t
        ) d
    CROSS APPLY d.[vals].nodes('/H/r') S(a)
    ) TEMP ON t.productid = TEMP.productid
    AND t.title = TEMP.title --and isnull(temp.FourthPostionValue, 0) = 0 
    AND charindex(isnull(TEMP.FourthPostionValue, 2), t.versionNo) = 0

SELECT *
FROM @t

利用以下事实,即每个ProductID的ProductVersionID似乎已经同意您的条件假设,并通过查看更多数据进行确认

DELETE FROM table FROM table T1 
   WHERE ProductVersionID < 
     (SELECT max(ProductVersionID) 
         FROM table T2 WHERE T1.ProductID = T2.ProductID)

OP没有那么清楚,也没有试图与我们一起解决问题,这对我们没有帮助

但是,我将再次尝试:

如果列中的版本“13.0.0.0”和“13.0.0.725”是合法的,或者至少是更正式的产品版本,并且要删除与此模式不匹配的所有其他记录…则使用LEN函数。一次扫描,完成

 CREATE TABLE #tableA (
    productid INT
    ,title VARCHAR(15)
    , [Version] VARCHAR(50)
    )

INSERT INTO #tableA
VALUES (1,'SQL Server','13')
     , (1,'SQL Server','13.0.0')
     , (1,'SQL Server','13.0.0.0')
     , (1,'SQL Server','13.0.0.275')
     , (2,'Visual Studio','13')
     , (2,'Visual Studio','13.0.0')
     , (2,'Visual Studio','13.0.0.0')
     , (2,'Visual Studio','13.0.0.275')

SELECT  *
FROM #TableA
WHERE LEN( SUBSTRING(Version
                       , CHARINDEX('.', Version)
                       , LEN(Version) ) 
          )  < 6
这里的关键是确定你想要的长度。0.0.0'为6个字符长。如果您只想保留“13”,可以添加特殊的异常,例如“13”


剩下的就交给你了。

请放大图像以获得更清晰的数据视图版本的数据类型是什么?为什么是13.0.0275,逻辑是什么,以及您想要的mysql或sqlserver语法。@Ajay2707:很明显,他的逻辑将两个版本定义为相同的,如果它们只相差一个或多个.0后缀。所以13,13.0,13.0.0都是一样的,而13.0.0.275是不同的。事实上,我想要更精致的版本,而不是不那么精致的版本。它希望13.0.0.0应该在那里,13.0,13.0.0记录应该被删除。同样在这种情况下,例如,版本“13.11”按字母顺序比版本“13.101”大。请解释您需要的确切规则。其他答案直接使用字符串版本查找max/最新版本:这不正确,您可以阅读有关SQL Server中字符串排序的更多信息。无论如何,为了避免不必要的复杂性,我建议用适当的int作为版本号来设计数据结构。如果你认为你知道什么,我错了,我很高兴你指出了。我认为你的解决方案没有那么有用。您的选择将把13折成13.0.0.275。原来的海报似乎更希望13、13.0、13.0.0折叠在一起,但13.0.0.275分开。他在大约一小时前发表了这样的评论。字符串版本可能是唯一可靠的数据,必须使用它。有时您无法根据自己的喜好设计数据结构-处理必须在某个地方进行,如果可以在SQL Server中轻松完成,那么为什么不呢。@RossPresser OP写道,所以我想删除版本为13.0、13.0.0、13.0.0.0的行,只保留版本为13.0.0.275的行。就在一个小时前,我看到可能是那个家伙改变了主意…:-数据有13行,没有后缀。。。他希望保留该版本,并删除后缀为零的版本。请注意,如果该版本可能类似于“13.0.14.1”,则您必须在代码中对此进行调整。
DELETE FROM table 
FROM table T1 
WHERE T1.Version IN  
(
SELECT T1.Version
   FROM table T2 WHERE 
   ((
        (T2.Version = T1.Version+ '.0') 
        OR (T2.Version = T1.Version+ '.0.0')  
        OR (T2.Version = T1.Version+ '.0.0.0')
   )
   AND T2.ProductID = T1.ProductID )
 CREATE TABLE #tableA (
    productid INT
    ,title VARCHAR(15)
    , [Version] VARCHAR(50)
    )

INSERT INTO #tableA
VALUES (1,'SQL Server','13')
     , (1,'SQL Server','13.0.0')
     , (1,'SQL Server','13.0.0.0')
     , (1,'SQL Server','13.0.0.275')
     , (2,'Visual Studio','13')
     , (2,'Visual Studio','13.0.0')
     , (2,'Visual Studio','13.0.0.0')
     , (2,'Visual Studio','13.0.0.275')

SELECT  *
FROM #TableA
WHERE LEN( SUBSTRING(Version
                       , CHARINDEX('.', Version)
                       , LEN(Version) ) 
          )  < 6