AdventureWorks Database: Fetch columns using multiple CTE in a single query
164. From the following table write a query in SQL to find the SalesPersonID, salesyear, totalsales, salesquotayear, salesquota, and amt_above_or_below_quota columns. Sort the result set in ascending order on SalesPersonID, and SalesYear columns.
Sample table: Sales.SalesOrderHeadersalesorderid|revisionnumber|orderdate |duedate |shipdate |status|onlineorderflag|purchaseordernumber|accountnumber |customerid|salespersonid|territoryid|billtoaddressid|shiptoaddressid|shipmethodid|creditcardid|creditcardapprovalcode|currencyrateid|subtotal |taxamt |freight |totaldue |comment|rowguid |modifieddate | ------------+--------------+-----------------------+-----------------------+-----------------------+------+---------------+-------------------+--------------+----------+-------------+-----------+---------------+---------------+------------+------------+----------------------+--------------+-----------+----------+---------+-----------+-------+------------------------------------+-----------------------+ 43659| 8|2011-05-31 00:00:00.000|2011-06-12 00:00:00.000|2011-06-07 00:00:00.000| 5|false |PO522145787 |10-4020-000676| 29825| 279| 5| 985| 985| 5| 16281|105041Vi84182 | | 20565.6206| 1971.5149| 616.0984| 23153.2339| |79b65321-39ca-4115-9cba-8fe0903e12e6|2011-06-07 00:00:00.000| 43660| 8|2011-05-31 00:00:00.000|2011-06-12 00:00:00.000|2011-06-07 00:00:00.000| 5|false |PO18850127500 |10-4020-000117| 29672| 279| 5| 921| 921| 5| 5618|115213Vi29411 | | 1294.2529| 124.2483| 38.8276| 1457.3288| |738dc42d-d03b-48a1-9822-f95a67ea7389|2011-06-07 00:00:00.000| 43661| 8|2011-05-31 00:00:00.000|2011-06-12 00:00:00.000|2011-06-07 00:00:00.000| 5|false |PO18473189620 |10-4020-000442| 29734| 282| 6| 517| 517| 5| 1346|85274Vi6854 | 4| 32726.4786| 3153.7696| 985.553| 36865.8012| |d91b9131-18a4-4a11-bc3a-90b6f53e9d74|2011-06-07 00:00:00.000| 43662| 8|2011-05-31 00:00:00.000|2011-06-12 00:00:00.000|2011-06-07 00:00:00.000| 5|false |PO18444174044 |10-4020-000227| 29994| 282| 6| 482| 482| 5| 10456|125295Vi53935 | 4| 28832.5289| 2775.1646| 867.2389| 32474.9324| |4a1ecfc0-cc3a-4740-b028-1c50bb48711c|2011-06-07 00:00:00.000| 43663| 8|2011-05-31 00:00:00.000|2011-06-12 00:00:00.000|2011-06-07 00:00:00.000| 5|false |PO18009186470 |10-4020-000510| 29565| 276| 4| 1073| 1073| 5| 4322|45303Vi22691 | | 419.4589| 40.2681| 12.5838| 472.3108| |9b1e7a40-6ae0-4ad3-811c-a64951857c4b|2011-06-07 00:00:00.000| 43664| 8|2011-05-31 00:00:00.000|2011-06-12 00:00:00.000|2011-06-07 00:00:00.000| 5|false |PO16617121983 |10-4020-000397| 29898| 280| 1| 876| 876| 5| 806|95555Vi4081 | | 24432.6088| 2344.9921| 732.81| 27510.4109| |22a8a5da-8c22-42ad-9241-839489b6ef0d|2011-06-07 00:00:00.000| 43665| 8|2011-05-31 00:00:00.000|2011-06-12 00:00:00.000|2011-06-07 00:00:00.000| 5|false |PO16588191572 |10-4020-000146| 29580| 283| 1| 849| 849| 5| 15232|35568Vi78804 | | 14352.7713| 1375.9427| 429.9821| 16158.6961| |5602c304-853c-43d7-9e79-76e320d476cf|2011-06-07 00:00:00.000| -- more --Sample table: Sales.SalesPersonQuotaHistory
businessentityid|quotadate |salesquota|rowguid |modifieddate | ----------------+-----------------------+----------+------------------------------------+-----------------------+ 274|2011-05-31 00:00:00.000| 28000|99109bbf-8693-4587-bc23-6036ec89e1be|2011-04-16 00:00:00.000| 274|2011-08-31 00:00:00.000| 7000|dfd01444-8900-461c-8d6f-04598dae01d4|2011-07-17 00:00:00.000| 274|2011-12-01 00:00:00.000| 91000|0a69f453-9689-4ccf-a08c-c644670f5668|2011-10-17 00:00:00.000| 274|2012-02-29 00:00:00.000| 140000|da8d1458-5fb9-4c3e-9ead-8f5ce1393047|2012-01-15 00:00:00.000| 274|2012-05-30 00:00:00.000| 70000|760cef84-b980-417b-a667-7358c38857f0|2012-04-15 00:00:00.000| 274|2012-08-30 00:00:00.000| 154000|fb29e024-f26a-49aa-a7cc-c99ae7ba4853|2012-07-16 00:00:00.000| 274|2012-11-30 00:00:00.000| 107000|13947d2c-a254-47c9-8817-cbd186ffa526|2012-10-16 00:00:00.000| 274|2013-02-28 00:00:00.000| 58000|bc1a222f-47a0-48d1-9c56-ac873269dc98|2013-01-14 00:00:00.000| 274|2013-05-30 00:00:00.000| 263000|8b4e3cbf-f0ef-49c5-9a8c-87679055057e|2013-04-15 00:00:00.000| 274|2013-08-30 00:00:00.000| 116000|e9de95e3-b119-4441-bd1d-b27fc4516022|2013-07-16 00:00:00.000| 274|2013-11-30 00:00:00.000| 84000|7cea47b5-8391-4414-a866-ff6ec6628cd3|2013-10-16 00:00:00.000| 274|2014-03-01 00:00:00.000| 187000|0cfb6474-20aa-46d3-a5c0-29dba2eda025|2014-01-15 00:00:00.000| -- more --
Sample Solution:
-- Common Table Expressions (CTEs) are used to define two temporary result sets: Sales_CTE and Sales_Quota_CTE.
-- Sales_CTE calculates the total sales for each salesperson per year.
WITH Sales_CTE (SalesPersonID, TotalSales, SalesYear) AS
(
-- Selecting SalesPersonID, calculating the sum of TotalDue as TotalSales, and extracting the year from OrderDate as SalesYear
SELECT SalesPersonID, SUM(TotalDue) AS TotalSales, DATE_PART('year', OrderDate) AS SalesYear
FROM Sales.SalesOrderHeader
-- Filtering out rows where SalesPersonID is not null
WHERE SalesPersonID IS NOT NULL
-- Grouping the results by SalesPersonID and the year extracted from OrderDate
GROUP BY SalesPersonID, DATE_PART('year', OrderDate)
),
-- Sales_Quota_CTE calculates the total sales quota for each salesperson per year.
Sales_Quota_CTE (BusinessEntityID, SalesQuota, SalesQuotaYear) AS
(
-- Selecting BusinessEntityID, calculating the sum of SalesQuota as SalesQuota, and extracting the year from QuotaDate as SalesQuotaYear
SELECT BusinessEntityID, SUM(SalesQuota) AS SalesQuota, DATE_PART('year', QuotaDate) AS SalesQuotaYear
FROM Sales.SalesPersonQuotaHistory
-- Grouping the results by BusinessEntityID and the year extracted from QuotaDate
GROUP BY BusinessEntityID, DATE_PART('year', QuotaDate)
)
-- The main query combines data from the two CTEs to calculate the difference between total sales and sales quota for each salesperson and year.
SELECT SalesPersonID
, SalesYear
, CAST(TotalSales AS VARCHAR(10)) AS TotalSales
, SalesQuotaYear
, CAST(TotalSales AS VARCHAR(10)) AS SalesQuota
, CAST(TotalSales - SalesQuota AS VARCHAR(10)) AS Amt_Above_or_Below_Quota
FROM Sales_CTE
-- Joining Sales_CTE with Sales_Quota_CTE on SalesPersonID and SalesYear
JOIN Sales_Quota_CTE ON Sales_Quota_CTE.BusinessEntityID = Sales_CTE.SalesPersonID
AND Sales_CTE.SalesYear = Sales_Quota_CTE.SalesQuotaYear
-- Ordering the results by SalesPersonID and SalesYear
ORDER BY SalesPersonID, SalesYear;
Explanation:
- The query calculates the total sales and sales quota for each salesperson per year and then computes the difference between them.
- Two CTEs are defined: Sales_CTE and Sales_Quota_CTE, each responsible for computing total sales and total sales quota respectively.
- Sales_CTE calculates total sales by summing up the TotalDue column from the SalesOrderHeader table for each salesperson and year.
- Sales_Quota_CTE calculates total sales quota by summing up the SalesQuota column from the SalesPersonQuotaHistory table for each salesperson and year.
- The main query joins the two CTEs on SalesPersonID and SalesYear and calculates the difference between total sales and sales quota (TotalSales - SalesQuota).
- The results are ordered by SalesPersonID and SalesYear.
Sample Output:
salespersonid|salesyear|totalsales|salesquotayear|salesquota|amt_above_or_below_quota| -------------+---------+----------+--------------+----------+------------------------+ 274| 2011.0|32567.9155| 2011.0|32567.9155|-93432.084 | 274| 2012.0|516197.368| 2012.0|516197.368|45197.3680 | 274| 2013.0|485880.642| 2013.0|485880.642|-35119.358 | 274| 2014.0|201288.519| 2014.0|201288.519|14288.5196 | 275| 2011.0|986298.090| 2011.0|986298.090|-438701.90 | 275| 2012.0|3806298.30| 2012.0|3806298.30|-225701.69 | 275| 2013.0|4490942.20| 2013.0|4490942.20|-345057.79 | 275| 2014.0|1191828.47| 2014.0|1191828.47|322828.474 | 276| 2011.0|1294819.74| 2011.0|1294819.74|-788180.25 | 276| 2012.0|4328860.05| 2012.0|4328860.05|465860.053 | 276| 2013.0|4637217.83| 2013.0|4637217.83|-78782.167 | 276| 2014.0|1434121.43| 2014.0|1434121.43|310121.430 | 277| 2011.0|1477158.28| 2011.0|1477158.28|-805841.71 | 277| 2012.0|4865650.84| 2012.0|4865650.84|122650.842 | ...
Contribute your code and comments through Disqus.
Previous: Get mailing addresses for companies in cities begin with PA outside US.
Next: Cross product of BusinessEntityID and Department columns.
What is the difficulty level of this exercise?
Test your Programming skills with w3resource's quiz.
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics