<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 35.10\. 用戶定義聚集 在PostgreSQL里的聚集是用_狀態值_ 和_狀態轉換函數_表達的。 也就是說,聚集操作使用一個隨著每個輸入行被處理而變化的狀態值。 要定義一個新的聚集函數,就要選擇表示狀態值的數據類型、狀態初始值、狀態轉換函數。 該狀態轉換函數只是一個普通函數,也可以用于聚集的環境之外。 還可以聲明一個_最終處理函數_, 用于對付期望的聚集結果不同于需要保留在狀態值中數據的情況。 因此,除了被聚集用戶看到的參數和結果數據類型外,還有一種內部狀態值數據類型, 這種類型可能與參數和結果類型都不一樣。 如果定義了一個不使用最終處理函數的聚集,那么聚集就是對每條記錄的字段值進行函數計算。 `sum`(求和)是這類聚集的例子。它從零開始, 依次向"總和"狀態值追加當前的記錄值。比如,如果要把`sum`聚集用于復數, 只需要該數據類型的加法函數就行了。該聚集可以這樣定義: ``` CREATE AGGREGATE sum (complex) ( sfunc = complex_add, stype = complex, initcond = '(0,0)' ); SELECT sum(a) FROM test_complex; sum ----------- (34,53.9) ``` 請注意,上述依賴于函數重載:有多個名為`sum`的聚集函數, 但是PostgreSQL能夠正確選出作用于`complex`列類型的那個。 如果不存在非 NULL 輸入值,上面的`sum`定義將返回零值(初始狀態條件)。 要按照 SQL 標準的要求返回 NULL 只需忽略`initcond` 段就可以實現(這樣初始狀態條件將變為 NULL)。 通常這也意味著`sfunc`需要檢查 NULL 狀態條件輸入,不過對于`sum`, `max`,`min`這類的簡單聚集來說,把第一個非空輸入插入到狀態值里面, 然后從第二個非空輸入狀態值開始使用轉換函數就足夠了。 如果初始條件是 NULL 并且轉換函數被標記為"strict"(不能對 NULL 輸入調用), PostgreSQL就會自動處理這些內容。 另外一個"strict"轉換函數的缺省特性是:當碰到一個 NULL 輸入的時候, 前面一個狀態值會被保留下來不做改動。這樣,就忽略了 NULL 。 如果你希望對 NULL 輸入進行其它處理,只需要別把你的轉換函數定義為"strict", 并在編寫代碼的時候測試 NULL 并做相應處理即可。 `avg`(平均)是聚集更復雜一點的例子。它需要兩個運行時狀態: 輸入的總和以及輸入的數量。最終結果是通過把兩者相除得到的。 平均的典型實現是用一個數組做狀態值。比如,內建的`avg(float8)`實現是這樣的: ``` CREATE AGGREGATE avg (float8) ( sfunc = float8_accum, stype = float8[], finalfunc = float8_avg, initcond = '{0,0,0}' ); ``` (`float8_accum`要求一個三元素數組,而不是兩元素, 因為它累積平方和和輸入的總和和計數。這樣它就可以在一些除了`avg` 之外的聚集中使用了。) 聚集函數可以使用多態轉換函數或者最終處理函數,這樣,同一個函數就可以用于實現多個聚集。 參閱[Section 35.2.5](#calibre_link-909)獲取多態函數的解釋。再進一步, 聚集函數本身可以用多態的基本類型和狀態類型來聲明, 這樣就允許一個聚集定義用于多種輸入數據類型。下面是一個多態聚集的例子: ``` CREATE AGGREGATE array_accum (anyelement) ( sfunc = array_append, stype = anyarray, initcond = '{}' ); ``` 這里,任意聚集調用的實際狀態類型是和元素輸入類型相同的數組類型。 聚集的特征是連接所有的輸入到那個類型的數組里。(注意: 內建的聚集`array_agg`支持相同的功能,并且有比這個定義更好的性能。) 下面的例子使用兩個不同實際數據類型作為參數輸出: ``` SELECT attrelid::regclass, array_accum(attname) FROM pg_attribute WHERE attnum > 0 AND attrelid = 'pg_tablespace'::regclass GROUP BY attrelid; attrelid | array_accum ---------------+--------------------------------------- pg_tablespace | {spcname,spcowner,spcacl,spcoptions} (1 row) SELECT attrelid::regclass, array_accum(atttypid::regtype) FROM pg_attribute WHERE attnum > 0 AND attrelid = 'pg_tablespace'::regclass GROUP BY attrelid; attrelid | array_accum ---------------+--------------------------- pg_tablespace | {name,oid,aclitem[],text[]} (1 row) ``` 一個用 C 寫的函數可以判斷它是被當作一個聚集轉換函數調用還是通過調用`AggCheckCallContext` 作為最終的函數,例如: ``` if (AggCheckCallContext(fcinfo, NULL)) ``` 檢查這個的一個原因是,在它對于一個轉換函數為真的時候,左邊的輸入必須是一個臨時的轉換值, 因此可以安全地現場修改,而不用分配新的拷貝。參閱`int8inc()`的例子。 (這是函數里_唯一_可以修改輸入的傳遞引用的地方。特別的, 聚集最終的函數不應該在任何情況下修改他們的輸入, 因為在某些情況下它們將在相同的最終轉換值下重復執行。) 更詳細的信息請參考[CREATE AGGREGATE](#calibre_link-537)命令。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看