{
  "category": "Database functions",
  "display_name": "DSUM",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.DSUM",
  "implementation_state": {
    "answer_bank": null,
    "detail": "Recorded: 3 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 3 recorded answers",
    "workbook_corpus": {
      "cells": 3,
      "matched": 3
    }
  },
  "implementations": [
    {
      "commit": "9e1884369a678158dd82d3d74188daf986995e87",
      "flavour": "excel-compatibility-candidate",
      "language": "Rust",
      "name": "CalcFunc",
      "own_code": [
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/database.rs#L273-L273"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/aggregate::reader",
        "catalogue/aggregate::read_reference",
        "catalogue/comparison::numbers",
        "catalogue/comparison::in_band",
        "catalogue/comparison::Rounded::up",
        "catalogue/comparison::Roundings::of",
        "catalogue/comparison::Roundings::disjoint",
        "catalogue/comparison::texts",
        "catalogue/comparison/collation::compare",
        "catalogue/comparison/collation::weighed",
        "catalogue/comparison/collation::measured_iteration_extension",
        "catalogue/comparison/sort_key::table",
        "catalogue/comparison/sort_key::decode64",
        "catalogue/comparison/sort_key::Reader::byte",
        "catalogue/comparison/sort_key::Reader::varint",
        "catalogue/comparison/sort_key::Reader::done",
        "catalogue/comparison/sort_key::in_ranges",
        "catalogue/comparison/sort_key::build",
        "catalogue/comparison/sort_key::han_base",
        "catalogue/comparison/sort_key::derive",
        "catalogue/comparison/sort_key::shared_jamo_tails",
        "catalogue/comparison/sort_key::ordinary_jamo_prefix",
        "catalogue/comparison/sort_key::independent_jamo_suffix",
        "catalogue/comparison/sort_key::jamo_leading_primary",
        "catalogue/comparison/sort_key::leading_order",
        "catalogue/comparison/sort_key::Before::separate_special",
        "catalogue/comparison/sort_key::Gathered::kana",
        "catalogue/comparison/sort_key::Gathered::unit",
        "catalogue/comparison/sort_key::parts",
        "catalogue/comparison/sort_key::diacritic_order",
        "catalogue/comparison/sort_key::diacritics",
        "catalogue/conditional::range",
        "catalogue/conditional::row",
        "catalogue/conditional::offset",
        "catalogue/conditional::read_range",
        "catalogue/conditional::verdicts",
        "catalogue/conditional::used",
        "catalogue/conditional::Match::of",
        "catalogue/conditional::Match::negated",
        "catalogue/conditional::Op::holds",
        "catalogue/conditional::Op::is_equality",
        "catalogue/conditional::spells",
        "catalogue/conditional::criterion",
        "catalogue/conditional::database_criterion",
        "catalogue/conditional::rank",
        "catalogue/conditional::criterion_text",
        "catalogue/conditional::decided",
        "catalogue/conditional::Criterion::verdict",
        "catalogue/conditional::equality",
        "catalogue/conditional::is_surrogate",
        "catalogue/conditional::wildcard",
        "catalogue/database::label",
        "catalogue/database::same_label",
        "catalogue/database::field",
        "catalogue/database::matching",
        "catalogue/database::criterion_verdict",
        "catalogue/database::database",
        "catalogue/database::published",
        "decimal::low32",
        "decimal::Natural::from_u64",
        "decimal::Natural::pow10",
        "decimal::Natural::normalize",
        "decimal::Natural::is_zero",
        "decimal::Natural::mul_add_small",
        "decimal::Natural::times_pow10",
        "decimal::Natural::times_pow5",
        "decimal::Natural::times_pow2",
        "decimal::ExactDecimal::binary",
        "ported/excel_numeric::excel_sqrt_staged",
        "ported/text_kernels::text",
        "ported/text_kernels::text_from_str",
        "ported/text_kernels::fold_unit",
        "ported/text_kernels::push_singleton_or_original",
        "ported/text_kernels::push_lower",
        "ported/text_kernels::lower",
        "ported/variance_common::variance_from_values",
        "ported/variance_common::stdev_from_values"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/database.rs#L273-L273",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 3 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.DSUM.json",
  "name": "DSUM",
  "notes": [],
  "schema": "efh.function-reference/v1",
  "section_order": [
    "what-it-does",
    "try-it",
    "quirks",
    "how-to-implement",
    "version-differences",
    "alternatives"
  ],
  "sections": {
    "alternatives": "\n### Relationships\n\n\n- **Siblings**: the twelve database functions, sharing the selection mechanism and differing\n  only in the aggregate. [DCOUNT](FUNC.DCOUNT.md) counts what `DSUM` adds;\n  [DPRODUCT](FUNC.DPRODUCT.md) multiplies it; [DAVERAGE](FUNC.DAVERAGE.md) is `DSUM` over\n  `DCOUNT` except at the empty-selection boundary, where `DSUM` returns `0` and `DAVERAGE`\n  returns `#DIV/0!`.\n- **Nearest modern equivalent**: `SUMIFS` (and `SUMIF`), which take conditions as inline\n  arguments rather than as a worksheet-resident criteria table. Neither supersedes the other;\n  Excel supports both.\n- **Confused with**: `SUM` (no selection stage), `SUMPRODUCT` (often used to emulate criteria\n  arithmetically), and `SUBTOTAL`, which filters by hidden rows rather than by criteria.\n\n\n",
    "how-to-implement": "\n### Notes for implementers\n\n\n1. **Reduction order is observable.** The family declares a sequential left fold, so the\n   accumulation runs in record order. Pairwise or reassociated summation will differ in the last\n   bits on long or badly-scaled columns, and no compensated-summation scheme is implied.\n2. **Skip, do not coerce.** The scan admits only cells whose value kind is Number. Coercing\n   `\"3\"` to 3 here would change `DSUM`, `DCOUNT`, and `DAVERAGE` together and in the wrong\n   direction.\n3. **Numeric criteria comparison is not exact double comparison** — see the note in\n   [the shared mechanism](FUNC.DAVERAGE.md#numeric-comparison-is-not-exact-double-comparison).\n4. **The zero answer is load-bearing.** Returning an error for an empty selection would be a\n   different function; several of the siblings *do* error there, so a shared implementation must\n   branch on the aggregate rather than on the selection.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nReturns a Number.\n\n- **No record matches**: the sum of nothing is `0`. No error.\n- **Matching records whose field cells are all blank or all text**: also `0`, by the same route.\n  `DSUM` cannot distinguish \"nothing matched\" from \"everything that matched was empty\"; if you\n  need that distinction, pair it with [DCOUNT](FUNC.DCOUNT.md).\n- **Text that looks numeric in the field column** is skipped, not parsed. This is the range-scan\n  side of the asymmetry described in\n  [coercion and lifting](../model/02-coercion-and-lifting.md#direct-arguments-versus-range-scans).\n- **Logicals in the field column** are skipped.\n- **Arrays**: inline array literals are accepted wherever ranges are, since both resolve to a\n  grid. `DSUM` is not a lift kernel; array arguments are consumed whole.\n\n\n\n### Errors\n\n\n| Error | Condition |\n|---|---|\n| `#VALUE!` | *database* or *criteria* is not a grid or is empty; a database header cell is blank; a criteria header names no database field; *field* matches no header, or is a non-integer or out-of-range column index |\n| propagated | An error value in a header cell, a criteria cell, or a scanned field cell surfaces as that error |\n\n`DSUM` has no domain error of its own — no divisor, no minimum sample size. Every error it can\nreturn comes from argument shape, field resolution, or a propagated input error.\n\n",
    "sources": "- Microsoft, \"DSUM function\" —\n  <https://support.microsoft.com/en-us/office/dsum-function-53181285-0c4b-4f5a-aaa3-529a322be41b>\n- Handbook `CHARTER.md` sections 1, 3 and 7; `content/model/06-claim-language.md`.\n- Handbook call-model chapters 02 and 03 (range-scan coercion, error folding, reduction policy).\n- [DAVERAGE](FUNC.DAVERAGE.md) — the family's shared criteria-range mechanism.\n- `data/functions/FUNC.DSUM.json`, `data/presence/FUNC.DSUM.json`.\n\n",
    "version-differences": "No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.",
    "what-it-does": "\n`DSUM(database, field, criteria)` selects the records of *database* that satisfy *criteria*,\nreads the column named by *field*, and returns the sum of the numeric values found there.\n\nWith R the set of selected record rows, c the resolved field column, and\n\n    V = [ v : v = value of cell (r, c) for r in R, in record order, where v is a Number ]\n\nthe result is Σ V, summed as a left fold in record order. An empty V sums to 0 — `DSUM` has no\nempty-selection error, which is the main behavioural difference between it and\n[DAVERAGE](FUNC.DAVERAGE.md).\n\nNon-numeric cells in the field column contribute nothing: text (including text that reads as a\nnumber), logicals, and blanks are skipped rather than coerced to zero. The distinction matters\nbecause \"skipped\" and \"added as zero\" give the same total but different behaviour in the sibling\naggregates that count or divide.\n\nThe selection stage — how *criteria* picks records, how header matching works, what AND across a\nrow and OR down the rows mean, what a blank criteria cell means, and how a criteria expression\nis parsed — is identical for all twelve database functions and is explained once in\n[the criteria-range mechanism](FUNC.DAVERAGE.md#the-criteria-range-mechanism).\n\n\n\n### Arguments\n\n\nThree arguments, all required at the call site; the reference implementation declares an arity\nof exactly 3.\n\n- **`database`** — the header-plus-records range or array; the first row is the header row.\n- **`field`** — the column selector, as header text or as a 1-based column index *within the\n  database range*. Required for `DSUM`; only [DCOUNT](FUNC.DCOUNT.md) and\n  [DCOUNTA](FUNC.DCOUNTA.md) accept an omitted field.\n- **`criteria`** — the header-plus-conditions range or array.\n\nArgument roles and admissible values are the family's; see\n[the shared mechanism](FUNC.DAVERAGE.md#the-criteria-range-mechanism) for the full account,\nincluding the point that a criteria range with no condition rows, or with an all-blank condition\nrow, selects every record.\n\n\n"
  },
  "signature": {
    "display": "DSUM(database, field, criteria)",
    "parameters": [
      {
        "description": null,
        "name": "database",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "field",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "criteria",
        "optional": false,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 3,
        "min": 3
      },
      "category": "Database functions",
      "classification": {
        "arg_preparation_profile": "RefsVisibleInAdapter",
        "coercion_lift_profile": "Custom",
        "determinism_class": "Deterministic",
        "error_collapse_profile": "ReductionFold",
        "fec_dependency_profile": "RefOnly",
        "host_interaction_class": "None",
        "kernel_signature_class": "Custom",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "RefOnly",
        "thread_safety_class": "SafePure",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": "Total of a database column over the matching records",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Adds the numbers in the field column of records in the database that match the criteria",
        "microsoft_url": "https://support.microsoft.com/en-us/office/dsum-function-53181285-0c4b-4f5a-aaa3-529a322be41b"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "DSUM"
        },
        {
          "locale": "bg-BG",
          "name": "DSUM"
        },
        {
          "locale": "cs-CZ",
          "name": "DSUMA"
        },
        {
          "locale": "da-DK",
          "name": "DSUM"
        },
        {
          "locale": "de-DE",
          "name": "DSUM"
        },
        {
          "locale": "el-GR",
          "name": "DSUM"
        },
        {
          "locale": "en-AU",
          "name": "DSUM"
        },
        {
          "locale": "en-GB",
          "name": "DSUM"
        },
        {
          "locale": "en-US",
          "name": "DSUM"
        },
        {
          "locale": "es-ES",
          "name": "BDSUMA"
        },
        {
          "locale": "et-EE",
          "name": "DSUM"
        },
        {
          "locale": "fi-FI",
          "name": "TSUMMA"
        },
        {
          "locale": "fr-FR",
          "name": "BDSOMME*"
        },
        {
          "locale": "he-IL",
          "name": "DSUM"
        },
        {
          "locale": "hr-HR",
          "name": "DSUM"
        },
        {
          "locale": "hu-HU",
          "name": "AB.SZUM"
        },
        {
          "locale": "id-ID",
          "name": "DSUM"
        },
        {
          "locale": "it-IT",
          "name": "DSUM"
        },
        {
          "locale": "ja-JP",
          "name": "DSUM"
        },
        {
          "locale": "ko-KR",
          "name": "DSUM"
        },
        {
          "locale": "lt-LT",
          "name": "DSUM"
        },
        {
          "locale": "lv-LV",
          "name": "DSUM"
        },
        {
          "locale": "nb-NO",
          "name": "DSUM"
        },
        {
          "locale": "nl-NL",
          "name": "DBSOM"
        },
        {
          "locale": "pl-PL",
          "name": "BD.SUMA"
        },
        {
          "locale": "pt-BR",
          "name": "DSUM"
        },
        {
          "locale": "pt-PT",
          "name": "BDSOMA"
        },
        {
          "locale": "ro-RO",
          "name": "DSUM"
        },
        {
          "locale": "ru-RU",
          "name": "БДСУММ"
        },
        {
          "locale": "sk-SK",
          "name": "DSUM"
        },
        {
          "locale": "sl-SI",
          "name": "DSUM"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "DSUM"
        },
        {
          "locale": "sv-SE",
          "name": "DSUMMA"
        },
        {
          "locale": "th-TH",
          "name": "DSUM"
        },
        {
          "locale": "tr-TR",
          "name": "VSEÇTOPLA işlevi"
        },
        {
          "locale": "uk-UA",
          "name": "DSUM"
        },
        {
          "locale": "vi-VN",
          "name": "DSUM"
        },
        {
          "locale": "zh-CN",
          "name": "DSUM"
        },
        {
          "locale": "zh-HK",
          "name": "DSUM"
        },
        {
          "locale": "zh-TW",
          "name": "DSUM"
        }
      ],
      "signature": {
        "display": "DSUM(database, field, criteria)",
        "parameters": [
          {
            "description": null,
            "name": "database",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "field",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "criteria",
            "optional": false,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "DSUM",
      "version_marker": null,
      "xlcall": {
        "code": "41",
        "symbol": "xlfDsum"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/dsum-function-53181285-0c4b-4f5a-aaa3-529a322be41b"
  },
  "try_it": {
    "formula": "=DSUM(B2:D6,\"Amount\",F2:F3)",
    "inputs": {
      "B2": "Name",
      "B3": "A",
      "B4": "B",
      "B5": "C",
      "B6": "D",
      "C2": "Group",
      "C3": "East",
      "C4": "East",
      "C5": "West",
      "C6": "East",
      "D2": "Amount",
      "D3": 10,
      "D4": 20,
      "D5": 30,
      "D6": 40,
      "F2": "Group",
      "F3": "East"
    }
  },
  "url": "https://handbook.dnacalc.com/functions/DSUM.html",
  "variants": [],
  "versions": []
}