0

これは、cfquery 出力の前に「employeeRatings」テーブルから使用した RAW DATA のサンプルです。

        (showcasing employeeID:1128 for the month of May)

employeeID  |   Possible_Factor  |   Factor   |  ratingDate
=======================================================================
 1128       |        .1          |  .1        | 5/25/2013 2:05:13 PM 
 1128       |        .1          |  .0        | 5/22/2013 9:30:43 AM 
 1128       |        .2          |  .1        | 5/17/2013 9:42:09 AM 
 1128       |        .1          |  .1        | 5/13/2013 8:07:15 AM 
 1128       |        .1          |  .0        | 5/10/2013 7:52:51 AM 
 1128       |        .4          |  .0        | 5/6/2013 12:41:12 PM 

cfquery (SQL ステートメント) は次のとおりです。

SELECT ROUND(100 * (SUM(Factor) / SUM(Possible_Factor)), 2) AS employeeRating, CONVERT(CHAR(4), ratingDate, 100) + CONVERT(CHAR(4), ratingDate, 120) AS month, employeeID, DATEADD(MONTH, DATEDIFF(MONTH, 0, ratingDate), 0) AS shortdate 
FROM employeeRatings
GROUP BY CONVERT(CHAR(4), ratingDate, 100) + CONVERT(CHAR(4), ratingDate, 120), DATEADD(MONTH, DATEDIFF(MONTH, 0, ratingDate), 0), employeeID 
ORDER BY employeeID, DATEADD(MONTH, DATEDIFF(MONTH, 0, ratingDate), 0) DESC

cfquery の後、出力は次のようになります。

employeeID  |   employeeRating   |   month      |  shortdate
=======================================================================
 1128       |        30          |  May 2013    | 5/1/2013 12:00:00 AM 
 1128       |        60          |  April 2013  | 4/1/2013 12:00:00 AM
 1128       |        90          |  Jan 2013    | 1/1/2013 12:00:00 AM
 7310000    |        95          |  April 2013  | 4/1/2013 12:00:00 AM
 7310000    |        85          |  Mar 2013    | 3/1/2013 12:00:00 AM
 7310000    |        75          |  Feb 2013    | 2/1/2013 12:00:00 AM
 7310000    |        55          |  Jan 2013    | 1/1/2013 12:00:00 AM
 444981     |        27          |  Mar 2013    | 3/1/2013 12:00:00 AM
 444981     |        77          |  Jan 2013    | 1/1/2013 12:00:00 AM
 444981     |        97          |  Nov 2012    | 11/1/2012 12:00:00 AM
 444981     |        37          |  Sept 2012   | 9/1/2012 12:00:00 AM
 444981     |        47          |  Aug 2012    | 8/1/2012 12:00:00 AM

従業員を取り上げて、その LAST THREE 評価をリストする必要があります (月が null の場合は、null の月をスキップし、次の月の評価を取得して、文書化された最後の 3 つの評価を表示します)。これは、200 人を超える従業員を一覧表示する動的 cfquery です。目的の出力は次のとおりです。

supplierID  |   LastRating   |   SecondLastRating  |   ThirdLastRating
======================================================================
 1128       |        30      |       60            |         90
 7310000    |        95      |       85            |         75
 444981     |        27      |       77            |         97

SQL Server 2000 (互換性 80) で ColdFusion を使用していますが、使用している ColdFusion バージョンは cfloop グループ属性をサポートしていません。新しい出力を取得して新しいクエリに入れたいので、別のクエリと結合できます。解決策 = FB からのスターバックス ギフト ;) 皆様、お時間をいただき、ご検討いただきありがとうございます!!!!

4

3 に答える 3

3

SQL Server 2005 以降

別のオプションは、SQL Server のPIVOT演算子を使用することです

最初にROW_NUMBER()を使用して、従業員と日付でレコードをランク​​付けします。(注: テーブルに実際の日時列が含まれていない場合は、ID 列を代用するか、「月」をdatetimeusingにキャストできますconvert())。

    SELECT  employeeID
            , employeeRating
            , ROW_NUMBER() OVER ( 
                    PARTITION BY employeeID 
                    ORDER BY employeeID, theRatingDateCol DESC
            ) AS Row
    FROM   yourTable
    ...

結果:

employeeID  employeeRating Row
----------- -------------- --------------------
1128        30             1
1128        60             2
1128        90             3
444981      27             1
444981      77             2
444981      97             3
444981      37             4
7310000     95             1
7310000     85             2
7310000     75             3
7310000     55             4

次にPIVOT、上位 3 行の結果:

    ... 
    PIVOT
    (       
            MIN(employeeRating)
            FOR Row IN ( [1],[2],[3]) 
    )

完全なクエリ:

SELECT pvt.employeeID
        , pvt.[1] AS LastRating  
        , pvt.[2] AS SecondLastRating  
        , pvt.[3] AS ThirdLastRating  
FROM (
        --- order by employee and rating date (descending)
        SELECT  employeeID
                , employeeRating
                , ROW_NUMBER() OVER ( 
                    PARTITION BY employeeID 
                    ORDER BY employeeID, theRatingDateCol DESC
                ) AS Row
        FROM   yourTable
    ) data
    PIVOT
    (   -- take top 3 values
        MIN(employeeRating)
        FOR Row IN ( [1],[2],[3]) 
    ) pvt

結果:

employeeID  LastRating  SecondLastRating ThirdLastRating
----------- ----------- ---------------- ---------------
1128        30          60               90
444981      27          77               97
7310000     95          85               75

SQL Server 2000

残念ながら、SQL Server 2000 以前では、これらの機能はサポートされていません。ほど滑らかではPIVOTありませんが、サブクエリと を使用してシミュレートできますCASE

まず、 の代わりにサブクエリを使用しROW_NUMBER()ます。基本的にcount、以前の評価日を持つレコードの数を取得し、それを行番号の代わりに使用します。注: これは、評価日が従業員ごとに一意であることを前提としています。そうでない場合は、別の列を追加して同点を解消する必要があります。

次に、CASEを使用して行番号を調べ、最初の 3 つのレコードの列を生成します。

SELECT  r.employeeID
        , MAX( CASE WHEN r.Row = 0 THEN r.EmployeeRating ELSE 0 END ) AS LastRating  
        , MAX( CASE WHEN r.Row = 1 THEN r.EmployeeRating ELSE 0 END ) AS SecondLastRating  
        , MAX( CASE WHEN r.Row = 2 THEN r.EmployeeRating ELSE 0 END ) AS ThirdLastRating  
FROM  (
        SELECT  m.employeeID
                , m.employeeRating
                , m.theRatingDate
                , (  SELECT COUNT(*)
                     FROM   yourTable cnt
                    WHERE  cnt.employeeID = m.employeeID
                    AND    cnt.theRatingDate > m.theRatingDate
                ) AS Row
        FROM   yourTable m
        GROUP BY m.employeeID
            , m.employeeRating
            , m.theRatingDate
        ) r
WHERE  r.Row <= 2
GROUP BY r.employeeID

コールドフュージョン

最後のオプションは、ColdFusion を使用することです。James Mohler の回答を適応させて、別の「ピボット」クエリを作成できます。クエリ ループの前に、新しいクエリ オブジェクトを作成し、評価列に順番に名前を付けますrating1,rating2,rating3。外側のループ内で、従業員ごとに行を追加します。最後に、カウンターを使用して、内側のループ内の最初の 3 つの列を設定します。

注: 元のクエリは、次のように並べ替える必要employeeID, shortDate DESCがあります。そうしないと、コードが正しく機能しません。

<cfset newQuery = queryNew("employeeID,rating1,rating2,rating3", "integer,Decimal,Decimal,Decimal")>

<cfoutput query="originalQuery" group="employeeID">
    <!--- add new employee row --->
    <cfset ratingRow = queryAddRow(newQuery, 1)>
    <cfset newQuery["employeeID"][ratingRow] = employeeID>

    <!--- initialize rating counter --->
    <cfset ratingIndex = 0>
    <cfoutput>
        <cfset ratingColumn++>
        <!--- populate top 3 rating columns --->
        <cfif ratingColumn lte 3>
            <cfset newQuery["rating"& ratingColumn][ratingRow] = employeeRating>
        </cfif>
    </cfoutput>
</cfoutput>
于 2013-06-06T01:14:25.243 に答える
3

これがColdFusionのみのソリューションです

<table>
<tr>
    <td>SupplierID</td>
    <td>LastRating</td>
    <td>SecondLastRating</td>
    <td>ThirdLastRating</td>
</tr>
<cfoutput name="qrySupplier" group="employeeID">
<cfset Rating  = 0>
<tr>
    <td>#employeeid#</td>
    <cfoutput>
       <cfset Rating++>
       <cfif Rating LTE 3>
           <td>#employeerating#</td>
       </cfif>
     </cfoutput>
</tr>
</cfoutput>
</table>
于 2013-06-05T15:23:09.163 に答える