it-swarm.asia

اختبار إذا كان أي أعمدة فارغة

أحاول معرفة استعلام سهل يمكنني القيام به لاختبار ما إذا كان الجدول الكبير يحتوي على قائمة الإدخالات التي تحتوي على قيمة فارغة واحدة على الأقل (فارغة/فارغة) في أي عمود.

أنا بحاجة إلى شيء مثل

SELECT * FROM table AS t WHERE ANY(t.* IS NULL)

لا أريد أن أفعل

SELECT * FROM table AS t WHERE t.c1 = NULL OR t.c2 = NULL OR t.c3 = NULL

سيكون هذا استعلام ضخم.

16
Dexter

امتداد لإجابة @ db2 بأقل تشاحن يدوي (: قراءة: صفر):

DECLARE @tb nvarchar(512) = N'dbo.[table]';

DECLARE @sql nvarchar(max) = N'SELECT * FROM ' + @tb
    + ' WHERE 1 = 0';

SELECT @sql += N' OR ' + QUOTENAME(name) + ' IS NULL'
    FROM sys.columns 
    WHERE [object_id] = OBJECT_ID(@tb);

EXEC sys.sp_executesql @sql;
16
Aaron Bertrand

يجب عليك سرد جميع الأعمدة حسب تعليق JNK.

WHERE c1 IS NULL OR c2 IS NULL OR c3 IS NULL

ومع ذلك ، هناك نهج أقل كفاءة إلى حد ما يتجنب هذا.

;WITH xmlnamespaces('http://www.w3.org/2001/XMLSchema-instance' AS ns) 
SELECT * 
FROM   YourTable AS T1 
WHERE (
    SELECT T1.* 
    FOR XML PATH('row'), ELEMENTS XSINIL, TYPE
  ).exist('//*/@ns:nil') = 1 

(بناءً على هذا SO الجواب)

8
Martin Smith

لا يوجد بناء جميل في نيس ، لكن Management Studio يحتوي على ميزتين مناسبتين لإنشاء الاستعلام بسرعة.

في Object Explorer ، انتقل لأسفل إلى الجدول الذي تريده ، وقم بتوسيعه ، ثم اسحب مجلد "الأعمدة" بالكامل إلى محرر استعلامات فارغ. سيؤدي ذلك إلى إضافة قائمة أعمدة مفصولة بفواصل إلى الاستعلام.

بعد ذلك ، افتح Find And Replace. أضبط "Find What" على , وضبط "استبدال بـ" على IS NULL OR (بمسافة بادئة) ثم اضغط على "استبدال الكل". سيكون عليك تنظيف آخر واحد في التسلسل يدويًا.

لا تزال قبيحة ، لكنها أقل كثافة في العمالة.

5
db2

حلول متعددة لـ: بعض القيم الخالية ، وجميع القيم الخالية ، والأعمدة الفردية والمتعددة بالإضافة إلى جعلها سريعة باستخدام Top 1

إذا كنت بحاجة إلى اختبار أعمدة متعددة ، فيمكنك استخدام ما يلي:

Column_1 Column_2 Column_3
-------- -------- --------
1        2        NULL
1        NULL     NULL
5        6        NULL

أولاً ، اختبار للقيم الخالية واحتسابها:

select 
    sum(case when Column_1 is null then 1 else 0 end) as Column_1, 
    sum(case when Column_2 is null then 1 else 0 end) as Column_2, 
    sum(case when Column_3 is null then 1 else 0 end) as Column_3,
from TestTable 

ينتج عددًا من القيم الخالية:

Column_1  Column_2  Column_3
0         1         3

حيث تكون النتيجة 0 ، لا توجد فارغة.

ثاني ، لنحسب غير NULLs:

select 
    sum(case when Column_1 is null then 0 else 1 end) as Column_1, 
    sum(case when Column_2 is null then 0 else 1 end) as Column_2, 
    sum(case when Column_3 is null then 0 else 1 end) as Column_3,
from TestTable

... ولكن نظرًا لأننا نحسب غير NULLs هنا ، يمكن تبسيط ذلك إلى:

select 
    count(Column_1) as Column_1, 
    count(Column_2) as Column_2, 
    count(Column_3) as Column_3,
from TestTable

ينتج أحدهما:

Column_1  Column_2  Column_3
3         2         0

عندما تكون النتيجة 0 ، يتكون العمود بالكامل من NULLs.

أخيرًا ، إذا كنت تحتاج فقط إلى التحقق من عمود معين ، فإن TOP 1 يكون أسرع لأنه يجب أن يتوقف عند أول نتيجة. يمكنك بعد ذلك استخدام العد (*) اختياريًا لإعطاء نتيجة نمط منطقي:

select top 1 'There is at least one NULL' from TestTable where Column_3 is NULL

select count(*) from (select top 1 'There is at least one NULL' AS note from TestTable where Column_3 is NULL) a

0 = لا يوجد NULLs ، 1 = لا يوجد NULL واحد على الأقل

أو

select top 1 'There is at least one non-NULL' AS note from TestTable where Column_3 is not NULL

select count(*) from (select top 1 'There is at least one non-NULL' AS note from TestTable where Column_3 is not NULL) a

0 = جميعها خالية ، 1 = يوجد واحد على الأقل غير فارغ

آمل أن يساعد هذا.

4
jwolf

UNPIVOT يترجم الأعمدة إلى صفوف. في العملية يلغي القيم الخالية ( مرجع ).

بالنظر إلى المدخلات

create table #t
(
    ID  int primary key,
    c1  int null,
    c2  int null
);

insert #t(id, c1, c2)
values
    (1, 12, 13),
    (2, null, 14),
    (3, 15, null),
    (4, null, null);

استعلام UNPIVOT

select
    ID, ColName, ColValue
from
(
    select *
    from #t
) as p
unpivot
(
    ColValue for ColName in
    (c1, c2)                  -- explicit source column names required
) as unpvt;

سوف ينتج الناتج

| ID | ColName | ColValue |
|----|---------|----------|
| 1  | c1      | 12       |
| 1  | c2      | 13       |
| 2  | c2      | 14       |
| 3  | c1      | 15       |

للأسف تم التخلص من الصف 4 تمامًا نظرًا لأنه لا يحتوي إلا على القيم الخالية! يمكن إعادة تقديمه بسهولة عن طريق إدخال قيمة وهمية في استعلام المصدر:

select
    ID, ColName, ColValue
from
(
    select
        -5 as dummy,               -- injected here, -5 is arbitrary
        *
    from #t
) as p
unpivot
(
    ColValue for ColName in
    (dummy, c1, c2)                -- referenced here
) as unpvt;

من خلال تجميع الصفوف في ID ، يمكننا حساب القيم غير الفارغة. ستحدد مقارنة إجمالي عدد الأعمدة في الجدول المصدر الصفوف التي تحتوي على واحد أو أكثر من القيم الخالية.

select
    ID
from
(
    select -5 as dummy, *
    from #t
) as p
unpivot
(
    ColValue for ColName in
    (dummy, c1, c2)
) as unpvt
group by ID
having COUNT(*) <> 3;

أحسب 3 ك
عدد الأعمدة في جدول المصدر #t
+ 1 للعمود الوهمي المحقون
- 1 للمعرف ، وهو غير محوَّل

يمكن الحصول على هذه القيمة في وقت التشغيل من خلال فحص جداول الكتالوج.

يمكن استرداد الصفوف الأصلية من خلال الانضمام إلى النتائج.

إذا كان سيتم التحقيق في القيم بخلاف NULL ، فيمكن تضمينها في بند حيث:

...
) as unpvt
where ColValue <> ''      -- will eliminate empty strings

نقاش

ويتطلب هذا معرفًا يتم نقله من خلال UNPIVOT. سيكون المفتاح هو الأفضل. في حالة عدم وجود أي شيء ، يمكن إدخاله بواسطة وظيفة النافذة ROW_NUMBER () ، على الرغم من أن هذا قد يكون مكلفًا للتنفيذ.

يجب إدراج جميع الأعمدة بشكل صريح داخل عبارة UNPIVOT. يمكن سحبها باستخدام SSMS ، كما اقترح @ db2. لن تكون ديناميكية عندما يكون تعريف الجدول chagnes ، كما سيكون اقتراح آرون برتراند. هذا هو الحال بالنسبة لكل SQL تقريبًا.

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

2
Michael Green