Frage

Ich bin mit SQL Server 2005. Mit der Abfrage unten (vereinfachte aus meiner realen Abfrage):

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

Gibt es eine Möglichkeit, eine Zählung deutliche, ohne sie

zu tun

"Achtung: Nullwert durch ein Aggregat oder andere SET-Operation beseitigt wird"

Hier sind die Alternativen, die ich mir vorstellen kann:

  1. Drehen ANSI_WARNINGS off
  2. Die Trennung in zwei Abfragen, eines mit Zählung verschieden und eine where-Klausel nulls zu beseitigen, eine mit der Summe:

    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. Ignorieren Sie die Warnung im Client

Gibt es einen besseren Weg, dies zu tun? Ich werde wahrscheinlich nach unten gehen Route 2, aber nicht wie die Code-Duplizierung.

War es hilfreich?

Lösung

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

Dank Eoin ich einen Weg, dies zu tun ausgearbeitet. Sie können auch die NULL-Werte unterschiedliche Werte zählen und dann die Zählung entfernen aufgrund Nullen, wenn es deutliche jede mit einer Summe waren.

Andere Tipps

Überall haben Sie eine Null möglicherweise zurückgegeben, verwenden Sie

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

Das wird sub out alle Nullwerte für -1 für die Dauer der Abfrage und sie werden als solche gezählt / aggregiert werden, dann können Sie tun genau das Gegenteil in Ihrer feinen Verpackung Abfrage ...

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

Dies ist eine späte Kenntnis, aber es war die Rückkehr auf Google zu sein, wollte ich es erwähnen.

Ändern NULL auf einem anderen Wert ist eine schlechte Idee (tm).

COUNT () tut es, nicht DISTINCT.

Verwenden Sie stattdessen DISTINCT in einer Unterabfrage und die gibt eine Zahl zurück, und aggregieren, dass in der äußeren Abfrage.

Ein einfaches Beispiel hierfür ist:

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

Dies ermöglicht COUNT(*) verwendet werden, die NULL-Werte nicht ignorieren (weil es Aufzeichnungen zählt, nicht Werte).

Wenn Sie nicht wie die Code-Duplizierung, warum dann nicht einen gemeinsamen Tabellenausdruck verwenden? z.B.

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top