【问题标题】:Comparing the length of two similar strings and picking the longest比较两个相似字符串的长度并选择最长的
【发布时间】:2018-02-23 16:16:03
【问题描述】:

我正在尝试比较两个字符串并选择最长的字符串(如果它们相似),我已经通过使用以下代码设法选择了最长的字符串:

SELECT D.RID, ProductID, Product, [Length] FROM (
SELECT RID, MAX([Length]) AS theLength FROM SortData GROUP BY RID)
AS X INNER JOIN SortData AS D ON D.RID = X.RID AND D.[Length] = X.theLength

但是我现在正在尝试确保代码只选择最长的字符串,如果它与它比较的单词相似,我已经尝试了以下代码,但如果有人可以的话,我将不胜感激帮帮我:

SELECT D.RID, D.ProductID, Product, [Length] FROM (
SELECT RID, Product, MAX([Length]) AS theLength FROM SortData GROUP BY RID)
AS X INNER JOIN SortData AS D ON D.RID = X.RID AND D.[Length] = X.theLength WHERE
D.Product LIKE Product

使用此代码我得到以下错误:

消息 8120,级别 16,状态 1,第 3 行列“SortData.Product”为 在选择列表中无效,因为它不包含在 聚合函数或 GROUP BY 子句。消息 209,级别 16,状态 1, 第 5 行不明确的列名称“产品”。消息 209,级别 16,状态 1, 第 2 行不明确的列名称“产品”。

我想选择的数据示例:

1 山姆
1 萨曼莎
2 奥利弗
3 奥利
4 本杰明
4 本
...
我希望输出列表如下:

1 萨曼莎
2 奥利弗
3 奥利
4 本杰明
...

为了澄清我在此示例的上下文中尝试执行的操作,我尝试比较两个名称,如果它们是 LIKE(例如 x.Name LIKE 名称),则选择最长的...

这里要求的是进一步的测试数据:

1 氢
1 氧化氢
1 一氧化碳
2 碳
2 碳
2 二氧化碳
3 一氧化碳
3 二氧化碳
3 氧气
4 二氧化氢

期望的结果如下:

1 氧化氢
1 一氧化碳
2 二氧化碳
3 一氧化碳
3 氧气
4 二氧化氢

【问题讨论】:

  • 使用新的示例数据,John 和我自己的代码仍然返回所需的输出。
  • 它没有...当我给代码提供 ID 为 1 到 6 的 Sam、Ben、Benjamin、Ollie、Oliver 和 Samantha 的列表时,我仍然得到完全相同的列表吗?要添加,如果 id 相同,它将只取最大的,在您提供的任何代码中,没有比较 LIKE 让我同时获得 Samantha 和 Benjamin,这意味着 Ollie 和 Oliver 应该是 LIKE Sam、Ben、Benjamin、Ollie , Oliver 和 Samantha,如果你的代码中有类似的东西?
  • 在下面查看我的编辑。新的示例数据实际上与原始数据没有什么不同,并且发布的代码仍然返回您所说的所需输出。帮助我们了解问题。

标签: sql-server sql-like


【解决方案1】:

也许是另一种选择:WITH TIES 子句与 Row_Number() 一致

示例

Select Top 1 with ties * 
 From  YourTable
 Order By Row_Number() over (Partition by ID Order By Len(Name) desc)

【讨论】:

  • 好约翰。我喜欢这种方法。不知道我以前见过这样的做法。 :)
  • @SeanLange 我只是一个懒惰的人。唯一的优点是没有额外的字段。执行/性能与cte相同。
  • 不,你并不懒惰。懒惰和高效编码之间存在巨大差异。
  • @JohnCappelletti 我要问的要点是我的代码已经删除了最大的字符串......虽然这看起来很漂亮......
【解决方案2】:

您的查询与您的示例数据和输出不符。因此,我围绕提供的示例数据构建了它,以演示解决此问题的一种方法。

declare @Something table
(
    Col1 int
    , Col2 varchar(20)
)

insert @Something values
(1, 'Sam')
, (1, 'Samantha')
, (2, 'Oliver')
, (3, 'Ollie')

select x.Col1
    , x.Col2
from
(
    select *
        , RowNum = ROW_NUMBER() over(partition by Col1 order by LEN(Col2) desc)
    from @Something
) x
where x.RowNum = 1

---编辑---

为了证明此代码仍能从您的新示例数据中返回所需的输出...

declare @Something table
(
    Col1 int
    , Col2 varchar(20)
)

insert @Something values
(1, 'Sam')
, (1, 'Samantha')
, (2, 'Oliver')
, (3, 'Ollie')
, (4, 'Benjamin')
, (4, 'Ben')

select x.Col1
    , x.Col2
from
(
    select *
        , RowNum = ROW_NUMBER() over(partition by Col1 order by LEN(Col2) desc)
    from @Something
) x
where x.RowNum = 1

这会返回:

1   Samantha
2   Oliver
3   Ollie
4   Benjamin

由于您声称这仍然不起作用,您需要提供一个示例来说明这不起作用或为什么不起作用。你一直提到 LIKE,但没有解释或演示它是如何在这里发挥作用的。帮助我了解问题,我可以帮助您找到解决方案。

【讨论】:

  • 只有当它们像另一个具有相同 id 的字符串时,我才尝试比较这两者...
  • 这是什么意思?如果 Col1 有两行 1 而 col2 是 Sean 和 Ollie,会发生什么?他们俩都被退回了吗?您如何确定它们相似?萨曼莎和桑普森呢?还是彼此“喜欢”?你需要解释一下游戏规则。
  • 好吧,忘记示例数据,尝试将 Oliver 和 Ollies 的 ID 更改为 1...它不会比较它们是否相似。
  • 定义相似的含义。知道 Oliver 和 Ollie 应该被视为相同的标准是什么?而且我们不能忘记示例数据,您需要修复它来演示问题。如果它们的长度相同怎么办?哪一个会被退回?
  • 我会添加更多数据,你是对的 我希望结果为:1 Samantha 2 Oliver 3 Ollie 4 Benjamin 但尝试将您的数据更改为 1 Samantha 1 Oliver 1 Ollie 1 Benjamin 看看结果如何结果是...我有很多 ID 和相关数据我发布了简单的数据以便更容易理解您过度简化了问题...并忽略了我的解释...
【解决方案3】:

我最终弄清楚并使用了以下代码:

SELECT D.RID, ProductID, D.Product, [Length] FROM 
(
SELECT RID, MAX([Length]) AS theLength 
FROM SortData GROUP BY RID
) AS X 
INNER JOIN SortData AS D ON D.RID = X.RID AND D.[Length] = X.theLength
WHERE D.Product LIKE Product
GO

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-11
    • 2021-04-19
    • 2012-04-07
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多