Skip to content

Commit b165c3a

Browse files
Update Advanced Problems.MD
1 parent 83d40cf commit b165c3a

File tree

1 file changed

+284
-19
lines changed

1 file changed

+284
-19
lines changed

Advanced Problems.MD

+284-19
Original file line numberDiff line numberDiff line change
@@ -696,32 +696,297 @@ ORDER BY TotalInGrooup DESC
696696
How would you write the SQL?
697697
There's a table called CustomerGroupThreshold that you will need to use. Use only orders from 2016.**
698698
```SQL
699+
WITH cte AS(
700+
SELECT
701+
o.CustomerID,
702+
c.CompanyName,
703+
SUM(d.Quantity * d.UnitPrice) AS TotalAmount
704+
FROM Orders o
705+
LEFT JOIN OrderDetails d
706+
ON o.OrderID = d.OrderID
707+
LEFT JOIN Customers C
708+
ON o.CustomerID = c.CustomerID
709+
WHERE YEAR(o.OrderDate) = 2016
710+
GROUP BY o.CustomerID, c.CompanyName
711+
)
712+
SELECT TOP(10)
713+
c.CustomerID,
714+
c.CompanyName,
715+
c.TotalAmount,
716+
g.CustomerGroupName
717+
FROM cte c
718+
JOIN CustomerGroupThresholds g
719+
ON c.TotalAmount BETWEEN g.RangeBottom AND g.RangeTop
720+
ORDER BY c.CustomerID
699721
```
700722
**Result:**
701723

724+
- 81 rows were affeted, showing only the top 10
702725

726+
| CustomerID | CompanyName | TotalAmount | CustomerGroupName |
727+
|------------|------------------------------------|-------------|-------------------|
728+
| ALFKI | Alfreds Futterkiste | 2302,20 | Medium |
729+
| ANATR | Ana Trujillo Emparedados y helados | 514,40 | Low |
730+
| ANTON | Antonio Moreno Taquería | 660,00 | Low |
731+
| AROUT | Around the Horn | 5838,50 | High |
732+
| BERGS | Berglunds snabbköp | 8110,55 | High |
733+
| BLAUS | Blauer See Delikatessen | 2160,00 | Medium |
734+
| BLONP | Blondesddsl père et fils | 730,00 | Low |
735+
| BOLID | Bólido Comidas preparadas | 280,00 | Low |
736+
| BONAP | Bon app' | 7185,90 | High |
737+
| BOTTM | Bottom-Dollar Markets | 12227,40 | Very High |
738+
739+
**52. Some Northwind employees are planning a business trip, and would like to visit as many suppliers and customers as possible. For their planning, they’d like
740+
to see a list of all countries where suppliers and/or customers are based.**
741+
```SQL
742+
SELECT Country FROM Suppliers
743+
UNION
744+
SELECT Country FROM Customers
745+
ORDER BY Country
746+
```
747+
**Result:**
703748

749+
| Country |
750+
|-------------|
751+
| Argentina |
752+
| Australia |
753+
| Austria |
754+
| Belgium |
755+
| Brazil |
756+
| Canada |
757+
| Denmark |
758+
| Finland |
759+
| France |
760+
| Germany |
761+
| Ireland |
762+
| Italy |
763+
| Japan |
764+
| Mexico |
765+
| Netherlands |
766+
| Norway |
767+
| Poland |
768+
| Portugal |
769+
| Singapore |
770+
| Spain |
771+
| Sweden |
772+
| Switzerland |
773+
| UK |
774+
| USA |
775+
| Venezuela |
776+
777+
**53. The employees going on the business trip don’t want just a raw list of countries, they want more details. We’d like to see one column with the suppliers country and other with customers country.**
778+
```SQL
779+
WITH SupplierCountries AS(
780+
SELECT
781+
DISTINCT Country
782+
FROM Suppliers
783+
),
784+
CustomerCountries AS(
785+
SELECT
786+
DISTINCT Country
787+
FROM Customers
788+
)
789+
SELECT
790+
s.Country As SupplierCountries,
791+
c.Country AS CustomerCountry
792+
FROM SupplierCountries s
793+
FULL OUTER JOIN Customers c
794+
ON s.Country = c.Country
795+
GROUP BY s.Country, c.Country
796+
```
797+
**Result:**
704798

799+
| SupplierCountries | CustomerCountry |
800+
|-------------------|-----------------|
801+
| NULL | Argentina |
802+
| NULL | Austria |
803+
| NULL | Belgium |
804+
| NULL | Ireland |
805+
| NULL | Mexico |
806+
| NULL | Poland |
807+
| NULL | Portugal |
808+
| NULL | Switzerland |
809+
| NULL | Venezuela |
810+
| Australia | NULL |
811+
| Brazil | Brazil |
812+
| Canada | Canada |
813+
| Denmark | Denmark |
814+
| Finland | Finland |
815+
| France | France |
816+
| Germany | Germany |
817+
| Italy | Italy |
818+
| Japan | NULL |
819+
| Netherlands | NULL |
820+
| Norway | Norway |
821+
| Singapore | NULL |
822+
| Spain | Spain |
823+
| Sweden | Sweden |
824+
| UK | UK |
825+
| USA | USA |
826+
827+
**54. The output of the above is improved, but it’s still not ideal. What we’d really like to see is the country name, the total suppliers, and the total customers.**
828+
```SQL
829+
WITH SupplierCountries AS (
830+
SELECT
831+
Country,
832+
Count(*) AS Total
833+
FROM Suppliers
834+
GROUP BY Country
835+
),
836+
CustomerCountries AS (
837+
SELECT
838+
Country,
839+
Count(*) AS Total
840+
FROM Customers
841+
GROUP BY Country
842+
)
843+
SELECT
844+
ISNULL(SupplierCountries.Country, CustomerCountries.Country) AS Country,
845+
ISNULL(SupplierCountries.Total,0) AS TotalSuppliers,
846+
ISNULL(CustomerCountries.Total,0) AS TotalCustomers
847+
FROM SupplierCountries
848+
FULL OUTER JOIN CustomerCountries
849+
ON CustomerCountries.Country = SupplierCountries.Country
850+
```
851+
**Result:**
705852

853+
| Country | TotalSuppliers | TotalCustomers |
854+
|-------------|----------------|----------------|
855+
| Argentina | 0 | 3 |
856+
| Australia | 2 | 0 |
857+
| Austria | 0 | 2 |
858+
| Belgium | 0 | 2 |
859+
| Brazil | 1 | 9 |
860+
| Canada | 2 | 3 |
861+
| Denmark | 1 | 2 |
862+
| Finland | 1 | 2 |
863+
| France | 3 | 11 |
864+
| Germany | 3 | 11 |
865+
| Ireland | 0 | 1 |
866+
| Italy | 2 | 3 |
867+
| Japan | 2 | 0 |
868+
| Mexico | 0 | 5 |
869+
| Netherlands | 1 | 0 |
870+
| Norway | 1 | 1 |
871+
| Poland | 0 | 1 |
872+
| Portugal | 0 | 2 |
873+
| Singapore | 1 | 0 |
874+
| Spain | 1 | 5 |
875+
| Sweden | 2 | 2 |
876+
| Switzerland | 0 | 2 |
877+
| UK | 2 | 7 |
878+
| USA | 4 | 13 |
879+
| Venezuela | 0 | 4 |
880+
881+
**55. Looking at the Orders table—we’d like to show details for each order that was the first in that particular country, ordered by OrderID. So, we need one row per ShipCountry, and CustomerID, OrderID, and OrderDate should be of the first order from that country.**
882+
```SQL
883+
WITH CTE as(
884+
SELECT
885+
ShipCountry,
886+
CustomerID,
887+
OrderID,
888+
CONVERT(DATE, OrderDate) AS OrderDate,
889+
ROW_NUMBER() OVER (PARTITION BY ShipCountry ORDER BY ShipCountry, OrderID) AS OrderNumber
890+
FROM Orders
891+
)
892+
SELECT
893+
ShipCountry,
894+
CustomerID,
895+
OrderID,
896+
OrderDate
897+
FROM CTE
898+
WHERE OrderNumber = 1
899+
```
900+
**Result:**
706901

902+
| ShipCountry | CustomerID | OrderID | OrderDate |
903+
|-------------|------------|---------|------------|
904+
| Argentina | OCEAN | 10409 | 2015-01-09 |
905+
| Austria | ERNSH | 10258 | 2014-07-17 |
906+
| Belgium | SUPRD | 10252 | 2014-07-09 |
907+
| Brazil | HANAR | 10250 | 2014-07-08 |
908+
| Canada | MEREP | 10332 | 2014-10-17 |
909+
| Denmark | SIMOB | 10341 | 2014-10-29 |
910+
| Finland | WARTH | 10266 | 2014-07-26 |
911+
| France | VINET | 10248 | 2014-07-04 |
912+
| Germany | TOMSP | 10249 | 2014-07-05 |
913+
| Ireland | HUNGO | 10298 | 2014-09-05 |
914+
| Italy | MAGAA | 10275 | 2014-08-07 |
915+
| Mexico | CENTC | 10259 | 2014-07-18 |
916+
| Norway | SANTG | 10387 | 2014-12-18 |
917+
| Poland | WOLZA | 10374 | 2014-12-05 |
918+
| Portugal | FURIB | 10328 | 2014-10-14 |
919+
| Spain | ROMEY | 10281 | 2014-08-14 |
920+
| Sweden | FOLKO | 10264 | 2014-07-24 |
921+
| Switzerland | CHOPS | 10254 | 2014-07-11 |
922+
| UK | BSBEV | 10289 | 2014-08-26 |
923+
| USA | RATTC | 10262 | 2014-07-22 |
924+
| Venezuela | HILAA | 10257 | 2014-07-16 |
925+
926+
**56. There are some customers for whom freight is a major expense when ordering from Northwind. However, by batching up their orders, and making one larger order instead of multiple smaller orders in a short period of time, they could reduce their freight costs significantly.
927+
Show those customers who have made more than 1 order in a 5 day period. The sales people will use this to help customers reduce their costs.**
928+
```SQL
929+
SELECT TOP(10)
930+
InitialOrder.CustomerID,
931+
InitialOrder.OrderID AS InitialOrderID,
932+
InitialOrder.OrderDate AS InitialOrderDate,
933+
NextOrder.OrderID AS NextOrderID,
934+
NextOrder.OrderDate AS NextOrderDate,
935+
DATEDIFF(dd, InitialOrder.OrderDate, NextOrder.OrderDate) AS DaysBetween
936+
FROM Orders InitialOrder
937+
JOIN Orders NextOrder
938+
ON InitialOrder.CustomerID = NextOrder.CustomerID
939+
WHERE InitialOrder.OrderID < NextOrder.OrderID AND DATEDIFF(dd, InitialOrder.OrderDate, NextOrder.OrderDate) <= 5
940+
ORDER BY InitialOrder.CustomerID, InitialOrder.OrderID
941+
```
942+
**Result:**
707943

944+
- 71 rows were affeted, showing only the top 10
945+
946+
| CustomerID | InitialOrderID | InitialOrderDate | NextOrderID | NextOrderDate | DaysBetween |
947+
|------------|----------------|-------------------------|-------------|-------------------------|-------------|
948+
| ANTON | 10677 | 2015-09-22 20:00:00.000 | 10682 | 2015-09-25 04:00:00.000 | 3 |
949+
| AROUT | 10741 | 2015-11-14 10:00:00.000 | 10743 | 2015-11-17 18:00:00.000 | 3 |
950+
| BERGS | 10278 | 2014-08-12 14:00:00.000 | 10280 | 2014-08-14 10:00:00.000 | 2 |
951+
| BERGS | 10444 | 2015-02-12 11:00:00.000 | 10445 | 2015-02-13 20:00:00.000 | 1 |
952+
| BERGS | 10866 | 2016-02-03 01:00:00.000 | 10875 | 2016-02-06 21:00:00.000 | 3 |
953+
| BONAP | 10730 | 2015-11-05 07:00:00.000 | 10732 | 2015-11-06 15:00:00.000 | 1 |
954+
| BONAP | 10871 | 2016-02-05 19:00:00.000 | 10876 | 2016-02-09 17:00:00.000 | 4 |
955+
| BONAP | 10932 | 2016-03-06 01:00:00.000 | 10940 | 2016-03-11 02:00:00.000 | 5 |
956+
| BOTTM | 10410 | 2015-01-10 18:00:00.000 | 10411 | 2015-01-10 21:00:00.000 | 0 |
957+
| BOTTM | 10944 | 2016-03-12 04:00:00.000 | 10949 | 2016-03-13 13:00:00.000 | 1 |
958+
959+
**57. There’s another way of solving the problem above, using Window functions. We would like to see the following results.**
960+
```SQL
961+
WITH cte AS(
962+
SELECT
963+
CustomerID,
964+
CONVERT(DATE, OrderDate) AS OrderDate,
965+
CONVERT(DATE, LEAD(OrderDate,1) OVER (PARTITION BY CustomerID ORDER BY CustomerID, OrderDate)) AS NextOrderDate
966+
FROM Orders
967+
--ORDER BY CustomerID, OrderID
968+
)
969+
SELECT
970+
cte.CustomerID,
971+
cte.OrderDate,
972+
cte.NextOrderDate,
973+
DATEDIFF(DD, cte.OrderDate, cte.NextOrderDate) AS DaysBetweenOrders
974+
FROM cte
975+
WHERE DATEDIFF(DD, cte.OrderDate, cte.NextOrderDate) <=5
976+
```
977+
**Result:**
708978

709-
710-
711-
712-
713-
714-
715-
716-
717-
718-
719-
720-
721-
722-
723-
724-
725-
726-
727-
979+
- 69 rows were affeted, showing only the top 10
980+
981+
| CustomerID | OrderDate | NextOrderDate | DaysBetweenOrders |
982+
|------------|------------|---------------|-------------------|
983+
| ANTON | 2015-09-22 | 2015-09-25 | 3 |
984+
| AROUT | 2015-11-14 | 2015-11-17 | 3 |
985+
| BERGS | 2014-08-12 | 2014-08-14 | 2 |
986+
| BERGS | 2015-02-12 | 2015-02-13 | 1 |
987+
| BERGS | 2016-02-03 | 2016-02-06 | 3 |
988+
| BONAP | 2015-11-05 | 2015-11-06 | 1 |
989+
| BONAP | 2016-02-05 | 2016-02-09 | 4 |
990+
| BONAP | 2016-03-06 | 2016-03-11 | 5 |
991+
| BOTTM | 2015-01-10 | 2015-01-10 | 0 |
992+
| BOTTM | 2016-03-12 | 2016-03-13 | 1 |

0 commit comments

Comments
 (0)