This query does not make sense. You say the sub-queries run fine -- but there is no way they can. Try running this query
SELECT p.PK_Product_ID AS Product_ID, COUNT(o.PK_Order_ID) AS 2013_Orders,
SUM((p.UnitPrice*od.Quantity)) AS 2013_Gross_Value
FROM [Order Details] AS od, p, Orders AS o
WHERE od.FK_Product_ID = p.PK_Product_ID
AND od.FK_Order_ID = o.PK_Order_ID
AND YEAR(o.OrderDate) = 2013
GROUP BY p.PK_Product_ID
I would expect it to give an error that "p" is not the name of a table.
Maybe you mean this?
SELECT p.PK_Product_ID AS Product_ID, COUNT(o.PK_Order_ID) AS 2013_Orders,
SUM((p.UnitPrice*od.Quantity)) AS 2013_Gross_Value
FROM [Order Details] AS od, Products as p, Orders AS o
WHERE od.FK_Product_ID = p.PK_Product_ID
AND od.FK_Order_ID = o.PK_Order_ID
AND YEAR(o.OrderDate) = 2013
GROUP BY p.PK_Product_ID
Which means you probably want something like this:
SELECT p.PK_Product_ID, a.[2013_Orders], a.[2013_Gross_Value], b.[2014_Orders], b.[2014_Gross_Value]
FROM Products AS p
LEFT JOIN (
SELECT p.PK_Product_ID AS Product_ID, COUNT(o.PK_Order_ID) AS 2013_Orders, SUM((p.UnitPrice*od.Quantity)) AS 2013_Gross_Value
FROM [Order Details] AS od
JOIN Products as p ON od.FK_Product_ID = p.PK_Product_ID
JOIN Orders AS o ON od.FK_Order_ID = o.PK_Order_ID AND YEAR(o.OrderDate) = 2013
GROUP BY p.PK_Product_ID
) AS a ON p.PK_Product_ID = a.Product_ID
LEFT JOIN (
SELECT p.PK_Product_ID AS Product_ID, COUNT(o.PK_Order_ID) AS 2013_Orders, SUM((p.UnitPrice*od.Quantity)) AS 2013_Gross_Value
FROM [Order Details] AS od
JOIN Products as p ON od.FK_Product_ID = p.PK_Product_ID
JOIN Orders AS o ON od.FK_Order_ID = o.PK_Order_ID AND YEAR(o.OrderDate) = 2013
GROUP BY p.PK_Product_ID
) AS b ON p.PK_Product_ID = b.Product_ID;
However, I would not bother with two sub-queries -- or even 1 sub-query -- it will just slow you down -- do it like this:
SELECT p.PK_Product_ID,
SUM(CASE WHEN COALESCE(o.OrderYear,0) == 2013 THEN 1 ELSE 0 END) as 2013_Orders,
SUM(CASE WHEN COALESCE(o.OrderYear,0) == 2013 THEN OrderValue ELSE 0 END) as 2013_Gross_Value,
SUM(CASE WHEN COALESCE(o.OrderYear,0) == 2014 THEN 1 ELSE 0 END) as 2014_Orders,
SUM(CASE WHEN COALESCE(o.OrderYear,0) == 2014 THEN OrderValue ELSE 0 END) as 2014_Gross_Value,
FROM Products AS p
LEFT JOIN [Order Details] AS od ON od.FK_Product_ID = p.PK_Product_ID
LEFT JOIN Orders AS o ON od.FK_Order_ID = o.PK_Order_ID
WHERE YEAR(o.OrderDate) in (2013, 2014) -- this is not needed but will may make it faster
GROUP BY p.PK_Product_ID
remember, in SQL you should think in groups -- the first group is orders... the year comes in later.