سؤال

لدي بضع طاولات تبدو وكأنها هذا الجدول 1

user_id   |  name
-------------------------   
x111      |   Smith, James
x112      |   Smith, Jane

إلخ..

الجدول 2

id    |   code    |    date       |  incident_code    | user_id
-----------------------------------------------------------------
1     |    102008 |   10/20/2008  |    1              | x111
2     |    113008 |   11/30/2008  |    3              | x111
3     |    102008 |   10/20/2008  |    2              | x112
4     |    113008 |   11/30/2008  |    5              | x112 

ما أود عرضه هو شيء مثل هذا

user_id     |    user_name    |   INCIDENT IN OCT 2008   | INCIDENT IN NOV 2008
------------------------------------------------------------------------------ 
x111        |    Smith, John  |   1                      | 3
x112        |    Smith, Jane  |   2                      | 5

إلخ..

سيتم استبدال الحيازة_Code بالوصف الفعلي للحادث الذي يقع في طاولة أخرى، لكنني اعتقدت أنني سأرى كيف سيعمل هذا أولا.

سيكون بعض رؤوس الأعمدة ثابتة بينما سيتم إنشاء آخرين بناء على التاريخ. هل يعرف أحد أحدا كيف يمكنني القيام بذلك باستخدام SQL Server 2005؟ بعض الأمثلة ستكون مفيدة للغاية.

شكرا مقدما

هل كانت مفيدة؟

المحلول

إليك حل ينشئ ويدير SQL الديناميكي مع Pivot:

DECLARE @pivot_list AS VARCHAR(MAX)

--
;
WITH    cols
          AS ( SELECT DISTINCT
                        'INCIDENT IN ' + LEFT(UPPER(CONVERT(VARCHAR, [date], 107)),
                                              3) + ' '
                        + SUBSTRING(UPPER(CONVERT(VARCHAR, [date], 107)), 9, 4) AS col
               FROM     so926209_2
             )
    SELECT  @pivot_list = COALESCE(@pivot_list + ', ', '') + '[' + col + ']'
    FROM    cols

--
DECLARE @template AS VARCHAR(MAX)
SET @template = 'WITH incidents AS (
SELECT  [user_id],
        incident_code,
        ''INCIDENT IN '' + LEFT(UPPER(CONVERT(VARCHAR, [date], 107)), 3)
        + '' '' + SUBSTRING(UPPER(CONVERT(VARCHAR, [date], 107)), 9, 4) AS col
FROM    so926209_2
)
,results AS (
SELECT * FROM incidents PIVOT (MAX(incident_code) FOR col IN ({@pivot_list})) AS pvt
)
SELECT results.[user_id]
    ,so926209_1.[name]
    ,{@select_list}
FROM results INNER JOIN so926209_1 ON so926209_1.[user_id] = results.[user_id]
'

DECLARE @sql AS VARCHAR(MAX)
SET @sql = REPLACE(REPLACE(@template, '{@pivot_list}', @pivot_list), '{@select_list}', @pivot_list)

--PRINT @sql
EXEC (@sql)

أين so926209_1, so926209_2 هي طاولتك 1 والجدول 2

لاحظ أنه إذا كان لديك حوادث متعددة في شهر واحد لنفس الشخص، فإن مثالك لا يظهر كيف تريد معالجة ذلك. يأخذ هذا المثال فقط الحادث الأخير في الشهر.

نصائح أخرى

هذا يبدو وكأنه مهمة إعداد التقارير. الإبلاغ، المشار إليه، المشار إليه في كثير من الأحيان من منظور قاعدة البيانات كليا، معالجة Aanalytical عبر الإنترنت، يميل إلى الاختلاف بشكل متكرر من الوصول إلى قاعدة البيانات "التقليدية"، OLTP (معالجة المعاملات عبر الإنترنت) في ذلك، غالبا ما تتكون في كثير من الأحيان من مجموعات كبيرة من البيانات التي تمتد فترات أكبر من الوقت. في كثير من الأحيان، نوع التجميع الخاص بك تبحث عنه.

استخدام محور ك Tetraneutron المقترح سيكون كافيا لمجموعات البيانات الأصغر. ومع ذلك، مثل حجم البيانات التي تحتاج إلى الإبلاغ عن النمو، قد تحتاج إلى شيء أكثر تقدما. يتم توفير OLAP من قبل SQL Server Analysis Services (SSAs)، متوفرة في عامي 2005 و 2005. باستخدام SSAs، يمكنك إنشاء مستودعات بيانات متعددة الأبعاد تم إكمالها مسبقا من قاعدة بيانات OLTP مباشرة، أو من قاعدة بيانات مستودع بيانات وسيطة. توفر بيانات متعددة الأبعاد (يشار إليها عادة كمكعبات) طريقة أسرع بكثير للوصول إلى نوع البيانات التي يمكنك الحصول عليها من محور، دون التدخل في أداء معالجة المعاملات القياسية الخاصة بك في قاعدة بيانات OLTP الخاصة بك.

إذا كان لديك أكثر من كمية صغيرة من البيانات، فأنت بحاجة إلى الإبلاغ عنها، أوصي بإجراء فحص SQL Server Analysis Services 2005، أو OLAP، والمكعبات، و MDX (ملحقات متعددة الأبعاد ل T-SQL.) هناك منحنى تعلم أكبر لتعيين حتى مكعب OLAP، ولكن بمجرد إعداده، يمكن أن تكون فوائد وجود المرء ضخما إذا كان لديك احتياجات تقارير كبيرة.

استعلام مثل هذا سيعمل:

select
    u.User_id,
    u.Name,
    Okt2008Sum = sum(case when i.date between 
        '2008-10-01' and '2008-11-01' then 1 else 0 end),
    Nov2008Sum = sum(case when i.date between 
        '2008-11-01' and '2008-12-01'then 1 else 0 end)
from #incidents i
inner join #users u on i.user_id = u.user_id
group by u.user_id, u.name

اعتمادا على عميلك وعدد المرات التي يجب عليك تشغيلها، يمكنك إنشاء هذا الاستعلام. في SQL هذا سيظهر:

create table #months (
    MonthName varchar(25),
    StartDate datetime
)

insert into #months values ('Okt2008','2008-10-01')
insert into #months values ('Nov2008','2008-11-01')

declare @query varchar(8000)
select @query = 'select u.User_id, u.Name '

select @query = @query + ', ' + MonthName + 
    ' = sum(case when i.date between ''' + cast(StartDate as varchar) + 
    ''' and ''' + cast(dateadd(m,1,StartDate) as varchar) + 
    ''' then 1 else 0 end) '
from #Months

select @query = @query + '
    from #incidents i
    inner join #users u on i.user_id = u.user_id
    group by u.user_id, u.name'

exec (@query)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top