Advertisement
Guest User

4th

a guest
Jan 21st, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.17 KB | None | 0 0
  1. use master
  2. drop database yuliyayakovenko
  3. create database yuliyayakovenko
  4. use yuliyayakovenko
  5.  
  6.  
  7. create table Providers (
  8. id int identity(1, 1) primary key,
  9. pricePerBrick float,
  10. discountPriceThreshold float,
  11. discount float,
  12. deliveryPrice float
  13. )
  14.  
  15.  
  16. go
  17. create function GetProviderPrice(@providerId int, @bricks float) returns float
  18. begin
  19. declare @ppb float, @dpt float, @discount float, @dp float;
  20. select
  21. @ppb = P.pricePerBrick,
  22. @discount = P.discount,
  23. @dpt = P.discountPriceThreshold,
  24. @dp = P.deliveryPrice
  25. from Providers P where P.id = @providerId;
  26. return (
  27. case when (@ppb * @bricks > @dpt) then
  28. @ppb * @bricks + @dp * ((100 - @discount) / 100.0)
  29. else
  30. @ppb * @bricks + @dp
  31. end
  32. )
  33. end
  34. go
  35.  
  36.  
  37. go
  38. create function GetBestProviders(@brickWeight float, @totalWeight float)
  39. returns @result table (id int, price float) as
  40. begin
  41. declare @bricks int, @minPrice float
  42. set @bricks = ceiling(@totalWeight / @brickWeight)
  43. select @minPrice = min(dbo.GetProviderPrice(P.id, @bricks)) from Providers P
  44. insert @result select id, @minPrice as price from Providers
  45. where dbo.GetProviderPrice(id, @bricks) = @minPrice
  46. return
  47. end
  48. go
  49.  
  50.  
  51. go
  52. create function GetBreakPoint(@providerId int) returns float
  53. begin
  54. return (select (discountPriceThreshold / pricePerBrick) from Providers where id = @providerId)
  55. end
  56. go
  57.  
  58.  
  59. go
  60. create function GetDiscountDelivery(@providerId int) returns float
  61. begin
  62. return (select ((100 - discount) / 100) * deliveryPrice from Providers where id = @providerId)
  63. end
  64. go
  65.  
  66.  
  67. go
  68. create function GetSegments()
  69. returns @result table (segmentS int, segmentE int) as
  70. begin
  71. declare @coords table (coordX float)
  72. declare @scoords table (id int identity(1, 1) primary key, coordX float)
  73. declare @LENGTH int
  74. set @LENGTH = 1
  75.  
  76. -- Здесь расставляются точки на оси X (кирпичи):
  77. insert @coords
  78. select abs(A.deliveryPrice - B.deliveryPrice) / abs(A.pricePerBrick - B.pricePerBrick)
  79. from Providers A cross join Providers B
  80. where A.id != B.id
  81.  
  82. insert @coords
  83. select abs(dbo.GetDiscountDelivery(A.id) - dbo.GetDiscountDelivery(B.id)) / abs(A.pricePerBrick - B.pricePerBrick)
  84. from Providers A cross join Providers B
  85. where A.id != B.id
  86.  
  87. insert @coords
  88. select abs(dbo.GetDiscountDelivery(A.id) - B.deliveryPrice) / abs(A.pricePerBrick - B.pricePerBrick)
  89. from Providers A cross join Providers B
  90. where A.id != B.id
  91.  
  92. insert @coords select dbo.GetBreakPoint(id) from Providers
  93. insert @coords values (0), (9999999)
  94. insert @scoords select distinct * from @coords order by coordX
  95. select @LENGTH = count(*) - 1 from @coords
  96. insert @result select A.coordX, B.coordX from
  97. (select * from @scoords order by coordX OFFset 0 rows fetch next @LENGTH rows onLY) A join
  98. (select * from @scoords order by coordX OFFset 1 rows) B on A.id + 1 = B.id
  99. order by A.coordX
  100. return
  101. end
  102. go
  103.  
  104.  
  105. go
  106. create function GetProvideronSegment(@segmentS int, @segmentE int) returns int
  107. begin
  108. declare @minPrice float
  109. select @minPrice = min(dbo.GetProviderPrice(id, (@segmentS+@segmentE) / 2 )) from Providers
  110. return (select top 1 id from Providers where dbo.GetProviderPrice(id, (@segmentS+@segmentE) / 2) = @minPrice)
  111. end
  112. go
  113.  
  114.  
  115. go
  116. create function Getoptimaltable()
  117. returns @result table (id int, segmentS int, segmentE int, providerId int) as
  118. begin
  119. declare @lastId int, @lastProviderId int
  120. declare @tmp table (id int identity(1, 1) primary key, segmentS int, segmentE int, providerId int)
  121.  
  122. insert @tmp
  123. select segmentS, segmentE, dbo.GetProvideronSegment(segmentS, segmentE)
  124. from dbo.GetSegments() order by segmentS
  125. select @lastId = count(*) from @tmp
  126. set @lastProviderId = -99999999
  127. while (@lastId > 0)
  128. begin
  129. if ((select providerId from @tmp where id = @lastId) = @lastProviderId)
  130. begin
  131. with LR as (select top 1 * from @result order by id asC)
  132. update LR set segmentS = (select segmentS from @tmp where id = @lastId)
  133. end
  134. else
  135. begin
  136. insert @result select * from @tmp where id = @lastId
  137. end
  138. select @lastProviderId = providerId from @tmp where id = @lastId
  139. set @lastId -= 1
  140. end
  141. return
  142. end
  143. go
  144.  
  145.  
  146. insert into Providers values (10, 0, 0, 7000)
  147. insert into Providers values (12, 30000, 100, 6000)
  148. insert into Providers values (14, 33000, 70, 5500)
  149.  
  150.  
  151. select id as N'Продавец', dbo.GetProviderPrice(id, 2700) as N'Цена' from Providers
  152. select id as N'Продавец', price as N'Цена' from dbo.GetBestProviders(1, 2700)
  153. select
  154. formatmessage('%d-%d', ceiling(segmentS), ceiling(segmentE)) as N'Количество кирпичей',
  155. providerId as N'Продавец',
  156. dbo.GetProviderPrice(P.id, segmentS) as N'Стартовая цена',
  157. dbo.GetProviderPrice(P.id, segmentE) as N'Конечная цена'
  158. from dbo.Getoptimaltable() join Providers P on P.id = providerId
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement