最佳组合问题 数据库中有一个产品表。产品有一个属性是point 然后会员也有一个point,有一个地方需要找出6个产品,他们point之和最接近于用户point

lovebanyi 2009-09-02 10:26:36
最佳组合问题
数据库中有一个产品表。
产品有一个属性是point
然后会员也有一个属性是point,
有一个地方需要找出6个产品,
他们point之和最接近于用户point

产品的point是可以重复的。产品至少有6个(默认条件)

首先我们可以得到两种极端条件。
1.用户的point非常小(小于产品里面point最小的哪个)所以他得到的最匹配产品就应该是point 升序排列里面,前面的几个。
2.用户的point非常大(大于所有的产品point之合)所以他得到的最匹配产品就应该是point 降序排列里面,前面的几个。
3,用户的point处在两个之间 (我们应该如何取舍判断呢?排列数可能是非常的多) sql应该什么样去写。 为了界面的好看我们可以也希望 point完全都不一样的 优先级更大。

...全文
120 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
wsxcdx 2009-09-02
  • 打赏
  • 举报
回复
这标题真长
csdyyr 2009-09-02
  • 打赏
  • 举报
回复
DECLARE @TB TABLE([ID] INT, [Point] INT)
INSERT @TB
SELECT 1, 0 UNION ALL
SELECT 2, 78 UNION ALL
SELECT 3, 21 UNION ALL
SELECT 4, 58 UNION ALL
SELECT 5, 34 UNION ALL
SELECT 6, 21 UNION ALL
SELECT 7, 46 UNION ALL
SELECT 8, 41 UNION ALL
SELECT 9, 2 UNION ALL
SELECT 10, 1 UNION ALL
SELECT 11, 41 UNION ALL
SELECT 12, 15 UNION ALL
SELECT 13, 12 UNION ALL
SELECT 14, 20 UNION ALL
SELECT 15, 60 UNION ALL
SELECT 16, 52 UNION ALL
SELECT 17, 94 UNION ALL
SELECT 18, 30 UNION ALL
SELECT 19, 95 UNION ALL
SELECT 20, 61 UNION ALL
SELECT 21, 88 UNION ALL
SELECT 22, 0

select *,seq=identity(int,1,1) into # from @TB where Point<>0 order by Point

declare @P int
set @P=100

select top 6 *
from (
select ID,Point
from #
where seq<=(
select top 1 seq
from (
select *,(select sum(Point) from # where seq<=t.seq) as totalP
from # AS t
) ta
order by abs(totalP-@P))
) tb
order by Point desc

drop table #
haitao 2009-09-02
  • 打赏
  • 举报
回复
好像是背包问题,只是个数确定了,也许可以完全枚举各种可能
xiequan2 2009-09-02
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 lovebanyi 的回复:]
需求是我们会输入一个point 这个时候要求数据库返回6个productID 他们的point总和最接近我们输入的哪个。 最接近是这样理解的。。 我们输入100 6个产品point刚好是100ok最佳。 如果没有 99 (101) 98 (102) 97 (103)都是接近的。
[/Quote]
参考这个,上次我写过
http://topic.csdn.net/u/20090804/09/c1ecfa8e-682c-4f7e-86a2-8c8c3c5076db.html
lovebanyi 2009-09-02
  • 打赏
  • 举报
回复
需求是我们会输入一个point 这个时候要求数据库返回6个productID 他们的point总和最接近我们输入的哪个。 最接近是这样理解的。。 我们输入100 6个产品point刚好是100ok最佳。 如果没有 99 (101) 98 (102) 97 (103)都是接近的。
soft_wsx 2009-09-02
  • 打赏
  • 举报
回复
用一个表处理吗?树型数据
--树型结构处理之双编号(广度深度排序)
if OBJECTPROPERTY(object_id('tb'),'isusertable')<>0
drop table tb
create table tb(ybh nvarchar(10),ebh nvarchar(10),beizhu nvarchar(1000))
insert tb
select '0001',null,'云南省'
union all select '0002','0001','昆明市'
union all select '0003','0001','昭通市'
union all select '0009','0001','大理市'
union all select '0008',null,'四川省'
union all select '0004',null,'贵州省'
union all select '0005','0002','五华区'
union all select '0007','0002','水富县'
union all select '0006','0005','西园路192号'
union all select '0010','0006','金色梧桐'
union all select '0011','0010','科技有限公司'
union all select '0015','0007','两碗乡'
union all select '0013','0015','两碗村'
union all select '0012','0013','某跨国集团董事长'
union all select '0014','0008','成都市'

--select * from tb
--广度排序(先显示第一层节点,再显示第二次节点......)
--定义辅助表
declare @level_tb table(bh nvarchar(10),level int)
declare @level int
set @level=0
insert @level_tb(bh,level)
select ybh,@level from tb where ebh is null
while @@ROWCOUNT>0
begin
set @level=@level+1
insert @level_tb(bh,level)
select ybh,@level
from tb a,@level_tb b
where a.ebh=b.bh
and b.level=@level-1
end
select a.*,b.* from tb a,@level_tb b where a.ybh=b.bh order by level


--深度排序(模拟单编码法)
declare @level_tt table(ybh nvarchar(1000),ebh nvarchar(1000),level int)
declare @level int
set @level=0
insert @level_tt(ybh,ebh,level)
select ybh,ybh,@level from tb where ebh is null
while @@ROWCOUNT>0
begin
set @level=@level+1
insert @level_tt(ybh,ebh,level)
select a.ybh,b.ebh+a.ybh,@level
from tb a,@level_tt b
where a.ebh=b.ybh and b.level=@level-1
end
select space(b.level*2)+'----'+a.beizhu,a.*,b.*
from tb a,@level_tt b
where a.ybh=b.ybh
order by b.ebh
lovebanyi 2009-09-02
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 htl258 的回复:]
SQL code--> 生成测试数据表:taIfnotobject_id('[p]')isnullDroptable[p]GoCREATETABLE[dbo].[P]([ID][int]IDENTITY(1,1)NOTNULL,[Point][int]NOTNULL,
)set nocountondeclare@iintdeclare@rndintset@i=0while@i<4000begin¡­
[/Quote]
可能没有理解好。 参数只要一个 用户point 6个产品point 总和最接近于它。(测试数据无数多的时候应该会找到相等的)
如果不过多。应该找到的是比它小一点点或大一点点的
华夏小卒 2009-09-02
  • 打赏
  • 举报
回复
这个只能帮顶
htl258_Tony 2009-09-02
  • 打赏
  • 举报
回复
上面是有问题的,楼主说下最终想实现的样子.
lovebanyi 2009-09-02
  • 打赏
  • 举报
回复
ID Point
1 0
2 78
3 21
4 58
5 34
6 21
7 46
8 41
9 2
10 1
11 41
12 15
13 12
14 20
15 60
16 52
17 94
18 30
19 95
20 61
21 88
22 0
23 56
24 25
25 92
26 94
27 56
28 68
29 63
30 73
31 63
32 58
33 5
34 44
35 19
36 6
37 48
38 97
39 89
40 5
41 8
42 13
43 45
44 67
45 63
46 93
47 90
48 89
49 71
50 72
51 27
52 81
53 24
54 10
55 40
56 35
57 46
58 90
59 25
60 11
61 77
62 31
63 62
64 32
65 53
66 52
67 45
68 66
69 52
70 46
71 50
72 16
73 84
74 73
75 23
76 5
77 54
78 62
79 54
80 6
81 17
82 71
83 67
84 27
85 21
86 64
87 30
88 40
89 42
90 58
91 36
92 67
93 29
94 3
95 12
96 90
97 84
98 94
99 82
100 7
101 11
102 145
103 52
104 658
105 943
106 855
107 133
108 502
109 678
110 638
111 948
112 193
113 173
114 74
115 239
116 440
117 110
118 123
119 693
120 848
121 583
122 480
123 875
124 746
125 285
126 281
127 859
128 307
129 291
130 865
131 305
132 808
133 429
134 45
135 675
136 897
137 10
138 913
139 589
140 444
141 810
142 667
143 313
144 999
145 63
146 300
147 498
148 206
149 994
150 84
151 419
152 993
153 66
154 731
155 657
156 240
157 723
158 633
159 604
160 544
161 856
162 809
163 520
164 299
165 38
166 635
167 580
168 919
169 80
170 705
171 42
172 293
173 469
174 951
175 80
176 40
177 449
178 854
179 847
180 677
181 849
182 624
183 807
184 618
185 107
186 563
187 761
188 876
189 421
190 937
191 918
192 308
193 365
194 409
195 579
196 777
197 442
198 874
199 662
200 464
201 423
202 813
203 322
204 332
205 745
206 446
207 315
208 202
209 583
210 191
211 981
212 563
213 662
214 600
215 491
216 72
217 576
218 423
219 121
220 910
221 148
222 787
223 137
224 797
225 421
226 953
227 549
228 735
229 862
230 375
231 903
232 381
233 186
234 55
235 746
236 452
237 907
238 186
239 526
240 402
241 187
242 580
243 41
244 698
245 789
246 689
247 265
248 67
249 835
250 273
251 860
252 895
253 67
254 472
255 694
256 907
257 417
258 414
259 530
260 544
261 525
262 100
263 478
264 623
265 716
266 444
267 292
268 168
269 870
270 759
271 108
272 593
273 65
274 339
275 47
276 203
277 644
278 512
279 597
280 185
281 194
282 412
283 152
284 60
285 618
286 783
287 103
288 207
289 556
290 302
291 11
292 710
293 387
294 741
295 254
296 851
297 20
298 300
299 248
300 457
301 707
302 509
303 452
304 529
305 522
306 746
307 354
308 600
309 663
310 516
311 820
312 603
313 850
314 524
315 707
316 971
317 438
318 135
319 961
320 124
321 127
322 656
323 963
324 225
325 641
326 831
327 661
328 64
329 771
330 30
331 782
332 602
333 935
334 744
335 944
336 485
337 442
338 600
.....
这个就是数据了。 第一个是id第二个是point 结果当然是要得到哪6个ID了
htl258_Tony 2009-09-02
  • 打赏
  • 举报
回复
--> 生成测试数据表:ta

If not object_id('[p]') is null
Drop table [p]
Go
CREATE TABLE [dbo].[P](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Point] [int] NOT NULL,
)

set nocount on
declare @i int
declare @rnd int
set @i=0
while @i <4000
begin
select @rnd = cast(rand()*1000 as int)

insert into P values(@rnd)
set @i=@i+1
end
set nocount off

declare @s varchar(800)
set @s='100,11,600,300,244,1111,10000'
select top 6 * from p order by charindex(','+ltrim(point)+',',','+@s+',')

/*
ID Point
7 49
6 319
5 604
4 717
3 393
2 741
*/
先弄一个
lovebanyi 2009-09-02
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 soft_wsx 的回复:]
大哥,给点数据,直观些!不会这么小气吧!
[/Quote]
已经有数据 和数据库的生成脚本了。。 没有办法编辑原来的贴子啊, 在第6楼
soft_wsx 2009-09-02
  • 打赏
  • 举报
回复
大哥,给点数据,直观些!不会这么小气吧!
lovebanyi 2009-09-02
  • 打赏
  • 举报
回复
主要是 第三个。
最佳组合每个人心里都可能有一个答案。有答案就给出吧。
条件是产品不能重复, 6 个产品的point都不一样,优先级最大, 两个pint一样。优先级较小。以此类推。得到答案 可能还是有比较多的组合。(再决定)。
lovebanyi 2009-09-02
  • 打赏
  • 举报
回复
运行生成 product 表 表名是p
CREATE TABLE [dbo].[P](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Point] [int] NOT NULL,
)

数据脚本。
declare @i int
declare @rnd int
set @i=0
while @i<4000
begin
select @rnd = cast(rand()*1000 as int)

insert into P values(@rnd)
set @i=@i+1
end
数据库请自已弄一个。
谢谢

当用户 point 是 100,11,600,300,244,1111,10000 等等 的时候。。。得出6个最匹配的产品


lihan6415151528 2009-09-02
  • 打赏
  • 举报
回复
这个是算法问题了。
soft_wsx 2009-09-02
  • 打赏
  • 举报
回复
请给出数据及想要的结果!谢谢!
--小F-- 2009-09-02
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 htl258 的回复:]
没数据,先帮顶,有数据再来SEE.
[/Quote]
.
htl258_Tony 2009-09-02
  • 打赏
  • 举报
回复
没数据,先帮顶,有数据再来SEE.
dawugui 2009-09-02
  • 打赏
  • 举报
回复
请给出测试数据,计算方法和正确结果.
加载更多回复(2)

22,210

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧