Storing borehole interval data (logs) in netcdf
tl;dr

I would suggest considering the borehole measurements as a vertical profile. In terms of the CF Convention it would be a featureType profile, which is described in the discrete sampling geometries section.

I didn't include all reference to the relevant sections in the CF Conventions below. Just comment if import things are missing.

Example netCDF

netcdf borehole_01 {
dimensions:
      z = 8 ;
      profile = 1 ;
      nv = 2 ;

variables:
    int profile(profile) ;
          profile:cf_role = "profile_id";
    double time(profile);
        time:standard_name = "time";
        time:long_name = "time" ;
        time:units = "days since 1970-01-01 00:00:00" ;
    float lon(profile);
        lon:standard_name = "longitude";
        lon:long_name = "longitude" ;
        lon:units = "degrees_east" ;
    float lat(profile);
        lat:standard_name = "latitude";
        lat:long_name = "latitude" ;
        lat:units = "degrees_north" ;
    float z(z) ;
        z:standard_name = "depth";
        z:long_name = "depth below ..." ;
        z:units = "m" ;
        z:positive = "down" ;
        z:axis = "Z" ;
        z:bounds = "z_bnds" ;
    float z_bnds(z, nv) ;
    float temp(profile, z) ;
        temp:standard_name = "soil_temperature" ;
        temp:long_name = "soil_temperature" ;
        temp:units = "K" ;
        temp:coordinates = "time lon lat z" ;
        temp:cell_methods = "z: mean" ;

// global attributes:
        :featureType = "profile";

data:

 z = 5, 15, 25, 45, 55, 70, 90, 150 ;

 z_bnds = 
  0, 10,
  10, 20,
  20, 30,
  40, 50,
  50, 60, 
  60, 80,
  80, 100,
  100, 200 ;

 temp = 279.4, 278.8, 278.3, 277.0, 277.1, 276.9, 277.0, 279.2 ;
}


Explanation

The variable temp is an example for a data variable in the file.

Basic depth information

Please see CF Conventions section 7.1 Cell Boundaries for details.

z_bnds provides the boundaries of intervals over which the temperature is averaged. The attribute bounds of variable z points to these boundary data. In this example, I wrote the average depth of each interval into the z variable. However, this is no requirement (as far as I know). It might be also the upper or lower depth of each interval or another depth in between. z_bnds automatically inherits all relevant attributs from z. Therefore, it has no own units and standard_name attributes. 

As you can see in the data for z_bnds (or in the table below), it is possible to skip depth ranges (between depth invertal 3 and 4) and to have differently spaced intervals (e.g. interval 6 compared to previous intervals).

| **depth interval** | **minimum** | **maximum** |
|--------------------|-------------|-------------|
| 1                  | 0           | 10          |
| 2                  | 10          | 20          |
| 3                  | 20          | *30*        |
| 4                  | *40*        | 50          |
| 5                  | 50          | 60          |
| 6                  | *60*        | *80*        |
| 7                  | 80          | 100         |
| 8                  | 100         | 200         |


Connecting data variables proberly to the vertical coordinate

Please see CF Conventions section 7.3 Cell Methods for details on the first paragraph and section 5.2 Two-Dimensional Latitude, Longitude, Coordinate Variables for details on the second paragraph.

The value z: mean of the attribute cell_methods of variable temp tells us that the temperature is an average value in z-direction over the interval provided in z_bnds. The latter (over the interval provided in z_bnds) is implicitely assumed.

The value time lon lat z of the coordinates attribute of variable temp indicates that the variables time, lon, lat and z provided temporal and spatial dimensions to each value of temp. Really proper software should be able to map each value of temp a the correspondinc time, lat and lon values via the dimension profile. However, implementing this properly is hard work. Therefore, most software package won't recognize it or might even have issues with it. I your software package throws errors, one first step should be to remove the attribute coordinates.

Setting global attributes

Please see CF Conventions section Features and feature types for details

The global attribute featureType is mandatory when we have a discret sampling geometry.

Several boreholes with different depth intervals

For details on coordinate variables and auxiliary coordinate variables please have a look into sections 1.2 Terminology and 5 Coordinate System

Via the dimension profile we could save several boreholes in one file. In the current situation, the samplings depths of each borehole would be the same. One could make the variable z and z_bnds dependent on profile to provide depth intervals for each borehole. However, then we needed to rename the variables z and z_bnds because a variable might only have the same name of a dimension, if the variable is onedimensional and only depends on this dimension (a coordiante variable). When a variable like the depth depends on two dimensions, it becomes and auxiliary coordinate variable and has to have a different names. Thus, we would have double depth(profile, z) instead of z(z) and double depth_bnds(profile, z, nv) instead of z_bnds(z, nv). The temp:coordiantes would have a value of time lat lon depth (because depth is the vertical coordinates) but temp:cell_methods would remain z: mean (because we calculate average in z-direction).