【问题标题】:How to calculate LCM value using SQL Server?如何使用 SQL Server 计算 LCM 值?
【发布时间】:2018-09-11 19:43:19
【问题描述】:

我有以下数据,我需要使用 T-SQL 查询根据组 id 计算 LCM(最低计算乘法)值。我们将不胜感激。

Groupid GroupValue
------------------
1        2
1        4
1        6
2        5
2        5
2       10
3        3
3       12
3        6
3        9

预期结果如下。

Groupid   GroupLCM
------------------
   1        12
   2        10
   3        36

【问题讨论】:

  • SQL 不是一种很好的语言,无法在数学上将数字分解为素数。
  • 在纯 T-SQL 中可行,但既不明显也不高效。如果您需要将其作为“真实”数据库的一部分(不是玩具练习),我可能会将其设为 CLR 自定义聚合; lcm(a,b) = a / gcd(a,b) * bgcd 是书中最古老的算法。 (字面意思。)

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


【解决方案1】:

一种可能的方法是使用如下的计数表

See working demo

; with detailedSet as 
(
    select 
        Groupid,
        GroupValue=abs(GroupValue),
        biggest=max(GroupValue) over (partition by Groupid),
        totalNumbers= count(1) over (partition by Groupid)
    from num
    )
,   
possibleLCMValues as 
(
    select Groupid, counter
    from detailedSet b
    cross apply 
    (
select counter= row_number() over ( order by (select null))  * biggest 
from sys.objects o1 cross join sys.objects o2
)c
where c.counter%GroupValue =0
group by Groupid, counter
having count(1)=max(totalNumbers)
)
,
LCMValues as
(
    select 
        Groupid,
        LCM=min(counter) 
    from possibleLCMValues
    group by Groupid
)

select * from LCMValues

【讨论】:

  • 我建议做两个细微的调整:1) 如果一个组只包含负数,为了防止出现无意义的结果,在detailedSet (lcm(a,b) = lcm(|a|,|b|)) 中使用abs(GroupValue)max(abs(GroupValue))。 2) 将c.counter < biggest * biggest 更改为c.counter / biggest < biggest 以避免整数溢出。
  • 感谢您的帮助。但是,当我再插入一个值为 8、9、23 的组 id 4 并验证结果时,我没有在最终结果集中获得组 id 4 值。可能是某些条件不满足。
  • @Nikunj 是的。其他数的乘积大于最大数的平方。我决定删除停止条件。
  • 我遇到了一些奇怪的问题,比如当我在 ssms 中从 rextester.com 运行相同的查询时,查询进入无限循环。但它在该链接中正常运行。任何人都可以检查您是否也面临同样的问题。
  • Dhruv,我只是告诉你,查询在 sys.objects 之间进行交叉连接。如果您的数据库有超过 1K 的对象,那么查询就会运行和运行。所以删除条件不是优化解决方案。
【解决方案2】:

我找到了我在下面的堆栈流问题上发布的解决方案。在最终结果表中,我们再次使用 max value 组 id 并获得 LCM 值。

请注意就像,我发布此问题是为了更优化解决方案以删除 for 循环,否则它也可以使用 for 循环正常工作。

How to update the column without loop in SQL Server?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多