The following code was presented as two different methods to achieve the same output:
-- 4) LIST ALL INVOICE INFORMATION WHERE BALANCE DUE IS > 0
-- AND LESS THAN THE AVERAGE BALANCE DUE
SELECT
invoices.invoice_number,
invoices.invoice_date,
invoices.invoice_total - payment_total - credit_total AS balance_due
FROM
invoices
WHERE
(invoice_total - payment_total - credit_total) > 0 AND
(invoice_total - payment_total - credit_total) <
(SELECT AVG(invoice_total - payment_total - credit_total)
FROM
invoices
WHERE
invoice_total - payment_total - credit_total > 0 )
ORDER BY
invoice_total DESC;
-- OR THIS WAY:
SELECT
invoice_number,
invoice_date,
invoice_total - payment_total - credit_total AS balance_due
FROM
invoices
HAVING
balance_due > 0 AND
balance_due <
(
SELECT AVG(invoice_total - payment_total - credit_total)
FROM invoices
WHERE invoice_total - payment_total - credit_total > 0
)
ORDER BY
invoice_total DESC;The premise was that HAVING and WHERE are functionally identical. That is incorrect.
Consider the following code:
SELECT
invoices.invoice_id,
invoices.invoice_date,
(invoice_total - credit_total - payment_total) AS balance_due
FROM
invoices
HAVING
balance_due > 0
AND
balance_due <
(SELECT AVG(invoice_total - payment_total - credit_total) AS AVERAGE FROM invoices HAVING AVERAGE > 0)
ORDER BY
invoice_total DESC;We receive the following output:
"invoice_id" "invoice_date" "balance_due"
"113" "2014-08-01" "224.00"
"110" "2014-07-28" "90.36"
"89" "2014-07-10" "85.31"
"100" "2014-07-22" "67.92"
"99" "2014-07-21" "59.97"
"94" "2014-07-18" "52.25"
"101" "2014-07-22" "30.75"HAVING is executed near the very end of the query. Because of this, aliases defined in the respective SELECT statements can be used in HAVING clauses, as opposed to WHERE clauses. However, because of this, every operation of every preceding clause has been completed by the time HAVING comes to pass. In figure-1, the subquery is effectively executed first. So, for the subquery, the table exists in this state, right before HAVING is computed:
(SELECT AVG(invoice_total - payment_total - credit_total) AS AVERAGE FROM invoices)Figure-1-1 is executed on the invoices table, using three columns to calculate the AVG. We can see the invoices table exists as such, via the statement figure-1-2:
(SELECT invoice_total, payment_total, credit_total FROM invoices)"invoice_total" "payment_total" "credit_total"
"3813.33" "3813.33" "0.00"
"40.20" "40.20" "0.00"
"138.75" "138.75" "0.00"
"144.70" "144.70" "0.00"
"15.50" "15.50" "0.00"
"42.75" "42.75" "0.00"
"172.50" "172.50" "0.00"
"95.00" "95.00" "0.00"
"601.95" "601.95" "0.00"
"42.67" "42.67" "0.00"
"42.50" "42.50" "0.00"
"662.00" "662.00" "0.00"
"16.33" "16.33" "0.00"
"6.00" "6.00" "0.00"
"856.92" "856.92" "0.00"
"9.95" "9.95" "0.00"
"10.00" "10.00" "0.00"
"104.00" "104.00" "0.00"
"116.54" "116.54" "0.00"
"6.00" "6.00" "0.00"
"4901.26" "4901.26" "0.00"
"108.25" "108.25" "0.00"
"9.95" "9.95" "0.00"
"1750.00" "1750.00" "0.00"
"129.00" "129.00" "0.00"
"10.00" "10.00" "0.00"
"207.78" "207.78" "0.00"
"109.50" "109.50" "0.00"
"450.00" "450.00" "0.00"
"63.40" "63.40" "0.00"
"7125.34" "7125.34" "0.00"
"953.10" "953.10" "0.00"
"220.00" "220.00" "0.00"
"127.75" "127.75" "0.00"
"1600.00" "1600.00" "0.00"
"565.15" "565.15" "0.00"
"36.00" "36.00" "0.00"
"61.50" "61.50" "0.00"
"37966.19" "37966.19" "0.00"
"639.77" "639.77" "0.00"
"53.75" "53.75" "0.00"
"400.00" "400.00" "0.00"
"21842.00" "21842.00" "0.00"
"19.67" "19.67" "0.00"
"2765.36" "2765.36" "0.00"
"224.00" "224.00" "0.00"
"1575.00" "1575.00" "0.00"
"33.00" "33.00" "0.00"
"16.33" "16.33" "0.00"
"116.00" "116.00" "0.00"
"2184.11" "2184.11" "0.00"
"1083.58" "1083.58" "0.00"
"46.21" "46.21" "0.00"
"313.55" "313.55" "0.00"
"40.75" "40.75" "0.00"
"2433.00" "2433.00" "0.00"
"1367.50" "1367.50" "0.00"
"53.25" "53.25" "0.00"
"13.75" "13.75" "0.00"
"2312.20" "2312.20" "0.00"
"25.67" "25.67" "0.00"
"26.75" "26.75" "0.00"
"2115.81" "2115.81" "0.00"
"23.50" "23.50" "0.00"
"6940.25" "6940.25" "0.00"
"31.95" "31.95" "0.00"
"1927.54" "1927.54" "0.00"
"936.93" "936.93" "0.00"
"175.00" "175.00" "0.00"
"6.00" "6.00" "0.00"
"108.50" "108.50" "0.00"
"10.00" "10.00" "0.00"
"290.00" "290.00" "0.00"
"41.80" "41.80" "0.00"
"27.00" "27.00" "0.00"
"241.00" "241.00" "0.00"
"904.14" "904.14" "0.00"
"1962.13" "1762.13" "200.00"
"2184.50" "2184.50" "0.00"
"2318.03" "2318.03" "0.00"
"26.25" "26.25" "0.00"
"17.50" "17.50" "0.00"
"39.77" "39.77" "0.00"
"111.00" "111.00" "0.00"
"158.00" "158.00" "0.00"
"739.20" "739.20" "0.00"
"60.00" "60.00" "0.00"
"147.25" "147.25" "0.00"
"85.31" "0.00" "0.00"
"38.75" "38.75" "0.00"
"32.70" "32.70" "0.00"
"16.62" "16.62" "0.00"
"162.75" "162.75" "0.00"
"52.25" "0.00" "0.00"
"600.00" "600.00" "0.00"
"26881.40" "26881.40" "0.00"
"356.48" "356.48" "0.00"
"579.42" "0.00" "0.00"
"59.97" "0.00" "0.00"
"67.92" "0.00" "0.00"
"30.75" "0.00" "0.00"
"20551.18" "0.00" "1200.00"
"2051.59" "2051.59" "0.00"
"44.44" "44.44" "0.00"
"503.20" "0.00" "0.00"
"23517.58" "21221.63" "2295.95"
"3689.99" "3689.99" "0.00"
"67.00" "67.00" "0.00"
"1000.46" "1000.46" "0.00"
"90.36" "0.00" "0.00"
"22.57" "22.57" "0.00"
"10976.06" "0.00" "0.00"
"224.00" "0.00" "0.00"
"127.75" "127.75" "0.00"
"8344.50" "0.00" "0.00"
"8344.50" "0.00" "0.00"