2016-10-07 10 views
0

ストアドプロシージャとして保存されるSQLクエリを作成します。このクエリは、XMLスクリプトによって呼び出されます。それは特定の形式でなければならず、値の列は1つしかありません。SQLクエリ - 複数の異なる合計を1つの列に入れます。

3つの異なる合計の結果を1つの列に別々の行で表示する必要があります。私はこれがどのように可能であるのか研究しておらず、現在値は3つの異なる '値'の列に出力されています。

クエリの目的は、特定の名前を持つSQLサーバー上のデータベースのサイズを表示することです。

クエリは現在、SQL Serverにクエリを実行しており、その名前に "@name"を含むデータベースを対象としています。ログファイルやオフラインデータベースを含むデータベースの合計サイズが表示されます。合計サイズが表示されていましたが、データベースファイルとログファイルの合計サイズを別々の行に別々の列に表示したい場合もあります。ここで

は私のクエリです:

declare 
    @name NVARCHAR(20) 
set 
    @name = 'H3' 

select 
    @name as Channel, 
    sum((a.size*8)/1024) Value, 
    SUM(CASE WHEN type_desc like 'ROWS' THEN (a.size*8)/1024 ELSE 0 END) Value, 
    SUM(CASE WHEN type_desc like 'LOG' THEN (a.size*8)/1024 ELSE 0 END) Value, 
    '1' as IsInt, 
    'MB' as Unit 
from 
    sys.databases b 
    left join sys.master_files a 
     on b.database_id = a.database_id 

where 
    b.name like '%'[email protected]+'%' 

出力が現在のようになります。私は、ディスプレイにそれをしたい

Channel Value Value Value IsInt Unit 
--------- ------- ------- ------ ------ ------ 
H3  140091 134737 5354 1  MB 

Channel Value IsInt Unit 
--------- ------- ------ ------ 
H3  140091 1  MB 
H3  134737 1  MB 
H3  5354 1  MB 

私は私のように、任意の助けをいただければ幸いです本当にこれに執着しています。 私は非常にSQLに新しいので、答えは明らかかもしれません。

これはたぶん、UNION ALLを使用して、2008年

+0

結果セットには常に1つのレコードが含まれますか? –

答えて

0

SQL Serverであり、あなたの問題を解決する3種類のクエリにクエリを分割しましたか?

declare @name NVARCHAR(20) 
set @name = 'H3' 

select 
@name as Channel, 
sum((a.size*8)/1024) Value, 
'1' as IsInt, 
'MB' as Unit 
from 
sys.databases b 
left join sys.master_files a on b.database_id = a.database_id 

where 
b.name like '%'[email protected]+'%' 

UNION ALL 

select 
@name as Channel, 
SUM(CASE WHEN type_desc like 'ROWS' THEN (a.size*8)/1024 ELSE 0 END) Value, 
'1' as IsInt, 
'MB' as Unit 
from 
sys.databases b 
left join sys.master_files a on b.database_id = a.database_id 

where 
b.name like '%'[email protected]+'%' 

UNION ALL 

select 
@name as Channel, 
SUM(CASE WHEN type_desc like 'LOG' THEN (a.size*8)/1024 ELSE 0 END) Value, 
'1' as IsInt, 
'MB' as Unit 
from 
sys.databases b 
left join sys.master_files a on b.database_id = a.database_id 

where 
b.name like '%'[email protected]+'%' 
+0

ありがとう!これは完全に機能しました。開始時に '@name'を宣言して設定するだけでした。以前は「UNION ALL」という言葉は聞いたことがありませんでしたが、仕事をしています。基本的には3つの出力テーブルを結合するか、3つのSELECT文を結合してテーブルを作成しますか? – Harnell

+0

@Harnellそれはうまくいった。 UNION ALLは、SELECTステートメントの結果を単に結合します。 UNION ALLを使用するには、各問合せの列数が同じでなければならないことに注意してください。 UNIONも似ていますが、重複する行を除外します。 – VDK

1

結果を作成し、UNION ALLを使用して結合するCTEを使用してください。ピボット/アンピボットを使用して

declare @name NVARCHAR(20) 
set @name = 'H3' 

;with cte_1 
as 
(select 
    @name as Channel, 
    sum((a.size*8)/1024) Value1, 
    SUM(CASE WHEN type_desc like 'ROWS' THEN (a.size*8)/1024 ELSE 0 END) Value2, 
    SUM(CASE WHEN type_desc like 'LOG' THEN (a.size*8)/1024 ELSE 0 END) Value3, 
    '1' as IsInt, 
    'MB' as Unit 
from 
    sys.databases b 
    left join sys.master_files a 
     on b.database_id = a.database_id 
where 
    b.name like '%'[email protected]+'%') 
SELECT Channel,Value1 Value,IsInt,Unit 
FROM cte_1 
UNION ALL 
SELECT Channel,Value2,IsInt,Unit 
FROM cte_1 
UNION ALL 
SELECT Channel,Value3,IsInt,Unit 
FROM cte_1 
+0

結果は整理されるべきだと思います。 –

+0

@TimBiegeleisen与えられたサンプルごとに、Outputは列の値を行に変換するだけでよい。 –

0

  declare 
       @name NVARCHAR(20) 
      set 
       @name = 'H3' 

       select Channel , Value ,IsInt ,Unit from 
          (
      select 
       @name as Channel, 
       sum((a.size*8)/1024) Value0, 
       SUM(CASE WHEN type_desc like 'ROWS' THEN (a.size*8)/1024 ELSE 0 END) Value1, 
       SUM(CASE WHEN type_desc like 'LOG' THEN (a.size*8)/1024 ELSE 0 END) Value2, 
       '1' as IsInt, 
       'MB' as Unit    
       from 
       sys.databases b 
       left join sys.master_files a 
       on b.database_id = a.database_id 
       where b.name like '%'[email protected]+'%' 

          ) as xx 
           unpivot 
           (
       Value for col in (Value0,Value1,value2) 
      )aaa 

を私たちはあなたがどんなconcenrsを持っている場合、あなたが必要なもの

1

があなたの結果をアンピボットすることで教えてください。それを行うにはさまざまな方法があります。最も一般的な方法は、UNION ALLメソッドまたはUNPIVOTメソッドを使用できます。しかし、通常より早くこれらの2以上である別の方法があり、CROSS APPLY方法:

DECLARE @name nvarchar(20) 
SET @name = 'H3'; 

WITH Cte(Channel, TotalValue, RowsValue, LogsValue, IsInt, Unit) AS(
    SELECT 
     @name AS Channel, 
     SUM((a.size * 8)/1024) Value, 
     SUM(CASE WHEN type_desc LIKE 'ROWS' THEN (a.size * 8)/1024 ELSE 0 END) AS Value, 
     SUM(CASE WHEN type_desc LIKE 'LOG' THEN (a.size * 8)/1024 ELSE 0 END) AS Value, 
     '1' AS IsInt, 
     'MB' AS Unit 
    FROM sys.databases b 
    LEFT JOIN sys.master_files a 
     ON b.database_id = a.database_id 

    WHERE b.name LIKE '%' + @name + '%' 
) 
SELECT 
    c.Channel, 
    t.value, 
    c.IsInt, 
    c.Unit 
FROM Cte c 
CROSS APPLY (VALUES 
    (c.TotalValue), (c.RowsValue), (c.LogsValue) 
) t(value) 

ここでは、アンピボットするさまざまな方法を比較するDwainキャンプの記事です:


VALUESに別の列を簡単に追加して、よりわかりやすいようにすることができますChannel

DECLARE @name nvarchar(20) 
SET @name = 'H3'; 

WITH Cte(Channel, TotalValue, RowsValue, LogsValue, IsInt, Unit) AS(
    SELECT 
     @name AS Channel, 
     SUM((a.size * 8)/1024) Value, 
     SUM(CASE WHEN type_desc LIKE 'ROWS' THEN (a.size * 8)/1024 ELSE 0 END) AS Value, 
     SUM(CASE WHEN type_desc LIKE 'LOG' THEN (a.size * 8)/1024 ELSE 0 END) AS Value, 
     '1' AS IsInt, 
     'MB' AS Unit 
    FROM sys.databases b 
    LEFT JOIN sys.master_files a 
     ON b.database_id = a.database_id 

    WHERE b.name LIKE '%' + @name + '%' 
) 
SELECT 
    c.Channel + ' ' + name AS Channel, 
    t.value, 
    c.IsInt, 
    c.Unit 
FROM Cte c 
CROSS APPLY (VALUES 
    ('Total', c.TotalValue), 
    ('Rows', c.RowsValue), 
    ('Logs', c.LogsValue) 
) t(name, value) 
+0

このメソッドもうまくいきます。ありがとうございます。私はそれがUNION ALLよりも速いのであればそれを使うべきだと思いますか? – Harnell

+0

はい、記事ごとに、2つより優れています。 –

+0

'UNION ALL'では、チャンネル列の名前を 'H3 Total'、 'H3 Databases'、 'H3 Log Files'に変更しました。私は3つの異なるselect文があるのでこれを簡単に行うことができるので、 "@name + 'Databases'をChannelとして編集するだけです。"クロス・アプライを使用してこれを行うにはどうすればよいですか? – Harnell

関連する問題