سؤال

أنا أستخدم SQL Server 2005.باستخدام الاستعلام أدناه (مبسط من استعلامي الحقيقي):

select a,count(distinct b),sum(a) from 
(select 1 a,1 b union all
select 2,2 union all
select 2,null union all
select 3,3 union all
select 3,null union all
select 3,null) a
group by a

هل هناك أي طريقة للقيام بالعد المميز دون الحصول على

"تحذير:يتم التخلص من القيمة الخالية بواسطة عملية SET مجمعة أو أخرى."

فيما يلي البدائل التي يمكنني التفكير فيها:

  1. جارٍ إيقاف تشغيل ANSI_WARNINGS
  2. يتم الفصل إلى استعلامين، أحدهما يحتوي على عدد مميز وعبارة "حيث" لإزالة القيم الخالية، والآخر يحتوي على المجموع:

    select t1.a, t1.countdistinctb, t2.suma from
    (
        select a,count(distinct b) countdistinctb from 
        (
            select 1 a,1 b union all
            select 2,2 union all
            select 2,null union all
            select 3,3 union all
            select 3,null union all
            select 3,null
        ) a
        where a.b is not null
        group by a
    ) t1
    left join
    (
        select a,sum(a) suma from 
        (
            select 1 a,1 b union all
            select 2,2 union all
            select 2,null union all
            select 3,3 union all
            select 3,null union all
            select 3,null
        ) a
        group by a
    ) t2 on t1.a=t2.a
    
  3. تجاهل التحذير في العميل

هل هناك طريقة أفضل للقيام بذلك؟من المحتمل أن أسلك الطريق 2، لكن لا أحب تكرار الكود.

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

المحلول

select a,count(distinct isnull(b,-1))-sum(distinct case when b is null then 1 else 0 end),sum(a) from 
    (select 1 a,1 b union all
    select 2,2 union all
    select 2,null union all
    select 3,3 union all
    select 3,null union all
    select 3,null) a
    group by a

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

نصائح أخرى

من المحتمل أن يتم إرجاع قيمة فارغة في أي مكان، استخدم

CASE WHEN Column IS NULL THEN -1 ELSE Column END AS Column

سيؤدي ذلك إلى استبعاد جميع القيم الخالية الخاصة بك لـ -1 طوال مدة الاستعلام وسيتم حسابها/تجميعها على هذا النحو، ثم يمكنك القيام بالعكس في استعلام الالتفاف الدقيق الخاص بك...

SELECT  
    CASE WHEN t1.a = -1 THEN NULL ELSE t1.a END as a
    , t1.countdistinctb
    , t2.suma

هذه ملاحظة متأخرة، ولكن بما أنها كانت بمثابة العائد على Google، فقد أردت أن أذكرها.

يعد تغيير NULL إلى قيمة أخرى فكرة سيئة (tm).

COUNT() يقوم بذلك، وليس DISTINCT.

بدلاً من ذلك، استخدم DISTINCT في استعلام فرعي والذي يقوم بإرجاع رقم، ثم قم بتجميع ذلك في الاستعلام الخارجي.

مثال بسيط على ذلك هو:

WITH A(A) AS (SELECT NULL UNION ALL SELECT NULL UNION ALL SELECT 1)
SELECT COUNT(*) FROM (SELECT DISTINCT A FROM A) B;

وهذا يسمح ل COUNT(*) لاستخدامها، والتي لا تتجاهل القيم الخالية (لأنها تحسب السجلات، وليس القيم).

إذا كنت لا تحب تكرار التعليمات البرمجية، فلماذا لا تستخدم تعبير جدول شائع؟على سبيل المثال

WITH x(a, b) AS 
        (
                select 1 a,1 b union all
                select 2,2 union all
                select 2,null union all
                select 3,3 union all
                select 3,null union all
                select 3,null
        ) 
select t1.a, t1.countdistinctb, t2.suma from
(
        select a,count(distinct b) countdistinctb from 
        x a
        where a.b is not null
        group by a
) t1
left join
(
        select a,sum(a) suma from 
        x a
        group by a
) t2 on t1.a=t2.a
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top