076 computation debug and optimization
This commit is contained in:
+1
-1
@@ -86,7 +86,7 @@
|
|||||||
|
|
||||||
<!--- global settings --->
|
<!--- global settings --->
|
||||||
<!--- *************************************************************************************************** --->
|
<!--- *************************************************************************************************** --->
|
||||||
<cfset request.APP_VERSION="0.00.075"/> <!--- *********************************************************** --->
|
<cfset request.APP_VERSION="0.00.076"/> <!--- *********************************************************** --->
|
||||||
<!--- *************************************************************************************************** --->
|
<!--- *************************************************************************************************** --->
|
||||||
<cfset request.STAND=getStand()/>
|
<cfset request.STAND=getStand()/>
|
||||||
<cfset request.RECORDS_PER_PAGE=500/>
|
<cfset request.RECORDS_PER_PAGE=500/>
|
||||||
|
|||||||
+10
-10
@@ -174,7 +174,7 @@
|
|||||||
,siv.version
|
,siv.version
|
||||||
,siv.name_version
|
,siv.name_version
|
||||||
,siv.date_accept
|
,siv.date_accept
|
||||||
,siv.__index
|
,siv.__index as siv_index
|
||||||
,siv.date_nop
|
,siv.date_nop
|
||||||
,siv.date_end
|
,siv.date_end
|
||||||
,siv.is_easy
|
,siv.is_easy
|
||||||
@@ -189,7 +189,7 @@
|
|||||||
,p.__id as p_uid
|
,p.__id as p_uid
|
||||||
,p.name
|
,p.name
|
||||||
,s.probability_pc
|
,s.probability_pc
|
||||||
,d.__index
|
,d.__index as deal_index
|
||||||
,d.__id as deal_uid
|
,d.__id as deal_uid
|
||||||
,siv.end_customer as end_customer_uid
|
,siv.end_customer as end_customer_uid
|
||||||
,z.id_klienta as end_customer_wz
|
,z.id_klienta as end_customer_wz
|
||||||
@@ -204,7 +204,7 @@
|
|||||||
AND siv.is_actual
|
AND siv.is_actual
|
||||||
--AND a.is_actual
|
--AND a.is_actual
|
||||||
AND s.probability_pc > 0
|
AND s.probability_pc > 0
|
||||||
order by version::int
|
order by d.__index, siv.__index, p.__id, version::int
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
<cfoutput>
|
<cfoutput>
|
||||||
@@ -215,7 +215,7 @@
|
|||||||
<table class="worktable">
|
<table class="worktable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>__index</th>
|
<th>deal index</th>
|
||||||
<!--- <th>__name</th> --->
|
<!--- <th>__name</th> --->
|
||||||
<th width="20%">user description</th>
|
<th width="20%">user description</th>
|
||||||
<th width="25%">Компоненты</th>
|
<th width="25%">Компоненты</th>
|
||||||
@@ -229,9 +229,9 @@
|
|||||||
<th>version</th>
|
<th>version</th>
|
||||||
<th>name version</th>
|
<th>name version</th>
|
||||||
<th>date accept</th>
|
<th>date accept</th>
|
||||||
<th>__index</th>
|
<th>line version index</th>
|
||||||
<th width="5%">date nop</th>
|
<th width="5%">НОУ</th>
|
||||||
<th width="5%">date end</th>
|
<th width="5%">КОУ</th>
|
||||||
<th>is easy</th>
|
<th>is easy</th>
|
||||||
<th width="2%">Вер.%</th>
|
<th width="2%">Вер.%</th>
|
||||||
<th width="10%">Дополнительное соглашение</th>
|
<th width="10%">Дополнительное соглашение</th>
|
||||||
@@ -239,9 +239,9 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<cfoutput query="qService" group="__index">
|
<cfoutput query="qService" group="deal_index"> <!--- не оч понятно, какой из индексов брать --->
|
||||||
<tr>
|
<tr>
|
||||||
<td class="c"><a href="deal_service.cfm?__id=#__id#&#tr.fwx#" title="__id">#__index#</a></td>
|
<td class="c"><a href="deal_service.cfm?__id=#__id#&#tr.fwx#" title="__id">#deal_index#</a></td>
|
||||||
<!--- <td class="c">#__name#</td> --->
|
<!--- <td class="c">#__name#</td> --->
|
||||||
<td class="l">#user_description#</td>
|
<td class="l">#user_description#</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -278,7 +278,7 @@
|
|||||||
<td class="c">#version#</td>
|
<td class="c">#version#</td>
|
||||||
<td class="c">#name_version#</td>
|
<td class="c">#name_version#</td>
|
||||||
<td class="c">#date_accept#</td>
|
<td class="c">#date_accept#</td>
|
||||||
<td class="c">#__index#</td>
|
<td class="c">#siv_index#</td>
|
||||||
<td class="c">#dateFormat(date_nop,'YYYY-MM-DD')#</td>
|
<td class="c">#dateFormat(date_nop,'YYYY-MM-DD')#</td>
|
||||||
<td class="c<cfif isDate(date_end) AND date_end LT Now()> err</cfif>">#dateFormat(date_end,'YYYY-MM-DD')#</td>
|
<td class="c<cfif isDate(date_end) AND date_end LT Now()> err</cfif>">#dateFormat(date_end,'YYYY-MM-DD')#</td>
|
||||||
<td class="c">#is_easy#</td>
|
<td class="c">#is_easy#</td>
|
||||||
|
|||||||
+3
-2
@@ -231,9 +231,10 @@
|
|||||||
JOIN status s ON (d.deal_status_id = s.status_id)
|
JOIN status s ON (d.deal_status_id = s.status_id)
|
||||||
LEFT JOIN LATERAL unnest(d.params) AS arr(param_id) ON TRUE
|
LEFT JOIN LATERAL unnest(d.params) AS arr(param_id) ON TRUE
|
||||||
JOIN component p ON (p.__id = arr.param_id)
|
JOIN component p ON (p.__id = arr.param_id)
|
||||||
WHERE d.dt_from <= CURRENT_TIMESTAMP AND (CURRENT_TIMESTAMP < d.dt_next)
|
WHERE d.dt_from <= CURRENT_TIMESTAMP AND (CURRENT_TIMESTAMP < d.dt_next)
|
||||||
|
ORDER BY d.siv_uid, p.__id
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
<!--- Для корректной группировки должно быть отсортировано! --->
|
||||||
<!--- <cfdump var=#qService#/> --->
|
<!--- <cfdump var=#qService#/> --->
|
||||||
<cfoutput>
|
<cfoutput>
|
||||||
<h3>Услуги по данным CRM (из DWH, версии строк спецификации, только актуальные на сегодня, сделки с вероятностью от 50% (начиная с тестирования) <!--- (#qService.recordCount#) ---></h3>
|
<h3>Услуги по данным CRM (из DWH, версии строк спецификации, только актуальные на сегодня, сделки с вероятностью от 50% (начиная с тестирования) <!--- (#qService.recordCount#) ---></h3>
|
||||||
|
|||||||
@@ -0,0 +1,309 @@
|
|||||||
|
EXPLAIN PLAN FOR
|
||||||
|
SELECT
|
||||||
|
coalesce(coalesce(c.wz, m.wz), s.wz) as wz,s.wz as wzs,c.wz as wzc,m.wz as wzm,s.end_customer_wz as wze,coalesce(s.code, m.code) as code,s.code as s_code,s.sku_code as sku_code,m.code as m_code,s.component_quantity,s.service_quantity,s.service_discount,coalesce(s.free_tier,0) as free_tier,m.dimension1,s.type,m.unit,s.ed_izm,coalesce(s.service_quantity*(100.-s.service_discount)/100.*s.price*(100.-s.component_discount)/100., 0.) as discounted_price,s.serviceStart,s.serviceEnd,s.line_key,s.price,s.component_discount,m.raw_metric,m.metric,c.contragent,c.contragent_uid,c.responsible,c.responsible_email,c.responsible_status,s.contract,s.contract_uid,s.additional_agreement,s.additional_agreement_uid,s.deal,s.deal_uid,s.abstract_service,s.modifier,s.component,s.user_description
|
||||||
|
FROM qUnifiedMetric m
|
||||||
|
FULL JOIN qSpec s ON (m.wz=s.wz AND m.code=s.sku_code) -- сервис или компонент, но не цена с типом тарификации
|
||||||
|
LEFT JOIN qContragent c ON (trim(coalesce(s.wz,m.wz))=trim(c.wz)) -- пробелы тут стоили нескольких часов работы
|
||||||
|
WHERE 1=1 --AND (s.type=3 OR NOT m.metric IS NULL)
|
||||||
|
AND EXISTS(select * from qSpec qs where qs.wz=m.wz AND qs.type=3)
|
||||||
|
--AND s.wz='WZ01031'
|
||||||
|
--AND s.wz='WZ01762'
|
||||||
|
ORDER BY coalesce(coalesce(c.wz, m.wz), s.wz), coalesce(s.code, m.code)
|
||||||
|
PLAN
|
||||||
|
1 isDistinctSelect=[false]
|
||||||
|
2 isGrouped=[false]
|
||||||
|
3 isAggregated=[false]
|
||||||
|
4 columns=[
|
||||||
|
5 CASEWHEN arg_left=[
|
||||||
|
6 IS NULL arg_left=[
|
||||||
|
7 CASEWHEN arg_left=[
|
||||||
|
8 IS NULL arg_left=[ COLUMN: PUBLIC.QCONTRAGENT.WZ
|
||||||
|
9 ]] arg_right=[
|
||||||
|
10 arg_left=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ
|
||||||
|
11 ] arg_right=[ COLUMN: PUBLIC.QCONTRAGENT.WZ
|
||||||
|
12 ]]]] arg_right=[
|
||||||
|
13 arg_left=[ COLUMN: PUBLIC.QSPEC.WZ
|
||||||
|
14 ] arg_right=[
|
||||||
|
15 CASEWHEN arg_left=[
|
||||||
|
16 IS NULL arg_left=[ COLUMN: PUBLIC.QCONTRAGENT.WZ
|
||||||
|
17 ]] arg_right=[
|
||||||
|
18 arg_left=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ
|
||||||
|
19 ] arg_right=[ COLUMN: PUBLIC.QCONTRAGENT.WZ
|
||||||
|
20 ]]] nullable
|
||||||
|
21 COLUMN: PUBLIC.QSPEC.WZ AS WZS nullable
|
||||||
|
22 COLUMN: PUBLIC.QCONTRAGENT.WZ AS WZC nullable
|
||||||
|
23 COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ AS WZM nullable
|
||||||
|
24 COLUMN: PUBLIC.QSPEC.END_CUSTOMER_WZ AS WZE nullable
|
||||||
|
25
|
||||||
|
26 CASEWHEN arg_left=[
|
||||||
|
27 IS NULL arg_left=[ COLUMN: PUBLIC.QSPEC.CODE
|
||||||
|
28 ]] arg_right=[
|
||||||
|
29 arg_left=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.CODE
|
||||||
|
30 ] arg_right=[ COLUMN: PUBLIC.QSPEC.CODE
|
||||||
|
31 ] nullable
|
||||||
|
32 COLUMN: PUBLIC.QSPEC.CODE AS S_CODE nullable
|
||||||
|
33 COLUMN: PUBLIC.QSPEC.SKU_CODE AS SKU_CODE nullable
|
||||||
|
34 COLUMN: PUBLIC.QUNIFIEDMETRIC.CODE AS M_CODE nullable
|
||||||
|
35 COLUMN: PUBLIC.QSPEC.COMPONENT_QUANTITY nullable
|
||||||
|
36 COLUMN: PUBLIC.QSPEC.SERVICE_QUANTITY nullable
|
||||||
|
37 COLUMN: PUBLIC.QSPEC.SERVICE_DISCOUNT nullable
|
||||||
|
38
|
||||||
|
39 CASEWHEN arg_left=[
|
||||||
|
40 IS NULL arg_left=[ COLUMN: PUBLIC.QSPEC.FREE_TIER
|
||||||
|
41 ]] arg_right=[
|
||||||
|
42 arg_left=[
|
||||||
|
43 VALUE = 0, TYPE = INTEGER] arg_right=[ COLUMN: PUBLIC.QSPEC.FREE_TIER
|
||||||
|
44 ] nullable
|
||||||
|
45 COLUMN: PUBLIC.QUNIFIEDMETRIC.DIMENSION1 nullable
|
||||||
|
46 COLUMN: PUBLIC.QSPEC.TYPE nullable
|
||||||
|
47 COLUMN: PUBLIC.QUNIFIEDMETRIC.UNIT nullable
|
||||||
|
48 COLUMN: PUBLIC.QSPEC.ED_IZM nullable
|
||||||
|
49
|
||||||
|
50 CASEWHEN arg_left=[
|
||||||
|
51 IS NULL arg_left=[
|
||||||
|
52 DIVIDE arg_left=[
|
||||||
|
53 MULTIPLY arg_left=[
|
||||||
|
54 MULTIPLY arg_left=[
|
||||||
|
55 DIVIDE arg_left=[
|
||||||
|
56 MULTIPLY arg_left=[ COLUMN: PUBLIC.QSPEC.SERVICE_QUANTITY
|
||||||
|
57 ] arg_right=[
|
||||||
|
58 SUBTRACT arg_left=[
|
||||||
|
59 VALUE = 100, TYPE = DECIMAL] arg_right=[ COLUMN: PUBLIC.QSPEC.SERVICE_DISCOUNT
|
||||||
|
60 ]]] arg_right=[
|
||||||
|
61 VALUE = 100, TYPE = DECIMAL]] arg_right=[ COLUMN: PUBLIC.QSPEC.PRICE
|
||||||
|
62 ]] arg_right=[
|
||||||
|
63 SUBTRACT arg_left=[
|
||||||
|
64 VALUE = 100, TYPE = DECIMAL] arg_right=[ COLUMN: PUBLIC.QSPEC.COMPONENT_DISCOUNT
|
||||||
|
65 ]]] arg_right=[
|
||||||
|
66 VALUE = 100, TYPE = DECIMAL]]] arg_right=[
|
||||||
|
67 arg_left=[
|
||||||
|
68 VALUE = 0, TYPE = DECIMAL] arg_right=[
|
||||||
|
69 DIVIDE arg_left=[
|
||||||
|
70 MULTIPLY arg_left=[
|
||||||
|
71 MULTIPLY arg_left=[
|
||||||
|
72 DIVIDE arg_left=[
|
||||||
|
73 MULTIPLY arg_left=[ COLUMN: PUBLIC.QSPEC.SERVICE_QUANTITY
|
||||||
|
74 ] arg_right=[
|
||||||
|
75 SUBTRACT arg_left=[
|
||||||
|
76 VALUE = 100, TYPE = DECIMAL] arg_right=[ COLUMN: PUBLIC.QSPEC.SERVICE_DISCOUNT
|
||||||
|
77 ]]] arg_right=[
|
||||||
|
78 VALUE = 100, TYPE = DECIMAL]] arg_right=[ COLUMN: PUBLIC.QSPEC.PRICE
|
||||||
|
79 ]] arg_right=[
|
||||||
|
80 SUBTRACT arg_left=[
|
||||||
|
81 VALUE = 100, TYPE = DECIMAL] arg_right=[ COLUMN: PUBLIC.QSPEC.COMPONENT_DISCOUNT
|
||||||
|
82 ]]] arg_right=[
|
||||||
|
83 VALUE = 100, TYPE = DECIMAL]] nullable
|
||||||
|
84 COLUMN: PUBLIC.QSPEC.SERVICESTART nullable
|
||||||
|
85 COLUMN: PUBLIC.QSPEC.SERVICEEND nullable
|
||||||
|
86 COLUMN: PUBLIC.QSPEC.LINE_KEY nullable
|
||||||
|
87 COLUMN: PUBLIC.QSPEC.PRICE nullable
|
||||||
|
88 COLUMN: PUBLIC.QSPEC.COMPONENT_DISCOUNT nullable
|
||||||
|
89 COLUMN: PUBLIC.QUNIFIEDMETRIC.RAW_METRIC nullable
|
||||||
|
90 COLUMN: PUBLIC.QUNIFIEDMETRIC.METRIC nullable
|
||||||
|
91 COLUMN: PUBLIC.QCONTRAGENT.CONTRAGENT nullable
|
||||||
|
92 COLUMN: PUBLIC.QCONTRAGENT.CONTRAGENT_UID nullable
|
||||||
|
93 COLUMN: PUBLIC.QCONTRAGENT.RESPONSIBLE nullable
|
||||||
|
94 COLUMN: PUBLIC.QCONTRAGENT.RESPONSIBLE_EMAIL nullable
|
||||||
|
95 COLUMN: PUBLIC.QCONTRAGENT.RESPONSIBLE_STATUS nullable
|
||||||
|
96 COLUMN: PUBLIC.QSPEC.CONTRACT nullable
|
||||||
|
97 COLUMN: PUBLIC.QSPEC.CONTRACT_UID nullable
|
||||||
|
98 COLUMN: PUBLIC.QSPEC.ADDITIONAL_AGREEMENT nullable
|
||||||
|
99 COLUMN: PUBLIC.QSPEC.ADDITIONAL_AGREEMENT_UID nullable
|
||||||
|
100 COLUMN: PUBLIC.QSPEC.DEAL nullable
|
||||||
|
101 COLUMN: PUBLIC.QSPEC.DEAL_UID nullable
|
||||||
|
102 COLUMN: PUBLIC.QSPEC.ABSTRACT_SERVICE nullable
|
||||||
|
103 COLUMN: PUBLIC.QSPEC.MODIFIER nullable
|
||||||
|
104 COLUMN: PUBLIC.QSPEC.COMPONENT nullable
|
||||||
|
105 COLUMN: PUBLIC.QSPEC.USER_DESCRIPTION nullable
|
||||||
|
106
|
||||||
|
107 ]
|
||||||
|
108 [range variable 1
|
||||||
|
109 join type=INNER
|
||||||
|
110 table=QUNIFIEDMETRIC
|
||||||
|
111 alias=M
|
||||||
|
112 cardinality=3931
|
||||||
|
113 access=FULL SCAN
|
||||||
|
114 join condition = [index=SYS_IDX_10266
|
||||||
|
115 ]
|
||||||
|
116 ][range variable 2
|
||||||
|
117 join type=FULL
|
||||||
|
118 table=QSPEC
|
||||||
|
119 alias=S
|
||||||
|
120 cardinality=4819
|
||||||
|
121 access=INDEX PRED
|
||||||
|
122 join condition = [index=SYS_IDX_T_10270
|
||||||
|
123 start conditions=[
|
||||||
|
124 EQUAL arg_left=[ COLUMN: PUBLIC.QSPEC.WZ
|
||||||
|
125 ] arg_right=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ
|
||||||
|
126 ]]
|
||||||
|
127 other condition=[
|
||||||
|
128 EQUAL arg_left=[ COLUMN: PUBLIC.QSPEC.SKU_CODE
|
||||||
|
129 ] arg_right=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.CODE
|
||||||
|
130 ]]
|
||||||
|
131 ]
|
||||||
|
132 where condition = [
|
||||||
|
133 EXISTS arg_left=[
|
||||||
|
134 QUERY isDistinctSelect=[false]
|
||||||
|
135 isGrouped=[false]
|
||||||
|
136 isAggregated=[false]
|
||||||
|
137 columns=[ COLUMN: PUBLIC.QSPEC.WZ nullable
|
||||||
|
138 COLUMN: PUBLIC.QSPEC.CONTRAGENT_UID nullable
|
||||||
|
139 COLUMN: PUBLIC.QSPEC.CODE nullable
|
||||||
|
140 COLUMN: PUBLIC.QSPEC.SKU_CODE nullable
|
||||||
|
141 COLUMN: PUBLIC.QSPEC.PRICE nullable
|
||||||
|
142 COLUMN: PUBLIC.QSPEC.COMPONENT_DISCOUNT nullable
|
||||||
|
143 COLUMN: PUBLIC.QSPEC.CONTRAGENT nullable
|
||||||
|
144 COLUMN: PUBLIC.QSPEC.CONTRACT nullable
|
||||||
|
145 COLUMN: PUBLIC.QSPEC.CONTRACT_UID nullable
|
||||||
|
146 COLUMN: PUBLIC.QSPEC.DEAL nullable
|
||||||
|
147 COLUMN: PUBLIC.QSPEC.DEAL_UID nullable
|
||||||
|
148 COLUMN: PUBLIC.QSPEC.ABSTRACT_SERVICE nullable
|
||||||
|
149 COLUMN: PUBLIC.QSPEC.MODIFIER nullable
|
||||||
|
150 COLUMN: PUBLIC.QSPEC.USER_DESCRIPTION nullable
|
||||||
|
151 COLUMN: PUBLIC.QSPEC.LINE_KEY nullable
|
||||||
|
152 COLUMN: PUBLIC.QSPEC.SERVICESTART nullable
|
||||||
|
153 COLUMN: PUBLIC.QSPEC.SERVICEEND nullable
|
||||||
|
154 COLUMN: PUBLIC.QSPEC.SERVICE_DISCOUNT nullable
|
||||||
|
155 COLUMN: PUBLIC.QSPEC.SERVICE_QUANTITY nullable
|
||||||
|
156 COLUMN: PUBLIC.QSPEC.ED_IZM nullable
|
||||||
|
157 COLUMN: PUBLIC.QSPEC.COMPONENT nullable
|
||||||
|
158 COLUMN: PUBLIC.QSPEC.TYPE nullable
|
||||||
|
159 COLUMN: PUBLIC.QSPEC.COMPONENT_QUANTITY nullable
|
||||||
|
160 COLUMN: PUBLIC.QSPEC.ADDITIONAL_AGREEMENT nullable
|
||||||
|
161 COLUMN: PUBLIC.QSPEC.ADDITIONAL_AGREEMENT_UID nullable
|
||||||
|
162 COLUMN: PUBLIC.QSPEC.END_CUSTOMER_UID nullable
|
||||||
|
163 COLUMN: PUBLIC.QSPEC.END_CUSTOMER_WZ nullable
|
||||||
|
164 COLUMN: PUBLIC.QSPEC.END_CUSTOMER_NAME nullable
|
||||||
|
165 COLUMN: PUBLIC.QSPEC.FREE_TIER nullable
|
||||||
|
166
|
||||||
|
167 ]
|
||||||
|
168 [range variable 1
|
||||||
|
169 join type=INNER
|
||||||
|
170 table=QSPEC
|
||||||
|
171 alias=QS
|
||||||
|
172 cardinality=4819
|
||||||
|
173 access=INDEX PRED
|
||||||
|
174 join condition = [index=SYS_IDX_T_10270
|
||||||
|
175 start conditions=[
|
||||||
|
176 EQUAL arg_left=[ COLUMN: PUBLIC.QSPEC.WZ
|
||||||
|
177 ] arg_right=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ
|
||||||
|
178 ]
|
||||||
|
179 EQUAL arg_left=[ COLUMN: PUBLIC.QSPEC.TYPE
|
||||||
|
180 ] arg_right=[
|
||||||
|
181 VALUE = 3, TYPE = INTEGER]]
|
||||||
|
182 ]
|
||||||
|
183 ] ]
|
||||||
|
184 ] ]
|
||||||
|
185 ][range variable 3
|
||||||
|
186 join type=LEFT OUTER
|
||||||
|
187 table=QCONTRAGENT
|
||||||
|
188 alias=C
|
||||||
|
189 cardinality=2912
|
||||||
|
190 access=FULL SCAN
|
||||||
|
191 join condition = [index=SYS_IDX_10267
|
||||||
|
192 other condition=[
|
||||||
|
193 EQUAL arg_left=[
|
||||||
|
194 FUNCTION =[
|
||||||
|
195 TRIM([
|
||||||
|
196 VALUE = 26, TYPE = INTEGER][
|
||||||
|
197 VALUE = ' ', TYPE = CHARACTER][
|
||||||
|
198 CASEWHEN arg_left=[
|
||||||
|
199 IS NULL arg_left=[ COLUMN: PUBLIC.QSPEC.WZ
|
||||||
|
200 ]] arg_right=[
|
||||||
|
201 arg_left=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ
|
||||||
|
202 ] arg_right=[ COLUMN: PUBLIC.QSPEC.WZ
|
||||||
|
203 ]]]) returns VARCHAR]
|
||||||
|
204 ] arg_right=[
|
||||||
|
205 FUNCTION =[
|
||||||
|
206 TRIM([
|
||||||
|
207 VALUE = 26, TYPE = INTEGER][
|
||||||
|
208 VALUE = ' ', TYPE = CHARACTER][ COLUMN: PUBLIC.QCONTRAGENT.WZ
|
||||||
|
209 ]) returns VARCHAR]
|
||||||
|
210 ]]
|
||||||
|
211 ]
|
||||||
|
212 ]]
|
||||||
|
213 order by=[
|
||||||
|
214
|
||||||
|
215 CASEWHEN arg_left=[
|
||||||
|
216 IS NULL arg_left=[
|
||||||
|
217 CASEWHEN arg_left=[
|
||||||
|
218 IS NULL arg_left=[ COLUMN: PUBLIC.QCONTRAGENT.WZ
|
||||||
|
219 ]] arg_right=[
|
||||||
|
220 arg_left=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ
|
||||||
|
221 ] arg_right=[ COLUMN: PUBLIC.QCONTRAGENT.WZ
|
||||||
|
222 ]]]] arg_right=[
|
||||||
|
223 arg_left=[ COLUMN: PUBLIC.QSPEC.WZ
|
||||||
|
224 ] arg_right=[
|
||||||
|
225 CASEWHEN arg_left=[
|
||||||
|
226 IS NULL arg_left=[ COLUMN: PUBLIC.QCONTRAGENT.WZ
|
||||||
|
227 ]] arg_right=[
|
||||||
|
228 arg_left=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ
|
||||||
|
229 ] arg_right=[ COLUMN: PUBLIC.QCONTRAGENT.WZ
|
||||||
|
230 ]]]]
|
||||||
|
231 CASEWHEN arg_left=[
|
||||||
|
232 IS NULL arg_left=[ COLUMN: PUBLIC.QSPEC.CODE
|
||||||
|
233 ]] arg_right=[
|
||||||
|
234 arg_left=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.CODE
|
||||||
|
235 ] arg_right=[ COLUMN: PUBLIC.QSPEC.CODE
|
||||||
|
236 ]]]
|
||||||
|
237 PARAMETERS=[]
|
||||||
|
238 SUBQUERIES[
|
||||||
|
239 [level=1
|
||||||
|
240 isDistinctSelect=[false]
|
||||||
|
241 isGrouped=[false]
|
||||||
|
242 isAggregated=[false]
|
||||||
|
243 columns=[ COLUMN: PUBLIC.QSPEC.WZ nullable
|
||||||
|
244 COLUMN: PUBLIC.QSPEC.CONTRAGENT_UID nullable
|
||||||
|
245 COLUMN: PUBLIC.QSPEC.CODE nullable
|
||||||
|
246 COLUMN: PUBLIC.QSPEC.SKU_CODE nullable
|
||||||
|
247 COLUMN: PUBLIC.QSPEC.PRICE nullable
|
||||||
|
248 COLUMN: PUBLIC.QSPEC.COMPONENT_DISCOUNT nullable
|
||||||
|
249 COLUMN: PUBLIC.QSPEC.CONTRAGENT nullable
|
||||||
|
250 COLUMN: PUBLIC.QSPEC.CONTRACT nullable
|
||||||
|
251 COLUMN: PUBLIC.QSPEC.CONTRACT_UID nullable
|
||||||
|
252 COLUMN: PUBLIC.QSPEC.DEAL nullable
|
||||||
|
253 COLUMN: PUBLIC.QSPEC.DEAL_UID nullable
|
||||||
|
254 COLUMN: PUBLIC.QSPEC.ABSTRACT_SERVICE nullable
|
||||||
|
255 COLUMN: PUBLIC.QSPEC.MODIFIER nullable
|
||||||
|
256 COLUMN: PUBLIC.QSPEC.USER_DESCRIPTION nullable
|
||||||
|
257 COLUMN: PUBLIC.QSPEC.LINE_KEY nullable
|
||||||
|
258 COLUMN: PUBLIC.QSPEC.SERVICESTART nullable
|
||||||
|
259 COLUMN: PUBLIC.QSPEC.SERVICEEND nullable
|
||||||
|
260 COLUMN: PUBLIC.QSPEC.SERVICE_DISCOUNT nullable
|
||||||
|
261 COLUMN: PUBLIC.QSPEC.SERVICE_QUANTITY nullable
|
||||||
|
262 COLUMN: PUBLIC.QSPEC.ED_IZM nullable
|
||||||
|
263 COLUMN: PUBLIC.QSPEC.COMPONENT nullable
|
||||||
|
264 COLUMN: PUBLIC.QSPEC.TYPE nullable
|
||||||
|
265 COLUMN: PUBLIC.QSPEC.COMPONENT_QUANTITY nullable
|
||||||
|
266 COLUMN: PUBLIC.QSPEC.ADDITIONAL_AGREEMENT nullable
|
||||||
|
267 COLUMN: PUBLIC.QSPEC.ADDITIONAL_AGREEMENT_UID nullable
|
||||||
|
268 COLUMN: PUBLIC.QSPEC.END_CUSTOMER_UID nullable
|
||||||
|
269 COLUMN: PUBLIC.QSPEC.END_CUSTOMER_WZ nullable
|
||||||
|
270 COLUMN: PUBLIC.QSPEC.END_CUSTOMER_NAME nullable
|
||||||
|
271 COLUMN: PUBLIC.QSPEC.FREE_TIER nullable
|
||||||
|
272
|
||||||
|
273 ]
|
||||||
|
274 [range variable 1
|
||||||
|
275 join type=INNER
|
||||||
|
276 table=QSPEC
|
||||||
|
277 alias=QS
|
||||||
|
278 cardinality=4819
|
||||||
|
279 access=INDEX PRED
|
||||||
|
280 join condition = [index=SYS_IDX_T_10270
|
||||||
|
281 start conditions=[
|
||||||
|
282 EQUAL arg_left=[ COLUMN: PUBLIC.QSPEC.WZ
|
||||||
|
283 ] arg_right=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ
|
||||||
|
284 ]
|
||||||
|
285 EQUAL arg_left=[ COLUMN: PUBLIC.QSPEC.TYPE
|
||||||
|
286 ] arg_right=[
|
||||||
|
287 VALUE = 3, TYPE = INTEGER]]
|
||||||
|
288 ]
|
||||||
|
289 ] ]
|
||||||
|
290 ]]
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
Here is a detailed breakdown of your HSQLDB execution plan. The query contains a hidden performance trap—specifically, an accidental implicit Inner Join conversion and a costly Full Table Scan—which we can optimize.🚨 Critical Performance Issues Found1. The FULL JOIN Was Converted into an INNER JOIN (Lines 108–109)Look closely at Line 109: join type=INNER for table QUNIFIEDMETRIC (M).Why this happened: In your WHERE clause, you have an EXISTS subquery: where qs.wz = m.wz.The impact: Because m.wz must match something in qSpec to pass the EXISTS filter, any row where M exists but S does not (the "left" part of your FULL JOIN) is immediately discarded. HSQLDB noticed this and optimized your FULL JOIN down to a standard INNER JOIN.2. Full Table Scan on QCONTRAGENT (Lines 185–191)Look at Line 190: access=FULL SCAN for table QCONTRAGENT (C).Why this happened: Your join condition uses a function: ON (trim(coalesce(s.wz, m.wz)) = trim(c.wz)).The impact: Applying trim() to a column prevents the database from using standard indexes on c.wz. For every single row combination, HSQLDB is forced to scan the entire 2,912-row table sequentially.🔍 Step-by-Step Plan BreakdownStep 1: Scan QUNIFIEDMETRIC M (Lines 108–113)Access: FULL SCANRows: 3,931The database starts here because it serves as the base for evaluating the EXISTS clause.Step 2: Probe QSPEC S via Index (Lines 116–131)Access: INDEX PRED (Index Predicate) using index SYS_IDX_T_10270.Execution: It successfully uses the index on wz to fetch corresponding records from S. The secondary condition m.code = s.sku_code is evaluated as an "other condition" (filter) afterwards.Step 3: Evaluate the EXISTS Subquery (Lines 132–184)Access: INDEX PRED on QSPEC QS.The database runs a semi-join utilizing the index to verify if a matching wz with type = 3 exists. This part is relatively efficient.Step 4: Scan and Join QCONTRAGENT C (Lines 185–202)Access: FULL SCANBecause of the trim(...) wrappers, it falls back to a nested loop full table scan to evaluate the dynamic string alignment.🛠️ Optimization RecommendationsTo speed up this query dramatically, apply these two adjustments:1. Explicitly clean the data instead of using trim() in the joinIf possible, run a one-time script to permanently clean whitespace from your database tables:sqlUPDATE qContragent SET wz = TRIM(wz);
|
||||||
|
UPDATE qSpec SET wz = TRIM(wz);
|
||||||
|
UPDATE qUnifiedMetric SET wz = TRIM(wz);
|
||||||
|
Use code with caution.Once cleaned, rewrite the join smoothly to leverage indexes:sqlLEFT JOIN qContragent c ON (coalesce(s.wz, m.wz) = c.wz)
|
||||||
|
Use code with caution.2. Downgrade FULL JOIN to LEFT JOIN or INNER JOINSince your EXISTS condition fundamentally breaks the FULL JOIN behavior anyway, changing the keyword to LEFT JOIN qSpec s or INNER JOIN qSpec s makes your code match its real execution pathway, preventing the optimizer from doing unnecessary planning logic.If you'd like to check how to implement a functional index to bypass the trim() problem, let me know which HSQLDB version you are currently running!
|
||||||
@@ -14,9 +14,10 @@
|
|||||||
<cfparam name="dt_start" type="date" default=#dateAdd('m',-1,createDateTime(year(Now()),month(Now()),1,0,0,0))#/>
|
<cfparam name="dt_start" type="date" default=#dateAdd('m',-1,createDateTime(year(Now()),month(Now()),1,0,0,0))#/>
|
||||||
<cfset hours=dateDiff('h', dt_start, dateAdd('d', 1, dt_finish))/>
|
<cfset hours=dateDiff('h', dt_start, dateAdd('d', 1, dt_finish))/>
|
||||||
<cfparam name="only_articles_in_spec" type="boolean" default=false/>
|
<cfparam name="only_articles_in_spec" type="boolean" default=false/>
|
||||||
|
<cfparam name="wz" default=""/>
|
||||||
|
|
||||||
<!--- *** коды лучше взять из каталога --->
|
<!--- *** коды лучше взять из каталога --->
|
||||||
<cfquery name="qCode" datasource="dwh" cachedWithin=#createTimeSpan(0, 0, 25, 0)#>
|
<cfquery name="qCode" datasource="dwh" cachedWithin=#createTimeSpan(0, 0, 20, 0)#>
|
||||||
select distinct p.code
|
select distinct p.code
|
||||||
from elma.deals d
|
from elma.deals d
|
||||||
join elma.deals_services siv on (d.__id=ANY(siv.deal))
|
join elma.deals_services siv on (d.__id=ANY(siv.deal))
|
||||||
@@ -31,25 +32,28 @@
|
|||||||
<cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
<cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
||||||
|
|
||||||
<!--- <cfdump var=#qCode#/> --->
|
<!--- <cfdump var=#qCode#/> --->
|
||||||
<cfquery name="qContragent" datasource="dwh" cachedWithin=#createTimeSpan(0, 0, 25, 0)#>
|
<cfquery name="qContragent" datasource="dwh" cachedWithin=#createTimeSpan(0, 0, 22, 0)#>
|
||||||
select k.id_klienta as wz, k.__id::text as contragent_uid, k.__name as contragent,
|
select upper(trim(k.id_klienta)) as wz, k.__id::text as contragent_uid, k.__name as contragent,
|
||||||
c.__name as responsible, c.email as responsible_email, c.__status_status as responsible_status
|
c.__name as responsible, c.email as responsible_email, c.__status_status as responsible_status
|
||||||
from elma.companies k
|
from elma.companies k
|
||||||
LEFT OUTER JOIN elma.comp_users_ext c on (k.responsible=c.__id)
|
LEFT OUTER JOIN elma.comp_users_ext c on (k.responsible=c.__id)
|
||||||
where k."__deletedAt" IS NULL
|
where k."__deletedAt" IS NULL
|
||||||
|
<cfif len(wz)>
|
||||||
|
AND k.id_klienta like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#wz#%"/>
|
||||||
|
</cfif>
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
<cfoutput>qContragent:#getTickCount()-request.startTickCount#</cfoutput>
|
<cfoutput>qContragent:#getTickCount()-request.startTickCount#</cfoutput>
|
||||||
<cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
<cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
||||||
<!--- <cfif isDefined("DEBUG")>
|
|
||||||
<cfdump var=#qContragent#/>
|
|
||||||
<cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
|
||||||
</cfif> --->
|
|
||||||
<!--- нужны компании, которые есть в пейге --->
|
|
||||||
<!--- <cfset qFreeTier=queryNew("code,free_tier","CF_SQL_VARCHAR,CF_SQL_NUMERIC",[['paas.s3.ceph.vol-m',1],['paas.s3.ceph.get-m',10],['paas.s3.ceph.put-m',1],['paas.s3.ceph.trf-m',100]])/> --->
|
|
||||||
|
|
||||||
<cfquery name="qSpec" datasource="dwh" cachedWithin=#createTimeSpan(0, 0, 25, 0)#>
|
<cfquery name="qSpec" datasource="dwh" cachedWithin=#createTimeSpan(0, 0, 23, 0)#>
|
||||||
select k.id_klienta as wz, k.__id::text as contragent_uid,
|
WITH
|
||||||
|
status(status, status_id, probability_pc)
|
||||||
|
AS (VALUES
|
||||||
|
('Закрыта неуспешно',7,0),('Закрыта успешно',6,100),('Договор подписан',5,100),('Договор на подписании',15,90),('Договор на согласовании',12,70),
|
||||||
|
('Тестирование',8,50),('Отправлено ТКП',10,20),('Внутреннее согласование',37,10),('Проработка решения',4,10),('Сбор потребностей',1,0)
|
||||||
|
)
|
||||||
|
select upper(trim(k.id_klienta)) as wz, k.__id::text as contragent_uid,
|
||||||
p.code,
|
p.code,
|
||||||
SUBSTRING(p.code FROM 1 FOR LENGTH(p.code) - 2) as sku_code,
|
SUBSTRING(p.code FROM 1 FOR LENGTH(p.code) - 2) as sku_code,
|
||||||
p.price, p.discount as component_discount, k.__name as contragent, a.__name as contract, a.__id::text as contract_uid, d.__name as deal, d.__id::text as deal_uid, siv.abstractive_service as abstract_service, siv.modifier, siv.user_description, siv.hash as line_key
|
p.price, p.discount as component_discount, k.__name as contragent, a.__name as contract, a.__id::text as contract_uid, d.__name as deal, d.__id::text as deal_uid, siv.abstractive_service as abstract_service, siv.modifier, siv.user_description, siv.hash as line_key
|
||||||
@@ -61,9 +65,14 @@
|
|||||||
,z.id_klienta as end_customer_wz
|
,z.id_klienta as end_customer_wz
|
||||||
,z.__name as end_customer_name
|
,z.__name as end_customer_name
|
||||||
,ft.free_tier
|
,ft.free_tier
|
||||||
|
,s.probability_pc
|
||||||
|
,siv.__id::text as siv_uid
|
||||||
from elma.deals d
|
from elma.deals d
|
||||||
join elma.deals_services siv on (d.__id=ANY(siv.deal))
|
JOIN STATUS s ON (d.__status_status = s.status_id)
|
||||||
join elma.service_parametrs p on (p.__id = ANY(siv.params))
|
join elma.deals_services siv on (d.__id=ANY(siv.deal))
|
||||||
|
--join elma.service_parametrs p on (p.__id = ANY(siv.params))
|
||||||
|
LEFT JOIN LATERAL unnest(siv.params) AS arr(param_id) ON TRUE
|
||||||
|
JOIN elma.service_parametrs p ON (p.__id = arr.param_id)
|
||||||
join elma.companies k on (d._companies=k.__id)
|
join elma.companies k on (d._companies=k.__id)
|
||||||
join elma.additional_agreements aa on (aa.__id = ANY(siv.additional_agreement))
|
join elma.additional_agreements aa on (aa.__id = ANY(siv.additional_agreement))
|
||||||
join elma.aggrements a on (aa.contract_uid = a.__id)
|
join elma.aggrements a on (aa.contract_uid = a.__id)
|
||||||
@@ -72,10 +81,22 @@
|
|||||||
where p.type IN (2,3) AND aa.is_actual
|
where p.type IN (2,3) AND aa.is_actual
|
||||||
AND siv.date_nop < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_finish#/>
|
AND siv.date_nop < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_finish#/>
|
||||||
AND (siv.date_end > <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_start#/> OR siv.date_end IS NULL)/*****/
|
AND (siv.date_end > <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_start#/> OR siv.date_end IS NULL)/*****/
|
||||||
|
AND aa."__deletedAt" IS NULL
|
||||||
|
AND a."__deletedAt" IS NULL
|
||||||
|
AND d."__deletedAt" IS NULL
|
||||||
|
AND siv."__deletedAt" IS NULL
|
||||||
|
AND p."__deletedAt" IS NULL
|
||||||
|
AND p.cnt <> 0 --похоже, только так можно отфильтровать паразитные строки с нулем
|
||||||
|
<cfif len(wz)>
|
||||||
|
AND k.id_klienta like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#wz#%"/>
|
||||||
|
</cfif>
|
||||||
--AND k.id_klienta='WZ01031'
|
--AND k.id_klienta='WZ01031'
|
||||||
--AND k.id_klienta='WZ01112'
|
--AND k.id_klienta='WZ01112'
|
||||||
order by k.id_klienta, p.code
|
order by k.id_klienta, p.code
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
<!--- select * from elma.deals_services where __id='019edf9c-c1e8-7acd-8b63-5369e5be5bf5'
|
||||||
|
union all
|
||||||
|
select * from elma.deals_services where __id='019edf9c-c23d-7ad6-a990-643dd09579b8' --->
|
||||||
<!--- здесь имеем список кодов с ценами и WZ. Каждому коду можно поставить в соответствие запрос, который даст по нему выборку. Изредка один запрос может вывести 2 кода, но разбить на 2 запроса легко. Кроме того, запросы можно объединить через union в один - может быть, так будет лучше читаться (быстрее выполняться не будет) --->
|
<!--- здесь имеем список кодов с ценами и WZ. Каждому коду можно поставить в соответствие запрос, который даст по нему выборку. Изредка один запрос может вывести 2 кода, но разбить на 2 запроса легко. Кроме того, запросы можно объединить через union в один - может быть, так будет лучше читаться (быстрее выполняться не будет) --->
|
||||||
<cfoutput>qSpec:#getTickCount()-request.startTickCount#</cfoutput><cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
<cfoutput>qSpec:#getTickCount()-request.startTickCount#</cfoutput><cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
||||||
<cfif isDefined("DEBUG")>
|
<cfif isDefined("DEBUG")>
|
||||||
@@ -91,7 +112,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<cfquery name="qComputing" datasource="billing-vc" cachedWithin=#createTimeSpan(0, 0, 25, 0)#>
|
<cfquery name="qComputing" datasource="billing-vc" cachedWithin=#createTimeSpan(0, 0, 25, 0)#>
|
||||||
select m.clientid as wz, vdc.name as vdc,
|
select upper(trim(m.clientid)) as wz, vdc.name as vdc,
|
||||||
case
|
case
|
||||||
WHEN vdc.name LIKE '%-v1cl1%' THEN 'iaas.ngc.i29'
|
WHEN vdc.name LIKE '%-v1cl1%' THEN 'iaas.ngc.i29'
|
||||||
WHEN vdc.name LIKE '%-v1cl2%' THEN 'iaas.ngc.i31'
|
WHEN vdc.name LIKE '%-v1cl2%' THEN 'iaas.ngc.i31'
|
||||||
@@ -105,15 +126,20 @@
|
|||||||
from ngcloud_ru.capacity_resource
|
from ngcloud_ru.capacity_resource
|
||||||
join ngcloud_ru.vdc on capacity_resource.vdc_id=vdc.id
|
join ngcloud_ru.vdc on capacity_resource.vdc_id=vdc.id
|
||||||
join ngcloud_ru.tenant t on (t.id=vdc.tenant_id)
|
join ngcloud_ru.tenant t on (t.id=vdc.tenant_id)
|
||||||
left outer join
|
LEFT JOIN LATERAL (
|
||||||
(select tenant_id, ts, metadata_id,
|
SELECT m.clientid
|
||||||
ROW_NUMBER() OVER (PARTITION BY tenant_id ORDER BY ts desc, metadata_id desc) as rn
|
FROM ngcloud_ru.tenant_metadata tm
|
||||||
from ngcloud_ru.tenant_metadata
|
JOIN ngcloud_ru.metadata m ON tm.metadata_id = m.id
|
||||||
) tm on (t.id = tm.tenant_id AND tm.rn = 1)
|
WHERE tm.tenant_id = t.id
|
||||||
left outer join ngcloud_ru.metadata m on (tm.metadata_id=m.id)
|
ORDER BY tm.ts DESC, tm.metadata_id DESC
|
||||||
|
LIMIT 1
|
||||||
|
) m ON true
|
||||||
where length(m.clientid) > 0
|
where length(m.clientid) > 0
|
||||||
AND capacity_resource.timestamp >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_start#/>
|
AND capacity_resource.timestamp >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_start#/>
|
||||||
AND capacity_resource.timestamp < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dateAdd("d",1,dt_finish)#/>
|
AND capacity_resource.timestamp < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dateAdd("d",1,dt_finish)#/>
|
||||||
|
<cfif len(wz)>
|
||||||
|
AND m.clientid like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#wz#%"/>
|
||||||
|
</cfif>
|
||||||
group by m.clientid, vdc.name
|
group by m.clientid, vdc.name
|
||||||
order by m.clientid, vdc.name;
|
order by m.clientid, vdc.name;
|
||||||
</cfquery>
|
</cfquery>
|
||||||
@@ -133,8 +159,8 @@
|
|||||||
|
|
||||||
|
|
||||||
<!--- переделать storage_profile_types с расшифровкой ssd, sata, можно прямо до каталожного кода --->
|
<!--- переделать storage_profile_types с расшифровкой ssd, sata, можно прямо до каталожного кода --->
|
||||||
<cfquery name="qStorage" datasource="billing-vc" cachedWithin=#createTimeSpan(0, 0, 25, 0)#>
|
<cfquery name="qStorage" datasource="billing-vc" cachedWithin=#createTimeSpan(0, 0, 27, 0)#>
|
||||||
select m.clientid as wz, vdc.name as vdc,
|
select upper(trim(m.clientid)) as wz, vdc.name as vdc,
|
||||||
case
|
case
|
||||||
WHEN vdc.name LIKE '%-v1cl1%' THEN 'iaas.ngc.i29'
|
WHEN vdc.name LIKE '%-v1cl1%' THEN 'iaas.ngc.i29'
|
||||||
WHEN vdc.name LIKE '%-v1cl2%' THEN 'iaas.ngc.i31'
|
WHEN vdc.name LIKE '%-v1cl2%' THEN 'iaas.ngc.i31'
|
||||||
@@ -156,16 +182,21 @@
|
|||||||
from ngcloud_ru.capacity_storage
|
from ngcloud_ru.capacity_storage
|
||||||
join ngcloud_ru.vdc on capacity_storage.vdc_id=vdc.id
|
join ngcloud_ru.vdc on capacity_storage.vdc_id=vdc.id
|
||||||
join ngcloud_ru.tenant t on t.id=vdc.tenant_id
|
join ngcloud_ru.tenant t on t.id=vdc.tenant_id
|
||||||
left outer join
|
LEFT JOIN LATERAL (
|
||||||
(select tenant_id, ts, metadata_id,
|
SELECT m.clientid
|
||||||
ROW_NUMBER() OVER (PARTITION BY tenant_id ORDER BY ts desc, metadata_id desc) as rn
|
FROM ngcloud_ru.tenant_metadata tm
|
||||||
from ngcloud_ru.tenant_metadata
|
JOIN ngcloud_ru.metadata m ON tm.metadata_id = m.id
|
||||||
) tm on (t.id = tm.tenant_id AND tm.rn = 1)
|
WHERE tm.tenant_id = t.id
|
||||||
left outer join ngcloud_ru.metadata m on (tm.metadata_id=m.id)
|
ORDER BY tm.ts DESC, tm.metadata_id DESC
|
||||||
|
LIMIT 1
|
||||||
|
) m ON true
|
||||||
join ngcloud_ru.storage_profile_types on capacity_storage.storage_profile_types_id=storage_profile_types.id
|
join ngcloud_ru.storage_profile_types on capacity_storage.storage_profile_types_id=storage_profile_types.id
|
||||||
where length(m.clientid) > 0
|
where length(m.clientid) > 0
|
||||||
AND capacity_storage.timestamp >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_start#/>
|
AND capacity_storage.timestamp >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_start#/>
|
||||||
AND capacity_storage.timestamp < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dateAdd("d",1,dt_finish)#/>
|
AND capacity_storage.timestamp < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dateAdd("d",1,dt_finish)#/>
|
||||||
|
<cfif len(wz)>
|
||||||
|
AND m.clientid like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#wz#%"/>
|
||||||
|
</cfif>
|
||||||
group by m.clientid, vdc.name, storage_profile_types.name
|
group by m.clientid, vdc.name, storage_profile_types.name
|
||||||
order by m.clientid, vdc.name, storage_profile_types.name;
|
order by m.clientid, vdc.name, storage_profile_types.name;
|
||||||
</cfquery>
|
</cfquery>
|
||||||
@@ -178,7 +209,7 @@
|
|||||||
</cfif>
|
</cfif>
|
||||||
|
|
||||||
|
|
||||||
<cfquery name="qStorageAge" datasource="billing-vc" cachedWithin=#createTimeSpan(0, 0, 25, 0)#>
|
<cfquery name="qStorageAge" datasource="billing-vc" cachedWithin=#createTimeSpan(0, 0, 27, 0)#>
|
||||||
select max(capacity_storage.timestamp) as dt_load from ngcloud_ru.capacity_storage
|
select max(capacity_storage.timestamp) as dt_load from ngcloud_ru.capacity_storage
|
||||||
</cfquery>
|
</cfquery>
|
||||||
<cfoutput>qStorageAge:#getTickCount()-request.startTickCount#</cfoutput><cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
<cfoutput>qStorageAge:#getTickCount()-request.startTickCount#</cfoutput><cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
||||||
@@ -188,7 +219,7 @@
|
|||||||
HOT_FREE_LIMIT 1 10 1 100
|
HOT_FREE_LIMIT 1 10 1 100
|
||||||
--->
|
--->
|
||||||
<!--- надо дисконтировать не ГБ-часы а ГБ-месяцы --->
|
<!--- надо дисконтировать не ГБ-часы а ГБ-месяцы --->
|
||||||
<cfquery name="qS3Vol" datasource="billing-s3" cachedWithin=#createTimeSpan(0, 0, 25, 0)#>
|
<cfquery name="qS3Vol" datasource="billing-s3" cachedWithin=#createTimeSpan(0, 0, 29, 0)#>
|
||||||
select /* *** ниже дублирование кода агрегации - round ceil etc, обратить внимание при правке */
|
select /* *** ниже дублирование кода агрегации - round ceil etc, обратить внимание при правке */
|
||||||
(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>) as vol_B
|
(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>) as vol_B
|
||||||
,sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>/1024/1024/1024 as vol_GB
|
,sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>/1024/1024/1024 as vol_GB
|
||||||
@@ -204,7 +235,10 @@ HOT_FREE_LIMIT 1 10 1 100
|
|||||||
join s3billing.bucket_info ON bucket_info.id=bucket_stat.bucket_id
|
join s3billing.bucket_info ON bucket_info.id=bucket_stat.bucket_id
|
||||||
where bucket_stat.placement_id in (1,2)
|
where bucket_stat.placement_id in (1,2)
|
||||||
AND bucket_stat.timestamp_addition >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_start#/>
|
AND bucket_stat.timestamp_addition >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_start#/>
|
||||||
AND bucket_stat.timestamp_addition < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dateAdd("d",1,dt_finish)#/>
|
AND bucket_stat.timestamp_addition < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dateAdd("d",1,dt_finish)#/>
|
||||||
|
<cfif len(wz)>
|
||||||
|
AND 'WZ'||lpad(bucket_stat.owner, 5, '0') like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#wz#%"/> /*выглядит очень неэффективным запросом*/
|
||||||
|
</cfif>
|
||||||
group by bucket_stat.owner, bucket_stat.placement_id, bucket_info.name
|
group by bucket_stat.owner, bucket_stat.placement_id, bucket_info.name
|
||||||
order by bucket_stat.owner, bucket_stat.placement_id, bucket_info.name;
|
order by bucket_stat.owner, bucket_stat.placement_id, bucket_info.name;
|
||||||
</cfquery>
|
</cfquery>
|
||||||
@@ -216,13 +250,13 @@ HOT_FREE_LIMIT 1 10 1 100
|
|||||||
<cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
<cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
||||||
</cfif>
|
</cfif>
|
||||||
|
|
||||||
<cfquery name="qS3VolAge" datasource="billing-s3" cachedWithin=#createTimeSpan(0, 0, 25, 0)#>
|
<cfquery name="qS3VolAge" datasource="billing-s3" cachedWithin=#createTimeSpan(0, 0, 29, 0)#>
|
||||||
select max(timestamp_addition) as dt_load from s3billing.bucket_stat
|
select max(timestamp_addition) as dt_load from s3billing.bucket_stat
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
<cfoutput>qS3VolAge:#getTickCount()-request.startTickCount#</cfoutput><cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
<cfoutput>qS3VolAge:#getTickCount()-request.startTickCount#</cfoutput><cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
||||||
|
|
||||||
<cfquery name="qS3OpsTrf" datasource="billing-s3">
|
<cfquery name="qS3OpsTrf" datasource="billing-s3" cachedWithin=#createTimeSpan(0, 0, 30, 0)#>
|
||||||
select
|
select
|
||||||
sum(
|
sum(
|
||||||
CASE WHEN
|
CASE WHEN
|
||||||
@@ -294,6 +328,9 @@ select
|
|||||||
where 1=1
|
where 1=1
|
||||||
AND usage_bucket_by_user.time >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_start#/>
|
AND usage_bucket_by_user.time >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_start#/>
|
||||||
AND usage_bucket_by_user.time < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dateAdd("d",1,dt_finish)#/>
|
AND usage_bucket_by_user.time < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dateAdd("d",1,dt_finish)#/>
|
||||||
|
<cfif len(wz)>
|
||||||
|
AND 'WZ'||lpad(user_info.name, 5, '0') like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#wz#%"/> /*выглядит очень неэффективным запросом*/
|
||||||
|
</cfif>
|
||||||
group by user_info.name, bucket_info.placement_id, bucket_info.name
|
group by user_info.name, bucket_info.placement_id, bucket_info.name
|
||||||
order by user_info.name, bucket_info.placement_id, bucket_info.name;
|
order by user_info.name, bucket_info.placement_id, bucket_info.name;
|
||||||
</cfquery>
|
</cfquery>
|
||||||
@@ -305,7 +342,7 @@ select
|
|||||||
<cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
<cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
||||||
</cfif>
|
</cfif>
|
||||||
|
|
||||||
<cfquery name="qS3OpsTrfAge" datasource="billing-s3" cachedWithin=#createTimeSpan(0, 0, 25, 0)#>
|
<cfquery name="qS3OpsTrfAge" datasource="billing-s3" cachedWithin=#createTimeSpan(0, 0, 30, 0)#>
|
||||||
select max(time) as dt_load from s3billing.usage_bucket_by_user
|
select max(time) as dt_load from s3billing.usage_bucket_by_user
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
@@ -353,26 +390,40 @@ order by wz, code
|
|||||||
</cfif>
|
</cfif>
|
||||||
|
|
||||||
|
|
||||||
|
<!--- загружаем рекордсеты в inmemory db, вместо чтобы мучиться с QoQ --->
|
||||||
<cfset db = new MemoryDbHelper()/>
|
<cfset db = new MemoryDbHelper()/>
|
||||||
<cfset db.register("qUnifiedMetric", qUnifiedMetric, "inmem")/>
|
<cfset db.register("qUnifiedMetric", qUnifiedMetric, "inmem")/>
|
||||||
<cfset db.register("qContragent", qContragent, "inmem")/>
|
<cfset db.register("qContragent", qContragent, "inmem")/>
|
||||||
<cfset db.register("qSpec", qSpec, "inmem")/>
|
<cfset db.register("qSpec", qSpec, "inmem")/>
|
||||||
|
|
||||||
|
<!--- Сопоставляем спецификации с метриками
|
||||||
|
В спецификации у нас есть контрагент (WZ) - это могут быть многие спецификации из многих договоров
|
||||||
|
проследить за версионностью спецификаций. в payg-report мы делаем отчет по дням, и для каждого дня проверяем актуальность спецификации для него
|
||||||
|
в метрике у нас только WZ контрагента (потому что нет объекта биллинга и даже контракта) и расшифрованный код без суффикса типа тарификации (который относится у нас не к продукту, а к цене)
|
||||||
|
FULL JOIN, потому что нам нужны бесхозные записи с той и другой стороны
|
||||||
|
При этом важно именно как мы обрабатываем бесхозные записи с каждой стороны
|
||||||
|
Они образуются за счет несовпадения кодов (нет в договоре - метрика есть, строчки нет. в том числе, если в договоре неправильный артикул)
|
||||||
|
Частичное совпадение кодов: есть фикс на тот же артикул. Показываем, но учитываем с нулевой ценой (потому что цена на фикс на другие единицы измерения, на месяц)
|
||||||
|
Отдельный вопрос: как мы обрабатываем Fixed PAYG и что с ним придумать
|
||||||
|
Контрагента со спекой нельзя INNER JOIN - есть вариант WZ с метрикой, но без спеки. В порядке ошибки может быть метрика без спеки и контрагента (orphan WZ). Либо осознанно записали вместо WZ что-то по своему усмотрению, благо там текстовое поле
|
||||||
|
Но нас тут совершенно не интересуют контрагенты без спек и метрик
|
||||||
|
Группировка: по контрагенту,
|
||||||
|
|
||||||
|
--->
|
||||||
|
|
||||||
<cfquery name="qCharge" datasource="inmem">
|
<cfquery name="qCharge" datasource="inmem">
|
||||||
|
/*EXPLAIN PLAN FOR*/
|
||||||
SELECT
|
SELECT
|
||||||
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
|
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
|
||||||
<d:field title="WZ">coalesce(coalesce(c.wz, m.wz), s.wz) as wz</d:field>
|
<d:field title="WZ">coalesce(coalesce(c.wz, m.wz), s.wz) as wz</d:field>
|
||||||
<!--- <d:field title="WZ">f.wz as wzf</d:field> --->
|
<d:field title="WZ spec">s.wz as wzs</d:field>
|
||||||
<d:field title="WZ">s.wz as wzs</d:field>
|
<d:field title="WZ contragent">c.wz as wzc</d:field>
|
||||||
<d:field title="WZ">c.wz as wzc</d:field>
|
<d:field title="WZ metric">m.wz as wzm</d:field>
|
||||||
<!--- <d:field title="WZ">cs.wz as wzcs</d:field> --->
|
<d:field title="WZ конечника">s.end_customer_wz as wze</d:field>
|
||||||
<d:field title="WZ">m.wz as wzm</d:field>
|
<d:field title="Артикул">coalesce(s.sku_code, m.code) as code</d:field>
|
||||||
<d:field title="WZE">s.end_customer_wz as wze</d:field>
|
<d:field title="Артикул по специф.">s.code as s_code</d:field><!--- содержит суффикс типа тарификации --->
|
||||||
<d:field title="Артикул">coalesce(s.code, m.code) as code</d:field>
|
<d:field title="SKU code по специф.">s.sku_code as sku_code</d:field><!--- без суффикса --->
|
||||||
<d:field title="Артикул по специф.">s.code as s_code</d:field>
|
<d:field title="Артикул по метрикам">m.code as m_code</d:field><!--- без суффикса --->
|
||||||
<d:field title="SKU code">s.sku_code as sku_code</d:field>
|
|
||||||
<d:field title="Артикул по метрикам">m.code as m_code</d:field>
|
|
||||||
<d:field title="Кол-во компонента по спец.">s.component_quantity</d:field>
|
<d:field title="Кол-во компонента по спец.">s.component_quantity</d:field>
|
||||||
<d:field title="Кол-во сервиса по спец.">s.service_quantity</d:field>
|
<d:field title="Кол-во сервиса по спец.">s.service_quantity</d:field>
|
||||||
<d:field title="Скидка на сервис">s.service_discount</d:field>
|
<d:field title="Скидка на сервис">s.service_discount</d:field>
|
||||||
@@ -407,22 +458,30 @@ SELECT
|
|||||||
<d:field title="Клиентс. назв.">s.user_description</d:field>
|
<d:field title="Клиентс. назв.">s.user_description</d:field>
|
||||||
</d:field_set>
|
</d:field_set>
|
||||||
FROM qUnifiedMetric m
|
FROM qUnifiedMetric m
|
||||||
FULL JOIN qSpec s ON (m.wz=s.wz AND m.code=s.sku_code) -- сервис или компонент, но не цена с типом тарификации
|
FULL JOIN qSpec s ON (m.wz=s.wz AND m.code=s.sku_code) -- сервис или компонент, но не цена с типом тарификации, суффикс типа тарификации отрезан
|
||||||
LEFT JOIN qContragent c ON (trim(coalesce(s.wz,m.wz))=trim(c.wz)) -- пробелы тут стоили нескольких часов работы
|
LEFT JOIN qContragent c ON ((coalesce(s.wz,m.wz))=(c.wz)) -- пробелы в составе WZ стоили нескольких часов работы
|
||||||
<!--- LEFT JOIN qContragent cs ON (s.wz=cs.wz) -- неуклюже, но иначе контрагент теряется --->
|
--(поскольку trim слева в джойне катастрофически замедляет работу, делаем чистку выше при формировании исходных резалтсетов)
|
||||||
WHERE 1=1 --AND (s.type=3 OR NOT m.metric IS NULL)
|
WHERE 1=1
|
||||||
<cfif only_articles_in_spec>
|
<cfif only_articles_in_spec>
|
||||||
AND EXISTS(select * from qSpec qs where qs.wz=m.wz AND qs.type=3)
|
AND EXISTS(select * from qSpec qs where qs.wz=m.wz AND qs.type=3)
|
||||||
<!--- вообще-то есть смысл добавить и все строки, где что-то намеряли --->
|
<!--- вообще-то есть смысл добавить и все строки, где что-то намеряли --->
|
||||||
</cfif>
|
</cfif>
|
||||||
|
<cfif len(wz)>
|
||||||
|
AND (
|
||||||
|
m.wz like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#wz#%"/>
|
||||||
|
OR s.wz like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#wz#%"/>
|
||||||
|
OR c.wz like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#wz#%"/>
|
||||||
|
)
|
||||||
|
<!--- вообще-то есть смысл добавить и все строки, где что-то намеряли --->
|
||||||
|
</cfif>
|
||||||
--AND s.wz='WZ01031'
|
--AND s.wz='WZ01031'
|
||||||
--AND s.wz='WZ01762'
|
--AND s.wz='WZ01762
|
||||||
<!---
|
<!---
|
||||||
AND 1=0
|
AND 1=0
|
||||||
--->
|
--->
|
||||||
ORDER BY coalesce(coalesce(c.wz, m.wz), s.wz), coalesce(s.code, m.code)
|
ORDER BY coalesce(coalesce(c.wz, m.wz), s.wz), coalesce(s.code, m.code)
|
||||||
</cfquery>
|
</cfquery>
|
||||||
<!--- <cfdump var=#qCharge#/> --->
|
<!--- <cfdump var=#qCharge#/> --->
|
||||||
|
|
||||||
<cfoutput>qCharge:#getTickCount()-request.startTickCount#</cfoutput><cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
<cfoutput>qCharge:#getTickCount()-request.startTickCount#</cfoutput><cfif !isDefined("output_xls") AND !isDefined("output_json")><cfflush/></cfif>
|
||||||
<cfif isDefined("DEBUG")>
|
<cfif isDefined("DEBUG")>
|
||||||
@@ -460,6 +519,7 @@ ORDER BY coalesce(coalesce(c.wz, m.wz), s.wz), coalesce(s.code, m.code)
|
|||||||
Период с <input type="text" name="dt_start" value="#dateFormat(dt_start,'YYYY-MM-DD')#"/>
|
Период с <input type="text" name="dt_start" value="#dateFormat(dt_start,'YYYY-MM-DD')#"/>
|
||||||
по <input type="text" name="dt_finish" value="#dateFormat(dt_finish,'YYYY-MM-DD')#"/>
|
по <input type="text" name="dt_finish" value="#dateFormat(dt_finish,'YYYY-MM-DD')#"/>
|
||||||
Только PAYG <input type="checkbox" name="only_articles_in_spec" value="1"<cfif only_articles_in_spec> checked</cfif>/>
|
Только PAYG <input type="checkbox" name="only_articles_in_spec" value="1"<cfif only_articles_in_spec> checked</cfif>/>
|
||||||
|
WZ <input type="text" name="wz" value="#wz#"/> по вхождению подстроки, с учетом регистра
|
||||||
<input type="submit" style="cursor:pointer;"/>
|
<input type="submit" style="cursor:pointer;"/>
|
||||||
<input type="submit" name="DEBUG" value="DEBUG" style="cursor:pointer;"/>
|
<input type="submit" name="DEBUG" value="DEBUG" style="cursor:pointer;"/>
|
||||||
</form>
|
</form>
|
||||||
@@ -482,7 +542,7 @@ S3 операции и трафик: <b>#dateFormat(qS3OpsTrfAge.dt_load,'YYYY-M
|
|||||||
<th width="7%">Артикул специф.</th>
|
<th width="7%">Артикул специф.</th>
|
||||||
<th width="5%">Кол-во специф.</th>
|
<th width="5%">Кол-во специф.</th>
|
||||||
<th width="5%">Артикул метр.</th>
|
<th width="5%">Артикул метр.</th>
|
||||||
<th width="5%">Детализация</th>
|
<th width="10%">Детализация</th>
|
||||||
<th width="5%">Кол-во метр.</th>
|
<th width="5%">Кол-во метр.</th>
|
||||||
<th width="5%">Free Tier.</th>
|
<th width="5%">Free Tier.</th>
|
||||||
<th width="5%">Опл. объем</th>
|
<th width="5%">Опл. объем</th>
|
||||||
@@ -492,15 +552,15 @@ S3 операции и трафик: <b>#dateFormat(qS3OpsTrfAge.dt_load,'YYYY-M
|
|||||||
|
|
||||||
<td width="3%"> </td>
|
<td width="3%"> </td>
|
||||||
|
|
||||||
<td width="15%">Услуга</td>
|
<td width="10%">Услуга</td>
|
||||||
<td width="15%">Компонент</td>
|
<td width="10%">Компонент</td>
|
||||||
<td width="15%">Клиентс. назв.</td>
|
<td width="15%">Клиентс. назв.</td>
|
||||||
|
|
||||||
<td width="3%">GPL с НДС</td>
|
<td width="3%">GPL с НДС</td>
|
||||||
<td width="3%">Скидка%</td>
|
<td width="3%">Скидка%</td>
|
||||||
|
|
||||||
<td width="3%">Дата НОУ ***</td>
|
<td width="3%">Дата НОУ</td>
|
||||||
<td width="3%">Дата оконч.</td>
|
<td width="3%">Дата КОУ</td>
|
||||||
|
|
||||||
<td width="5%">Ключ строки</td>
|
<td width="5%">Ключ строки</td>
|
||||||
<td width="3%">Сырая метрика</td>
|
<td width="3%">Сырая метрика</td>
|
||||||
@@ -540,17 +600,22 @@ S3 операции и трафик: <b>#dateFormat(qS3OpsTrfAge.dt_load,'YYYY-M
|
|||||||
</tr>
|
</tr>
|
||||||
<cfoutput group="code">
|
<cfoutput group="code">
|
||||||
<cfoutput group="serviceStart">
|
<cfoutput group="serviceStart">
|
||||||
|
|
||||||
<cfset accum_metric_svc += isNumeric(metric) ? metric : 0/>
|
<cfset accum_metric_svc += isNumeric(metric) ? metric : 0/>
|
||||||
<cfset accum_metric_dimension_1 = 0/>
|
<cfset accum_metric_dimension_1 = 0/>
|
||||||
|
<cfset current_price=0/>
|
||||||
|
|
||||||
<cfoutput><!--- dimensions --->
|
<cfoutput><!--- dimensions --->
|
||||||
|
|
||||||
<cfif type EQ 3>
|
<cfif type EQ 3>
|
||||||
<cfset accum_metric_dimension_1 += isNumeric(metric) ? metric : 0/>
|
<cfset accum_metric_dimension_1 += isNumeric(metric) ? metric : 0/>
|
||||||
|
<cfset current_price=gaussianRound(discounted_price, 2)/>
|
||||||
</cfif>
|
</cfif>
|
||||||
<!--- детализация --->
|
<!--- детализация --->
|
||||||
<tr<cfif !len(unit)> class="gray"</cfif>>
|
<tr<cfif !len(unit)> class="gray"</cfif>>
|
||||||
<td>#currentRow#</a></td>
|
<td>#currentRow#</a></td>
|
||||||
|
|
||||||
<td<cfif type EQ 3> style="background:lightgreen;color:black;"</cfif>>#s_code#</td>
|
<td><div<cfif type EQ 3> style="background:lightgreen;color:black;"</cfif>>#s_code#</div></td>
|
||||||
<td class=<cfif type EQ 3 AND component_quantity NEQ 1>"err r"<cfelse>"r"</cfif>>#component_quantity#</td>
|
<td class=<cfif type EQ 3 AND component_quantity NEQ 1>"err r"<cfelse>"r"</cfif>>#component_quantity#</td>
|
||||||
<td>#m_code#</td>
|
<td>#m_code#</td>
|
||||||
<td>#dimension1#</td>
|
<td>#dimension1#</td>
|
||||||
@@ -592,16 +657,16 @@ S3 операции и трафик: <b>#dateFormat(qS3OpsTrfAge.dt_load,'YYYY-M
|
|||||||
</tr>
|
</tr>
|
||||||
</cfoutput>
|
</cfoutput>
|
||||||
<cfset final_metric_dimension_1 = ceiling(accum_metric_dimension_1)/>
|
<cfset final_metric_dimension_1 = ceiling(accum_metric_dimension_1)/>
|
||||||
<cfset cost_dimension_1 = precisionEvaluate("gaussianRound(max(final_metric_dimension_1 - free_tier, 0)*gaussianRound(discounted_price, 2), 2)")/>
|
<cfset cost_dimension_1 = precisionEvaluate("gaussianRound(max(final_metric_dimension_1 - free_tier, 0)*current_price, 2)")/>
|
||||||
<cfset accum_cost_svc = precisionEvaluate("accum_cost_svc + cost_dimension_1")/><!--- простое сложение дает ошибку округления и лишние знаки, но и precisionEvaluate не выглядит слишком надежным --->
|
<cfset accum_cost_svc = precisionEvaluate("accum_cost_svc + cost_dimension_1")/><!--- простое сложение дает ошибку округления и лишние знаки, но и precisionEvaluate не выглядит слишком надежным --->
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3"></td>
|
<td colspan="3"></td>
|
||||||
<td colspan="2" class="b">#code#</td>
|
<td colspan="2" class="b r">Итого #code#:</td>
|
||||||
<td class="b r" style="font-size:110%; padding:0 1em;"><cfif final_metric_dimension_1 NEQ 0 AND isNumeric(final_metric_dimension_1)>#round(final_metric_dimension_1,3)#</cfif></td>
|
<td class="b r" style="font-size:110%; padding:0 1em;"><cfif final_metric_dimension_1 NEQ 0 AND isNumeric(final_metric_dimension_1)>#round(final_metric_dimension_1,3)#</cfif></td>
|
||||||
<td class="b r">#free_tier#</td>
|
<td class="b r">#free_tier#</td>
|
||||||
<td class="b r" style="font-size:120%; padding:0 1em;"><cfif final_metric_dimension_1 NEQ 0 AND isNumeric(final_metric_dimension_1)>#max(ceiling(final_metric_dimension_1) - free_tier, 0)#</cfif></td>
|
<td class="b r" style="font-size:120%; padding:0 1em;"><cfif final_metric_dimension_1 NEQ 0 AND isNumeric(final_metric_dimension_1)>#max(ceiling(final_metric_dimension_1) - free_tier, 0)#</cfif></td>
|
||||||
<td class="b c">#unit# <cfif len(ed_izm)>[#ed_izm#]</cfif></td>
|
<td class="b c">#unit# <cfif len(ed_izm)>[#ed_izm#]</cfif></td>
|
||||||
<td class="b r">#gaussianRoundSafe(discounted_price,2)#</td>
|
<td class="b r">#current_price#</td>
|
||||||
<td class="b r">#gaussianRoundSafe(cost_dimension_1,2)#</td>
|
<td class="b r">#gaussianRoundSafe(cost_dimension_1,2)#</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td colspan="100"></td>
|
<td colspan="100"></td>
|
||||||
@@ -611,8 +676,8 @@ S3 операции и трафик: <b>#dateFormat(qS3OpsTrfAge.dt_load,'YYYY-M
|
|||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td bgcolor="##eee" style="border-bottom:2px solid gray;"></td>
|
<td bgcolor="##eee" style="border-bottom:2px solid gray;"></td>
|
||||||
<td bgcolor="##eee" colspan="9" class="r" style="border-bottom:2px solid gray;"><b>Итого</b> <a href="contragent.cfm?__id=#contragent_uid#&#tr.fwx#">#wz#</a> #contragent#:</td>
|
<td bgcolor="##eee" colspan="9" class="r b" style="border-bottom:2px solid gray;">Итого <a href="contragent.cfm?__id=#contragent_uid#&#tr.fwx#">#wz#</a> #contragent#:</td>
|
||||||
<td bgcolor="##eee" class="r b nw" style="border-bottom:2px solid gray; font-size:130%; padding:0 1em;">#accum_cost_svc#</td>
|
<td bgcolor="##eee" class="r b nw" style="border-bottom:2px solid gray; font-size:130%;">#accum_cost_svc#</td>
|
||||||
<td bgcolor="##eee" style="border-bottom:2px solid gray;"></td>
|
<td bgcolor="##eee" style="border-bottom:2px solid gray;"></td>
|
||||||
<td bgcolor="##eee" colspan="99" style="border-bottom:2px solid gray;"></td>
|
<td bgcolor="##eee" colspan="99" style="border-bottom:2px solid gray;"></td>
|
||||||
</tr >
|
</tr >
|
||||||
|
|||||||
Reference in New Issue
Block a user