SQL Server选择MAX版本值

时间:2015-07-24 08:47:45

标签: sql-server max sql-order-by

我在一个名为id和version的表中有两列,如下所示:

ScoreDoc[] hits = [create search];
IFormatter formatter = new SimpleHTMLFormatter("<b>", "</b>");
QueryScorer scorer = new QueryScorer(query, );
Highlighter highlighter = new Highlighter(formatter, scorer);

for (int i = 0; i < hits.Length; i++)
{
    int docId = hits[i].Doc;
    float score = hits[i].Score;
    Document doc = search.Doc(docId);

    string fragments = string.Empty;
    if (collectFragments)
    {
        TokenStream stream = _analyzer.TokenStream("", new StringReader(doc.Get(AppConstants.Fields.FullText)));
        fragments = highlighter.GetBestFragments(stream, doc.Get(AppConstants.Fields.FullText), 2, "...");
    }

    ...
}

我的要求是我必须为表中的每个id选择max(Version)。在这种情况下,我应该得到以下结果:

ID | Version |
1  | A.15    |
1  | Z.6     |
1  | C.5     |
1  | BD.3    |
1  | BD.2    |
1  | AB.13   |
2  | C.45    |
2  | Z.56    |
2  | Z.8     |

但我得到以下结果:

|ID | MAX(Version)|
| 1 | BD.3       |
| 2 | Z.56        |

当我使用此查询时:

|ID | MAX(Version)|
| 1 | Z.6         |
| 2 | Z.8         |

请建议我找到理想的结果。 谢谢。

5 个答案:

答案 0 :(得分:1)

您可以通过查找.之后的值来删除字符串的数字部分,如下所示:

DECLARE @val VARCHAR(5) = 'BD.34'
SELECT  CONVERT(INT, RIGHT(@val, LEN(@val) - CHARINDEX('.', @val))) AS Result

Result
======
34

然后,您可以将其纳入子查询,以便与GROUP BYMAX联系回主表,如下所示:

可运行代码:

CREATE TABLE #Versions
    (
      [ID] INT ,
      [Version] VARCHAR(5)
    );

INSERT  INTO #Versions
        ( [ID], [Version] )
VALUES  ( 1, 'A.15' ),
        ( 1, 'Z.6' ),
        ( 1, 'C.5' ),
        ( 1, 'BD.34' ),
        ( 1, 'BD.25' ),
        ( 1, 'AB.13' ),
        ( 2, 'C.45' ),
        ( 2, 'Z.56' ),
        ( 2, 'Z.8' );

SELECT  v.ID ,
        v.Version
FROM    #Versions v
        INNER JOIN ( 
              SELECT ID , 
                     MAX(CONVERT(INT, 
                         RIGHT(Version, 
                           LEN(Version) - CHARINDEX('.', Version)))) AS VersionNo
                     FROM   #Versions
                     GROUP BY ID
                   ) t ON t.ID = v.ID
                          AND '.' + CONVERT(VARCHAR(5), t.VersionNo) = '.'
                          + RIGHT(v.Version,
                                  LEN(v.Version) - CHARINDEX('.', v.Version))

DROP TABLE #Versions

<强>产地:

ID  Version
1   BD.34
2   Z.56

使用的加入会将MAX版本号保存在VersionNo主页中,我已将'.'添加到联接中并假设您的版本将始终采用以下格式:字符后跟句点/句号和数字部分。

答案 1 :(得分:1)

试试这个:

DECLARE @MyTable TABLE(ID INT, Version VARCHAR(10))

INSERT INTO @MyTable
VALUES (1,'A.15'), (1,'Z.6'), (1,'C.5'), (1,'BD.3'), (1,'BD.2'),
       (1,'AB.13'), (2,'C.45'), (2,'Z.56'), (2,'Z.8')

--
SELECT
    ID,
    Version
FROM
(
    SELECT
        ID,
        Version,
        ROW_NUMBER() OVER 
        (
            PARTITION BY    ID
            ORDER BY        LEN(LEFT(Version, CHARINDEX('.',Version)-1)) DESC, 
                            LEFT(Version, CHARINDEX('.',Version)-1) DESC, 
                            CAST(STUFF(Version, 1, CHARINDEX('.',Version),'') AS INT) DESC
        ) AS Pos
    FROM 
        @MyTable
) T
WHERE Pos = 1

答案 2 :(得分:0)

我想你想要以下内容:

SELECT ID,MAX(SUBSTRING(Version,charindex('.',Version),Len(Version)-charindex('.',Version)))
FROM table
GROUP BY ID

基本上上面的代码在&#39;。&#39;之后得到子字符串,因此是Version的数字部分,并找到该部分的最大值

答案 3 :(得分:0)

我们在这里不需要一个小组。它可以通过相对简单的查询来完成。查询中使用的逻辑类似于其他答案中使用的逻辑。

SELECT ID,version
FROM tmp a
where CAST(SUBSTRING(version,charindex('.',version)+1,Len(version)-charindex('.',version)) as integer)=
(select MAX(CAST(SUBSTRING(version,charindex('.',version)+1,Len(version)-charindex('.',version)) as integer)) from tmp b where a.id=b.id)

答案 4 :(得分:0)

这是我的方式(我们不关心这些字母,只关注数字)

DECLARE @MyTable TABLE(ID INT, Version VARCHAR(10))

INSERT INTO @MyTable VALUES(1,'A.15')
                    ,(1,'Z.6')
                    ,(1,'C.5')
                    ,(1,'BD.34')
                    ,(1,'BD.25')
                    ,(1,'AB.13')
                    ,(2,'C.45')
                    ,(2,'Z.56')
                    ,(2,'Z.8')


SELECT t1.ID, t1.Version 
FROM @MyTable AS t1
INNER JOIN (
    SELECT Id, MAX(CONVERT(INT,SUBSTRING(Version,CHARINDEX('.',Version)+1,LEN(Version)))) AS Number
    FROM @MyTable
    GROUP By ID ) AS t2
    ON t1.ID = t2.ID AND CONVERT(INT,SUBSTRING(t1.Version,CHARINDEX('.',t1.Version)+1,LEN(t1.Version))) = t2.Number