我在一个名为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 |
请建议我找到理想的结果。 谢谢。
答案 0 :(得分:1)
您可以通过查找.
之后的值来删除字符串的数字部分,如下所示:
DECLARE @val VARCHAR(5) = 'BD.34'
SELECT CONVERT(INT, RIGHT(@val, LEN(@val) - CHARINDEX('.', @val))) AS Result
Result
======
34
然后,您可以将其纳入子查询,以便与GROUP BY
和MAX
联系回主表,如下所示:
可运行代码:
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