A common source of confusion for Windows development is the Windows SDK naming scheme. For example: Can someone use the "Windows SDK for Windows Server 2008 and .NET Framework 3.5" to target Windows XP?
The recommendation is for developers to use the latest version of the Windows SDK they can for access to the latest technologies and APIs, given the restrictions of your projects development platform, target platforms, and toolset. Figuring out this matrix of choices is a bit challenging, so this blog post spells out some key differences.
For a more complete version history, you might want to check out Wikipedia.
Most developers get a copy of the Windows SDK or Platform SDK with their Visual Studio installation.
Windows 8.1 SDK
Windows 7.1A SDK for "xp_110" Platform Toolset
VS 2013 Express for Windows only includes a subset of the full Windows 8.1 SDK
Windows 8.0 SDK
VS 2012 Express for Windows only includes a subset of the full Windows 8.0 SDK
Windows SDK 7.0A
Similar to Windows SDK for Windows 7 and .NET Framework 3.5 SP1 (August 2009)
Windows SDK 6.0A
Similar to Windows SDK for Windows Vista Update and .NET Framework 3.0 (February 2007)
Similar to Windows Server 2003 SP1 Platform SDK (April 2005)
VS 2005 Express did not include the Platform SDK
Given the naming scheme for the Window SDKs, this is probably the most confusing aspect of choosing a Windows SDK. The easiest way to describe it is to list the last releases which allowed you to target a given OS.
Another aspect is that the Windows SDK often supports a smaller set of platforms for development (i.e. it can be installed on) compared to those it can target (i.e. deploy applications to).
Not all Windows SDKs can be used with all versions of Visual Studio. Changes in language features, /analyze SAL annotation, and other aspects of the compiler toolset are assumed as the baseline for a given Visual Studio release--usually that version that comes with a given Visual Studio release is the 'oldest' one it supports.
The standard way of doing this is to set a Preprocessor Define _WIN32_WINNT to the appropriate value for the 'oldest' version of Windows you are targeting (see Using the Windows Headers). This causes the headers to work in such a way that newer APIs are not available at build time. This can get a bit complicated for "Platform Updates" that put portions of newer OS features onto older version of Windows, but otherwise _WIN32_WINNT is usually sufficient to get the expected behavior. Otherwise, you can set a 'higher' value to give you access to newer APIs, but the programmer must take care to handle detection or fallback as needed for partially supported or unsupported APIs on down-level versions of Windows (i.e. WIC2, Direct3D 11)
Note that unlike previous Windows SDKs, the Windows 8.x SDKs use a default value of _WIN32_WINNT that is the 'newest' rather than the 'oldest' version of the OS.
Related: DirectX SDKs of a certain age, Windows 7.1 SDK, Windows 8.0 SDK, VS 2012 Update 1