2017-10-24 8 views
1

現在、数十のSELECT文を結合したスクリプトがあり、そのうち2つの例と結果の例を以下に示します。以下複数のSELECT文をPIVOTでフォーマットする

DECLARE @Age TABLE (name VARCHAR(30), total FLOAT, percentage FLOAT) 

INSERT INTO @Age 
    SELECT '0-18', (SELECT COUNT(*) FROM tblPerson p 
       INNER JOIN tblClient c ON c.intPersonID = p.intPersonID 
       WHERE ISNULL(dbo.fncReportClient_Age(p.dteBirthdate, GETDATE()), '') >= 0 AND ISNULL(dbo.fncReportClient_Age(p.dteBirthdate, GETDATE()), '') <= 18), '' 

UPDATE @Age 
    SET percentage = ROUND((SELECT total FROM @Age WHERE name = '0-18')/(SELECT SUM(total) FROM @Age) * 100, 2) 
    FROM @Age 
    WHERE name = '0-18' 
Etc. 


SELECT 
    g.nvhGenderName, 
    COUNT(*), 
     ROUND(COUNT(*) * 1.0/SUM(COUNT(*)) OVER() * 100, 2) 
FROM 
    tblClient c 
    LEFT JOIN tblPerson p ON p.intPersonID = c.intPersonID 
    LEFT JOIN tblGender g ON g.intGenderID = p.intGenderID 
GROUP BY g.nvhGenderName 

UNION ALL 

SELECT * FROM @Age 

結果の例:

Name | Total |  % | 
--------------------------------- 
Male | 6514 | 60.32 | 
Female | 4285 | 39.68 | 
0-18 | 279  | 1.58 | 
19-24 | 1748 | 9.93 | 
25-34 | 5423 | 30.80 | 
35-64 | 9546 | 54.21 | 
65+  | 614  | 3.50 | 

私が垂直とは対照的に、水平に、これらの結果を表示したいと思い、私はPIVOTでこれを行うことは可能だと思いますが、実際にそれらを使用したことがありません。私は、データが表示されるようにする方法の例を以下に示します。

Gender | Total | % | Age  | Total | % | 
------------------------------------------------------------- 
Male | 6514 | 60.32 | 0-18 | 279 | 1.58 | 
Female | 4285 | 39.68 | 19-24 | 1748 | 9.93 | 
     |   |  | 25-34 | 5423 | 30.80 | 
     |   |  | 35-64 | 9546 | 54.21 | 
     |   |  | 65+  | 614 | 3.50 |         

特に、私は複数のそれを必要とする(12)SELECTステートメントを結合するためにピボットを使用するかどうかはわかりませんよ。

これをどのようにフォーマットするかについての助力は、非常に高く評価されます。

+1

あなたが達成しようとしている何をちょうど一緒に「糊付け」しているだけで2ピボット結果セット、性別上の1つと年齢上の1つ、です。これがあなたがデータを提示する方法であると確信していますか?もしそうなら、おそらく、2つのクエリ結果をビジュアライゼーションエンジンに配信し、そこに組み合わせる方が良いでしょうか? –

+0

SQLは "プレゼンテーション"用に設計されていません(特に "pretty prsentation")。このレポートをどのようにユーザーに配信しますか? HTMLで? PHPを使用して? (もしそうなら、PHP/HTMLでこれを使用してください) –

答えて

0

実際にのレイアウトがになるはずですが、次のような場合があります。明らかに、私はテストの恩恵なしに、それをテストすることはできませんここに行く:

WITH myCTE AS (
     SELECT 
      COUNT(CASE WHEN oa.age >= 0 AND oa.age < 19 THEN p.intPersonID ELSE NULL END) c0019 
      , COUNT(CASE WHEN oa.age >= 19 AND oa.age < 25 THEN p.intPersonID ELSE NULL END) c1925 
      , COUNT(CASE WHEN oa.age >= 25 AND oa.age < 35 THEN p.intPersonID ELSE NULL END) c2535 
      , COUNT(CASE WHEN oa.age >= 35 AND oa.age < 65 THEN p.intPersonID ELSE NULL END) c3565 
      , COUNT(CASE WHEN oa.age >= 65     THEN p.intPersonID ELSE NULL END) c65on 
      , COUNT(CASE WHEN g.nvhGenderName = 'Male'  THEN p.intPersonID ELSE NULL END) cmale 
      , COUNT(CASE WHEN g.nvhGenderName = 'Female' THEN p.intPersonID ELSE NULL END) cfemale 
      , COUNT(*) ctotal 
     FROM tblClient c 
     LEFT JOIN tblPerson p ON p.intPersonID = c.intPersonID 
     OUTER APPLY (
      SELECT 
        dbo.fncReportClient_Age(p.dteBirthdate) AS age 
      ) AS oa 
     LEFT JOIN tblGender g ON g.intGenderID = p.intGenderID 
    ) 
SELECT 
     ca.Gender, ca.Total2, ca.Pct, ca.Age, ca.Total2, ca.Pct2 
FROM myCTE 
CROSS APPLY (
     VALUES 
      (1, 'Male' , t.cmale , (cmale * 100.0/ctotal), '0-18', c0019, (c0019 * 100.0/ctotal)) 
     , (2, 'Female',t.cfemale,(cfemale * 100.0/ctotal), '19-24', c1925, (c1925 * 100.0/ctotal)) 
     , (3, NULL,NULL,NULL, '25-34', c2535, (c2535 * 100.0/ctotal)) 
     , (4, NULL,NULL,NULL, '35-64', c3565, (c3565 * 100.0/ctotal)) 
     , (5, NULL,NULL,NULL, '65+' , c65on, (c65on * 100.0/ctotal)) 
    ) AS ca (rn, Gender, Total2, Pct, Age, Total2, Pct2) 
ORDER BY ca.rn 
;  

クエリの(下)第二部は、上記valuescross applyを兼ね備えunpivotingデータのための技術を使用しており、これは私たちが「レイアウトすることができます希望する最終結果の各行を行ごとに並べ替えます。 CTE(上記のクエリの上部)を使用して

は不可欠、それは代わりに、サブクエリの中に移動することができませんが、CTE内部クエリが最初のスタンドアロンを試されるべきであり、それはあなたが必要とするすべての番号を生成する必要がありますデータの1回のパスで(ジェンダー・テーブルがカウント結果を妨害しないと仮定して) count(case expression here)を使用すると、複数の別々のクエリが不要になります。私は途中で左結合を必要としないと思っています。もしそうであれば、外側適用をクロス適用に変更することもできます。 apply関数は関数を実行するために使用され、残りのクエリ(私はそのエイリアスとして "age"を使用した)でエイリアスによってその関数の結果を参照することができます。

私は人テーブルを数えるときにクライアントテーブルを使用する理由がわかりません。私はそれが必要ではないと思う。私の疑惑が正しい場合はCTEの詳細は、この置き換えることができ:

SELECT 
     COUNT(CASE WHEN oa.age >= 0 AND oa.age < 19 THEN 1 ELSE NULL END) c0019 
     , COUNT(CASE WHEN oa.age >= 19 AND oa.age < 25 THEN 1 ELSE NULL END) c1925 
     , COUNT(CASE WHEN oa.age >= 25 AND oa.age < 35 THEN 1 ELSE NULL END) c2535 
     , COUNT(CASE WHEN oa.age >= 35 AND oa.age < 65 THEN 1 ELSE NULL END) c3565 
     , COUNT(CASE WHEN oa.age >= 65     THEN 1 ELSE NULL END) c65on 
     , COUNT(CASE WHEN g.nvhGenderName = 'Male'  THEN 1 ELSE NULL END) cmale 
     , COUNT(CASE WHEN g.nvhGenderName = 'Feale' THEN 1 ELSE NULL END) cfemale 
     , COUNT(*) ctotal 
    FROM tblPerson p 
    CROSS APPLY (
     SELECT 
       dbo.fncReportClient_Age(p.dteBirthdate) AS age 
     ) AS oa 
    INNER JOIN tblGender g ON g.intGenderID = p.intGenderID 
+0

ところで、この提案は "unpivotを使って単一のピボットクエリをフォーマットする"ので、質問のタイトルとは全く異なります:) –

+0

あなたの質問は今解決されましたか?あなたはまだこの答えについて質問がありますか? [help/accepting](https://stackoverflow.com/help/someone-answers)の詳細については、[** Click The Tick **](https://ibb.co/ikqyO6)を承認して回答する –

関連する問題