• Ok, this gets you MOST of the way there. Couple of things though:

    1. Numbers don't have commas. It's 0.1 not 0,1 (which is a comma separated list of numbers 0 and 1). In my data I use proper numbers.
    2. Numbers should be stored as numbers, not strings. In my solution, I store the numbers as either integers or decimals.
    3. Your date ranges aren't inclusive. For example, you're ValidTo is 2017-0-01 and your next ValidFrom is 2017-02-01. What happens between 2017-01-01 and 2017-02-01? This query returns NULL for this period,as it appears there are not valid products for that date range. If this shouldn't be the case, your ValidTo should be 2017-01-31. Months have more than 1 day in them.
    4. N/A is not displayed, like Des mentioned. NULL is returned instead. Put the N/A in your presenation layer. N/A is not a nu,ber, so you can't mix the data types.

    Anyway, here's my answer:

    WITH Dates AS (
      SELECT ValidFrom, ProductCode
      FROM ListPrice
      UNION
      SELECT ValidTo, ProductCode
      FROM ListPrice
      UNION
      SELECT ValidFrom, ProductCode
      FROM Discounts
      UNION
      SELECT ValidTo, ProductCode
      FROM Discounts),
    DateRanges AS (
      SELECT ValidFrom, LEAD(ValidFrom) OVER (PARTITION BY ProductCode ORDER BY ValidFrom) AS ValidTo,
        ProductCode
      FROM Dates)
    SELECT DR.ProductCode, DR.ValidFrom, DR.ValidTo,
       LP.ListPrice,
       D.Discount1, D.Discount2,
       LP.ListPrice * (1 - D.Discount1) * (1 - D.Discount2) AS FinalPrice
    FROM DateRanges DR
      JOIN Discounts D ON DR.ProductCode = D.ProductCode
           AND DR.ValidFrom BETWEEN D.ValidFrom AND D.ValidTo
           AND DR.ValidTo BETWEEN D.ValidFrom AND D.ValidTo
      LEFT JOIN ListPrice LP ON D.ProductCode = LP.ProductCode
             AND DR.ValidFrom BETWEEN LP.ValidFrom AND LP.ValidTo
             AND DR.ValidTo BETWEEN LP.ValidFrom AND LP.ValidTo
    WHERE DR.ValidTo IS NOT NULL
    ORDER BY DR.ProductCode, DR.ValidFrom;


    If you don't understand any of it, please reply and ask.

    Thom~

    Excuse my typos and sometimes awful grammar. My fingers work faster than my brain does.
    Larnu.uk