6

私のピボットクエリは以下を生成します:

+-----------+----+----+---+---+---+---+---+
| client_id | 1  | 2  | 3 | 4 | 5 | 6 | 7 |
+-----------+----+----+---+---+---+---+---+
|    216436 |  9 |  0 | 0 | 0 | 0 | 0 | 0 |
|    110522 | 76 |  3 | 0 | 0 | 0 | 0 | 0 |
|    214981 |  0 |  1 | 0 | 0 | 0 | 0 | 0 |
|    216360 | 52 |  1 | 0 | 0 | 0 | 0 | 0 |
|    102574 |  1 |  0 | 0 | 0 | 0 | 0 | 0 |
|    211754 | 97 | 14 | 2 | 0 | 0 | 0 | 0 |
|    210734 |  8 |  4 | 0 | 0 | 0 | 0 | 0 |
|    100123 |  1 |  0 | 0 | 0 | 0 | 0 | 0 |
|    101840 |  2 |  0 | 0 | 0 | 0 | 0 | 0 |
+-----------+----+----+---+---+---+---+---+

クエリは次のとおりです。

   select client_id,
   [1],[2],[3],[4],[5],[6],[7] -- these are timestested (the amount of times tested)
   from
   (   SELECT DISTINCT CLIENT_ID
   , PATIENT_ID
   , count(*) over (partition by client_id, patient_id) AS patientcount

   from f_accession_daily) as SourceTable
   PIVOT
   (
   count(patient_id)
   for patientcount in ([1],[2],[3],[4],[5],[6],[7])
   ) as pivottable

次の表から、テストするたびに([1]、[2]、[3]などの場合)最大/最小の日付を取得する必要があります。

+-----------+-------------+-------+------------+------------+
| client_id | TimesTested | count | maxRecDate | minRecDate |
+-----------+-------------+-------+------------+------------+
|    100034 |           2 |     1 | 6/25/2008  | 6/23/2008  |
|    100034 |           1 |    20 | 6/30/2008  | 6/19/2008  |
|    100038 |           3 |     1 | 7/25/2008  | 7/23/2008  |
|    100038 |           1 |     4 | 7/25/2008  | 7/1/2008   |
|    100050 |           1 |    15 | 8/11/2008  | 7/14/2008  |
|    100060 |           1 |     2 | 8/12/2008  | 7/29/2008  |
|    100070 |           1 |     3 | 8/15/2008  | 8/15/2008  |
|    100049 |           1 |     3 | 8/22/2008  | 7/11/2008  |
|    100029 |           3 |     2 | 8/25/2008  | 6/18/2008  |
+-----------+-------------+-------+------------+------------+

上記のテーブルは次のように生成されます。

SELECT a.client_id AS client_id
,a.patientcount TimesTested
   , count(a.patientcount)/a.patientcount AS count
   , max(f.received_date) AS maxRecDate
   , min(f.received_date) AS minRecDate
FROM
(
   SELECT DISTINCT CLIENT_ID
   , PATIENT_ID
   , count(*) over (partition by client_id, patient_id) AS patientcount

   from f_accession_daily

) AS a
JOIN F_ACCESSION_DAILY AS f ON a.CLIENT_ID = f.CLIENT_ID
   AND a.PATIENT_ID = f.PATIENT_ID

GROUP BY a.CLIENT_ID, a.patientcount

私が取得する必要がある結果のテーブル:

+-----------+----+----------+-----------+----+----------+-----------+---+----------+-----------+---+----------+-----------+-----+
| client_id | 1  | maxdate1 | mindate1  | 2  | maxdate2 | mindate2  | 3 | maxdate3 | mindate3  | 4 | maxdate4 | mindate4  |  5  |
+-----------+----+----------+-----------+----+----------+-----------+---+----------+-----------+---+----------+-----------+-----+
|    216436 |  9 | 1/1/2011 | 1/23/1985 |  0 | 1/1/2011 | 1/23/1985 | 0 | 1/1/2011 | 1/23/1985 | 0 | 1/1/2011 | 1/23/1985 | etc |
|    110522 | 76 | 1/1/2011 | 1/23/1984 |  3 | 1/1/2011 | 1/23/1984 | 0 | 1/1/2011 | 1/23/1984 | 0 | 2/1/2011 | 1/23/1984 |     |
|    214981 |  0 | 1/1/2013 | 1/23/1985 |  1 | 1/1/2013 | 1/23/1985 | 0 | 1/1/2013 | 1/23/1985 | 0 | 1/1/2013 | 1/23/1985 |     |
|    216360 | 52 | 1/1/2011 | 1/23/1985 |  1 | 1/1/2011 | 1/23/1985 | 0 | 1/1/2011 | 1/23/1985 | 0 | 1/1/2011 | 1/23/1985 |     |
|    102574 |  1 | 1/1/2011 | 1/23/1985 |  0 | 1/1/2014 | 1/23/1980 | 0 | 2/1/2011 | 1/23/1985 | 0 | 1/1/2011 | 1/23/1985 |     |
|    211754 | 97 | 1/1/2012 | 1/23/1985 | 14 | 1/1/2012 | 1/23/1985 | 2 | 1/1/2012 | 1/23/1985 | 0 | 1/1/2012 | 1/23/1985 |     |
|    210734 |  8 | 1/1/2011 | 1/23/1984 |  4 | 1/1/2011 | 1/23/1984 | 0 | 1/1/2011 | 1/23/1984 | 0 | 1/1/2011 | 1/23/1984 |     |
|    100123 |  1 | 1/1/2011 | 1/23/1985 |  0 | 1/1/2011 | 1/23/1985 | 0 | 1/1/2011 | 1/23/1985 | 0 | 1/1/2011 | 1/23/1987 |     |
|    101840 |  2 | 1/1/2011 | 1/23/1985 |  0 | 1/1/2011 | 1/23/1980 | 0 | 1/1/2011 | 1/23/1985 | 0 | 1/1/2011 | 1/23/1985 |     |
+-----------+----+----------+-----------+----+----------+-----------+---+----------+-----------+---+----------+-----------+-----+

2つのテーブルを結合するにはどうすればよいですか?速度は関係ありません!よろしくお願いします。

4

2 に答える 2

1

きれいではありませんが、元のクエリをそのままにして、すべてを1つの[大きな]ステートメントにまとめました。

;WITH 
PivotQuery as (
    select client_id,
       [1],[2],[3],[4],[5],[6],[7]
       from
       (   SELECT DISTINCT CLIENT_ID
       , PATIENT_ID
       , count(*) over (partition by client_id, patient_id) AS patientcount

       from f_accession_daily) as SourceTable
       PIVOT
       (
       count(patient_id)
       for patientcount in ([1],[2],[3],[4],[5],[6],[7])
       ) as pivottable),

MinMaxTimes as (
    SELECT a.client_id AS client_id
    ,a.patientcount TimesTested
       , count(a.patientcount)/a.patientcount AS count
       , max(f.received_date) AS maxRecDate
       , min(f.received_date) AS minRecDate
    FROM
    (
       SELECT DISTINCT CLIENT_ID
       , PATIENT_ID
       , count(*) over (partition by client_id, patient_id) AS patientcount

       from f_accession_daily

    ) AS a
    JOIN F_ACCESSION_DAILY AS f ON a.CLIENT_ID = f.CLIENT_ID
       AND a.PATIENT_ID = f.PATIENT_ID

    GROUP BY a.CLIENT_ID, a.patientcount),

maxDates as (
SELECT client_id, [1] maxdate1, [2] maxdate2, [3] maxdate3, [4] maxdate4, [5] maxdate5, [6] maxdate6, [7] maxdate7
FROM MinMaxTimes t
PIVOT (max(maxRecDate)
for TimesTested IN ([1], [2], [3], [4], [5], [6], [7])
) as p),

minDates as (
SELECT client_id, [1] mindate1, [2] mindate2, [3] mindate3, [4] mindate4, [5] mindate5, [6] mindate6, [7] mindate7
FROM MinMaxTimes t
PIVOT (max(minRecDate)
for TimesTested IN ([1], [2], [3], [4], [5], [6], [7])
) as p)

SELECT p.client_id, 
    p.[1], max(maxdate1) maxdate1, max(mindate1) mindate1,
    p.[2], max(maxdate2) maxdate2, max(mindate2) mindate2,
    p.[3], max(maxdate3) maxdate3, max(mindate3) mindate3,
    p.[4], max(maxdate4) maxdate4, max(mindate4) mindate4,
    p.[5], max(maxdate5) maxdate5, max(mindate5) mindate5,
    p.[6], max(maxdate6) maxdate6, max(mindate6) mindate6,
    p.[7], max(maxdate7) maxdate7, max(mindate7) mindate7   
FROM PivotQuery p
LEFT OUTER JOIN maxDates a ON p.client_id = a.client_id
LEFT OUTER JOIN mindates i ON a.client_id = i.client_id
GROUP BY p.client_id, p.[1], p.[2], p.[3], p.[4], p.[5], p.[6], p.[7]
于 2012-10-19T18:59:05.920 に答える
1

2 つのクエリを結合する必要はありません。さらに、自己結合も使用する必要はありません。1 つのクエリで必要なすべてのデータを選択する方法を次に示します。

WITH counted AS (
  SELECT
    client_id,
    COUNT(*) AS TimesTested,
    MAX(received_date) AS maxdate,
    MIN(received_date) AS mindate
  FROM f_accession_daily
  GROUP BY
    client_id,
    patient_id
),
counted2 AS (
  SELECT
    client_id,
    TimesTested,
    CAST(COUNT(*) AS varchar(30)) AS count,
    CAST(MAX(maxdate) AS varchar(30)) AS maxdate,
    CAST(MIN(mindate) AS varchar(30)) AS mindate
  FROM counted
  GROUP BY
    client_id,
    TimesTested
),
unpivoted AS (
  SELECT
    client_id,
    ColumnName + CAST(TimesTested AS varchar(10)) AS ColumnName,
    ColumnValue
  FROM counted2
  UNPIVOT (
    ColumnValue FOR ColumnName IN (count, maxdate, mindate)
  ) u
),
pivoted AS (
  SELECT
    client_id,
    count1, maxdate1, mindate1,
    count2, maxdate2, mindate2,
    count3, maxdate3, mindate3,
    count4, maxdate4, mindate4,
    count5, maxdate5, mindate5,
    count6, maxdate6, mindate6,
    count7, maxdate7, mindate7
  FROM unpivoted
  PIVOT (
    MAX(ColumnValue) FOR ColumnName IN (
      count1, maxdate1, mindate1,
      count2, maxdate2, mindate2,
      count3, maxdate3, mindate3,
      count4, maxdate4, mindate4,
      count5, maxdate5, mindate5,
      count6, maxdate6, mindate6,
      count7, maxdate7, mindate7
    )
  ) p
)
SELECT *
FROM pivoted
;

これがどのように機能するかは次のとおりです。

  1. 最初の CTE ( counted) は、and によってデータをグループ化しclient_id、各グループpatient_idの行数、最大日付、および最小日付を計算します。

  2. 2 番目の CTE ( counted2) は、前の結果セットclient_idを行カウントを含む列 ( と呼ばれるTimesTested) でグループ化し、再び行をカウントして、グループごとの最大日付と最小日付を見つけます。生成された行セットは、質問の 2 番目のテーブルと似ていますが、それは違いcountますCOUNT(*)(最初のクエリで計算されるため)。さらに、集計結果はすべて文字列に変換され、ピボット解除の準備が整います。

  3. 次の CTEunpivotedは、上記のピボット解除を行い、次のような行セットを生成します。

    client_id  ColumnName  ColumnValue
    ---------  ----------  -----------
    211754     count1      97
    211754     maxdate1    1/1/2012
    211754     mindate1    1/23/1985
    211754     count1      14
    211754     maxdate1    1/1/2012
    211754     mindate1    1/23/1985
    ...
    
  4. 最後の CTEpivotedは、最後のステップを実行し、前の CTE の結果をピボットして、最終的に必要な出力を生成します。

于 2012-10-19T21:35:46.380 に答える