Prepstellar

SQL Fundamentals · SQL Foundations

25 cards

Values, Types, and Expressions

Swipe, scroll or use ← →
  1. Choosing a numeric type

    Picking a column type is a promise about what may be stored there, so the first decision for a number is how large it can grow. Whole numbers come in three sizes.

    Type Storage Range
    smallint Two bytes −32768 up to 32767
    integer Four bytes −2147483648 up to 2147483647
    bigint Eight bytes A much larger range

    The type integer is the common choice, as it offers the best balance between range, storage size, and performance, while smallint is generally only used if disk space is at a premium and bigint is designed for when the range of integer is insufficient.

    The declared range is enforced, not advisory: attempts to store values outside the allowed range result in an error.

    1 / 25
  2. Quick check

    A counter column will hold values in the low millions and needs no special tuning. Which whole-number type is the documented default choice, and what happens if a value ever exceeds its range?

    1. Asmallint, and an out-of-range value is widened automatically

      smallint is reserved for cases where disk space is at a premium, and no type silently widens itself to fit a value.

    2. Binteger, and an out-of-range value raises an error

      Right. integer is the balanced default for range, storage, and performance, and a value outside the allowed range is rejected with an error.

    3. Cbigint, and an out-of-range value is rounded to the nearest limit

      bigint exists for ranges that integer cannot hold, and nothing rounds a value to a range limit.

    2 / 25

  3. Choosing a numeric type

    Fractional quantities raise a different question: does the value have to be exact?

    The numeric type can store numbers with a very large number of digits, and it is especially recommended for storing monetary amounts and other quantities where exactness is required. The price is speed: calculations on numeric values are very slow compared to the integer types or the floating-point types.

    The alternative trades exactness for that speed. The types real and double precision are inexact, variable-precision numeric types, with real offering a precision of at least six decimal digits and double precision at least fifteen.

    Type Exact? Typical use
    numeric Yes Money and other amounts that must not drift
    real No At least six decimal digits of precision
    double precision No At least fifteen decimal digits of precision

    Inexactness has a visible symptom: comparing two floating-point values for equality might not always work as expected.

    3 / 25
  4. Choosing a numeric type

    A numeric column is declared with two numbers, and mixing them up is a classic error. The precision of a numeric value is the total count of significant digits on both sides of the decimal point, while the scale is the count of decimal digits in the fractional part.

    So a value written with two digits before the point and four after it has a precision of six and a scale of four: precision counts everything, scale counts only the fractional half.

    Value Precision Scale
    12.3456 6 4
    1234.56 6 2
    12345.6 6 1

    The pattern in that table is the point: the same precision can be split in different ways, and the scale is what says where the decimal point sits.

    4 / 25
  5. Quick check

    A numeric value is written with two digits before the decimal point and four after it. What are its precision and its scale?

    1. AA precision of four and a scale of two

      Four and two reverse the reading: neither figure counts only the digits before the point.

    2. BA precision of two and a scale of four digits

      Precision is never the count of the leading digits alone; it covers both sides of the point.

    3. CA precision of six, with a scale of four

      Right. Precision counts all six significant digits, while scale counts only the four fractional ones.

    5 / 25

  6. Choosing a numeric type

    Put the two properties together on the case that comes up most often: money.

    A ledger column that must be summed without accumulated rounding drift, and whose stored balances have to compare predictably, needs exactness rather than speed. If you require exact storage and calculations, such as for monetary amounts, use the numeric type instead, with a declared precision and scale.

    • double precision and real are documented as inexact, so equality tests on them can behave unexpectedly.
    • bigint is exact but holds no fractional part, so it can only carry an amount converted into whole units.
    • numeric accepts slower calculations in exchange for the exactness the ledger needs.
    6 / 25
  7. Quick check

    A ledger column stores monetary amounts that must be summed without rounding drift, and equality tests on balances must behave predictably. Reporting speed is secondary. Which type fits?

    1. Anumeric, with a declared precision and scale

      Right. numeric is the type recommended for monetary amounts and exact calculations, and its slower arithmetic is the accepted trade.

    2. Breal, because it stores each value in less space

      real is an inexact, variable-precision type, so stored amounts can drift and equality tests can surprise you.

    3. Cdouble precision, because it offers the widest documented range of digits

      double precision is also inexact; more digits of precision does not make its comparisons dependable.

    7 / 25

  8. Keep your progress in the app

    That’s 3 of 11 quick checks. In the app they stay answered, and every lesson remembers where you left off.

  9. Choosing character, Boolean, and date-time types

    Text has two length-limited types, and they differ in what they do with a value shorter than the limit.

    Both character varying with a length limit and character with a length limit can store strings up to that many characters rather than bytes, and storing a longer string raises an error unless the excess characters are all spaces, in which case the string is truncated to the maximum length.

    The difference appears with short values. Values of type character are physically padded with spaces to the declared width and are stored and displayed that way, while a character varying value simply stores the shorter string.

    Column Value written Held as
    character(6) ok ok — padded out to six characters
    character varying(6) ok ok — exactly as written
    8 / 25
  10. Quick check

    A short value is stored into a fixed-length character column. How is it held?

    1. ARejected, because the declared width was not filled by the value

      A shorter value is perfectly legal; only a longer one raises an error, and then only when the excess is not spaces.

    2. BPadded with spaces out to the declared width

      Right. The blank-padded character type widens a short value with spaces and stores and displays it that way.

    3. CStored exactly as written, with no padding

      Storing the value exactly as written is what character varying does, not the fixed-length type.

    9 / 25

  11. Choosing character, Boolean, and date-time types

    That padding changes how values compare. Trailing spaces in a character value are treated as semantically insignificant and are disregarded when comparing two values of type character, whereas trailing spaces are semantically significant in character varying and text values.

    The text type stores strings of any length, and the documentation advises that in most situations text or character varying should be used instead of the blank-padded type, which is usually the slowest of the three.

    Type Trailing spaces Length limit
    character(n) Disregarded when comparing Fixed, padded
    character varying(n) Significant Limited, not padded
    text Significant None

    Truth values have their own type, and it is a short list. The boolean type, whose alias is bool, is the logical Boolean type that holds true or false, and it is one of the types named by the SQL standard. Bit strings and binary data have their own types and express no truth value.

    10 / 25
  12. Choosing character, Boolean, and date-time types

    Points in time are split by intent rather than by precision.

    A date value is a calendar date of year, month, and day, a timestamp without time zone holds a date and a time with no zone information, and a timestamp with time zone, also spelled timestamptz, holds a date and a time including the time zone.

    A time of day alone follows the same split, with a with-time-zone spelling and a without-time-zone spelling, and an interval expresses a span of time rather than a point in it.

    Type Date Time Zone
    date Yes No No
    time No Yes Only in the with-time-zone spelling
    timestamp without time zone Yes Yes No
    timestamp with time zone Yes Yes Yes
    interval A span, not a point in time
    11 / 25
  13. Quick check

    An audit column must record a calendar date and a clock time in one value, and the zone in which the moment was recorded must be part of what is stored. Which declaration fits?

    1. Atimestamp with time zone

      Right. Only the with-time-zone spelling of the combined type carries both halves of the moment and its zone.

    2. Btimestamp without time zone, which keeps the date and the clock time

      This spelling does hold the date and the time, but it records no zone information at all.

    3. Ctime with time zone, which keeps the clock time and its zone

      A time-only type carries the zone but drops the calendar date, so one required component is missing.

    12 / 25

  14. Arithmetic and operator precedence

    Value expressions calculate values from primitive parts using arithmetic, logical, set, and other operations, and the result of such an expression is sometimes called a scalar to distinguish it from the result of a table expression.

    How an expression with several operators is grouped is not negotiable. The precedence and associativity of the operators is hard-wired into the parser, and parentheses have to be added when an expression with multiple operators should be parsed in some other way than the precedence rules imply.

    Binding Operators
    Tightest Unary sign, then exponentiation
    Then Multiplication, division, modulo
    Loosest Addition, subtraction

    In the documented ordering, exponentiation binds more tightly than multiplication, division, and modulo, which in turn bind more tightly than addition and subtraction; unary sign operators bind more tightly still. Most operators have the same precedence and are left-associative.

    13 / 25
  15. Quick check

    An arithmetic expression mixes an addition and a multiplication with no parentheses. How is it grouped, and how can that grouping be changed?

    1. AAddition binds first, and a cast is what regroups the expression

      Addition is the looser of the two, and a cast changes a value's type rather than the grouping of an expression.

    2. BThe operators apply from left to right as written

      Left-to-right applies between operators of the same precedence, not between two of different precedence.

    3. CMultiplication binds first, and parentheses are what regroup it

      Right. Multiplication binds more tightly than addition, and parentheses are the documented way to impose another reading.

    14 / 25

  16. Arithmetic and operator precedence

    Precedence is not the same thing as evaluation order, and confusing the two produces bugs that appear only under load.

    The order of evaluation of subexpressions is not defined, and the inputs of an operator or function are not necessarily evaluated from left to right, so a calculation must never depend on a side effect happening first.

    Question Answer
    Which operator groups with which operands? Fixed by precedence and associativity
    In which order are the subexpressions actually computed? Not defined

    Read that as a rule for writing code: parentheses are how you control meaning, and nothing you write in one operand is guaranteed to run before the other.

    15 / 25
  17. Comparing values and combining predicates

    A comparison is an expression like any other, and its result has a type. All comparison operators are binary operators that return values of type boolean.

    That single fact explains a common error. Chaining a comparison so that the result of one feeds straight into another is not valid, because there is no comparison operator between a Boolean result and a number.

    The range test has its own predicate. The BETWEEN predicate performs the range test instead, and it treats the endpoint values as included in the range, so a value equal to either endpoint passes. An exclusive range has to be written out with strict comparisons.

    Comparison operators are available for all built-in data types that have a natural ordering, and values of related types can usually be compared because the parser coerces the less-general type to the more-general one.

    16 / 25
  18. Quick check

    How does the BETWEEN predicate treat the two endpoint values of its range?

    1. AOnly the lower endpoint is included

      The endpoints are not treated differently from each other; neither one is singled out.

    2. BBoth endpoints are included in the range

      Right. BETWEEN includes both endpoints, so a value equal to either of them passes the test.

    3. CNeither endpoint is included, so the range is strictly between them

      An exclusive range is not what BETWEEN provides; it has to be written out with strict comparisons.

    17 / 25

  19. Comparing values and combining predicates

    Predicates are then combined with the logical operators, and they too have a fixed order of binding. In the documented precedence ordering, NOT for logical negation binds more tightly than AND for logical conjunction, which binds more tightly than OR for logical disjunction, so a condition that mixes them without parentheses is grouped in that order.

    Two further properties matter when a condition gets complicated:

    • Boolean combinations of AND, OR, and NOT in a qualification can be reorganized in any manner allowed by the laws of Boolean algebra, so the written arrangement is not necessarily the one that is executed.
    • If the result of an expression can be determined by evaluating only some parts of it, the remaining subexpressions might not be evaluated at all, which is not the same as the guaranteed left-to-right behaviour some programming languages provide.

    Together those two rules say the same thing as the section above: write conditions whose meaning survives regrouping, and never rely on one side being tested first.

    18 / 25
  20. Quick check

    Which ordering describes how the logical operators bind, from the tightest to the loosest?

    1. ANOT, then AND, then OR

      Right. Negation binds most tightly, conjunction next, and disjunction loosest, so an unparenthesised mixture groups in that order.

    2. BAND, then OR, and finally NOT

      Negation is the tightest of the three, so it cannot come last in the ordering.

    3. COR first, then NOT, and finally AND

      Disjunction is the loosest of the three, so it cannot bind more tightly than the other two.

    19 / 25

  21. Concatenating text without relying on implicit conversion

    Joining text is where types quietly matter. The string concatenation operator, written as two vertical bars, joins two strings into one.

    It is more forgiving than it looks, and that is the trap. It will accept non-string input so long as at least one input is of string type, and for other cases inserting an explicit coercion to text is what makes the non-string input acceptable. So a label built from a text prefix and a number happens to work, but only because of that accommodation — write the conversion yourself and the expression no longer depends on it.

    Two limits are worth carrying:

    • The non-string input cannot be of an array type, so an array has to be cast to text explicitly before it is joined.
    • Strings here include values of the character, character varying, and text types, and a character value is converted to text before the operator is applied, which strips any trailing spaces it carried.
    20 / 25
  22. Quick check

    A label must join a text prefix to a numeric column with the concatenation operator, and the code must not depend on the engine accepting a non-string operand. What is the dependable approach?

    1. AJoin the operands directly, since one is already text

      Joining directly works only because one side is a string, which is exactly the accommodation the requirement rules out.

    2. BConvert the text prefix to the column's numeric type first

      Converting the string side to a number removes the string operand the operator needs, so nothing is left to join.

    3. CCoerce the numeric column to text explicitly before joining it

      Right. Inserting an explicit coercion to text is what makes a non-string input acceptable without leaning on that accommodation.

    21 / 25

  23. Calling functions with positional, named, and default arguments

    The same function can be called in more than one way, and the notation decides which arguments may be left out.

    In positional notation a function call is written with its argument values in the same order as they are defined in the function declaration, while in named notation the arguments are matched to the parameters by name and can be written in any order. In named notation the parameter name is written before the value and separated from it by an arrow token.

    Parameters that have default values given in the declaration need not be written in the call at all, but the freedom this gives differs by notation: in positional notation parameters can only be omitted from right to left, whereas named notation can omit any combination of defaulted parameters.

    Notation Arguments matched by Which defaults may be dropped
    Positional Their order in the declaration Only from the right
    Named Their parameter name Any combination of them
    Mixed Position first, then name As allowed by the named part

    Mixed notation combines the two, with positional arguments written first, because named arguments cannot precede positional ones. One current limit: named and mixed notations cannot currently be used when calling an aggregate function, although they do work when an aggregate function is used as a window function.

    22 / 25
  24. Quick check

    A function declares three parameters, the second and third carrying defaults. Which call form can supply the third while leaving the second at its default?

    1. ANamed notation, which can omit any combination of defaulted parameters

      Right. Named notation matches each argument to its parameter by name, so any defaulted parameter can be skipped.

    2. BPositional notation, which may omit a parameter at any position

      Positional notation can only drop defaulted parameters from the right, so the second cannot be skipped while the third is supplied.

    3. CNamed notation, provided its named arguments come first

      Named arguments can never come before positional ones: mixed notation puts the positional arguments first.

    23 / 25

  25. Key takeaways

    • integer is the balanced default for whole numbers, and a value outside a type's range raises an error.
    • numeric is the type recommended when exactness is required, such as for monetary amounts, at the cost of slower calculations; real and double precision are inexact.
    • Precision counts every significant digit of a numeric value and scale counts only the fractional ones.
    • character pads values to its declared width and disregards trailing spaces when comparing, while character varying and text keep them.
    • boolean holds true and false, and only the with-time-zone spelling of a timestamp records zone information.
    • Comparison operators are binary and return a Boolean, and BETWEEN includes both endpoints.
    • Multiplication binds more tightly than addition, and NOT more tightly than AND, then OR — parentheses impose any other grouping, and evaluation order is never promised.
    • Concatenation accepts a non-string operand only when one operand is already a string, so write the conversion to text yourself.
    • A defaulted parameter can be dropped from the right in positional notation, while named notation can drop any combination of them.
    24 / 25
  26. Quick check

    Which summary keeps the type and expression rules straight?

    1. AFloating point is the exact type for money, and BETWEEN excludes its endpoints

      The floating-point types are documented as inexact, and BETWEEN treats both endpoint values as included.

    2. Bnumeric is the exact type for money, BETWEEN includes both endpoints, and parentheses override precedence

      Right. Exactness comes from numeric, the range test is inclusive, and grouping is changed only with parentheses.

    3. Ccharacter varying pads its values, and evaluation order runs strictly from left to right

      The blank-padded fixed-length type is the one that pads, and the order of evaluation of subexpressions is not defined.

    25 / 25

  27. 11 quick checks · then the test

    In the app, finishing the quick checks opens this lesson’s 10-question test, and the ones you miss come back exactly when you’re about to forget them.

The whole course, on your phone

Lessons you can read, audio you can listen to on the way to work, and practice that remembers what you got wrong.