يتم حذف القيمة المميزة والقيمة الخالية بشكل إجمالي
-
21-08-2019 - |
سؤال
أنا أستخدم 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 مجمعة أو أخرى."
فيما يلي البدائل التي يمكنني التفكير فيها:
- جارٍ إيقاف تشغيل ANSI_WARNINGS
يتم الفصل إلى استعلامين، أحدهما يحتوي على عدد مميز وعبارة "حيث" لإزالة القيم الخالية، والآخر يحتوي على المجموع:
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
تجاهل التحذير في العميل
هل هناك طريقة أفضل للقيام بذلك؟من المحتمل أن أسلك الطريق 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