YouTube2Text

SQL Full Course for Beginners (30 Hours) – From Zero to Hero — Transcript

by Data with Baraa · 363,984 words · 48,358 segments · language en · Watch on YouTube

Full transcript

  1. 0:00Hello and welcome to this unique course
  2. 0:01to master SQL. My name is Barzalini and
  3. 0:04I lead big data projects at
  4. 0:05Mercedes-Benz over a decade of
  5. 0:07experience in SQL data engineering,
  6. 0:10building data warehouses and data
  7. 0:12analytics. Now, of course, the first
  8. 0:13question is what makes this course so
  9. 0:15special. Well, not only you will learn
  10. 0:17how to write SQL codes, but more
  11. 0:19important than that, you will learn how
  12. 0:21exactly SQL works behind the scenes. So
  13. 0:24I'm going to break complex concept in
  14. 0:26SQL using hundreds of animated visuals.
  15. 0:29This makes it really easier to
  16. 0:31understand SQL and as well it is more
  17. 0:33fun than just sharing my screen and I
  18. 0:35just show you code. Right. The second
  19. 0:37reason is this course is taught by me. I
  20. 0:39have industrial experience and I will be
  21. 0:42sharing with you everything that I know
  22. 0:43about SQL and how I use it in my real
  23. 0:46projects. So I will be sharing with you
  24. 0:47hundreds of best practices, tips and
  25. 0:50tricks and I'm going to show you my
  26. 0:51decision-m process in SQL. So by the end
  27. 0:54of this course, you will be ready to
  28. 0:56solve any complex task like I do using
  29. 0:58SQL. So now I designed this course to
  30. 1:01cover the basics like writing your first
  31. 1:03SQL query and then we're going to keep
  32. 1:05progressing in the course by covering
  33. 1:07advanced techniques in SQL like the
  34. 1:09window functions, stored procedures,
  35. 1:11indexes and even at the end we're going
  36. 1:13to build a data warehouse using SQL. And
  37. 1:16this course is suitable for anyone data
  38. 1:18engineers, data analyst, data scientist
  39. 1:20and even for students. And by the way
  40. 1:22the good news everything is for free
  41. 1:24from the start until the ends I will be
  42. 1:26sharing with you as well a lot of
  43. 1:28materials code presentations and
  44. 1:30animations and there are no hidden
  45. 1:32costs. So you don't have to pay for
  46. 1:34anything. But my friends in return I
  47. 1:36really appreciate it if you support the
  48. 1:37channel in order to grow. All right my
  49. 1:39friends I'm really excited about it. I
  50. 1:41don't know about you. If you are
  51. 1:42motivated join me learning SQL. This is
  52. 1:45going to be amazing. So let's
  53. 1:50go. All right. Now I'm going to show you
  54. 1:52the road map in order to learn
  55. 1:53everything about SQL starting from very
  56. 1:56basics and then advance step by step
  57. 1:58until we have very advanced topics. So
  58. 2:00now at the start we have to understand
  59. 2:02few stuff like what is SQL, why to learn
  60. 2:04it, what are databases and the types of
  61. 2:07databases and after the theory we're
  62. 2:09going to prepare your PC with data and
  63. 2:11the softwares. Now once we have
  64. 2:12everything then we can go to the next
  65. 2:14chapter. This is the basics how to query
  66. 2:16data using SQL and here we're going to
  67. 2:18cover the basic components in each SQL
  68. 2:21query like select from where those
  69. 2:24basics. Now once you understand how to
  70. 2:26query the data, how to get the data out
  71. 2:28of the database the next step we're
  72. 2:30going to go and learn how to define the
  73. 2:32structure of the database. How to create
  74. 2:34a new table add a new column remove
  75. 2:37column and as well how to drop a table.
  76. 2:39So with that you are defining new stuff
  77. 2:41in the database and then the next
  78. 2:43chapter you have to learn about the data
  79. 2:45manipulation. This time we're going to
  80. 2:46go inside the table and we're going to
  81. 2:48learn how to insert a new data, how to
  82. 2:50update the data and as well delete few
  83. 2:53rows from our database. So with that you
  84. 2:54have the basics how to query data, how
  85. 2:57to define the structure of your tables
  86. 2:58and how to manipulate your data. And I
  87. 3:01can say with that you cover the basics
  88. 3:02about SQL. Now after that we start with
  89. 3:05the intermediate phase where we're going
  90. 3:06to deep dive into topics like how to
  91. 3:08filter your data. Here we're going to
  92. 3:10learn about the comparison operators,
  93. 3:12logical operators, between and like. So
  94. 3:15all the operators that you can use in
  95. 3:17order to build a condition in order to
  96. 3:19filter your data. Then after that it's
  97. 3:21going to be very interesting topic. You
  98. 3:23have to learn how to combine them. And
  99. 3:24here we have two mechanism either using
  100. 3:26the join or using the set operators. And
  101. 3:29oh my god joining data. It's going to be
  102. 3:31very interesting topic. Here we're going
  103. 3:33to cover like a lot of stuff like we're
  104. 3:34going to start with the basic joins and
  105. 3:36then we go to advanced and then you have
  106. 3:38to learn how to choose the right join
  107. 3:40and after that you have to learn about
  108. 3:42the set operators and here you have like
  109. 3:44four methods union union all except
  110. 3:46intersects. So with that you learn how
  111. 3:48to combine multiple tables by combining
  112. 3:51the columns or the rows of your tables.
  113. 3:54So this is very important. Now moving on
  114. 3:56in our course. Now using SQL you can do
  115. 3:58a lot of stuff cleaning up the data a
  116. 4:01lot of data preparations and at the end
  117. 4:03you can do a lot of analytics and
  118. 4:05aggregations. So there are like two
  119. 4:07families of functions. The first one is
  120. 4:09the role level functions and here we
  121. 4:10have a lot of stuff you can transform
  122. 4:12your string values the numbers date and
  123. 4:15time and how to handle the nulls in SQL
  124. 4:17and at the end the amazing case
  125. 4:19statements. So all those stuffs are
  126. 4:21transformation for only one single
  127. 4:23value. We call it role level functions.
  128. 4:25And after you learn how to do data
  129. 4:26transformations, then you have to learn
  130. 4:28about how to do data analytics and
  131. 4:30aggregations using SQL functions. So
  132. 4:33we're going to start with very basics
  133. 4:34like the aggregate functions. And then
  134. 4:36we're going to deep dive into the window
  135. 4:38functions, analytical functions. And
  136. 4:40here we have like aggregates, ranking
  137. 4:42and value functions. Those are very
  138. 4:44important tool for any data analyst or
  139. 4:47data scientist doing analytics task in
  140. 4:49SQL. So I can say the rowle functions is
  141. 4:52for data engineers and the analytical
  142. 4:54functions are for data analysts. So at
  143. 4:56the chapter 8 we can say you have
  144. 4:58covered now the intermediate level and
  145. 5:00the last four chapters they will be the
  146. 5:02advanced stuff in SQL. So here there are
  147. 5:05a lot of techniques that you have to
  148. 5:06learn about SQL. So the first one is the
  149. 5:09subquery query inside another query and
  150. 5:11the very famous CTE common table
  151. 5:14expression. A lot of developers like
  152. 5:16this one and then you will learn about
  153. 5:17how to create views in the database.
  154. 5:20This technique if you learn it you're
  155. 5:21going to be really professional in SQL.
  156. 5:23Then we're going to learn how to create
  157. 5:24tables using select the temporal tables
  158. 5:27and then we're going to learn about the
  159. 5:28third procedures how to write a program
  160. 5:30in SQL and after that of course comes
  161. 5:33the triggers. So those are the advanced
  162. 5:35techniques that you have to learn in SQL
  163. 5:37in order to do advanced projects using
  164. 5:40SQL. So now once you learn all those
  165. 5:42concepts and you start writing a lot of
  166. 5:44SQL codes you will notice that some
  167. 5:46queries going to be really slow and for
  168. 5:48that you have to learn how to optimize
  169. 5:50the performance of your queries and here
  170. 5:52there are a lot of techniques. The most
  171. 5:53famous one is to create an index in the
  172. 5:55database or create a partition and at
  173. 5:58the end I will be sharing with you the
  174. 6:00top 10 best practices that I have
  175. 6:02learned in my projects on how to
  176. 6:04optimize the performance of your
  177. 6:05queries. So this is very important and
  178. 6:08then we're going to move to very
  179. 6:09interesting one. I will be sharing with
  180. 6:11you how I use AI like shy GBT or copilot
  181. 6:14as I'm using SQL in my projects. So here
  182. 6:17you have to learn how to write correct
  183. 6:19prompts to get assistance from AI as you
  184. 6:22are using SQL. And finally and my
  185. 6:24favorite one it will be about SQL
  186. 6:27projects. So my friends here you have to
  187. 6:28bring everything that you have learned
  188. 6:30about SQL in handon projects. With real
  189. 6:34projects you will get challenges and
  190. 6:36struggle and here going to happen the
  191. 6:37magic and the real learning and here
  192. 6:39there are three types of projects. The
  193. 6:41first one is data warehousing project.
  194. 6:43This is very data engineering focused
  195. 6:45project where you're going to learn how
  196. 6:46to build real data warehouse where
  197. 6:48you're going to take the data from the
  198. 6:49raw formats and then process it in
  199. 6:51different layers. Once you build it then
  200. 6:53you jump to another project. Here you're
  201. 6:55going to start exploring the data and
  202. 6:57start getting the first insights about
  203. 6:59the business. And the last project that
  204. 7:01you can do is the advanced data
  205. 7:03analytics project. So this is very
  206. 7:05important section where you do SQL
  207. 7:07projects. So my friends this is the road
  208. 7:09map on how to learn SQL. So as you can
  209. 7:12see it takes you step by step from
  210. 7:13basics to intermediate and you will end
  211. 7:16up having advanced topics and with that
  212. 7:18I can tell you you will learn everything
  213. 7:19about SQL. Okay. So now let's start with
  214. 7:21the first chapter the introduction to
  215. 7:23SQL and here we're going to cover few
  216. 7:24topics. So we have to understand first
  217. 7:26what is exactly SQL? Why we have to
  218. 7:28learn it? what are databases and the
  219. 7:31different SQL commands that we have in
  220. 7:32SQL. So it is the basics the theory
  221. 7:35about SQL. So what is exactly SQL? Let's
  222. 7:42go. So what is exactly SQL? Everything
  223. 7:45generate data and data is everywhere.
  224. 7:47Your first name is data your mobile and
  225. 7:50everything inside the mobile is data.
  226. 7:51Car is as well generating a lot of data.
  227. 7:54Bank, your finance statements,
  228. 7:55everything is data. And now of course
  229. 7:57the question is where do we store our
  230. 7:58data? Personally we store a lot of our
  231. 8:00data in like excels, spreadsheets in a
  232. 8:03text file. So you store a lot of your
  233. 8:05data in different files. Now how about
  234. 8:08companies? They have a lot of things
  235. 8:09that generate a lot of data that the
  236. 8:11products that they produce their
  237. 8:13customers as well generating a lot of
  238. 8:15data and sales informations and a lot of
  239. 8:17things. So companies generate massive
  240. 8:20amount of data. So now the big question
  241. 8:21is how they handle the data how they
  242. 8:23store it. Of course, they cannot go
  243. 8:25unused like simple files. They need
  244. 8:27something bigger, stronger and smarter.
  245. 8:29And here where the database comes in. So
  246. 8:31think about the database. It's like a
  247. 8:33container for storing data. But instead
  248. 8:35of just dumping files into folders, the
  249. 8:38database organized the data. So it is
  250. 8:40easy to access, to manage and to search.
  251. 8:43So a database simply it is a container
  252. 8:45that stores data. So now you might ask
  253. 8:48why we are using database. Can't we just
  254. 8:50use files like I do it personally? Well,
  255. 8:52let me tell you why we use databases.
  256. 8:54Imagine that someone asks the following
  257. 8:55question. Go and find the total spending
  258. 8:58in your data. So now, in order for Mike
  259. 9:00to find the total spending and the
  260. 9:02costs, he will be opening each of those
  261. 9:04files one by one, searching for the
  262. 9:06costs trying to combine the data and
  263. 9:09it's going to be very long and messy
  264. 9:11process. But now in the other side, if
  265. 9:13your data in database and you want to
  266. 9:14ask a question, it's going to be very
  267. 9:16easy. So all what you have to do is to
  268. 9:18talk to the database to ask a question
  269. 9:20and the database can answer your
  270. 9:22question with a result. And now comes of
  271. 9:24course the question how do we talk to a
  272. 9:26database? Well we use SQL. SQL is the
  273. 9:30language that you use in order to talk
  274. 9:33to the database. It stands for
  275. 9:35structured query language SQL. And here
  276. 9:38you have people that call it SQL like me
  277. 9:41and others that call it SQL. There is no
  278. 9:43right and wrong but if you follow me
  279. 9:45through the course I think you will
  280. 9:47start saying SQL. So by using SQL you
  281. 9:50can ask the database you can ask your
  282. 9:52data and the database going to answer
  283. 9:54your question by sending you a result.
  284. 9:56So this process is very easy simple and
  285. 9:58fast and this is way better than having
  286. 10:00your data stored in different files.
  287. 10:02Another reason why we use databases is
  288. 10:04that they can handle really huge amount
  289. 10:07of data. So sometimes we have like
  290. 10:09millions of data inside our database but
  291. 10:11in the other side if you are storing
  292. 10:12your data inside spreadsheets and you
  293. 10:14have like massive amount of data what
  294. 10:16can happen your spreadsheets going to
  295. 10:18just break they simply can't handle big
  296. 10:20data and another reason why we use
  297. 10:22databases is that it is just secure. It
  298. 10:25is safer to store important and critical
  299. 10:27data inside the database than just
  300. 10:29storing it in spreadsheets and files. So
  301. 10:31the databases are secure and you can
  302. 10:33control who is accessing what. So it is
  303. 10:36just more professional to store the data
  304. 10:38inside a database. All right my friends
  305. 10:40so far what we have learned most of the
  306. 10:42companies stores their data inside a
  307. 10:44container called a database and for you
  308. 10:47in order to ask questions and to talk to
  309. 10:49your database you have to speak the
  310. 10:51language of
  311. 10:55SQL. Now I'm going to show you how it
  312. 10:57looks like usually in companies. So we
  313. 10:59have our data inside the database and
  314. 11:01then you will have multiple people with
  315. 11:03multiple roles that are just writing
  316. 11:05different SQLs in order to talk to the
  317. 11:08data. But now not only employees and
  318. 11:09people interact with the database. You
  319. 11:11could build a website or an application
  320. 11:14that as well interacts with the database
  321. 11:16by sending different SQLs. And of
  322. 11:18course, depend on how many people are
  323. 11:19interacting with the application and the
  324. 11:21website, it might generate really
  325. 11:23massive amount of SQLs that sent to the
  326. 11:26database. And not only that, you might
  327. 11:28has as well tools in order to do data
  328. 11:30visualizations where you have like a
  329. 11:32dashboard or reports maybe created using
  330. 11:34PowerBI or Tableau and it is used by
  331. 11:37stakeholders and managers in order to
  332. 11:39make decisions and as well those tools
  333. 11:42will be connected to the database and
  334. 11:44creating SQLs. So now as you can see we
  335. 11:46have a lot of interactions with the
  336. 11:48database from people applications tools
  337. 11:51a lot of things are generating SQLs and
  338. 11:54interacting with the database but the
  339. 11:56database is just a container and storage
  340. 11:58right so we need something a software
  341. 12:00that manage all those requests and
  342. 12:02that's why we have something called
  343. 12:04database management system DPMS so it is
  344. 12:07a software that going to manage all
  345. 12:09those different requests to our database
  346. 12:11and it going to make the priority which
  347. 12:13SQL must be executed First, this
  348. 12:15software can as well manage the security
  349. 12:18whether the SQL is allowed to be
  350. 12:20executed in the first place. So my
  351. 12:22friends, the DPMS is the software that
  352. 12:24going to manage the database. And now we
  353. 12:26are not done yet. There is something
  354. 12:28missing. So we have our data, we have
  355. 12:30the software. What is missing here is
  356. 12:31the hardware. So in real companies, we
  357. 12:33cannot run that on our PC because first
  358. 12:36our PC is weak and as well it goes
  359. 12:38offline. That's why we need a server.
  360. 12:40server it is like very powerful PC and
  361. 12:43as well it lives 24/7 so it is always
  362. 12:46available and here we can decide whether
  363. 12:48we're going to have a server inside the
  364. 12:49company or we can use cloud services in
  365. 12:52order to run our database so my friends
  366. 12:54so far what we have learned the database
  367. 12:56it is container to store the data the
  368. 12:58SQL it is the language in order to talk
  369. 13:01to the database the DPMS it is the
  370. 13:03manager it manage the database and the
  371. 13:06server it is the physical machine where
  372. 13:08the database lives so this is how it
  373. 13:10looks
  374. 13:13Like and now my friends there are
  375. 13:16different types of databases. So let's
  376. 13:18see what do we have. The first and the
  377. 13:19most famous one it is the relational
  378. 13:22database. It is very simple. It is like
  379. 13:24spreadsheets call them table where we
  380. 13:26have columns and rows and then there is
  381. 13:28like a relationship between those tables
  382. 13:30to describe how they relate to each
  383. 13:32other and that's why we call it
  384. 13:33relational database. So if people hear a
  385. 13:35database they're going to think about
  386. 13:37this one. Now we have another type of
  387. 13:39databases called key value. This time
  388. 13:41the data is organized completely
  389. 13:43different where you have pairs of keys
  390. 13:45and values. Think about it. It's like a
  391. 13:47big dictionary where you have a word
  392. 13:49like the key and the definition of the
  393. 13:51word this is the value. And now moving
  394. 13:53on to the next one. This is as well
  395. 13:54important column based. So now instead
  396. 13:56of grouping the data by the rows this
  397. 13:59type of databases group the data into
  398. 14:01columns. That's why it's called column
  399. 14:03paste. And this is very advanced
  400. 14:05database in order to handle huge amount
  401. 14:07of data where the main purpose is to
  402. 14:09search for data. Moving on to another
  403. 14:11database called graph database. The main
  404. 14:13focus here is the relationship between
  405. 14:15objects. So the main idea here is how to
  406. 14:18connect my data points. And now finally
  407. 14:20we have the document database. The data
  408. 14:22is stored as entire documents where the
  409. 14:25structure of the data is not that
  410. 14:26important. What is more important is to
  411. 14:28fit everything in one page in one
  412. 14:30document. And now if you look to those
  413. 14:32five types, we can group the document,
  414. 14:34graph, column based, key value, all
  415. 14:36those databases called NoSQL databases
  416. 14:39and the relational database, SQL
  417. 14:42database. And in this course, we will be
  418. 14:44focusing of course on the relational
  419. 14:45database. And I'm sure you have heard
  420. 14:47about like the Microsoft SQL server, the
  421. 14:50MySQL, the
  422. 14:52possesses they are SQL relational
  423. 14:55database. And for the key value you have
  424. 14:57the radius the Amazon Dynamo DB and we
  425. 15:00have for the column paste we have the
  426. 15:01Cassandra and the red shift. For the
  427. 15:03graph database we have the Neo 4G and
  428. 15:06the very famous database the MongoDB as
  429. 15:08a document database. Now my friends for
  430. 15:11this course we're going to be focusing
  431. 15:12on the SQL relational databases because
  432. 15:15it is the most famous one and the most
  433. 15:18used one in companies and I will be
  434. 15:20focusing on the Microsoft SQL server. So
  435. 15:22those are the different types of
  436. 15:23databases.
  437. 15:28Now the databases are very structured
  438. 15:30and organized. It has the following
  439. 15:32hierarchy. The starting point is the
  440. 15:34server as we learned it is powerful PC
  441. 15:36and it is where the database lives and
  442. 15:38inside it we can have multiple
  443. 15:40databases. So maybe you have a database
  444. 15:42for the sales and another one for the
  445. 15:44HR. So the server can host multiple
  446. 15:47databases and as we learned a database
  447. 15:49is a container of your data. Now moving
  448. 15:51on to the next level. In each database
  449. 15:53we can have multiple schemas. A schema
  450. 15:56it is like category or you can call it a
  451. 15:58logical container that we can use it in
  452. 16:00order to group up related objects like
  453. 16:02let's say you have hundred of tables. So
  454. 16:04you can split all the tables that has to
  455. 16:06do with the orders in one schema and
  456. 16:08then another group of tables with the
  457. 16:10schema customers and so on. So it help
  458. 16:13you to organize your tables and your
  459. 16:14objects in the database. And now if you
  460. 16:16go inside schema you can have multiple
  461. 16:18objects like tables. So now of course
  462. 16:20the question is what is a table? It is
  463. 16:23like spreadsheet. It organize your data
  464. 16:25into columns. The column define the data
  465. 16:27that you store inside it. So you have
  466. 16:29one column about the customer ID.
  467. 16:31Another column about the names, the
  468. 16:33scores, the birthday. So each column is
  469. 16:35about one type of data and sometimes we
  470. 16:38call the columns as fields. Now the
  471. 16:39other thing that we have in tables is
  472. 16:41the rows or sometimes we call it
  473. 16:43records. It is where actually the data
  474. 16:45is stored. Now in this example each
  475. 16:47record represent one customer one
  476. 16:50person. So we have one record for Maria,
  477. 16:52John and Peter. Those we call them rows.
  478. 16:55Now in each table there is like one very
  479. 16:57important column called the primary key.
  480. 16:59It is always very important to have like
  481. 17:01one unique identifier for each customer
  482. 17:04for each row and we use it for different
  483. 17:06purposes in order to combine it with
  484. 17:08another table in order to identify
  485. 17:10quickly one customer. So it is unique.
  486. 17:13It's like fingerprint and there is no
  487. 17:14two customers having the same ID. Now
  488. 17:17the overlapping between the columns and
  489. 17:18the rows we have a single value a cell
  490. 17:21and each value each column stores
  491. 17:24specific data type. A data type it is
  492. 17:26like what kind of data we are storing
  493. 17:28like an integer 1 2 30 or a decimal
  494. 17:31where you have a decimal point 3.14. Now
  495. 17:34if you want to store characters we have
  496. 17:36different data types for that like you
  497. 17:37want to store the name or the
  498. 17:39description. So here we can use the char
  499. 17:42or the vchar. So you store inside them
  500. 17:44like the first name Maria or something.
  501. 17:46Now you might ask what is a char or
  502. 17:48vchar. So the char always a fixed one.
  503. 17:50So if you define it like five characters
  504. 17:52always it's going to go and reserve five
  505. 17:54characters from the space. But if you
  506. 17:56want things more dynamic then you go
  507. 17:58with the vchar. And now moving on we
  508. 18:00have another data types called the date
  509. 18:02and time. So if you want to store a date
  510. 18:04like the birth dates and if you want to
  511. 18:05store the time information you can use
  512. 18:07the time data type. So we call those
  513. 18:09stuff int, decimal, char, date, time.
  514. 18:12They are data types. So my friends, as
  515. 18:14you can see, SQL databases are very
  516. 18:16organized and
  517. 18:20structured. Okay. So now let's focus
  518. 18:22more about the SQL itself. We have in
  519. 18:24SQL different type of commands. So let's
  520. 18:27say that we have a database and this
  521. 18:28database is empty. So we have nothing
  522. 18:30inside it. Now, of course, the first
  523. 18:32thing that you have to do is to write an
  524. 18:34SQL with the command create in order to
  525. 18:37create brand new table in the database.
  526. 18:39So, once you executed the database going
  527. 18:41to go and build one, but this table is
  528. 18:43empty. So, we have nothing inside it. So
  529. 18:45now what you have done here is you have
  530. 18:47defined something new, right? And we
  531. 18:49call this type of commands the data
  532. 18:51definition language, the DDL. We have
  533. 18:53create to create something new, alter in
  534. 18:56order to edit something that already
  535. 18:57exists and drop in order to delete
  536. 19:00something. to drop for example a table.
  537. 19:02So this is the first family of commands.
  538. 19:04Now if you look at our table, it is
  539. 19:05empty. What do we need? We need data. So
  540. 19:07let's say that we have a website or an
  541. 19:09application. Now this application is
  542. 19:11generating a lot of data. Now in order
  543. 19:13for this application to move the data
  544. 19:15inside our new table, it must use the
  545. 19:18SQL command insert. So if you execute
  546. 19:20insert, you can add a new data inside
  547. 19:22your table. This type of commands we
  548. 19:25call it data manipulation language. And
  549. 19:27here we have three commands. insert in
  550. 19:29order to insert a new data, update in
  551. 19:31order to update an already existing data
  552. 19:33and delete in order to go and delete
  553. 19:35data from your table and that's why we
  554. 19:36call it data manipulation language
  555. 19:38because you are manipulating your data.
  556. 19:40So what do we have now? We have table,
  557. 19:42we have data inside the table. Now what
  558. 19:44we can do we can start asking questions.
  559. 19:46So let's say that you have analytical
  560. 19:48question about your data. Now all what
  561. 19:50you have to do is to write something
  562. 19:51called SQL query and inside it you use
  563. 19:54the command select but the whole thing
  564. 19:56we call it a query. So you send a query
  565. 19:58to the database, you have a question and
  566. 20:00the database can return for you the
  567. 20:02result, the data answering your query,
  568. 20:05your question and we call this type of
  569. 20:07activities using SQL, the data query
  570. 20:10language. And here we have only one and
  571. 20:12it is very famous. We have the select.
  572. 20:15We can use it in order to query our
  573. 20:17data. So those are the three different
  574. 20:19commands in SQL. And of course, we're
  575. 20:21going to learn all of them, but we will
  576. 20:22spend most of our time learning how to
  577. 20:25write the correct query for the correct
  578. 20:31answer. And now you might ask me, Barra,
  579. 20:33why we have to learn SQL? And if the
  580. 20:35time goes back, are you going to learn
  581. 20:37SQL again? Well, for sure, of course.
  582. 20:40And here are the top three reasons that
  583. 20:42I have. The first one, you have to learn
  584. 20:43it in order to talk to the data. You
  585. 20:45know, most of the companies stores their
  586. 20:47data in databases, and this is a
  587. 20:49standard way. This is how they do it.
  588. 20:50And if you want to work on the company
  589. 20:52in the data field and you want to talk
  590. 20:54to their data, then you have to use SQL.
  591. 20:56It's like you move to another country
  592. 20:58where they speak another language and
  593. 21:00you want to live there for a long time,
  594. 21:01you have to speak their language. The
  595. 21:03same thing here. If you want to work
  596. 21:04with data, you have to learn the
  597. 21:06language in order to speak to the
  598. 21:08database, the SQL. So this is for me the
  599. 21:10most important reason why we have to
  600. 21:11learn SQL and SQL it is in high demand.
  601. 21:14If you go now and check the job
  602. 21:15description of the software developer,
  603. 21:17data analyst, data engineer, data
  604. 21:19scientist, I promise you you will find
  605. 21:21there that they going to demand for SQL.
  606. 21:23So you will find they going to ask for
  607. 21:25SQL skills almost in each job
  608. 21:27description. So if you check for any
  609. 21:29data related jobs, you will find that
  610. 21:31they going to ask for SQL skills. Now
  611. 21:33another reason that I have is it is
  612. 21:35industry standard. So if you go and
  613. 21:37check multiple modern data platforms and
  614. 21:40tools like PowerBI, Tableau, Kafka,
  615. 21:42Spark, Synaps, you will understand that
  616. 21:45there will be always a section where you
  617. 21:47have to enter SQL code. So most of those
  618. 21:49vendors adopt SQL because it is the
  619. 21:52standard. It is widely used. It is like
  620. 21:54selling points that their tools are
  621. 21:56easy. So those are my top three reasons
  622. 21:58why SQL is still relevant and why you
  623. 22:01have to learn it. Okay, my friends. So
  624. 22:02with that we have now clear
  625. 22:03understanding what is an SQL why we need
  626. 22:06it what are databases and their
  627. 22:08different types why do we have DBMS
  628. 22:10servers and as well now you have
  629. 22:12understanding how things are very
  630. 22:14organized and structured inside the
  631. 22:16databases so that's all this is SQL all
  632. 22:19right so with that we have covered the
  633. 22:20basics about what is SQL and databases
  634. 22:23now in the next step we're going to go
  635. 22:25and set up our environments so that
  636. 22:27means we're going to prepare your PC
  637. 22:28with the data with the databases and all
  638. 22:30the tools that you need in order to
  639. 22:32learn
  640. 22:36SQL. Okay. So now go to the link in the
  641. 22:38description and you will land here in my
  642. 22:40newsletter website and you can subscribe
  643. 22:42if you want to get weekly news about my
  644. 22:45content. I make as well post about data
  645. 22:48and many other projects. So once you do
  646. 22:50that what we're going to do now we're
  647. 22:51going to go to the downloads over here
  648. 22:53and you will find here all the materials
  649. 22:55of different courses and the one that we
  650. 22:56want is SQL ultimate course. Let's go
  651. 22:58over here. Now once you do that you will
  652. 23:00land to this page where I have listed
  653. 23:02all the important links. So the first
  654. 23:04one and the most important one is to go
  655. 23:06and download the course materials. Here
  656. 23:08you can find everything code the slides
  657. 23:10the presentations the whole course or if
  658. 23:12you don't want that you can go to my get
  659. 23:14repository and there you will find
  660. 23:15exactly the same materials. So let's go
  661. 23:17and download everything. Okay. So now go
  662. 23:19and put the downloaded folder somewhere
  663. 23:21safe and let's go inside it. And here
  664. 23:24you can find three things. The first one
  665. 23:26is the data sets. Here if you go inside
  666. 23:28it you will find the data for the course
  667. 23:30the databases that we will be using in
  668. 23:32order to practice SQL. So everything is
  669. 23:35available here. Now the second folder
  670. 23:37you can find all the documentations. So
  671. 23:39that means all the visuals the
  672. 23:40presentation slides everything that I
  673. 23:43present during the course. It is
  674. 23:44available here as a documentation notes
  675. 23:46for you. Now moving on to the third one
  676. 23:48we have the scripts. So during the
  677. 23:50course we will be writing a lot of SQL
  678. 23:52codes and all those codes are here
  679. 23:54available. So that means those are all
  680. 23:56the codes that is used in the course.
  681. 23:58Okay. So with that you have now all the
  682. 24:00course materials. All right. So now the
  683. 24:02next step is that we have to go and
  684. 24:03download the SQL Server Express and you
  685. 24:05can find the link as well over here. So
  686. 24:07let's go there SQL Server Express. And
  687. 24:09now we're going to land on the Microsoft
  688. 24:11page where we can see the different
  689. 24:13offering from Microsoft where it's
  690. 24:14called server. So either we have it on
  691. 24:16the Azure or we can download it on the
  692. 24:18on premises. But we don't want those
  693. 24:20stuff. Just scroll down to see those two
  694. 24:22options. So the first option on the left
  695. 24:24side we have the developer edition. You
  696. 24:26will get all the features and services
  697. 24:28that Microsoft offers with the SQL
  698. 24:31server. It is as well free but the
  699. 24:33installation here is little bit
  700. 24:34complicated. But in the second option on
  701. 24:36the right side we have the express
  702. 24:38edition. Installation here going to be
  703. 24:40really fast and very easy. You will get
  704. 24:42as well all the stuff that you need for
  705. 24:44practicing SQL and learn SQL. So both of
  706. 24:46the options are free. It's just a matter
  707. 24:48of the installation. We will go now for
  708. 24:50the express edition. So go and click
  709. 24:53download now and it's very small file.
  710. 24:55So let's go and start it. And now the
  711. 24:57installation going to start. So we have
  712. 24:59basic, custom and download media. So
  713. 25:00download media means download now and
  714. 25:02later we're going to do the
  715. 25:03installation. Custom means we have more
  716. 25:05control on how to download and install
  717. 25:07the stuff. The basic is the easiest one
  718. 25:09and the quickest one. So let's go with
  719. 25:11the basics and click on that. And let's
  720. 25:13go and accept all those stuff. And now
  721. 25:16let's click on install. So now it's
  722. 25:18going to install the applications,
  723. 25:19drivers and so on. It may take a little
  724. 25:22bit
  725. 25:24time. So in order to do that, let's go
  726. 25:27and click on install SS SMS. So let's
  727. 25:30click on that and as well we can find
  728. 25:32the link over here. So let's go to SQL
  729. 25:34Server Management Studio. So let's click
  730. 25:36on that. You can find of course this
  731. 25:38link as well with the other links that I
  732. 25:40have collected. So now we are again at
  733. 25:41Microsoft page. Let's go scroll down and
  734. 25:44now we will see the following link free
  735. 25:46download for SQL Server Management
  736. 25:48Studio SS SMS. So let's go and click on
  737. 25:51that and then it's going to go and
  738. 25:52download it. Let's go and start it. So
  739. 25:55the first thing that we have to define
  740. 25:56the location. I will go with the default
  741. 25:58stuff. So let's click on
  742. 26:02install. Okay. Setup completed. We just
  743. 26:05installed SM SS SMS. So let's go and
  744. 26:09close it. So now let's go and start it.
  745. 26:11If you go to your menu over here, search
  746. 26:13for SQL Server and you will find it
  747. 26:15here. SQL Server Management Studio.
  748. 26:17Let's go and start it. Okay, so now
  749. 26:20we're going to get this window in order
  750. 26:21to connect to our server. So again, what
  751. 26:23is our server? It is the one we have
  752. 26:25installed at the first step, SQL Server
  753. 26:28Express. And that's why you're going to
  754. 26:29see in the server name, your PC name, of
  755. 26:32course, like it's not going to be my PC
  756. 26:34name. But here we have something called
  757. 26:36SQL Express. This is the server we just
  758. 26:38installed. So in the first option, we
  759. 26:40have database engines. We have reporting
  760. 26:42services. Those are different stuff from
  761. 26:44Microsoft. We're going to leave it as a
  762. 26:46database engine. And it should be like
  763. 26:48this. SQL Express. Now, how to access
  764. 26:51this database? We have the following
  765. 26:53stuff. We can do that using the window
  766. 26:55authentications or SQL server
  767. 26:56authentications. I'm going to say that
  768. 26:58let's stick with the window
  769. 26:59authentication. And the username going
  770. 27:01to be the PC name and as well the window
  771. 27:04user. If you don't have it for some
  772. 27:06reason those informations, you can go to
  773. 27:08your search search for
  774. 27:10cmd and then here you can say who am I?
  775. 27:15And with that you will get the PC name
  776. 27:17and as well the user that you are
  777. 27:19currently logged in. And this is exactly
  778. 27:21what I'm seeing over here. One more
  779. 27:22thing if you're having issue connecting
  780. 27:24to your database make sure to check the
  781. 27:26encryption. It should be mandatory and
  782. 27:28to click on the trust server
  783. 27:30certificates. So once you do that you
  784. 27:31will be able to connect. Okay. So with
  785. 27:33that we have the server we have the
  786. 27:35client. And now the last step we have to
  787. 27:37go and create the database. We want to
  788. 27:39insert our data. So now if you look to
  789. 27:41the object explorer and open the
  790. 27:43databases you can see that we don't have
  791. 27:44any database. So now let's do something
  792. 27:46about it. Go back to the course
  793. 27:48materials inside the data sets you will
  794. 27:50find the following. You will find we
  795. 27:52have here three folders MySQL postcress
  796. 27:55and SQL server. So if you want to follow
  797. 27:57with this course using different
  798. 27:59database like MySQL and Postgress you
  799. 28:01can find the exact same data for the
  800. 28:03database that you are using. But now in
  801. 28:05this course we are using the SQL server.
  802. 28:07So if you follow me with that go inside
  803. 28:10the SQL server folder and here you will
  804. 28:12find four files with different
  805. 28:13extensions. So what is going on here?
  806. 28:15Now for this course we have two
  807. 28:16databases. One that is very simple
  808. 28:19called my database and second one that
  809. 28:21has more tables called sales DB. And now
  810. 28:24in SQL server there are multiple ways on
  811. 28:26how to create databases. I will show you
  812. 28:28now two methods on how to create the
  813. 28:30database. Now the first option we want
  814. 28:32to create the database from a script.
  815. 28:34And if you look to those files, we have
  816. 28:36here two files with the extension SQL.
  817. 28:39Those are files with SQL code. So let's
  818. 28:41start with the first one, the init SQL
  819. 28:43server my
  820. 28:45database.SQL. Go inside it. And now here
  821. 28:47we have the SQL code. Copy everything.
  822. 28:49And now let's go back to our studio and
  823. 28:51then go to the menu and click on new
  824. 28:53query. And here in the middle you can
  825. 28:55paste the code. So now we have the code
  826. 28:57for the first database. And all what you
  827. 28:59have to do is to go and execute it. So
  828. 29:01once we executed you will see we will
  829. 29:03not get any error. And now on the left
  830. 29:05side we don't see yet our database
  831. 29:07because we have to refresh. So right
  832. 29:09click on the databases and click
  833. 29:10refresh. And now you can see it my
  834. 29:12database. So now let's see the content.
  835. 29:14Go extend it and then go extend the
  836. 29:16tables. And now you see here our two
  837. 29:18tables customers and orders. Inside
  838. 29:20those tables we can find our data. In
  839. 29:22order to see the data right click for
  840. 29:24example of the customers and let's go
  841. 29:26with the option select top 1,000 rows.
  842. 29:28Once you do that you can see now in the
  843. 29:30results we have here five customers.
  844. 29:33This is our data inside the table
  845. 29:34customers. So here again about the
  846. 29:36interface on the left side we have the
  847. 29:38object explorer where you can see the
  848. 29:40whole structure of the database from
  849. 29:41server to databases to tables. So you
  850. 29:44can see the whole structure on the top
  851. 29:46we have a menu with a lot of icons and
  852. 29:48then in the middle this place here we
  853. 29:50call it the SQL editor. We're going to
  854. 29:52go and write their SQL codes and then
  855. 29:55once you execute it at the bottom you
  856. 29:57will get the result and messages and
  857. 29:59below the SQL editor we have the output.
  858. 30:01So here you can see for example the data
  859. 30:03the results or different messages from
  860. 30:05the database. So the interface is very
  861. 30:07simple. Now we have to go and get our
  862. 30:09second database. So if you go back to
  863. 30:11our files you can find a second SQL file
  864. 30:14the initql server sales db.sql. Open
  865. 30:17that and let's go and copy everything
  866. 30:19here and let's go back to our studio.
  867. 30:22Same thing you have to go and create a
  868. 30:23new query then paste the whole code and
  869. 30:26this database is about the sales DB. So
  870. 30:29let's go and execute it and with that we
  871. 30:31will not get any errors and now we go to
  872. 30:33the left side and we do the same thing
  873. 30:35refresh and we can see the second
  874. 30:37database sales DB. Now we can go and
  875. 30:39explore it. So extend it go to the
  876. 30:41tables and here you can see five tables
  877. 30:43customers employees orders products. So
  878. 30:46here this is the intermediate database
  879. 30:48for our course. So now let's go and
  880. 30:49check our data. For example, let's go to
  881. 30:51the orders, right click on it and select
  882. 30:53top 10,00. And those are the orders of
  883. 30:56our database. Perfect. So everything is
  884. 30:58working. So those are the main two
  885. 31:00databases that we will be working
  886. 31:02through the whole course. And of course
  887. 31:03if you want to go and practice using
  888. 31:05another database, it's totally fine. For
  889. 31:07example, in Microsoft, there are a
  890. 31:09database called Adventure Works. It is
  891. 31:11really amazing. And I'm going to show
  892. 31:13you now how to import it. We can go over
  893. 31:14here the adventure works. So let's click
  894. 31:17on this link. So now we are again in
  895. 31:18Microsoft page. If you scroll down you
  896. 31:21can see here three different types of
  897. 31:22databases. The OLTB, data warehouse and
  898. 31:25lightweights. So they are like different
  899. 31:27databases. The OLTP is the most like
  900. 31:30complicated one. A lot of tables and
  901. 31:32transactions and so on. The data
  902. 31:34warehouse it is like really nice one in
  903. 31:36order to do data analyzes and stuff. The
  904. 31:38lightweight it is the simplest one. So
  905. 31:40let's go for example and get the data
  906. 31:42warehouse. So click on that and now as
  907. 31:44you can see the extension of this file
  908. 31:47isbak and now I'm going to show you the
  909. 31:49second way on how to create databases in
  910. 31:51SQL server. So now all what you have to
  911. 31:53do is to go to the following path. It
  912. 31:55really depends where you have installed
  913. 31:57the SQL server. So for me I have
  914. 31:59installed it in the program files
  915. 32:00Microsoft SQL Server MSSQL SQL Express
  916. 32:04then MSSQL backup. You have to go there.
  917. 32:07So here what you can do you can place
  918. 32:09all the files with the extension bak.
  919. 32:12For example, the adventure works that we
  920. 32:13just installed. This is a backup file
  921. 32:16for the database and we want to go and
  922. 32:18restore it and with that you are
  923. 32:20creating like a database. So this is the
  924. 32:22second method on how to create databases
  925. 32:24in SQL server by restoring the database.
  926. 32:27If for some reason the script didn't
  927. 32:29work for you. Now let me show you
  928. 32:30quickly how we can do that. Let's go
  929. 32:32back to our studio. Right click on the
  930. 32:34database and then here we have an option
  931. 32:36called restore database. Click on that.
  932. 32:38And now here we have two options under
  933. 32:40the source database and device. The
  934. 32:42default going to be database but we have
  935. 32:44to switch to a device because we want to
  936. 32:46import it from files. And then we go to
  937. 32:49these three dots. Click on that. And now
  938. 32:51we have to go to the option add. And now
  939. 32:53it's going to take you to the place
  940. 32:54where the SQL server creates backups. So
  941. 32:57here we can find our files and what we
  942. 32:59want you to create is the adventure
  943. 33:00works. Select that. Then okay, one more
  944. 33:03okay and one final okay. So now the
  945. 33:06database will be restored and it is
  946. 33:08successfully. So now on the left side we
  947. 33:10can see our third database. If you don't
  948. 33:12see it go and refresh of course and here
  949. 33:14you will find a lot of tables in the
  950. 33:16adventure works. And as usual we can go
  951. 33:18and explore the data by selecting top
  952. 33:20thousand rows. So my friends now you
  953. 33:22have three databases but of course our
  954. 33:24focus is only the first two that we have
  955. 33:25done my database and sales DB. And with
  956. 33:28that you have learned two ways on how to
  957. 33:30import databases into SQL server. So
  958. 33:33with that my friends we have prepared
  959. 33:34everything. We have the SQL Server
  960. 33:36Express running on your local PC. We
  961. 33:38have the studio the clients where we're
  962. 33:40going to use it in order to interact
  963. 33:42with the database and we have created
  964. 33:44our two databases that we will be using
  965. 33:47in order to practice SQL. So we are
  966. 33:49ready. All right my friends. So with
  967. 33:50that we are done with the first chapter.
  968. 33:52We have our introduction to SQL and now
  969. 33:54we're going to start learning the first
  970. 33:56thing in SQL and that is how to query
  971. 33:58our data. So let's go and start with
  972. 34:00that.
  973. 34:05Okay, so now we can understand exactly
  974. 34:07what is an SQL query. Now normally your
  975. 34:09data is inside the table and your table
  976. 34:11is inside the database and now you might
  977. 34:13have a question from the business like
  978. 34:15what is the total sales? What is the
  979. 34:17total number of customers? So any
  980. 34:19question that you have in your mind and
  981. 34:21you want to go and ask your data you
  982. 34:23want to go and retrieve data from the
  983. 34:25database and in order to do that you
  984. 34:27have to talk to the database using its
  985. 34:29language the SQL. So in order to do that
  986. 34:32you're going to go and write a query
  987. 34:34where you write inside the query
  988. 34:36something called select statement and
  989. 34:38with that you are asking the database
  990. 34:40for data. So once you execute your query
  991. 34:42the database going to go and fetch your
  992. 34:44data and then it prepares a result to be
  993. 34:47sent back to you. So with that you are
  994. 34:49asking the database a question by
  995. 34:51writing a query and the database going
  996. 34:53to process your query and answer your
  997. 34:55question by sending back data and with
  998. 34:57that we are like reading our data from
  999. 35:00the database and the queries will not
  1000. 35:02modify anything will not change the data
  1001. 35:04inside your tables or even change the
  1002. 35:06structure of the database. So you use
  1003. 35:08select statement only in order to read
  1004. 35:11something from the database. You just
  1005. 35:13want to retrieve data from the database.
  1006. 35:16So this is what we mean with a
  1007. 35:20query. And now my friends, each SQL
  1008. 35:23query has usually different sections,
  1009. 35:25different components. We call them
  1010. 35:27clauses. And this is amazing because
  1011. 35:29you're going to have enough tools to
  1012. 35:31write a query that matches any question
  1013. 35:33that you have about your data. So what
  1014. 35:35we're going to do, we're going to cover
  1015. 35:36all those clauses step by step in order
  1016. 35:39to write any query that you need. So now
  1017. 35:41we're going to start with two clauses
  1018. 35:43that makes the simplest query in SQL.
  1019. 35:45the select and from. So let's start with
  1020. 35:51that. All right. So now it's really
  1021. 35:53important for me that you understand how
  1022. 35:55SQL works with the code with the
  1023. 35:57queries. So now what I'm going to do,
  1024. 35:58I'm going to show you on the right side
  1025. 36:00the syntax of the query in SQL and then
  1026. 36:03on the left side I'm going to show you
  1027. 36:04exactly step by step how SQL going to go
  1028. 36:07and execute your query. So now we have
  1029. 36:09the table customers inside our database
  1030. 36:11and we will start with the easiest form
  1031. 36:13where we're going to select everything.
  1032. 36:15Select the star. So the select star is
  1033. 36:17going to go and retrieve all the columns
  1034. 36:20from your table. So everything and the
  1035. 36:22from clause it's going to tell SQL where
  1036. 36:24to find your data. So with the select we
  1037. 36:27select the columns that we want and the
  1038. 36:29from you specify the table where your
  1039. 36:31data come from. So the syntax going to
  1040. 36:33be very simple. In each query we start
  1041. 36:35always with the select. And now since we
  1042. 36:37want all the columns we're going to
  1043. 36:39write star and with that SQL going to
  1044. 36:41understand I want to see everything. And
  1045. 36:43then after that comes the keyword from.
  1046. 36:45And now we want to tell SQL where the
  1047. 36:46data come from. So we have to specify
  1048. 36:48the table name. And that's it. This is
  1049. 36:50all what you need to do. So once you
  1050. 36:52execute it what's going to happen? SQL
  1051. 36:54going to go and execute first the from
  1052. 36:56clause. So it's going to go and retrieve
  1053. 36:58all the data from the database to the
  1054. 37:00results. And then in the next step going
  1055. 37:02to go and check the select statement. So
  1056. 37:04which columns we have to keep in the
  1057. 37:06result since you are saying star then
  1058. 37:08the SQL going to keep everything all the
  1059. 37:10columns and with that you will see in
  1060. 37:11the result everything all the columns
  1061. 37:13and all the rows. So that's it. This is
  1062. 37:16how it works. Now let's go back to scale
  1063. 37:18in order to select few data from our
  1064. 37:19database. Okay. So back to our studio.
  1065. 37:21Let's go and start a new query and let's
  1066. 37:24go and find our database just to expand
  1067. 37:26it and our tables. Now it is very
  1068. 37:28important to make sure that you are
  1069. 37:30connected to the correct database. So go
  1070. 37:32to the top left in the menu over here
  1071. 37:34and make sure to select your database.
  1072. 37:36So my database like this or we have a
  1073. 37:38command for that called use and then
  1074. 37:40just write the database name like this.
  1075. 37:42So I'm telling SQL just use my database
  1076. 37:45like this and with that SQL going to
  1077. 37:47switch to your database. Now if you are
  1078. 37:49learning any new programming language,
  1079. 37:50it is very important to understand about
  1080. 37:52the comments. So comments are like notes
  1081. 37:54that you add to your code in order to
  1082. 37:56understand what is going on. And of
  1083. 37:58course the engine, the database will not
  1084. 38:00go and execute it. it's going to go and
  1085. 38:02ignore everything inside it. And there
  1086. 38:04is like two ways on how to do that.
  1087. 38:05Either you make inline comments by
  1088. 38:07typing two dashes like this and then you
  1089. 38:09write anything this is a comment. So now
  1090. 38:13in SQL if you see it is green that means
  1091. 38:15it is a comments. Now the other type you
  1092. 38:18can have multiple line comments and in
  1093. 38:20order to do that what you can do you can
  1094. 38:21write slash and then start and then you
  1095. 38:24can write anything this and then start a
  1096. 38:26new line is a comment. So as you can see
  1097. 38:29all the lines after the slash star it is
  1098. 38:32getting green that means it is a comment
  1099. 38:34and now let's say that you are at the
  1100. 38:35end. So in order to close it you write
  1101. 38:37again star and then slash and that you
  1102. 38:40are telling SQL I'm done with my
  1103. 38:41comments. So those are the two types of
  1104. 38:43writing comments in SQL. Now back to our
  1105. 38:45query. Let's say that we have the
  1106. 38:47following task says retrieve all
  1107. 38:49customer data. So I would like to see in
  1108. 38:51the results all the data of my customers
  1109. 38:53everything all the rows and all the
  1110. 38:55columns. So currently our data is stored
  1111. 38:57inside the table called customer and I
  1112. 38:59need to see all the data in the output.
  1113. 39:01In order to do that we're going to write
  1114. 39:03a query and all our query start always
  1115. 39:05with a select and since I need
  1116. 39:07everything all the columns we write star
  1117. 39:09and then a new line. Let's go and
  1118. 39:10specify for SQL from where it's going to
  1119. 39:13go and get the data. So it's going to be
  1120. 39:15from and then we going to write the name
  1121. 39:17of the table. It must be exactly like it
  1122. 39:19is in the database. So it's called
  1123. 39:21customers and you have to have it here
  1124. 39:23as a customers. So that's it. Let's go
  1125. 39:25and execute it. And now if you look to
  1126. 39:27the results, you can see we have four
  1127. 39:29columns and five rows. So with that you
  1128. 39:32are seeing everything inside the table
  1129. 39:34customers. You can see we have five
  1130. 39:35customers and you can see all the
  1131. 39:37columns about the customers. So this is
  1132. 39:39very simple. We have ask question for
  1133. 39:41the database using SQL query and the
  1134. 39:44database should answer our question by
  1135. 39:46returning our data in the results. All
  1136. 39:48right. So now let's move to another
  1137. 39:49task. I'm going to go and create a new
  1138. 39:51query and this time we're going to
  1139. 39:52retrieve all the order data. So that
  1140. 39:54means I would like to see all the data
  1141. 39:55inside the orders. So let's go and write
  1142. 39:57a very simple query. We start as usual
  1143. 40:00with select and since we want
  1144. 40:01everything. So it is select star from
  1145. 40:04our table orders. So that's it. Let's go
  1146. 40:07and execute. And with that you can see
  1147. 40:08in the output we have again four columns
  1148. 40:11but this time we have only four rows. So
  1149. 40:13that means in this table we have four
  1150. 40:15orders and we can see all the data
  1151. 40:17inside this table. So with that we can
  1152. 40:19understand we have five customers inside
  1153. 40:22our database and these customers did
  1154. 40:24generate four orders. So as you can see
  1155. 40:26we are now talking to our database and
  1156. 40:28this is the simplest form of query in
  1157. 40:34SQL. All right. So now let's move to the
  1158. 40:36next step in our query where you say you
  1159. 40:39know what I don't want to see all the
  1160. 40:40columns from the database. I want to be
  1161. 40:42more specific. So I would like to select
  1162. 40:44exactly the columns that I need. So now
  1163. 40:47we want to select few columns from the
  1164. 40:49database where we select only the
  1165. 40:51columns that we need instead of
  1166. 40:53everything. Now about the syntax we're
  1167. 40:54going to go and change a little thing.
  1168. 40:56So instead of using star we're going to
  1169. 40:58go and make a list of columns that we
  1170. 41:00want to see in the output. So we're
  1171. 41:02going to select column one column two
  1172. 41:04and we're going to separate them using a
  1173. 41:06comma. So we are just writing a list of
  1174. 41:08columns exactly after the select. And
  1175. 41:10for the from it's going to stay as it
  1176. 41:12is. So from a table. Now if you execute
  1177. 41:14this what going to happen as usual SQL
  1178. 41:16going to start with the from. So it's
  1179. 41:18going to go and get the data from the
  1180. 41:19database and then the next step is going
  1181. 41:21to go and check the select. So what
  1182. 41:23going to happen? SQL going to go and
  1183. 41:24keep only two columns like for example
  1184. 41:27the name and the country and all the
  1185. 41:29columns that are not mentioned in the
  1186. 41:31select statements will be excluded. So
  1187. 41:33SQL going to go and remove it from the
  1188. 41:35results and keeps only the columns that
  1189. 41:37we mentioned in our query. So this time
  1190. 41:40instead of having four columns in the
  1191. 41:41output we can have only two. So with
  1192. 41:43that you are like filtering the columns
  1193. 41:45and you are selecting exactly what you
  1194. 41:47need. So now let's go back to SQL in
  1195. 41:49order to practice this. All right. So
  1196. 41:51now we have the following task and it
  1197. 41:53says retrieve each customer's name,
  1198. 41:55country and score. So that means I don't
  1199. 41:58want to see everything from the table
  1200. 42:00customers. I need only to see the three
  1201. 42:02columns. So let's see how we can do
  1202. 42:04that. As usual we start with select and
  1203. 42:06I'm going to go with a star in order to
  1204. 42:08see the whole table first from the table
  1205. 42:09customers. So it's exactly like before.
  1206. 42:12Let's go and execute it. And now I can
  1207. 42:13see everything inside the table
  1208. 42:15customers. But the task says I need only
  1209. 42:17three columns. So now what we're going
  1210. 42:18to do instead of the star, we're going
  1211. 42:20to make a list of columns. So we start a
  1212. 42:23new line and then we write the name of
  1213. 42:25the first column. So the first name and
  1214. 42:27a new line for the second column for the
  1215. 42:30country and then again a comma and then
  1216. 42:32we write a score. So with that we have
  1217. 42:34the three columns. Now what I usually
  1218. 42:36do, I go and select them and give it
  1219. 42:38then a push using a tab. This just looks
  1220. 42:40nicer and easier to read. So with that
  1221. 42:42we have now between the select and from
  1222. 42:44list of columns. Now there is like
  1223. 42:46mistake that happens a lot where we go
  1224. 42:48and type a comma after the last column.
  1225. 42:50So if you do that and execute it you
  1226. 42:52will get an error because SQL going to
  1227. 42:54expect from you a column after the comma
  1228. 42:56and since there is no column and
  1229. 42:58immediately you have a from you will get
  1230. 43:00an error. So there is no need for a
  1231. 43:01comma after the last column. Now let's
  1232. 43:03remove it and execute. And now that you
  1233. 43:05can see in the output we don't have four
  1234. 43:07columns we have only three. the first
  1235. 43:09name, the country and the score. And by
  1236. 43:11the way, they are ordered exactly like
  1237. 43:14you selected in your query. So first we
  1238. 43:16have the first name and then the country
  1239. 43:19and then the last one the score. So that
  1240. 43:20means if I go and now change the order.
  1241. 43:23So let's get the country at the end and
  1242. 43:25execute. You will see the country at the
  1243. 43:28end. I'm going to go and put it back in
  1244. 43:30between to match exactly like the task
  1245. 43:32and remove the last comma. So execute
  1246. 43:35again. And with that we have selected
  1247. 43:37few columns from our table. So we are
  1248. 43:39more specific to what we need. Okay. So
  1249. 43:41that we have covered the two select and
  1250. 43:43from next we're going to talk about the
  1251. 43:45wear clause that you can use in order to
  1252. 43:48filter your data. So let's
  1253. 43:53go. So what is exactly where? We use
  1254. 43:56where in order to filter our data based
  1255. 43:58on a condition and any data that fulfill
  1256. 44:01the condition going to stay in the
  1257. 44:03output in the result and the data that
  1258. 44:06don't meet the condition will be
  1259. 44:08filtered out of the results. Condition
  1260. 44:09could be anything like for example we
  1261. 44:11say the score must be higher than 500 or
  1262. 44:14you can say the country must be equal to
  1263. 44:16Germany. So any condition that you have
  1264. 44:18in your question. Now let's see the
  1265. 44:19syntax in SQL. As usual we start with a
  1266. 44:22select. We select the columns that we
  1267. 44:24need. Then we write from where the data
  1268. 44:26come from and then after the from we're
  1269. 44:28going to write the where and exactly
  1270. 44:30after that you specify your condition.
  1271. 44:32So now let's see how SQL going to
  1272. 44:33execute this. First SQL start as usual
  1273. 44:36from the from. So it's going to go and
  1274. 44:37get your data from the database and
  1275. 44:39after that SQL going to go and execute
  1276. 44:42the wear clause. So let's say that the
  1277. 44:44condition should be higher than 500. And
  1278. 44:46now what going to happen? SQL going to
  1279. 44:48check each row whether it meets this
  1280. 44:51condition or not. So for example for
  1281. 44:52Maria she doesn't fulfill the condition
  1282. 44:54because her score the 350 is not higher
  1283. 44:58than 500. So she doesn't fulfill the
  1284. 45:00condition and SQL going to go and remove
  1285. 45:03completely this row this record from the
  1286. 45:05results. Now SQL going to go to the
  1287. 45:07second record. So Joan is fulfilling the
  1288. 45:10condition. So he going to stay in the
  1289. 45:11result. The same thing for George. Now
  1290. 45:13moving on to the fourth one Martin. So
  1291. 45:16this customer is not fulfilling the
  1292. 45:18condition and SQL going to go and remove
  1293. 45:20it from the results. The same things
  1294. 45:22happen for the last customer. The score
  1295. 45:23is zero and not fulfilling the
  1296. 45:25condition. So that means if we apply
  1297. 45:27this filter, SQL going to return only
  1298. 45:29two customers out of five. So with that
  1299. 45:32we are filtering the rows based on
  1300. 45:34condition using the work clause. Now as
  1301. 45:36you can see in the result we are getting
  1302. 45:38all the columns but if you specify in
  1303. 45:40the query like for example only two
  1304. 45:42columns like the name and the country
  1305. 45:44then SQL going to start removing as well
  1306. 45:47the columns of the results. And this
  1307. 45:49means in the output we will get only two
  1308. 45:51columns and two rows. So with that you
  1309. 45:53are filtering the columns and the rows
  1310. 45:56of your results. So now let's go back to
  1311. 45:58scale in order to practice this. All
  1312. 45:59right. So let's have the following task
  1313. 46:01and it says retrieve customers with a
  1314. 46:04score not equal to zero. So now if you
  1315. 46:06are looking to our task you see we have
  1316. 46:08like here a condition. The condition
  1317. 46:09says the score must not be equal to
  1318. 46:12zero. So I don't want to see all the
  1319. 46:13customers. I want to see only the
  1320. 46:15customers thus fulfill this condition.
  1321. 46:18So it's like we have to filter the data.
  1322. 46:19So let's go and solve the task. Let's
  1323. 46:21start as usual. Select star. There's no
  1324. 46:23specifications about the columns from
  1325. 46:25our table customers. Okay. So I'm going
  1326. 46:28to start with this. Let's go and execute
  1327. 46:30it. Now if you look at the result, you
  1328. 46:31can see like almost all the customers
  1329. 46:33are fulfilling the condition. Their
  1330. 46:35scores are not equal to zero. Only one.
  1331. 46:38The last customer his score is zero. So
  1332. 46:40this customer does not fulfill our
  1333. 46:42condition. Now let's go and build filter
  1334. 46:44for that. So we're going to say where.
  1335. 46:46And now there will be a section that is
  1336. 46:48only focusing on how to build conditions
  1337. 46:50and filtering in SQL. So don't worry a
  1338. 46:52lot about the syntax of the conditions.
  1339. 46:54We're going to cover that later of
  1340. 46:55course but it is very simple. Now for
  1341. 46:57the condition we need a column. So in
  1342. 46:58which column is our condition based on
  1343. 47:00it's going to be on the score. So we're
  1344. 47:02going to write here score and since we
  1345. 47:04are saying not equal there is like an
  1346. 47:06operator in SQL called not equal and
  1347. 47:08then we have to write a value after
  1348. 47:10that. It's going to be a zero. So again
  1349. 47:11the condition is like this. The score
  1350. 47:13must not be equal to zero. It's very
  1351. 47:16simple, right? And with that we have our
  1352. 47:18condition and we are using the where in
  1353. 47:20order to filter the data. So let's go
  1354. 47:22and execute it. And now as you can see
  1355. 47:23SQL did remove the last customer because
  1356. 47:26he is not fulfilling this condition. And
  1357. 47:28we have now only the rows that fulfill
  1358. 47:31our condition. So as you can see it is
  1359. 47:33very simple how to filter the data. All
  1360. 47:35what you have to do is to write where
  1361. 47:36clause after the from and then write a
  1362. 47:39condition after that. Now let's have
  1363. 47:40another task like for example it says
  1364. 47:42retrieve customers from Germany. So I
  1365. 47:45don't want to see all customers from
  1366. 47:46different countries. I just want to see
  1367. 47:48the customers that come from Germany. So
  1368. 47:50that means we have a condition here.
  1369. 47:52Country of the customer must be equal to
  1370. 47:55Germany. So let's go and remove the
  1371. 47:56current condition. It is not the one
  1372. 47:58that we need and execute. If you are
  1373. 48:00looking to the results, we have two
  1374. 48:02customers that come from Germany and we
  1375. 48:04are interested only to show those two
  1376. 48:06customers. So let's go and make a filter
  1377. 48:08for that. We're going to write where
  1378. 48:10clause and after that we need a column.
  1379. 48:12The column going to be the country. So
  1380. 48:14we're going to write here country and
  1381. 48:15this time the country must be equal to
  1382. 48:18Germany. So we're going to write an
  1383. 48:20equal operator. So we're going to write
  1384. 48:22Germany like this exactly like the value
  1385. 48:24inside our data. But now as you can see
  1386. 48:26we are getting like an error here. And
  1387. 48:28that's because in SQL if you want to
  1388. 48:30write a value that contains characters
  1389. 48:33then you have to put it between two
  1390. 48:35single quotes. So at the start you put a
  1391. 48:37single quote and as well at the end. And
  1392. 48:39now as you can see the red line is away
  1393. 48:41and the value now is red and that's
  1394. 48:43because it is a string value. It is a
  1395. 48:45value that contains characters and with
  1396. 48:47that you will not get an error. So if
  1397. 48:49your columns contains only numbers you
  1398. 48:51can write it without single quotes. But
  1399. 48:53if your values contains characters then
  1400. 48:55you have to write it between two single
  1401. 48:57quotes. Okay. So now back to our
  1402. 48:58condition the country must be equal to
  1403. 49:00Germany. Let's go and execute it. And it
  1404. 49:03is working. So as you can see now we are
  1405. 49:04seeing in the output only the customers
  1406. 49:07does fulfill my condition where the
  1407. 49:09country is equal to Germany. So this is
  1408. 49:11exactly how we work with the wear clause
  1409. 49:13in order to filter our data. So my
  1410. 49:15friends this is how you filter your
  1411. 49:17rows. And now let's say that I would
  1412. 49:18like to filter the rows together with
  1413. 49:20the columns. So I just want to keep the
  1414. 49:22first name and the country and not
  1415. 49:24interested to see the scores and the
  1416. 49:25ids. So in order to do that we're going
  1417. 49:27to go to the select and list the columns
  1418. 49:29that we want to see. So the first name
  1419. 49:32and after that a comma then the country
  1420. 49:34and that's it. So let's go and give it a
  1421. 49:37push and execute it. So we have two rows
  1422. 49:39and two columns. So guys as you can see
  1423. 49:42SQL is very simple. All right. So with
  1424. 49:44that you have learned how to filter your
  1425. 49:46data using the wear clause. Next we're
  1426. 49:48going to talk about how to sort your
  1427. 49:50data using the order by. So let's
  1428. 49:56go. Okay. So what is exactly order by?
  1429. 49:59You can use this type of clouds in order
  1430. 50:01to sort your data. And of course, in
  1431. 50:03order to sort your data, you have to
  1432. 50:04decide on two mechanism. Either you want
  1433. 50:06to sort your data ascending from the
  1434. 50:09lowest value to the highest value or
  1435. 50:11exactly the opposite way using
  1436. 50:13descending from the highest value to the
  1437. 50:15lowest. And the syntax kind of looks
  1438. 50:17like this. So as usual, we start with
  1439. 50:18the select and then from and after the
  1440. 50:21from you can specify order by and with
  1441. 50:23that you are telling SQL we have to sort
  1442. 50:25the data and you have to specify two
  1443. 50:27things. First you have to specify for
  1444. 50:29SQL the column that should be used in
  1445. 50:31order to sort the results. So for
  1446. 50:33example you can say score and after the
  1447. 50:36column name you have to specify the
  1448. 50:37mechanism. So for example you say
  1449. 50:39ascending from the lowest to the
  1450. 50:41highest. And in SQL if you don't specify
  1451. 50:43the mechanism the default going to be
  1452. 50:45ascending. So you will not get an error
  1453. 50:47if you don't specify anything after the
  1454. 50:49column name. But my advice here is
  1455. 50:51always to specify something after the
  1456. 50:54column easier because it's just
  1457. 50:56straightforward and easier to understand
  1458. 50:58and if someone reads it can understand
  1459. 51:00immediately it's going to be ascending
  1460. 51:02because maybe not everyone knows what is
  1461. 51:04the default in SQL. So always specify a
  1462. 51:07value even if it's like easier to skip
  1463. 51:09it and if you want to store the data
  1464. 51:10from the highest to the lowest then you
  1465. 51:12can specify descending. So as usual SQL
  1466. 51:15going to go and start from the from it's
  1467. 51:16going to go and grab your data from
  1468. 51:18database. Then the second step is SQL
  1469. 51:20going to go and sort the result. So the
  1470. 51:22order by going to be executed and SQL
  1471. 51:24going to see okay I'm going to sort it
  1472. 51:25by the score and using the sending
  1473. 51:28mechanism and still going to go and
  1474. 51:29start like moving around your rows where
  1475. 51:32the first row going to be the customer
  1476. 51:34with the highest score and in this
  1477. 51:36example John has the highest score the
  1478. 51:38900. So John going to appear as a first
  1479. 51:41row at the result and that's because his
  1480. 51:43score and after that the second highest
  1481. 51:45is going to be George with 750 and SQL
  1482. 51:48going to go and keep sorting the data
  1483. 51:50and then we have 500 then 350 and the
  1484. 51:53last row going to be the customer with
  1485. 51:55the lowest score the zero. So this is
  1486. 51:57how SQL executes your order by. Now
  1487. 52:00let's go back to scale in order to
  1488. 52:01practice. All right. So now we have the
  1489. 52:03firming task and it says retrieve all
  1490. 52:05customers and sort the result by the
  1491. 52:08highest score first. So now by looking
  1492. 52:10at the task we need all the customers.
  1493. 52:12So there is like no conditions or
  1494. 52:14anything to filter but we have to sort
  1495. 52:16the results. So let's go and do that.
  1496. 52:18We're going to start as usual by
  1497. 52:19selecting all the columns from the table
  1498. 52:22customers. So now if you go and execute
  1499. 52:24it you will get all your customers and
  1500. 52:26you are now seeing the data exactly like
  1501. 52:28stored in the database. And you can see
  1502. 52:30the result is not sorted by the scores.
  1503. 52:32So we have here a low score then high
  1504. 52:34score then low and so on. Now the task
  1505. 52:37says we have to sort the results. So we
  1506. 52:39have to go and use the order by and now
  1507. 52:42you have to understand from which column
  1508. 52:43and we can get that from the task. So it
  1509. 52:45says it should be sorted by the score.
  1510. 52:48So we're going to go and define the
  1511. 52:49score here. And the final thing that you
  1512. 52:51have to define is the mechanism
  1513. 52:52descending or ascending. And you can get
  1514. 52:54it as well from the task. So we have to
  1515. 52:56sort the data by the highest score
  1516. 52:58first. So the highest first and then the
  1517. 53:00lowest. So that means we're going to go
  1518. 53:02and use the descending. So that's all.
  1519. 53:04Let's go and execute it. Now as you can
  1520. 53:06see in the results, the first customer
  1521. 53:08has the highest score. Then we have the
  1522. 53:10second one with the second highest until
  1523. 53:12the last one with the lowest score.
  1524. 53:14That's it. This is how you sort your
  1525. 53:16data. And with that we have solved the
  1526. 53:17task. Now let's do exactly the opposite.
  1527. 53:20So we want to sort the results by the
  1528. 53:22lowest score first. So that means we
  1529. 53:24want to see first the customers with the
  1530. 53:26lowest score like here in this example
  1531. 53:28we should see the ID number five as the
  1532. 53:30first because he has the lowest score
  1533. 53:32the zero. Now in order to do that all
  1534. 53:34what you have to do is to switch the
  1535. 53:35mechanism instead of descending when you
  1536. 53:37can use ascending. Let's go and execute
  1537. 53:39it. And that's it. As you can see now we
  1538. 53:41have the lowest score then the second
  1539. 53:43lowest score until the last row. It's
  1540. 53:46going to be the customer with the
  1541. 53:47highest score. So the lowest score comes
  1542. 53:50first. So it is very simple. This is how
  1543. 53:52you sort your data using
  1544. 53:56SQL. And now I'm going to show you one
  1545. 53:58more thing that you can do with the
  1546. 54:00order by. You can sort your data using
  1547. 54:02multiple columns. And we call it nested
  1548. 54:04sorting. So now let's take this very
  1549. 54:06simple example where you want to sort
  1550. 54:08your data using country. So we are
  1551. 54:10saying order by the column country and
  1552. 54:13the mechanism going to be ascending. So
  1553. 54:15from the lowest to the highest. Now if
  1554. 54:16you do that going to go and sort the
  1555. 54:18data this time based on the country. So
  1556. 54:20we're going to have like the first two
  1557. 54:22customers from Germany. It is sorting it
  1558. 54:24alphabetically. Then we have the UK and
  1559. 54:26the last two going to be from USA. Now
  1560. 54:28if you are checking the final results
  1561. 54:29you might say you know what there is
  1562. 54:31like something wrong. The data is not
  1563. 54:34completely sorted correctly. So if you
  1564. 54:36are looking to the first two customers
  1565. 54:37that come from country Germany. You can
  1566. 54:39see the scores are sorted in ascending
  1567. 54:42way from the lowest to the highest. So
  1568. 54:44first we have 350 then 500. Then UK it's
  1569. 54:47fine because we have only one customer.
  1570. 54:49Now if you look to the customers from
  1571. 54:51USA you see that it is like sorted the
  1572. 54:53way around. It is sorted descending from
  1573. 54:56the highest to the lowest. So first we
  1574. 54:58have the score 900 then zero. So there
  1575. 55:00is like no clean way on how the data is
  1576. 55:02sorted and the result is not really
  1577. 55:04clean and this issue happens usually if
  1578. 55:06you are sorting your data based in a
  1579. 55:08column that has repetition like here the
  1580. 55:10country we have twice Germany and twice
  1581. 55:12USA. So now in order to refine the
  1582. 55:15sorting and make it more correct, we can
  1583. 55:17include in the sorting another column in
  1584. 55:20this scenario for example the score. So
  1585. 55:22we can make a list of columns in the
  1586. 55:24order by and we can separate them using
  1587. 55:26the comma. And of course you can have
  1588. 55:27different mechanism for each column like
  1589. 55:29for the country we are saying it is
  1590. 55:31ascending but for the score we say you
  1591. 55:33know what let's make it descending. It
  1592. 55:34will not be only one for all columns. So
  1593. 55:37now what can happen is we're going to
  1594. 55:38start sorting the data for each section.
  1595. 55:41So for the two customers from Germany
  1596. 55:43the sorting going to be from the highest
  1597. 55:44to the lowest. So it's going to go and
  1598. 55:46switch the two customers. So Martin
  1599. 55:48going to be first because he has higher
  1600. 55:50score than Maria. And with that we are
  1601. 55:52refining the scores based on the same
  1602. 55:54value of course the country. Now for the
  1603. 55:56UK nothing going to happen because we
  1604. 55:58have only one value and for the USA as
  1605. 56:00well nothing going to happen because it
  1606. 56:02is already sorted in the correct way
  1607. 56:04from the highest to the lowest. So as
  1608. 56:06you can see if you are including a
  1609. 56:07second column you are refining your
  1610. 56:10sorting and as well my friends the order
  1611. 56:12is very important. So this is how you
  1612. 56:14can do nested sorting in SQL. Let's go
  1613. 56:17back to our SQL and start practicing.
  1614. 56:19All right so now we have the following
  1615. 56:20task and it says retrieve all customers
  1616. 56:23and sort the results by the country and
  1617. 56:26then by the highest score. So again we
  1618. 56:29need all customers. So select everything
  1619. 56:31from customers table. And now the task
  1620. 56:33says we have to sort the result by the
  1621. 56:36country. So we're going to start with
  1622. 56:37the order by and since it says by the
  1623. 56:39country. We're going to go with the
  1624. 56:40country and we're going to sort it
  1625. 56:42alphabetically. So it's going to be
  1626. 56:43ascending. So let's go execute it. Now
  1627. 56:46you can see the data is sorted
  1628. 56:47completely differently by the country.
  1629. 56:49So we have first Germany, UK and then
  1630. 56:51USA. But that's not all and says then by
  1631. 56:55the highest score. So we have to go and
  1632. 56:57include another column in the sorting
  1633. 56:59and we can go and add that by adding a
  1634. 57:01comma and then mention another column
  1635. 57:03the score and now we have to specify the
  1636. 57:05mechanism. It says by the highest score.
  1637. 57:07So the highest must come first and with
  1638. 57:09that we are using descending. Now what
  1639. 57:11is the current situation in that? If you
  1640. 57:13look to the results for example for
  1641. 57:15those two customers we have 350 and then
  1642. 57:18500. So that means the scores are sorted
  1643. 57:21ascending right the same thing for USA.
  1644. 57:23So from the lowest to the highest. Now
  1645. 57:25if you go and do it like this what going
  1646. 57:27to happen it's going to go and switch
  1647. 57:29it. So you can see over here now for
  1648. 57:31Germany first comes the highest the 500
  1649. 57:33and then the 350 and for USA as well
  1650. 57:36they switched. So we have the highest
  1651. 57:38and then the lowest and with that we
  1652. 57:40have solved the task. Now again the
  1653. 57:41order of those columns are very
  1654. 57:43important. So since the scores comes
  1655. 57:45after the country we will not get the
  1656. 57:47highest scores first at the results. So
  1657. 57:49we will not get the 900 as a first row.
  1658. 57:52And that's because the scores must be
  1659. 57:54sorted after the country. So the country
  1660. 57:56has more priority. Now if you go and
  1661. 57:58flip that. So let's go over here and
  1662. 58:01says sort first the score and then the
  1663. 58:03country. So let's go and execute it.
  1664. 58:05It's called has first to sort the
  1665. 58:07scores. So with that you will get the
  1666. 58:09900 first, right? And then the
  1667. 58:11countries. And since there is like no
  1668. 58:13duplicates in the scores, this makes no
  1669. 58:15sense at all. So you can go and skip it.
  1670. 58:17So nested sorting only makes sense if
  1671. 58:19you have repetition in your results and
  1672. 58:22you can use the help of a second column
  1673. 58:25in order to make the sorting perfect. So
  1674. 58:28that's it and with that of course we
  1675. 58:29have solved the task. All right. So with
  1676. 58:31that you have learned how to sort your
  1677. 58:32data using order by. Now in the next
  1678. 58:35step we're going to talk about how to
  1679. 58:37aggregate and group up your data using
  1680. 58:39group by and we're going to put it
  1681. 58:41between the where and the order by
  1682. 58:43because in the order of the query the
  1683. 58:45group by comes between the where and the
  1684. 58:47order by. So let's
  1685. 58:52go. Okay. So what is exactly group by?
  1686. 58:54It's going to go and combine the rows
  1687. 58:56with the same value. So it's going to go
  1688. 58:58and combine and smash press your rows to
  1689. 59:01make it aggregated and more combined. So
  1690. 59:03all what group by does it aggregates a
  1691. 59:06column by another column. Like for
  1692. 59:08example, if you want to find the total
  1693. 59:10score by country. So you aggregate all
  1694. 59:13the scores value for one country. If you
  1695. 59:16have this kind of tasks, then you can
  1696. 59:17use the group I. Let's see the syntax of
  1697. 59:20that. We will start as usual with the
  1698. 59:21select. And now what we want to see in
  1699. 59:23the result is two columns. So we have to
  1700. 59:25specify like a category like the
  1701. 59:27country. This is the value that you want
  1702. 59:29to group the data by. and another one
  1703. 59:31where you are doing the aggregations. So
  1704. 59:33for example you are saying I would like
  1705. 59:35to see the total score. So we use the
  1706. 59:37function sum in order to summarize the
  1707. 59:39values of the score. After that as usual
  1708. 59:41we use the from in order to select the
  1709. 59:43data from specific table. And now comes
  1710. 59:45the magic we use after the from group
  1711. 59:47by. And now understands okay I have now
  1712. 59:50to combine the data. I have to group up
  1713. 59:52the data by something. And this time we
  1714. 59:54are saying you have to group up the data
  1715. 59:56by the country. So that means each value
  1716. 59:58of the country must be presented in the
  1717. 1:00:00output only once and for each country we
  1718. 1:00:03want to see the aggregation and that is
  1719. 1:00:06the total score. So let's see how is
  1720. 1:00:08going to execute it. So it's going to
  1721. 1:00:09first start with the from it's going to
  1722. 1:00:10go and get the data from the database
  1723. 1:00:12and then it's still going to execute the
  1724. 1:00:13group by and now scale understand okay I
  1725. 1:00:16have to group up now the data by the
  1726. 1:00:17country and it understands it has to
  1727. 1:00:20aggregate the scores for that. So it's
  1728. 1:00:22going to go and identify the rows that
  1729. 1:00:24are sharing the same value. Like for
  1730. 1:00:26example here we have two rows for
  1731. 1:00:28Germany and it's going to bring it to
  1732. 1:00:29the results. So now we have two rows for
  1733. 1:00:31the same country but since we are saying
  1734. 1:00:34group by country SQL going to try and
  1735. 1:00:36combine them smash them together in only
  1736. 1:00:38one row. So each value of the country
  1737. 1:00:40must exist at maximum once. We cannot
  1738. 1:00:43leave it like this. So now what we going
  1739. 1:00:45to do with the scores? We have two
  1740. 1:00:46scores. Now SQL going to check the
  1741. 1:00:48aggregate function. It is the
  1742. 1:00:49summarization. So, and it's going to go
  1743. 1:00:51and add those values 350 + 500. And with
  1744. 1:00:54that, we're going to get the total score
  1745. 1:00:56of 850. And with that, as you can see,
  1746. 1:00:59scale is combining those two rows into
  1747. 1:01:01one. So, in the output, Germany will
  1748. 1:01:03exist only one. And about the scores, we
  1749. 1:01:05will get the total score. And the same
  1750. 1:01:07thing going to happen for the next
  1751. 1:01:09value. In the country, we have the USA.
  1752. 1:01:11We have it twice. So, we're going to get
  1753. 1:01:13two rows. And scale going to combine
  1754. 1:01:15those two rows in one because USA must
  1755. 1:01:17exist only once. And with the scores we
  1756. 1:01:20will have the total scores. So 900 plus
  1757. 1:01:22zero we will get 900. And with that it's
  1758. 1:01:25still converted those two rows into one.
  1759. 1:01:27And for the last value in the countries
  1760. 1:01:29we have the UK. It's going to stay as it
  1761. 1:01:31is. There is no need to smash and
  1762. 1:01:33combine anything because it's already
  1763. 1:01:35one value. So my friends if you are
  1764. 1:01:36looking to the output you can see we
  1765. 1:01:38grouped the original data by the
  1766. 1:01:41country. And that means we're going to
  1767. 1:01:42get one row for each value inside the
  1768. 1:01:45country column. So my friends the
  1769. 1:01:47original data you have five rows in the
  1770. 1:01:49output if you are using group by like
  1771. 1:01:51this you will get only three rows. So
  1772. 1:01:53this is exactly how the group by works.
  1773. 1:01:56Let's go back to scale and practice.
  1774. 1:01:58Okay. So we have the following task and
  1775. 1:01:59it says find the total score for each
  1776. 1:02:02country. So from reading this you can
  1777. 1:02:04understand we have to do aggregations
  1778. 1:02:06and we have to combine the data by a
  1779. 1:02:08column. So now usually I start like
  1780. 1:02:09this. I start selecting the columns that
  1781. 1:02:12I need in order to solve this task. So
  1782. 1:02:14what do we need? We need the country and
  1783. 1:02:17score from our table customers. So let's
  1784. 1:02:20start like this. Now you can see we have
  1785. 1:02:21the countries and the scores. And the
  1786. 1:02:23task says we have to group up the data
  1787. 1:02:25by the country. So that means this is
  1788. 1:02:27the column where we're going to do the
  1789. 1:02:28group by and the total scores will be
  1790. 1:02:31aggregated. So what we have to do? We're
  1791. 1:02:32going to use the group by since it says
  1792. 1:02:34for each country. We're going to use it
  1793. 1:02:36over here. Group by country. And now we
  1794. 1:02:38have to go and aggregate the scores. We
  1795. 1:02:41cannot leave it like this. So we're
  1796. 1:02:42going to say the sum of the score. So
  1797. 1:02:44let's go and execute it. And with that,
  1798. 1:02:47as you can see, we are getting the total
  1799. 1:02:49scores for each country. So now instead
  1800. 1:02:51of having five customers, we have only
  1801. 1:02:54three rows now. And that's because the
  1802. 1:02:56countries has three rows. And now if you
  1803. 1:02:58check the result, you can see something
  1804. 1:03:00weird. It says no column name. And
  1805. 1:03:02that's because we have changed the
  1806. 1:03:04scores. It's not anymore the original
  1807. 1:03:06score. It is it is the total scores. We
  1808. 1:03:09have summarized those values. So SQL
  1809. 1:03:12don't know how we going to call it. So
  1810. 1:03:14those values doesn't come directly from
  1811. 1:03:16the database. It is manipulation that
  1812. 1:03:18you have done here. Now in order to give
  1813. 1:03:20a nice name for that we can go and add
  1814. 1:03:22aliases. An alias it is only like a name
  1815. 1:03:25that lives inside your query. So we can
  1816. 1:03:27do it like this as and you can specify
  1817. 1:03:29any name you want like for example total
  1818. 1:03:32score. And now scale can understand okay
  1819. 1:03:34this is the name for this column and if
  1820. 1:03:36you go and execute it you will see the
  1821. 1:03:38new name in the results. But you have to
  1822. 1:03:40understand this name exists only in this
  1823. 1:03:42query. You are not renaming anything
  1824. 1:03:44inside your database and you cannot use
  1825. 1:03:47it in any other queries. It is just
  1826. 1:03:49something that is known inside this
  1827. 1:03:51query and only for your results. And of
  1828. 1:03:53course you can rename anything any
  1829. 1:03:54column like for example here you can say
  1830. 1:03:57this is the customer country and if you
  1831. 1:04:00execute it you are just renaming the
  1832. 1:04:02column in the output. So this is really
  1833. 1:04:04nice in SQL. Okay. So now there is like
  1834. 1:04:06one more thing about the group I the
  1835. 1:04:08non-aggregated columns that you are
  1836. 1:04:10adding in the select must be as well
  1837. 1:04:12mentioned in the group I. So now for
  1838. 1:04:14example let's say that okay I'm seeing
  1839. 1:04:16now the countries the total scores I
  1840. 1:04:18would like to see as well the first
  1841. 1:04:20name. So you go over here and say you
  1842. 1:04:22know what let's get the first name. So
  1843. 1:04:24country first name the total scores and
  1844. 1:04:26execute. You will get an error because
  1845. 1:04:28it's going to tell you I need only the
  1846. 1:04:30columns that you want to group the data
  1847. 1:04:32by or should be aggregated. So now the
  1848. 1:04:35first name it is not aggregated and as
  1849. 1:04:37well not used for the group I. So it is
  1850. 1:04:40just here to confuse SQL and it will not
  1851. 1:04:42work. So if you bring a column either it
  1852. 1:04:45should be in the aggregation or it
  1853. 1:04:47should be part of the group I. So in
  1854. 1:04:49order to fix this and you really want to
  1855. 1:04:50see the first name you can go over here
  1856. 1:04:52and say you know what let's add it to
  1857. 1:04:54the group I and execute. This time it
  1858. 1:04:57going to work because all the columns
  1859. 1:04:59that are mentioned here is as well part
  1860. 1:05:01of the group I. So now as you can see we
  1861. 1:05:03have the countries the first name and
  1862. 1:05:05the total scores and you can see again
  1863. 1:05:07we have five rows we don't have three
  1864. 1:05:09rows and that's because now you are
  1865. 1:05:11combining the data by the country and as
  1866. 1:05:14well the first name and now you can see
  1867. 1:05:15in the output we are getting five rows
  1868. 1:05:18we are not getting anymore the three
  1869. 1:05:19rows the three countries and that's
  1870. 1:05:21because SQL now grouping the data by two
  1871. 1:05:24columns the combination of the country
  1872. 1:05:26and the first name and those two columns
  1873. 1:05:28gives five combinations and that means
  1874. 1:05:30you will get five rows so that means you
  1875. 1:05:32have to be really careful what you are
  1876. 1:05:34defining in the group I and the number
  1877. 1:05:36of the unique values that those columns
  1878. 1:05:38are generating going to define the
  1879. 1:05:41output the results. So if you go and
  1880. 1:05:43remove the first name and from here as
  1881. 1:05:45well you are grouping by only one column
  1882. 1:05:47and this column has only three values
  1883. 1:05:49and that's why you are getting three
  1884. 1:05:51rows and with that of course we have
  1885. 1:05:52solved the task and now let's extend the
  1886. 1:05:54task and say find the total score and
  1887. 1:05:57total number of customers for each
  1888. 1:05:59country. So that means we need two
  1889. 1:06:01aggregations. We have the total score
  1890. 1:06:03and as well we need the total number of
  1891. 1:06:05customers. So from reading this you can
  1892. 1:06:07understand we still want to group up the
  1893. 1:06:09data by the country but this time we
  1894. 1:06:11need two type of aggregations. We need
  1895. 1:06:14the total number of customers and the
  1896. 1:06:16total scores. So we have almost
  1897. 1:06:17everything but what is missing is the
  1898. 1:06:19second aggregation. Now what you can do
  1899. 1:06:21you can go over here and add another
  1900. 1:06:23aggregate function called the count. And
  1901. 1:06:26what we want to count is the number of
  1902. 1:06:28customers. So we can go and add the ID
  1903. 1:06:30over here and call it total customers.
  1904. 1:06:33So now of course SQL going to So now if
  1905. 1:06:34you go and execute it, you will get as
  1906. 1:06:37well the total customers by the country.
  1907. 1:06:39And now as you can see SSQL has no
  1908. 1:06:41problem with the ID and that's because
  1909. 1:06:42you are aggregating the ID. So SQL know
  1910. 1:06:45what to do with it and how to combine
  1911. 1:06:47it. So that means you don't have to
  1912. 1:06:48mention the ID in the country because
  1913. 1:06:51you are aggregating it. So that's all
  1914. 1:06:53with that we have solved as well the
  1915. 1:06:54task. All right. Right. So with this you
  1916. 1:06:56have learned how to group up your data
  1917. 1:06:58using the group eye. Next we're going to
  1918. 1:07:00talk about another technique on how to
  1919. 1:07:01filter your data but this time using the
  1920. 1:07:04having clause. So let's
  1921. 1:07:09go. All right. So what is exactly
  1922. 1:07:11having? You can use it in order to
  1923. 1:07:13filter your data but after the
  1924. 1:07:15aggregation. So that means we can use
  1925. 1:07:18the having only after using the group I.
  1926. 1:07:21So let's see the syntax of that. So
  1927. 1:07:23again like the previous example we are
  1928. 1:07:25finding the total score by country. So
  1929. 1:07:27we have our select from group I and now
  1930. 1:07:30you say you know what I would like to
  1931. 1:07:31filter the end results and in order to
  1932. 1:07:33do that we use the having after the
  1933. 1:07:36group I and now like the wear clause you
  1934. 1:07:38have to specify a condition. So we have
  1935. 1:07:40the following condition where we want to
  1936. 1:07:42see in the results only the countries if
  1937. 1:07:45their total score is higher than 800. So
  1938. 1:07:48this going to be our condition. So now
  1939. 1:07:50you might noticing something with the
  1940. 1:07:51group by we are using the country the
  1941. 1:07:54column where we are grouping the data by
  1942. 1:07:55its value but with the having we are
  1943. 1:07:58using the aggregated column the sum of
  1944. 1:08:01the score. So this is how the syntax
  1945. 1:08:03works and now let's see how is going to
  1946. 1:08:05execute it. So as usual SQL start with
  1947. 1:08:07the from we are getting our data and
  1948. 1:08:09then the second step is going to go and
  1949. 1:08:11aggregate the data by the country. So
  1950. 1:08:13it's like before going to group the rows
  1951. 1:08:16with the same value of the country. So
  1952. 1:08:18we're going to have one row for each
  1953. 1:08:20country and this is what going to happen
  1954. 1:08:21if you use group I and with that we have
  1955. 1:08:23now aggregated values right and after
  1956. 1:08:26the group IQL going to go and execute
  1957. 1:08:28the having. So having it is like a
  1958. 1:08:30filter. Now we have a nice condition the
  1959. 1:08:32total sale must be higher than 800 and
  1960. 1:08:35SQL going to go and check the new
  1961. 1:08:36results after the aggregation. So in
  1962. 1:08:39Germany we have the total sales of 850.
  1963. 1:08:41So it meets the condition and it going
  1964. 1:08:43to stay in the results. The same thing
  1965. 1:08:44for USA it is higher as well than 900s
  1966. 1:08:47but for UK it is not meeting the
  1967. 1:08:49condition 750 it is not higher than 800
  1968. 1:08:53and SQL going to go and filter out this
  1969. 1:08:55row so that means after applying the
  1970. 1:08:57having we will get only two countries
  1971. 1:08:59because they have values that is
  1972. 1:09:01fulfilling the condition and that's it
  1973. 1:09:03is what can happen if you are using
  1974. 1:09:05having it is simply filtering the data
  1975. 1:09:07but now you might be confused you say
  1976. 1:09:09you know what we have used the wear
  1977. 1:09:10clouds to filter the data so why we have
  1978. 1:09:12in SQL another cloud how to filter my
  1979. 1:09:15data. Can't we just use the where? Well,
  1980. 1:09:17in SQL there are like different ways on
  1981. 1:09:19how to filter your data based on the
  1982. 1:09:21scenario. So now let's go and add both
  1983. 1:09:23of the filters in my query. We are
  1984. 1:09:25already using the having after the group
  1985. 1:09:27I and now let's go and add the wear.
  1986. 1:09:29Usually the wear comes between the from
  1987. 1:09:31and the group I so directly after the
  1988. 1:09:33from. And here we are saying the score
  1989. 1:09:35must be higher than 400. So now we are
  1990. 1:09:37filtering based on the scores twice,
  1991. 1:09:39right? Once we are saying the score
  1992. 1:09:41higher than 400 and by having we are
  1993. 1:09:43saying the sum of score must be higher
  1994. 1:09:45than 800. So what is the big difference?
  1995. 1:09:48It is when the filter is happening. If
  1996. 1:09:50you want to filter the data before the
  1997. 1:09:52aggregation you want to filter the
  1998. 1:09:54original data then you can go and use
  1999. 1:09:57the wear clause. But if you want to
  2000. 1:09:59filter the data after the aggregations
  2001. 1:10:01after the group by then you can go and
  2002. 1:10:03use having. So it's really all about
  2003. 1:10:05when the filter is happening. So let's
  2004. 1:10:07see how is still going to execute this.
  2005. 1:10:09So as usual first the from going to be
  2006. 1:10:11executed to get the data. Then after
  2007. 1:10:13that the second step the wear going to
  2008. 1:10:15be executed. This is our first filter.
  2009. 1:10:17So SQL going to filter the data using
  2010. 1:10:19where before doing any aggregations and
  2011. 1:10:22based on our condition the first
  2012. 1:10:24customer will be filtered out because
  2013. 1:10:26score is less than 400 and the same
  2014. 1:10:28thing for the last customer. Now after
  2015. 1:10:30the applying the wear clouds we will get
  2016. 1:10:32only three rows only three customers.
  2017. 1:10:35And now next SQL going to go and execute
  2018. 1:10:36the group by. So it's still going to go
  2019. 1:10:38and group the data by the country. So
  2020. 1:10:40now we have fewer data to be combined.
  2021. 1:10:42So the values will not be summarized
  2022. 1:10:44because we have only one row for each
  2023. 1:10:46country. Now after the data is
  2024. 1:10:47aggregated by the group by then SQL
  2025. 1:10:50going to activate the second filter
  2026. 1:10:52having. So the next step is going to
  2027. 1:10:54execute the having and here SQL going to
  2028. 1:10:56filter the new results based on the
  2029. 1:10:58total scores and still going to check
  2030. 1:11:00one by one. So, USA is meeting the
  2031. 1:11:02condition. UK going to be filtered out
  2032. 1:11:04because it is not higher than 800. And
  2033. 1:11:06this time Germany as well will be
  2034. 1:11:08filtered out because this time it is not
  2035. 1:11:10fulfilling the condition. In the
  2036. 1:11:12previous example without the wear, we
  2037. 1:11:14had more scores for Germany. That's why
  2038. 1:11:16it passed the test. But this time since
  2039. 1:11:18we filtered a lot of customers using the
  2040. 1:11:20wear, Germany will not have enough
  2041. 1:11:22scores pass the second filter. So with
  2042. 1:11:24that in the output we will get only one
  2043. 1:11:26row and that's because we are filtering
  2044. 1:11:28a lot of data. So it is very simple
  2045. 1:11:30where going to be executed before the
  2046. 1:11:32group by before the aggregations having
  2047. 1:11:34going to be executed after the group by
  2048. 1:11:36after the aggregations. So now let's go
  2049. 1:11:38back to scale in order to practice.
  2050. 1:11:40Okay. So now we have very interesting
  2051. 1:11:42task find the average score for each
  2052. 1:11:44country considering only customers with
  2053. 1:11:46a score not equal to zero. So it sounds
  2054. 1:11:49like condition and return only those
  2055. 1:11:51countries with an average score greater
  2056. 1:11:53than 430. So this is again another
  2057. 1:11:56condition. So I know there is a lot of
  2058. 1:11:58things that's going on. Let's do it step
  2059. 1:12:00by step. Usually I start by doing a very
  2060. 1:12:02simple select statement with the columns
  2061. 1:12:04and data that I need. So let's start
  2062. 1:12:06with a simple select. So what do we need
  2063. 1:12:08over here? We need a score. We need a
  2064. 1:12:10country. Again we need a score country.
  2065. 1:12:13So all what we need is two columns. Now
  2066. 1:12:15I'm going to go and select the ID just
  2067. 1:12:17to see the customer ID. Then let's go
  2068. 1:12:19and get the country score from our table
  2069. 1:12:22customers. So let's go and query that.
  2070. 1:12:23So now as you can see I start with the
  2071. 1:12:25basics. Query the data and then build up
  2072. 1:12:27on top of it the second step. Now what
  2073. 1:12:29do we have in the task? We have to find
  2074. 1:12:30the average score for each country. That
  2075. 1:12:33means we have to do some aggregations.
  2076. 1:12:35And here we have two conditions. The
  2077. 1:12:36first condition says we need only the
  2078. 1:12:39customers with a score not equal to
  2079. 1:12:40zero. And the second one we need only
  2080. 1:12:43the countries with an average score
  2081. 1:12:44greater than 430. Now you have to decide
  2082. 1:12:47for each condition whether you're going
  2083. 1:12:49to use the where or having. Now for the
  2084. 1:12:52first one we want to filter based on the
  2085. 1:12:54scores. So that means we want to filter
  2086. 1:12:56before the aggregations. It's not saying
  2087. 1:12:59the average score. It's saying the score
  2088. 1:13:00itself. So that means we can use for
  2089. 1:13:03this a wear condition. Now about the
  2090. 1:13:05second one it says countries with an
  2091. 1:13:07average score greater than 430. That
  2092. 1:13:09means we want to filter the data after
  2093. 1:13:12aggregating the score. So that means for
  2094. 1:13:14this condition we have to use the
  2095. 1:13:16having. Now what I would like to do is
  2096. 1:13:18to implement the first condition. It's
  2097. 1:13:20very simple. We're going to say where
  2098. 1:13:22after the from the score is not equal to
  2099. 1:13:25zero. So let's go and execute it. And
  2100. 1:13:27with that we don't have any customers
  2101. 1:13:29where the scores is not equal to zero.
  2102. 1:13:32So that we have solved this part. But
  2103. 1:13:34now for the second condition first we
  2104. 1:13:36have to do the aggregations. So we're
  2105. 1:13:37going to start with the average score.
  2106. 1:13:40We're going to go over here and say
  2107. 1:13:41average and we're going to call it
  2108. 1:13:43average score. Now we don't want to see
  2109. 1:13:45only the average score. We want to see
  2110. 1:13:47the average score for each country. So
  2111. 1:13:49that means we have to aggregate by the
  2112. 1:13:51country and for that we use the group I
  2113. 1:13:54group by comes always after the wear
  2114. 1:13:56clause. So group by and which column?
  2115. 1:13:58It's going to be the country. So
  2116. 1:14:00country. Now there is like an issue
  2117. 1:14:02here. You cannot execute it like this.
  2118. 1:14:04We have to go and get rid of the ID. We
  2119. 1:14:06don't need it at all. So let's go and
  2120. 1:14:08execute it. So with that we have the
  2121. 1:14:10average score for each country and we
  2122. 1:14:12have solved the first part. So that
  2123. 1:14:14means the first and the second part they
  2124. 1:14:17are completed. Now we're going to talk
  2125. 1:14:18about the last part. The average score
  2126. 1:14:20must be higher than 430. And for that
  2127. 1:14:23we're going to use the having and having
  2128. 1:14:25comes after the group by. Now we need to
  2129. 1:14:27specify the condition. It must be the
  2130. 1:14:29aggregated column. So we're going to
  2131. 1:14:31take the average score from here and put
  2132. 1:14:33it after the having and it should be
  2133. 1:14:35greater than 430. So that's it. With
  2134. 1:14:38that we have the last part as well.
  2135. 1:14:40Let's go and execute it now. And with
  2136. 1:14:42that my friends we have filtered the
  2137. 1:14:44data after the aggregation. So this is
  2138. 1:14:47how I decide between the where and
  2139. 1:14:49having. It is very simple. All right. So
  2140. 1:14:51with that you have learned how to filter
  2141. 1:14:53the aggregated data using the having.
  2142. 1:14:55And now next we're going to go back to
  2143. 1:14:56the top where we can use there the
  2144. 1:14:58keyword distinct exactly after the
  2145. 1:15:00select. So let's go now and learn about
  2146. 1:15:03the
  2147. 1:15:06distinct. Okay. So what is exactly
  2148. 1:15:09distinct? If you use it in SQL, it's
  2149. 1:15:11going to go and remove duplicates in
  2150. 1:15:12your data. Duplicates are like repeated
  2151. 1:15:15values in your data and it's going to
  2152. 1:15:16make sure that each value appears only
  2153. 1:15:19once in the results. So it sounds very
  2154. 1:15:21simple and as well the syntax is easy.
  2155. 1:15:23So as usual we start always with a
  2156. 1:15:25select but directly after the select we
  2157. 1:15:28use the keyword distinct. So there is
  2158. 1:15:30nothing between them and then the normal
  2159. 1:15:32stuff we specify the columns and then
  2160. 1:15:34the from in order to get the data from
  2161. 1:15:36table. Let's say that I would like to
  2162. 1:15:37get a list of unique values of the
  2163. 1:15:39country. So the first thing that SQL
  2164. 1:15:41going to do of course is to get the data
  2165. 1:15:42from the database using the from. And
  2166. 1:15:44now the second step is the select. So
  2167. 1:15:47SQL going to execute it and going to
  2168. 1:15:48select only one column the country. All
  2169. 1:15:51other columns going to be excluded and
  2170. 1:15:53removed from the results. And now SQL
  2171. 1:15:55going to go to the third step. It's
  2172. 1:15:56going to go and apply the distincts on
  2173. 1:15:58the country values. So it acts like a
  2174. 1:16:00filter where it going to make sure each
  2175. 1:16:02value happens only once. So it's going
  2176. 1:16:04to start with the first value Germany.
  2177. 1:16:06Now it's going to look to the results.
  2178. 1:16:07Do we have Germany? Well, we don't have
  2179. 1:16:09anything yet. So that's why it's going
  2180. 1:16:11to include it in the results. Then the
  2181. 1:16:12next value is going to be USA. The same
  2182. 1:16:14thing. We don't have USA in the results.
  2183. 1:16:16So it's going to go and include it. And
  2184. 1:16:18this happens as well for the UK. We
  2185. 1:16:20don't have UK in the final results.
  2186. 1:16:22That's why it's going to go as well
  2187. 1:16:23included. Now comes Germany again. Now
  2188. 1:16:26it's going to say wait, we have it
  2189. 1:16:28already. So it will not go and add it
  2190. 1:16:30again in the output because it must
  2191. 1:16:32appear only once. So we will not have
  2192. 1:16:34Germany twice. And as well for the last
  2193. 1:16:36value the USA we have it already in the
  2194. 1:16:38results that's why it will not appear
  2195. 1:16:40again and with that we have removed the
  2196. 1:16:42duplicates or the repetition inside our
  2197. 1:16:45data. So each value is unique. Now let's
  2198. 1:16:47go back to SQL. Okay that task is very
  2199. 1:16:49simple. It says return unique list of
  2200. 1:16:52all countries. So let's go and do that.
  2201. 1:16:54It's going to be funny. So select and
  2202. 1:16:56now let's get the column country from
  2203. 1:16:58our table customers like this. Now you
  2204. 1:17:01can see we have a list of all countries
  2205. 1:17:02but the task says we need a unique list.
  2206. 1:17:05So that means I cannot have here
  2207. 1:17:06repetitions inside it. And with that
  2208. 1:17:08we're going to use the very nice
  2209. 1:17:09distinct. So if you do it like this
  2210. 1:17:13let's go and execute. You will see there
  2211. 1:17:15will be no duplicates in your results
  2212. 1:17:16and all the values in the result going
  2213. 1:17:18to be unique. So with that we have
  2214. 1:17:19solved the task. It's it's very simple.
  2215. 1:17:21Now there is like one thing about the
  2216. 1:17:22distinct that I see a lot of people
  2217. 1:17:24using it a lot in cases that it's not
  2218. 1:17:27really necessary. So for example, let's
  2219. 1:17:29go and get the ID. Now if you go and
  2220. 1:17:31execute it, you can see here we have a
  2221. 1:17:33list of all ids and there are no
  2222. 1:17:35duplicates. But now if I go and remove
  2223. 1:17:37the distinct and executed, we will get
  2224. 1:17:39the same results because the ids are
  2225. 1:17:42usually unique. So it really makes no
  2226. 1:17:44sense to go and say distinct because as
  2227. 1:17:46you can see the database has to go and
  2228. 1:17:48make sure each value happens only once.
  2229. 1:17:50So there's like extra work for the SQL
  2230. 1:17:52and it is usually an expensive
  2231. 1:17:54operation. So if your data is already
  2232. 1:17:56unique, don't go and apply distincts.
  2233. 1:17:58Only if you see repetitions and
  2234. 1:18:00duplicates and you don't want to see
  2235. 1:18:01that only in this scenario, go and apply
  2236. 1:18:03the distinct. Don't go blindly for each
  2237. 1:18:06query applying distinct just in case
  2238. 1:18:08there is duplicates. This is usually bad
  2239. 1:18:10practices. Okay. So that's all for
  2240. 1:18:12distinct. Okay my friends. So with that
  2241. 1:18:14you have learned how to remove the
  2242. 1:18:15duplicates using the distinct. In the
  2243. 1:18:17next step we're going to talk about
  2244. 1:18:19another keyword that you can use
  2245. 1:18:20together with the select. You can use
  2246. 1:18:22top in order to limit your data. So now
  2247. 1:18:24let's go and understand what this
  2248. 1:18:29means. Okay. So what is exactly top or
  2249. 1:18:32in other databases we call it limit. So
  2250. 1:18:34it is again some kind of filtering in
  2251. 1:18:36SQL. If you use it, it's going to go and
  2252. 1:18:38restrict the number of rows returned in
  2253. 1:18:41the results. So you have a control on
  2254. 1:18:43how many rows you want to see in the
  2255. 1:18:45results. The syntax is very simple as
  2256. 1:18:47well. Directly after the selects you're
  2257. 1:18:49going to use the keyword top and then
  2258. 1:18:51you specify the number of rows you want
  2259. 1:18:53to see in the results. So for example
  2260. 1:18:55three and then only after that you
  2261. 1:18:56specify the columns that you want and
  2262. 1:18:58then from which table. Now let's see how
  2263. 1:19:00going to execute it. So as usual the
  2264. 1:19:02from going to be executed we will get
  2265. 1:19:04our data and then the second step is
  2266. 1:19:06going to go and select the columns. In
  2267. 1:19:08this case all the columns going to stay
  2268. 1:19:09and then after that it's going to
  2269. 1:19:11execute that top. So how it works? It's
  2270. 1:19:13very simple. For each row in database,
  2271. 1:19:16we have a row number. It has nothing to
  2272. 1:19:18do with your data with the ids. For
  2273. 1:19:20example, here like in the current
  2274. 1:19:21result, we have row number 1 2 3 4 5.
  2275. 1:19:24Those numbers are not your actual data.
  2276. 1:19:27It is something technical from the
  2277. 1:19:28database. So it is not equal to the ids.
  2278. 1:19:31For example, the ids is actually your
  2279. 1:19:33content your data. So here we are not
  2280. 1:19:35filtering based on the data based on the
  2281. 1:19:37row numbers. So since here we have
  2282. 1:19:39defined three SQL going to count. Okay.
  2283. 1:19:41row number one 2 three and that's it. So
  2284. 1:19:44it's going to make a cut and all the
  2285. 1:19:46rows after number three they will be
  2286. 1:19:48excluded from the results and you will
  2287. 1:19:50get only the three rows at the results.
  2288. 1:19:52So now as you can see this type of
  2289. 1:19:54filtering is not based on a condition or
  2290. 1:19:56something it's just based on the row
  2291. 1:19:58numbers. So whatever results you have in
  2292. 1:20:00your data it will go and make a cut at
  2293. 1:20:03specific row. So let's go to scale and
  2294. 1:20:05practice that. Okay. So now we have a
  2295. 1:20:07very simple task. It says retrieve only
  2296. 1:20:09three customers. So let's go and do
  2297. 1:20:11that. We're going to go and select star
  2298. 1:20:13from our table customers and execute it.
  2299. 1:20:16Now as you can see in the output we have
  2300. 1:20:17five customers. But the task says we
  2301. 1:20:19want only three. And there is no
  2302. 1:20:21specifications at all about any
  2303. 1:20:23condition. So I don't have to go and
  2304. 1:20:25make a work clause where we write a
  2305. 1:20:26condition based on our data. We just
  2306. 1:20:29want three customers. So we can do that
  2307. 1:20:31very simply by just adding top exactly
  2308. 1:20:34after the select and then specify the
  2309. 1:20:36number of rows you want to see from the
  2310. 1:20:38output. So select top three and then the
  2311. 1:20:40star. Let's go and execute it. And with
  2312. 1:20:42that we are getting three customers.
  2313. 1:20:44That's it. It's very simple. All right.
  2314. 1:20:46Now moving on to another task. It says
  2315. 1:20:48retrieve the top three customers with
  2316. 1:20:51the highest scores. Now of course this
  2317. 1:20:53is like a mix between ordering the data
  2318. 1:20:55and filtering the data. Right? So we
  2319. 1:20:57usually sort the data by the scores from
  2320. 1:20:59the highest to the lowest. But now it's
  2321. 1:21:01like we are doing both together. So
  2322. 1:21:03let's do it again step by step. I will
  2323. 1:21:05just back to the select star from
  2324. 1:21:07customers. Now what we can do we can go
  2325. 1:21:09and sort the data by the score from the
  2326. 1:21:11highest to the lowest using the order by
  2327. 1:21:14so order by score and then descending.
  2328. 1:21:16So let's go and execute it. And now you
  2329. 1:21:18can see the first customer is with the
  2330. 1:21:19highest score and then the second
  2331. 1:21:21highest and so on. Now I think you
  2332. 1:21:23already got it in order to get the top
  2333. 1:21:26three customers with the highest scores.
  2334. 1:21:28What you have to do is to just go over
  2335. 1:21:30here and say top three and execute it.
  2336. 1:21:33And with that you have now a really nice
  2337. 1:21:35analyzis on your data. It's like a
  2338. 1:21:37reports where we are finding the top
  2339. 1:21:39customers with the highest score. So
  2340. 1:21:41this is really amazing and very easy. So
  2341. 1:21:43as you can see mixing the top with the
  2342. 1:21:45sorting the data you can make top end
  2343. 1:21:48analyzes or bottom end analyzers. So
  2344. 1:21:50let's have this task retrieve the lowest
  2345. 1:21:52two customers based on the score. So now
  2346. 1:21:54we want to get the lowest scores in our
  2347. 1:21:56table. And in order to do that is very
  2348. 1:21:58simple. What we're going to do we're
  2349. 1:22:00going to flip that. So we're going to
  2350. 1:22:01sort our data based on the scores
  2351. 1:22:02ascending from the lowest to the
  2352. 1:22:04highest. And since we want only the
  2353. 1:22:06lowest two customers, we're going to
  2354. 1:22:07replace the three with a two and execute
  2355. 1:22:09it. And with that, we're going to get at
  2356. 1:22:10the lowest two customers. It is Peter
  2357. 1:22:12and Maria. They have the lowest scores.
  2358. 1:22:14Again, it's very easy. Okay, this is
  2359. 1:22:16fun. Let's go to the next one. Get the
  2360. 1:22:18two most recent orders. Well, this time
  2361. 1:22:21we are speaking about another table.
  2362. 1:22:23Let's go and select everything from the
  2363. 1:22:24table orders like this. So now, as you
  2364. 1:22:28can see, we have here four orders and we
  2365. 1:22:30want the two most recent orders. So most
  2366. 1:22:33recent means we have to deal with the
  2367. 1:22:35order dates and we can build that by
  2368. 1:22:37sorting the data by the order dates. So
  2369. 1:22:40order by order dates and since we are
  2370. 1:22:43saying the most recent orders so from
  2371. 1:22:45the highest date to the lowest that
  2372. 1:22:47means descending right let's go and
  2373. 1:22:49execute it and as you can see based on
  2374. 1:22:51our data and now we can look to our
  2375. 1:22:52result this is the last order in our
  2376. 1:22:54business based on the order age and this
  2377. 1:22:57one is one of the earliest orders. So
  2378. 1:22:59with that we have sorted the data and
  2379. 1:23:01since we want the two most recent orders
  2380. 1:23:03we go over here and say we go exactly
  2381. 1:23:05after the select and say top two and
  2382. 1:23:08execute and with that we have now the
  2383. 1:23:10last two orders in our business. So as
  2384. 1:23:13you can see combining the top with the
  2385. 1:23:14order by you can do amazing analyszis.
  2386. 1:23:17All right so this is how you limit your
  2387. 1:23:19data using top and with that you have
  2388. 1:23:20learned the basics everything that you
  2389. 1:23:22can learn and with that you have learned
  2390. 1:23:23all the clauses the sections that you
  2391. 1:23:26can use in any query in SQL. Now next
  2392. 1:23:29what we're going to do we're going to
  2393. 1:23:30put everything together in one query in
  2394. 1:23:33order to learn how SQL going to go and
  2395. 1:23:35deal with all those clauses and how SQL
  2396. 1:23:37going to go and execute it. So let's go
  2397. 1:23:39and do
  2398. 1:23:42that. Okay. So now I'm going to show you
  2399. 1:23:45the coding order of a query compared to
  2400. 1:23:48the execution order that happens in the
  2401. 1:23:50database. So the coding order of a query
  2402. 1:23:52starts always with a select and then
  2403. 1:23:54exactly after that you can put a
  2404. 1:23:56distinct and then after the distinct you
  2405. 1:23:58can put a top. So this is the order of
  2406. 1:24:00all those keywords and then you can go
  2407. 1:24:02and select like few columns and after
  2408. 1:24:04you specify the columns separated with a
  2409. 1:24:06comma you tell SQL from which table your
  2410. 1:24:08data come from using the from clause.
  2411. 1:24:11Now after that if you want to filter the
  2412. 1:24:13data before the aggregation you can use
  2413. 1:24:14the where clause and this always comes
  2414. 1:24:17directly after the from. And if you want
  2415. 1:24:19to group the data then you have to do it
  2416. 1:24:21after the wear clause using the group by
  2417. 1:24:23and after the group buys comes the
  2418. 1:24:25having if you want to filter the data.
  2419. 1:24:27And the last thing that you can specify
  2420. 1:24:29in query it is always the order by. So
  2421. 1:24:32this is the order of all those
  2422. 1:24:33components of the query. And if you
  2423. 1:24:35don't follow this order you will get an
  2424. 1:24:37error from the database. Now if you look
  2425. 1:24:39to this query there are a lot of things
  2426. 1:24:41that's going to filter your data. So
  2427. 1:24:43let's check them one by one. The first
  2428. 1:24:44thing that you can do is to filter the
  2429. 1:24:46columns. If you don't want to see all
  2430. 1:24:47the columns, you want to see only
  2431. 1:24:49specific columns, you use the select and
  2432. 1:24:51of course you must use it. So the
  2433. 1:24:53columns that you specify will be shown
  2434. 1:24:55in the results. So it's like filtering
  2435. 1:24:56the columns. Now there is another type
  2436. 1:24:58of filter where you filter out the
  2437. 1:25:00duplicates if you want to see unique
  2438. 1:25:02results and that's using the distinct.
  2439. 1:25:04So this is another type of filter.
  2440. 1:25:06Moving on, we can filter the result
  2441. 1:25:08based on the row numbers. So we can
  2442. 1:25:10limit the result using the top. But this
  2443. 1:25:12type of filter doesn't need any
  2444. 1:25:14conditions. It's purely based on the row
  2445. 1:25:17number in the results. Now moving on, if
  2446. 1:25:19you want to filter your data based on
  2447. 1:25:20conditions based on your data, you can
  2448. 1:25:22filter the rows before the aggregation
  2449. 1:25:25using the wear clause. And the last type
  2450. 1:25:28of filtering, you can filter your rows
  2451. 1:25:30after the aggregation using the having.
  2452. 1:25:32So as you can see, we have like five
  2453. 1:25:34different types and how to filter the
  2454. 1:25:36results in SQL. So now let's see the
  2455. 1:25:38execution order. As we learned the first
  2456. 1:25:41thing that's going to happen is that SQL
  2457. 1:25:43going to execute the from clause. So SQL
  2458. 1:25:45going to go and find your data in the
  2459. 1:25:47database where all the next steps going
  2460. 1:25:49to be paste on this data. Now the next
  2461. 1:25:51step that is going to do is that it's
  2462. 1:25:53going to go and filter the data using
  2463. 1:25:55the wear clause. This has to be happen
  2464. 1:25:57before anything else. So before any
  2465. 1:25:59aggregations and so on we have to make
  2466. 1:26:01scope of the data. So once SQL apply it
  2467. 1:26:03maybe some of the rows going to be
  2468. 1:26:05removed and once the data is filtered
  2469. 1:26:07the third step SQL going to execute the
  2470. 1:26:10group I so going to take the results and
  2471. 1:26:12start combining the similar values in
  2472. 1:26:15one row and start aggregating the data
  2473. 1:26:17based on the aggregate function that you
  2474. 1:26:18have specified. So now after the group
  2475. 1:26:20by after aggregating the data what is
  2476. 1:26:23going to do now it's going to go and
  2477. 1:26:24apply the second type of filter the
  2478. 1:26:26having. So based on the condition the
  2479. 1:26:27SQL going to go and start removing few
  2480. 1:26:30aggregated data away and keep the rest.
  2481. 1:26:32Now moving on to the step number five.
  2482. 1:26:34Finally it's going to go and execute the
  2483. 1:26:37select distinct. So SQL going to go and
  2484. 1:26:39start selecting the columns that we need
  2485. 1:26:41to see in the results and remove the
  2486. 1:26:42other stuff. And once the columns are
  2487. 1:26:44selected SQL going to go and execute the
  2488. 1:26:47order by. So SQL going to start sorting
  2489. 1:26:49the data based on the column that you
  2490. 1:26:51have specified and the mechanism as
  2491. 1:26:53well. So the data will be sorted
  2492. 1:26:55differently. And my friends the last
  2493. 1:26:57step that going to happen in your query
  2494. 1:26:59will be always the top statements. So
  2495. 1:27:02based on the final final results SQL
  2496. 1:27:04going to go and execute the top. So here
  2497. 1:27:06we are saying top two that means we want
  2498. 1:27:08to keep only the first two rows without
  2499. 1:27:10any conditions. So SQL going to count
  2500. 1:27:12okay row number one two and after that
  2501. 1:27:14it's going to make cuts and remove
  2502. 1:27:16anything after that. So this is the last
  2503. 1:27:19filter that's going to happen and as
  2504. 1:27:20well the last step. So now if you sit
  2505. 1:27:22back and look at this the coding order
  2506. 1:27:24is completely different than the
  2507. 1:27:26execution order in the coding we have
  2508. 1:27:27first to specify the select actually the
  2509. 1:27:30select going to be executed just almost
  2510. 1:27:32at the end. So at the step number five
  2511. 1:27:34and once you understand how SQL execute
  2512. 1:27:36your query you can understand how to
  2513. 1:27:39build correct
  2514. 1:27:43queries. So now the first thing that we
  2515. 1:27:45have learned that we can go and have
  2516. 1:27:47like one query right something like this
  2517. 1:27:50select star from customers. Now this is
  2518. 1:27:52one query and in the output we have one
  2519. 1:27:54results but did you know that in SQL we
  2520. 1:27:57can have like multiple queries and
  2521. 1:27:59multiple results in one go. So we can do
  2522. 1:28:02everything together like for example
  2523. 1:28:03let's say I'm selecting as well the data
  2524. 1:28:05from orders. So that means we have two
  2525. 1:28:08queries and now if you go and execute
  2526. 1:28:11what can happens you will get two result
  2527. 1:28:13grids. The first result grid is for the
  2528. 1:28:16first query and the second one is for
  2529. 1:28:18the second query. So with that you can
  2530. 1:28:20do multiple queries in the same window
  2531. 1:28:23and with that the results can be
  2532. 1:28:25splitted into multiple window depend how
  2533. 1:28:27many queries you have and usually in SQL
  2534. 1:28:29you might find that by the end of each
  2535. 1:28:31query there is a semicolon like this. So
  2536. 1:28:34at the end of the first query we have
  2537. 1:28:35semicolon and for the second query we
  2538. 1:28:37have as well at the end another
  2539. 1:28:39semicolon. For the SQL server it is not
  2540. 1:28:41a must but for other databases if you
  2541. 1:28:43have multiple queries in one execution
  2542. 1:28:46you must separate them with a semicolon
  2543. 1:28:48and with that the database can
  2544. 1:28:49understand okay this is the end of the
  2545. 1:28:52first query and this is the end of the
  2546. 1:28:54second query. So you have like
  2547. 1:28:56separations between
  2548. 1:29:01queries. Okay. Now moving on to another
  2549. 1:29:03cool thing in SQL. Now what if we don't
  2550. 1:29:06want to query the data inside our
  2551. 1:29:08tables, we would like to show a static
  2552. 1:29:10value from us from the one that is
  2553. 1:29:12writing the query. And this is very
  2554. 1:29:13practical. If you are like practicing
  2555. 1:29:15and you want to check something using a
  2556. 1:29:17value from you, not from the tables. So
  2557. 1:29:20how we can do that? It is very simple.
  2558. 1:29:22We're going to write select and then now
  2559. 1:29:24after that instead of having a column
  2560. 1:29:26name you can go and add any value like 1
  2561. 1:29:292 3. So it is just a number and we do
  2562. 1:29:32not specify after that any table. So we
  2563. 1:29:34leave it like this. Select 1 2 3 and we
  2564. 1:29:36don't need to use the from close. So now
  2565. 1:29:39if you go and execute it you will get 1
  2566. 1:29:412 3. So this is a static value. And of
  2567. 1:29:43course you can go and rename the column
  2568. 1:29:45like static number. So execute it again.
  2569. 1:29:49So with that we have a static value. And
  2570. 1:29:51you can go and add anything like string
  2571. 1:29:53as well. So let's say hello as static
  2572. 1:29:56for example string. So let's go and
  2573. 1:29:58execute. Now we have two queries. The
  2574. 1:30:00second one you can see our static value.
  2575. 1:30:02Hello. So in queries we can add values
  2576. 1:30:04from us. Not only selecting data from
  2577. 1:30:07the queries but of course you can go and
  2578. 1:30:08mix stuff. So we can have like in one
  2579. 1:30:10query data from the database and static
  2580. 1:30:13data from us. So let me show you what I
  2581. 1:30:15mean. Let's go over here and say select
  2582. 1:30:17and let's go and get for example the ID
  2583. 1:30:20the first name from the table customers
  2584. 1:30:23like this. So with that we can see we
  2585. 1:30:24are getting data from the database. But
  2586. 1:30:27now I can go and add something from me
  2587. 1:30:29new customer and we can call it customer
  2588. 1:30:32type. So now what is going on here? Two
  2589. 1:30:34columns from the database and one column
  2590. 1:30:37from us. It is the static one. So if you
  2591. 1:30:39go and execute it, you can see for the
  2592. 1:30:41ID and the first name those data comes
  2593. 1:30:43from the database. But for each record
  2594. 1:30:45we are always getting the same static
  2595. 1:30:47value new customer, new customer and so
  2596. 1:30:48on. So this piece of information comes
  2597. 1:30:51from the query. It is not stored inside
  2598. 1:30:53the database and those two informations
  2599. 1:30:55come from the stored data inside the
  2600. 1:30:57database. So this is really cool thing.
  2601. 1:30:59You can add few informations from you
  2602. 1:31:02and you can get the data from the
  2603. 1:31:03database. This is the static
  2604. 1:31:08values. Okay. One more cool thing that I
  2605. 1:31:11want to show you that if you have a
  2606. 1:31:12query like this you are selecting from
  2607. 1:31:14table and filtering the data and now you
  2608. 1:31:16would like not to execute the whole
  2609. 1:31:17thing. You would like to execute only a
  2610. 1:31:19part of this query. So now sometimes as
  2611. 1:31:21you are writing a query, you don't want
  2612. 1:31:23to execute the whole thing. You want to
  2613. 1:31:25execute only part of the query. Like for
  2614. 1:31:27example, I would like to see all the
  2615. 1:31:28customers again in this query without
  2616. 1:31:30this filter. So instead of removing it
  2617. 1:31:33and then query and then again adding it,
  2618. 1:31:35what you can do, you can highlight what
  2619. 1:31:37you want without now the filter and
  2620. 1:31:39execute. So without the database going
  2621. 1:31:41to execute exactly what you highlighted.
  2622. 1:31:43And now as you can see I'm getting all
  2623. 1:31:44the customers without the filter. And if
  2624. 1:31:46you don't highlight anything and
  2625. 1:31:48execute, what's going to happen? It's
  2626. 1:31:49still going to execute the whole thing
  2627. 1:31:51inside the editor. And this is really
  2628. 1:31:53nice if you want to query another table
  2629. 1:31:55quickly in the same editor. Like we want
  2630. 1:31:56to select everything from the orders
  2631. 1:31:58just quickly. So you can highlight only
  2632. 1:32:00this query and execute. And with that
  2633. 1:32:02SQL is ignoring everything else and only
  2634. 1:32:05executing what I'm highlighting. And
  2635. 1:32:07this is really nice. It gives us like
  2636. 1:32:08speed and dynamic. And you're going to
  2637. 1:32:10find me doing that a lot in the course.
  2638. 1:32:12So this is really nice. Okay. My
  2639. 1:32:14friends. So with that we have learned
  2640. 1:32:15the basics about SQL query. the basic
  2641. 1:32:18components of the select statements and
  2642. 1:32:20with that you can talk to our database
  2643. 1:32:22in order to get data. Now in the next
  2644. 1:32:24chapter we're going to learn how to
  2645. 1:32:25define the structure of our database. So
  2646. 1:32:27we're going to learn the data definition
  2647. 1:32:29language DDL. So let's
  2648. 1:32:34go. Okay. So usually if you have like an
  2649. 1:32:37empty database what you want to do is to
  2650. 1:32:39go and define the structure of your
  2651. 1:32:41data. So one of the first things that we
  2652. 1:32:43usually do is we go and create a new
  2653. 1:32:45tables. So here we have a command called
  2654. 1:32:47create and if you use it you can create
  2655. 1:32:49a new object inside the database like
  2656. 1:32:52for example a table. So once you execute
  2657. 1:32:54it you're going to get brand new table
  2658. 1:32:56and usually the table going to be empty
  2659. 1:32:57without any data. So it is very simple.
  2660. 1:33:00This is what the create command does.
  2661. 1:33:02And now let's go to SQL in order to
  2662. 1:33:04create a new table. So my friends we
  2663. 1:33:06have the following task. Create a new
  2664. 1:33:07table called persons with columns ID
  2665. 1:33:11person name birth date and phone. Okay.
  2666. 1:33:13So this time we will not start by select
  2667. 1:33:16we will start with the command create
  2668. 1:33:18table. So we are telling SQL to create a
  2669. 1:33:20table and after that we have to define
  2670. 1:33:22the name of the table. So in this task
  2671. 1:33:24we have to call it persons. Now we have
  2672. 1:33:26to go and open two parenthesis like this
  2673. 1:33:28and in between we have to define the
  2674. 1:33:31columns. So what do we need? First we
  2675. 1:33:33need an ID. So this is the first column
  2676. 1:33:35name. And next we have to define which
  2677. 1:33:37data type for this column. It's going to
  2678. 1:33:38be an int. So it is a number does not
  2679. 1:33:41contain any characters. And now next we
  2680. 1:33:43can define some constraints and we
  2681. 1:33:44cannot have a person without an ID. So
  2682. 1:33:46it should not be in null. So not null.
  2683. 1:33:48This is the first column. So we have
  2684. 1:33:50defined the name of the column, the data
  2685. 1:33:52type and the constraint. Okay. So let's
  2686. 1:33:54go to the second column and here we're
  2687. 1:33:55going to have a comma and the next one
  2688. 1:33:57name going to be person name. So this is
  2689. 1:34:00the column name and the person name we
  2690. 1:34:02can have. And now the data type for this
  2691. 1:34:04column it going to be a varchar because
  2692. 1:34:06the person name contains characters. So
  2693. 1:34:08vchar. And now we have to define the
  2694. 1:34:10length. So I'm going to go with 50
  2695. 1:34:12characters. And now I would say this is
  2696. 1:34:14a must. So each person should has a
  2697. 1:34:16name. So we're going to say not null as
  2698. 1:34:18well. So that we have the name, the type
  2699. 1:34:21and the constraint. Now let's move to
  2700. 1:34:22the third column. It's going to be birth
  2701. 1:34:25date. Now which type of informations we
  2702. 1:34:27have inside the birth date? So it's
  2703. 1:34:29going to be a date, not a number, not
  2704. 1:34:31characters. So we're going to go with
  2705. 1:34:32the data date. And now about the
  2706. 1:34:34constraint well depends. I would say in
  2707. 1:34:37our application it is an optional
  2708. 1:34:39because this is very personal
  2709. 1:34:40information and maybe some persons will
  2710. 1:34:42not provide their birth dates. So this
  2711. 1:34:44is an optional and I will not say it is
  2712. 1:34:46not null. So nulls are allowed. Now
  2713. 1:34:48let's move on to the next one. It's
  2714. 1:34:49going to be the phone. So now what is
  2715. 1:34:51the data type of a phone? Well we have
  2716. 1:34:53some types numbers we have characters
  2717. 1:34:56special characters. So we could have
  2718. 1:34:57anything. So that's why I'm going to go
  2719. 1:34:59with the farchar. And here you can
  2720. 1:35:00specify the length that you think it's
  2721. 1:35:02okay. I'm going to go with 15. Now of
  2722. 1:35:04course depend on the system that you are
  2723. 1:35:06building. I would say the phones are
  2724. 1:35:07very important in order to validate
  2725. 1:35:09whether this is a real person. So we're
  2726. 1:35:12going to say not null. So we are not
  2727. 1:35:15allowing nulls in this field. Perfect.
  2728. 1:35:17So with that we have covered all the
  2729. 1:35:18columns that are required. We have
  2730. 1:35:20defined the data types and as well the
  2731. 1:35:22constraints. Now the last thing in each
  2732. 1:35:24database table we should has a primary
  2733. 1:35:27key in order to make sure this table has
  2734. 1:35:29an integrity and maybe as well
  2735. 1:35:31connectable to other tables. So now what
  2736. 1:35:33we're going to do, we're going to go and
  2737. 1:35:34add the primary key constraint, comma,
  2738. 1:35:36for the last column. And then we're
  2739. 1:35:38going to say constraint. Now we have to
  2740. 1:35:40give a primary key name. This is only
  2741. 1:35:42going to be visible for the database. So
  2742. 1:35:44I'm going to call it PK for primary key.
  2743. 1:35:46And here persons and then after that
  2744. 1:35:48we're going to say primary key. And
  2745. 1:35:51between two parentheses, we're going to
  2746. 1:35:53go and pick which one is the primary
  2747. 1:35:54key. And of course, it's going to be the
  2748. 1:35:56ID. So we're going to go over here and
  2749. 1:35:58say ID. So again, we are saying there is
  2750. 1:36:00a new constraint. This is the name of
  2751. 1:36:02it. It's only internal for the database.
  2752. 1:36:04And then we are saying this one is a
  2753. 1:36:06primary key on the field ID. So that's
  2754. 1:36:08it with that. We have defined a primary
  2755. 1:36:10key for our table. Let's go and execute
  2756. 1:36:13it. So as you can see it is successful.
  2757. 1:36:14Let's go and check our database for our
  2758. 1:36:16new table. So if you don't see it
  2759. 1:36:18already, you have to right click on the
  2760. 1:36:20database and then go and refresh. So
  2761. 1:36:22let's go to tables and now we have a
  2762. 1:36:24brand new table called persons. So with
  2763. 1:36:26that we have created our new table. Now
  2764. 1:36:28of course for the DDL commands you will
  2765. 1:36:30not get results or data. All what you're
  2766. 1:36:33getting is a message from the database
  2767. 1:36:35and the message says here the command
  2768. 1:36:37completed successfully and then we have
  2769. 1:36:39a date when this is completed. So that
  2770. 1:36:41means the DDL command will never return
  2771. 1:36:43data. It is changing the structure of
  2772. 1:36:45your database. It's not about retrieving
  2773. 1:36:48any data and so on. So this command did
  2774. 1:36:50change something in our database and in
  2775. 1:36:52this scenario it created a new table and
  2776. 1:36:54that's why we call this data definition
  2777. 1:36:57language DDL because we are defining the
  2778. 1:37:00database. Now of course if you go and
  2779. 1:37:01say select star from our new table
  2780. 1:37:04persons. So let's go highlight it and
  2781. 1:37:07then execute it. You will see we are
  2782. 1:37:09getting of course the columns. So the
  2783. 1:37:11ID, the person name, birth date, the
  2784. 1:37:13phone but we don't have any rows that
  2785. 1:37:16means our table is empty. Now what is
  2786. 1:37:18very important to that you go and save
  2787. 1:37:20those informations in an SQL script
  2788. 1:37:23because maybe later you have to redefine
  2789. 1:37:25this table but let's say that you have
  2790. 1:37:27created different queries and you have
  2791. 1:37:28lost the script and now I would like to
  2792. 1:37:30see again the create statements for this
  2793. 1:37:33table well there is trick for that if
  2794. 1:37:35you go to the left side you see the
  2795. 1:37:37persons right here right click on it and
  2796. 1:37:39then you have here script table as and
  2797. 1:37:41now we have here different options that
  2798. 1:37:43you can run on the table and the first
  2799. 1:37:45one says create two Then let's go to new
  2800. 1:37:48query
  2801. 1:37:49editor. So now what happened? The
  2802. 1:37:51database did read the metadata
  2803. 1:37:53informations about the person and
  2804. 1:37:55created your DDL query with many extra
  2805. 1:37:58stuff that we haven't done. But this is
  2806. 1:37:59the template that the database uses. So
  2807. 1:38:01now we can see a lot of stuff. But what
  2808. 1:38:03is interesting is this create table. So
  2809. 1:38:06we can see create table the schema DBU
  2810. 1:38:09the default one then the persons and
  2811. 1:38:11then we have our columns the data type
  2812. 1:38:13and as well the constraints. So with
  2813. 1:38:15that you got back your DDL statements
  2814. 1:38:17and many other stuff about the table
  2815. 1:38:19which is now not interesting. But now
  2816. 1:38:21what I really need is to see the create
  2817. 1:38:23statements about this table. So this is
  2818. 1:38:25how you can get back your DL command.
  2819. 1:38:27But of course what I recommend you is
  2820. 1:38:29always put your code inside a get
  2821. 1:38:31repository and always keep it up to
  2822. 1:38:33date. So that always you can check your
  2823. 1:38:35work and extend
  2824. 1:38:39it. Okay. So now what else you can do
  2825. 1:38:41with the structure of your database? If
  2826. 1:38:43you have already a table, what you can
  2827. 1:38:45do, you can go and edit and change the
  2828. 1:38:48definition of the table. So for example,
  2829. 1:38:50let's say I would like to add a new
  2830. 1:38:51column. In order to do that, we can use
  2831. 1:38:54the command alter. Alter means you want
  2832. 1:38:56to edit the definition of your table and
  2833. 1:38:59you want to change it like adding new
  2834. 1:39:01column or maybe changing the data type
  2835. 1:39:03and anything in the definition of the
  2836. 1:39:05table. So the alter command, you can use
  2837. 1:39:07it in order to change the definition of
  2838. 1:39:08your table. And now let's go back to
  2839. 1:39:10scale and try to change something. All
  2840. 1:39:12right. Now the task says add a new
  2841. 1:39:14column called email to the person's
  2842. 1:39:16table. So it is very simple what you can
  2843. 1:39:18do. We can use the alter table command.
  2844. 1:39:20So we are not creating new table. We
  2845. 1:39:23want to edit already existing table. So
  2846. 1:39:25which table we want to modify it's going
  2847. 1:39:27to be the persons. So we are telling SQL
  2848. 1:39:29we want to change something in the table
  2849. 1:39:31persons. And of course we have to tell
  2850. 1:39:32SQL what we want to change. Are we
  2851. 1:39:34removing a column? Are we adding column?
  2852. 1:39:36In this scenario we want to add new
  2853. 1:39:38column. So let's go and add the email
  2854. 1:39:41information. So this is the column name
  2855. 1:39:43and as you are creating a table you have
  2856. 1:39:45to define column name the data type and
  2857. 1:39:47the constraint. So now for the emails
  2858. 1:39:49we're going to have like characters,
  2859. 1:39:50numbers, special characters. So we're
  2860. 1:39:52going to go with the varchar and about
  2861. 1:39:54the length it's going to be let's say 50
  2862. 1:39:56and I'm going to say each person has to
  2863. 1:39:58has an email. So it's going to be not
  2864. 1:40:00null. So with that we are adding
  2865. 1:40:02completely a new column. So that's it.
  2866. 1:40:04Let's go and execute it. Now again this
  2867. 1:40:07is not a query. This is a DDL command
  2868. 1:40:09and in the output we will not get data.
  2869. 1:40:11We will get a message whether everything
  2870. 1:40:13went correctly. So it says command
  2871. 1:40:15completed successfully and the time when
  2872. 1:40:17this is completed. Now we can go and do
  2873. 1:40:19a simple query just to have a check to
  2874. 1:40:21the table. So and now you can see we
  2875. 1:40:23have our columns and at the end we have
  2876. 1:40:25a new column called emails. This is very
  2877. 1:40:27important. If you are adding new column
  2878. 1:40:29it's going to be always at the end of
  2879. 1:40:31the table. But now you might say you
  2880. 1:40:33know what I would like to have the email
  2881. 1:40:34like something in the middle maybe after
  2882. 1:40:36the person name. Well, in order to do
  2883. 1:40:38that, you have completely to delete and
  2884. 1:40:40drop the table and create it from the
  2885. 1:40:42scratch using create command which is
  2886. 1:40:45might be bad if you have data inside the
  2887. 1:40:47table. So if you are fine by adding your
  2888. 1:40:49new column at the end, you can use the
  2889. 1:40:50alter table. But if you say I would like
  2890. 1:40:52it in the middle, then sadly you have to
  2891. 1:40:54go and drop everything and start from
  2892. 1:40:56the scratch. Okay. So now let's have
  2893. 1:40:58another task and it says remove the
  2894. 1:40:59column phone from the person's table. So
  2895. 1:41:02now we're going to do exactly the
  2896. 1:41:03opposite. We're going to go remove it
  2897. 1:41:04completely with its data from the table.
  2898. 1:41:07So we're going to still saying alter
  2899. 1:41:09table persons. We are saying we want to
  2900. 1:41:11edit the definition of the table
  2901. 1:41:12persons. And now instead of adding we
  2902. 1:41:15will be dropping a column. And then
  2903. 1:41:18after that we have to specify as well
  2904. 1:41:19the column name. It's going to be the
  2905. 1:41:21phone. But we don't have to mention
  2906. 1:41:23again the data type and the constraint.
  2907. 1:41:26And that's because the database already
  2908. 1:41:27knows those informations. So we need
  2909. 1:41:29those informations if we are creating
  2910. 1:41:31something new. That's why we can get rid
  2911. 1:41:33of that. We just need the column name
  2912. 1:41:35and the database is going to do the
  2913. 1:41:36rest. So let's go and do that. Now you
  2914. 1:41:39can see successful. And now let's go and
  2915. 1:41:41check our table. And now as you can see
  2916. 1:41:43we have the ID, person name, birth date,
  2917. 1:41:45email, and we don't have the column
  2918. 1:41:47phone. Be careful. If you are deleting
  2919. 1:41:48column, you will be losing as well all
  2920. 1:41:50the data inside this column. So as you
  2921. 1:41:52can see, this is very simple. This is
  2922. 1:41:54how we can edit the definition of our
  2923. 1:41:56table by adding and removing columns.
  2924. 1:42:03Okay, now moving on to the last one in
  2925. 1:42:05this group of commands. So now so far
  2926. 1:42:07what we have done, we have created
  2927. 1:42:08something new in the database. We have
  2928. 1:42:10changed the definition of something
  2929. 1:42:12inside our database. And now the last
  2930. 1:42:14one, you can go and drop something from
  2931. 1:42:17the database. Let's say we have another
  2932. 1:42:18table and we don't need it anymore. So
  2933. 1:42:21we can go and use the drop command in
  2934. 1:42:23order to remove the table completely
  2935. 1:42:26from the database. And this means as
  2936. 1:42:28well removing everything the table and
  2937. 1:42:30the data inside it. So now let's go to
  2938. 1:42:32SQL and let's drop something from our
  2939. 1:42:34database. Okay. So now our task says
  2940. 1:42:36delete the table persons from the
  2941. 1:42:38database. This is the simplest form of
  2942. 1:42:41command in SQL but yet the most risky
  2943. 1:42:43one. So what we need? We have to delete
  2944. 1:42:46and drop the whole table persons. We
  2945. 1:42:48don't need it anymore. We're going to
  2946. 1:42:49say drop table and then all what we have
  2947. 1:42:52to do is to give the name of the table
  2948. 1:42:54persons. So three words. You don't have
  2949. 1:42:57to specify anything. Just destroy the
  2950. 1:42:59table persons. Let's go and execute it.
  2951. 1:43:01It is successful. So as you can see it
  2952. 1:43:03is very simple. Now on the left side to
  2953. 1:43:05your database go refresh and go to the
  2954. 1:43:07tables and you will not see the table
  2955. 1:43:09persons. So the drop command it is very
  2956. 1:43:11simple but yet very risky. So if you
  2957. 1:43:14compare now create table with a drop
  2958. 1:43:16table you can see destroying things is
  2959. 1:43:18way easier than building it. Those are
  2960. 1:43:20the commands create alter drop. those
  2961. 1:43:23commands we use in order to define the
  2962. 1:43:26structure of our database the DDL
  2963. 1:43:28commands that was very simple all right
  2964. 1:43:30so that's all about the data definition
  2965. 1:43:32language DDL and with that you have
  2966. 1:43:34learned how to define new stuff in your
  2967. 1:43:36database now moving on to the next one
  2968. 1:43:38we're going to learn about the data
  2969. 1:43:39manipulation language and here we're
  2970. 1:43:41going to learn how to manipulate our
  2971. 1:43:42data inside the database let's
  2972. 1:43:48go all right so now what we're going to
  2973. 1:43:50do we're going to go and modify and
  2974. 1:43:51manipulate your data inside the
  2975. 1:43:54database. So now sometimes what happens
  2976. 1:43:56you have a table inside your database
  2977. 1:43:58and the table is empty. You don't have
  2978. 1:44:00any rows any data inside the table. Now
  2979. 1:44:02in order to add your data to the table
  2980. 1:44:04what you can do you can use the command
  2981. 1:44:06insert. So insert going to go and add
  2982. 1:44:09new rows to your table and of course not
  2983. 1:44:12always the table must be empty to add
  2984. 1:44:13your data. You can add new rows to
  2985. 1:44:16already existing data and SQL going to
  2986. 1:44:18go and append it at the end of the
  2987. 1:44:20table. Now my friends in order to insert
  2988. 1:44:22new data to the target table there are
  2989. 1:44:24two methods. The first and the classical
  2990. 1:44:26way in order to insert new data we can
  2991. 1:44:29use the insert command and manually
  2992. 1:44:31specifying the values that should be
  2993. 1:44:33inserted to the table. So you're going
  2994. 1:44:35to start specifying in the script the
  2995. 1:44:37values and then they're going to be
  2996. 1:44:38inserted as a new rows to the target
  2997. 1:44:40table. So in this process you are
  2998. 1:44:42manually inserting new values to the
  2999. 1:44:44table using like an SQL scripts. So now
  3000. 1:44:47we're going to focus on this scenario on
  3001. 1:44:49how to insert data. All right. Now let's
  3002. 1:44:50check quickly the syntax of the insert
  3003. 1:44:52command. It start with the keyword
  3004. 1:44:54insert into and after that we have to
  3005. 1:44:56specify the table name. So where we want
  3006. 1:44:58to insert and then we make a list of all
  3007. 1:45:01columns that we want to insert. And then
  3008. 1:45:03we specify list of columns where we're
  3009. 1:45:05going to insert values into them. And
  3010. 1:45:07after that we say values. And finally
  3011. 1:45:09we're going to go now and specify the
  3012. 1:45:11data that should be inserted to the
  3013. 1:45:13table. and we make it as well as a list
  3014. 1:45:15like we have done for the columns. Now
  3015. 1:45:17in the insert statements specifying
  3016. 1:45:19those columns it is totally optional. So
  3017. 1:45:22if you don't specify the columns of the
  3018. 1:45:23table then SQL going to expect you to
  3019. 1:45:26insert values into each column because
  3020. 1:45:29sometimes of course we don't want to
  3021. 1:45:30insert value for each column. You can
  3022. 1:45:32skip few columns of course but if you
  3023. 1:45:34want to insert a value for each column
  3024. 1:45:37either you go and specify them as a list
  3025. 1:45:39or you can skip it. Now for the insert
  3026. 1:45:41statements there is very important rule.
  3027. 1:45:43The number of columns and values must
  3028. 1:45:46match. So if you specify here three
  3029. 1:45:48columns then you must insert as well
  3030. 1:45:50exactly three values. So this must be
  3031. 1:45:53matching. And one last thing about the
  3032. 1:45:55syntax you can insert multiple values in
  3033. 1:45:57one go. So for each row you can specify
  3034. 1:46:00a list of values that must be inserted.
  3035. 1:46:02So that's all about the syntax. Let's go
  3036. 1:46:04back to SQL in order to practice insert
  3037. 1:46:07command. Okay. So now let's go and
  3038. 1:46:08insert a new customers. So it's very
  3039. 1:46:10simple. It start with insert into. So we
  3040. 1:46:13are saying we want to insert data into.
  3041. 1:46:15So we have to go and specify the table
  3042. 1:46:17name customers. Now after that we have
  3043. 1:46:19to specify list of columns where we want
  3044. 1:46:22to insert data into it. And what we can
  3045. 1:46:24do we can go and check which columns do
  3046. 1:46:25we have inside our table. So we can see
  3047. 1:46:27we have ID, first name, country, score.
  3048. 1:46:29And we can go and make a list of that.
  3049. 1:46:31So we can say ID, first name, country
  3050. 1:46:35and score. So we just have a list of all
  3051. 1:46:38columns inside our table customers. Now
  3052. 1:46:41what we need? We need the values. So
  3053. 1:46:43which data should be inserted. So we can
  3054. 1:46:45go and open two parenthesis. And now we
  3055. 1:46:47have to specify an ID. We know the last
  3056. 1:46:49customer was five. So we're going to go
  3057. 1:46:51with the customer six. Now we have to
  3058. 1:46:53give the name of the customer. Let's go
  3059. 1:46:55for Anna. And then a country. Let's go
  3060. 1:46:57for USA. And this customer has no
  3061. 1:47:00scores. So what we can do? We can say
  3062. 1:47:02null. So we don't know the score of this
  3063. 1:47:05customer. nulls means nothing we don't
  3064. 1:47:07know. So with that you can go and insert
  3065. 1:47:09one row. But now let's say that I would
  3066. 1:47:11like to go and insert like a second row
  3067. 1:47:13one more customer. What we can do we can
  3068. 1:47:15separate this with a comma and then we
  3069. 1:47:18can go and repeat the whole thing again.
  3070. 1:47:20So the ID is seven. The next one let's
  3071. 1:47:22call this customer Sam and we don't know
  3072. 1:47:25the country of this customer. So we're
  3073. 1:47:27going to say it's null. But the score we
  3074. 1:47:28know it already. It is 100. So as you
  3075. 1:47:30can see we are adding a value for each
  3076. 1:47:32of those columns. And if you don't know
  3077. 1:47:34the answer then make it null. if the
  3078. 1:47:36database allows it to be null. Some
  3079. 1:47:38columns they are not allowed to be null
  3080. 1:47:40like the primary key. So if you go and
  3081. 1:47:41say over here null the database will not
  3082. 1:47:43allow it. Well actually we can go and
  3083. 1:47:45test it. Let's execute. And you can see
  3084. 1:47:47you cannot insert the value null into
  3085. 1:47:50the column ID. So this is not allowed.
  3086. 1:47:52Going to have a seven. But for the other
  3087. 1:47:53columns it is allowed. You can go and
  3088. 1:47:55check the definition of the table. Now
  3089. 1:47:57we go and execute. Now the output of the
  3090. 1:48:00modifications command is going to always
  3091. 1:48:02indicate what happens to the data. So it
  3092. 1:48:04says two rows affected. Affected might
  3093. 1:48:07be inserted, updated, deleted. So you're
  3094. 1:48:09going to get a general statement from
  3095. 1:48:11the database. But you are getting how
  3096. 1:48:13many record is affected. So we got two
  3097. 1:48:15because we have inserted two records. So
  3098. 1:48:17now as you can see it's not like the
  3099. 1:48:18query. We are not getting any data in
  3100. 1:48:21the output. We are just getting a
  3101. 1:48:22message. So this is a big difference
  3102. 1:48:24between querying the data using the
  3103. 1:48:26selects and modifying the data using
  3104. 1:48:28inserts. We are doing now direct
  3105. 1:48:30modifications to the data inside our
  3106. 1:48:32database. Of course, if you want to see
  3107. 1:48:34the data in the customers, what we can
  3108. 1:48:36do, we can go and query the data, right?
  3109. 1:48:39So, let's go and do that. Select star
  3110. 1:48:40from customers. I would like to see the
  3111. 1:48:42whole table. So, market and execute it.
  3112. 1:48:45Now, you can see we have seven
  3113. 1:48:47customers. So, we just manipulated our
  3114. 1:48:49data. We have here Anna and Sam. This is
  3115. 1:48:51how you can insert data to the database.
  3116. 1:48:53Now, there's like few rules you have to
  3117. 1:48:55be careful as you are inserting new data
  3118. 1:48:57to your tables. You have to pay
  3119. 1:48:58attention that the order of the columns
  3120. 1:49:00that you have defined. insert is
  3121. 1:49:03matching the values that you are
  3122. 1:49:04inserting over here. Let's have an
  3123. 1:49:06example. I'm going to go and remove this
  3124. 1:49:08over here and let's say that we are
  3125. 1:49:10inserting a new one number eight and now
  3126. 1:49:12in the first name instead of the name of
  3127. 1:49:14the customers we have inserted the
  3128. 1:49:16country like USA and in the country we
  3129. 1:49:19have inserted the name is just mistake
  3130. 1:49:21and we are all human right? So let's
  3131. 1:49:23have a name like this max. Now if you go
  3132. 1:49:24and execute it the database can accept
  3133. 1:49:27it because it is really hard for the
  3134. 1:49:28database to understand that you have
  3135. 1:49:30made here an error. Both of them are var
  3136. 1:49:32and the database doesn't care about the
  3137. 1:49:34content of the data as long as you are
  3138. 1:49:36following the rules of the data type. So
  3139. 1:49:37now if you go and select the data from
  3140. 1:49:39the customers you can see now we have a
  3141. 1:49:41customer called USA from the country
  3142. 1:49:44max. So the SQL going to do it blindly
  3143. 1:49:46like you insert the data as long as you
  3144. 1:49:48are following the data type rules and
  3145. 1:49:50the constraints. So for example, if you
  3146. 1:49:52made this error over here and you say
  3147. 1:49:54the id is max and let's say the first
  3148. 1:49:57name is let's say nine and you execute
  3149. 1:50:00it here the database is smart enough to
  3150. 1:50:02say you know what there is something
  3151. 1:50:04wrong the ID should not be strange so
  3152. 1:50:06the database going to reject your
  3153. 1:50:07inserts be careful of the order of your
  3154. 1:50:09columns now let's go and query again our
  3155. 1:50:11table now if you are in the insert
  3156. 1:50:13commands defining all the columns
  3157. 1:50:15exactly like the table so as you can see
  3158. 1:50:17we have here complete match ID first
  3159. 1:50:19name country score we have all the
  3160. 1:50:21columns and as well the correct order
  3161. 1:50:22there is like lazy way you can go and
  3162. 1:50:24remove the whole thing over here and
  3163. 1:50:26with that the database can understand
  3164. 1:50:28okay we are inserting values to all of
  3165. 1:50:30the columns so going to understand you
  3166. 1:50:32are inserting something to each columns
  3167. 1:50:34in the correct direction so let's go and
  3168. 1:50:36do that correctly nine and here let's
  3169. 1:50:39say we
  3170. 1:50:41have from Germany so if you go and
  3171. 1:50:44execute it it will be working even
  3172. 1:50:46though we didn't define the columns and
  3173. 1:50:48that's because the values that we are
  3174. 1:50:50inserting as exactly the same number of
  3175. 1:50:52columns of the table and following as
  3176. 1:50:54well the rules. Now moving on to the
  3177. 1:50:56next one, you can go and add only two
  3178. 1:50:58columns in the definition. If you know
  3179. 1:51:00already always the country and the score
  3180. 1:51:02is null. We know only two informations,
  3181. 1:51:05the ID and the name. Then you don't have
  3182. 1:51:07always to go and say null null null and
  3183. 1:51:08so on. We can go and skip that. Okay. So
  3184. 1:51:11now let me show you what I mean. We're
  3185. 1:51:12going to go after the table name and
  3186. 1:51:14we're going to define only two columns,
  3187. 1:51:15the ID and the first name. So that means
  3188. 1:51:18we are telling SQL we want to insert
  3189. 1:51:20only two columns. And now you have to be
  3190. 1:51:22careful. If you define here two columns
  3191. 1:51:24then the values should be as well two
  3192. 1:51:26columns. So we're going to remove the
  3193. 1:51:28country and the score. And we can go and
  3194. 1:51:30add only two informations. So 10. And we
  3195. 1:51:33can go and add here for example Sara. So
  3196. 1:51:35if you go and execute it, it will be
  3197. 1:51:37working. And now what is skill is doing
  3198. 1:51:39with the other two columns. It's going
  3199. 1:51:40to be nulls. So let's go and select
  3200. 1:51:42again from our table. You can see here
  3201. 1:51:44Sara has null in the country and as well
  3202. 1:51:47in the score because we didn't define
  3203. 1:51:48those informations. But be careful, you
  3204. 1:51:50cannot here skip a column that is not
  3205. 1:51:52allowed to be null. So you have always
  3206. 1:51:54have in your list all the columns that
  3207. 1:51:57are not null. So for example, I cannot
  3208. 1:51:58go and insert only the first name. I
  3209. 1:52:00will get an error because the database
  3210. 1:52:02can try to insert a null in the ID and
  3211. 1:52:04this is not allowed. So you can skip
  3212. 1:52:06only nullable
  3213. 1:52:11columns. All right, my friends. So that
  3214. 1:52:13was the first method on how to insert
  3215. 1:52:15data to your target table as you saw by
  3216. 1:52:18typing manually the values inside an
  3217. 1:52:20insert command using values. And now
  3218. 1:52:23let's move to another methods. We're
  3219. 1:52:25going to insert data but this time not
  3220. 1:52:27manually. We're going to insert data
  3221. 1:52:29using another table. So imagine we have
  3222. 1:52:31the following scenario. We have an
  3223. 1:52:32already existing table with data and
  3224. 1:52:35this going to be the source table, the
  3225. 1:52:36source of your data and we have another
  3226. 1:52:38table. This table is empty and we want
  3227. 1:52:41to insert a new data to this target
  3228. 1:52:43table. Now what we can do, we can take
  3229. 1:52:45the data from the source table and
  3230. 1:52:47insert it into the target table without
  3231. 1:52:49manually writing the script for the
  3232. 1:52:52values. So we are moving the data from
  3233. 1:52:54one table to another. Now in order to do
  3234. 1:52:56that we need to do two steps. The first
  3235. 1:52:58step we have to write an SQL query using
  3236. 1:53:01select from and so on in order to select
  3237. 1:53:04the data that we need from the source
  3238. 1:53:06table. And once you do that you will get
  3239. 1:53:09a results. So this is like you are doing
  3240. 1:53:11a normal query. You right select and you
  3241. 1:53:13will get an answer with the results. And
  3242. 1:53:15now what we can do in the next step we
  3243. 1:53:17can take this results and use an insert
  3244. 1:53:20command in order to insert this results
  3245. 1:53:23into the target table. And with that we
  3246. 1:53:26have moved the data from the source
  3247. 1:53:27table to the target table. So first
  3248. 1:53:29write the query on the source table. And
  3249. 1:53:32the second step use an insert to move
  3250. 1:53:34this results to the target table. So
  3251. 1:53:36let's go back to the scale in order to
  3252. 1:53:37do that. So now we have the following
  3253. 1:53:39task and it says insert data from the
  3254. 1:53:41table customers into the table persons.
  3255. 1:53:43So that means the source table is the
  3256. 1:53:46customers and the target table is
  3257. 1:53:48persons. Now how I usually do it that I
  3258. 1:53:51keep my eye on the target table to
  3259. 1:53:53understand the structure of this table
  3260. 1:53:55and I start writing the query from the
  3261. 1:53:58source table. If you go to the left
  3262. 1:54:00side, we can see okay, we have here an
  3263. 1:54:01ID. We have here person name, birth date
  3264. 1:54:04and phone. And you can see only the
  3265. 1:54:05birth date except nulls and the rest we
  3266. 1:54:08have always to provide informations. So
  3267. 1:54:10with that I have now understanding about
  3268. 1:54:12the table persons. Now next I'm going to
  3269. 1:54:14go and start writing the query from the
  3270. 1:54:16source. So we start like this. Select
  3271. 1:54:18star from our table customers just to
  3272. 1:54:21have an overview of our table. Now the
  3273. 1:54:23next step we're going to go and design a
  3274. 1:54:25perfect result from this query that is
  3275. 1:54:28matching the target table. So in the
  3276. 1:54:30output we need ID and we have it from
  3277. 1:54:32the customer from the original table.
  3278. 1:54:34We're going to go and select ID. Okay.
  3279. 1:54:36So now next we need a person name and
  3280. 1:54:39here we have from the original table
  3281. 1:54:40something called first name. So this is
  3282. 1:54:42a perfect match. So we're going to go
  3283. 1:54:44and select this table as a second
  3284. 1:54:46column. So we have covered the first
  3285. 1:54:48two. Then the third one is going to be
  3286. 1:54:49the birth date. Well, my friends, we
  3287. 1:54:51don't have birth dates, but the database
  3288. 1:54:53can accept it as a null. So, I'm going
  3289. 1:54:55to go and write a null because I don't
  3290. 1:54:57have such information from the source
  3291. 1:54:59table. And now the next one going to be
  3292. 1:55:00the phone as well. We don't have phone
  3293. 1:55:02informations. But we cannot have it as a
  3294. 1:55:04null because it says here not null. So,
  3295. 1:55:06what we're going to do, we're going to
  3296. 1:55:07go and add a static value, a default
  3297. 1:55:10value. So, we're going to have two
  3298. 1:55:12single quotes and in between we're going
  3299. 1:55:13to say unknown. Since it is var, it can
  3300. 1:55:16accept this word. So, now let's go and
  3301. 1:55:19just query. So we have the ID, we have
  3302. 1:55:21the first name, the birth date is empty,
  3303. 1:55:24and the phones is unknown. Now you might
  3304. 1:55:26say, but the column name is not matching
  3305. 1:55:29with the column name of the persons.
  3306. 1:55:31Well, the database does not care about
  3307. 1:55:32that. As long as the result of the data
  3308. 1:55:35is matching the table, it can go and
  3309. 1:55:37insert it. So the database will never
  3310. 1:55:40compare the column names together. But
  3311. 1:55:41if you like and go and add here like the
  3312. 1:55:43aliases exactly like the target table it
  3313. 1:55:46will not hurt but it has no effect on
  3314. 1:55:49the results. All right. Okay. So now we
  3315. 1:55:50have like query select and we have a
  3316. 1:55:52results but this is not an insert. So
  3317. 1:55:55how we going to insert the result of
  3318. 1:55:57this into the table persons. Well for
  3319. 1:55:59that we need the insert into command. So
  3320. 1:56:03insert into and now we have to specify
  3321. 1:56:05the target table going to be the
  3322. 1:56:07persons. And of course you can go and
  3323. 1:56:09list all the column names but if you
  3324. 1:56:11have like exact match you can skip it
  3325. 1:56:13but for me I would like always to add it
  3326. 1:56:15just to make sure that we don't have any
  3327. 1:56:18issue. So the ID, person name, birth
  3328. 1:56:20date and the
  3329. 1:56:22phone. So that's it. Let's go and
  3330. 1:56:26execute. So it is working now. We can
  3331. 1:56:28see 10 rows affected. Well that means 10
  3332. 1:56:31rows are inserted from the table
  3333. 1:56:33customers into the target persons. And
  3334. 1:56:36now what we can do we can go and query
  3335. 1:56:38the table persons just to check that
  3336. 1:56:40everything is working perfectly. Select
  3337. 1:56:42star from persons and let's go and
  3338. 1:56:45execute. And with that you can see our
  3339. 1:56:4710 persons that we have added from the
  3340. 1:56:49customers. So with that we have moved
  3341. 1:56:51the data from one table and inserted
  3342. 1:56:54into another table. And as you can see
  3343. 1:56:55it was very simple. First you have to
  3344. 1:56:57write a query from the source table in
  3345. 1:57:00order to collect the data that you need.
  3346. 1:57:02and then you go and insert it into the
  3347. 1:57:05target table. So this is really nice and
  3348. 1:57:07easy and this is another way on how to
  3349. 1:57:09insert data into your
  3350. 1:57:14database. Okay, so with that we have
  3351. 1:57:16learned how to insert data to our
  3352. 1:57:18tables. Now let's say that I don't have
  3353. 1:57:20something new. I don't have any rows to
  3354. 1:57:22be added to my table but I have an
  3355. 1:57:24update. I would like to go and change
  3356. 1:57:26the content of the already existing
  3357. 1:57:29rows. So what you can do? We can use the
  3358. 1:57:31command updates in order to change the
  3359. 1:57:34content of already existing rows. So
  3360. 1:57:37again my friends insert going to go and
  3361. 1:57:39insert completely new rows but update
  3362. 1:57:42going to go and change the data of
  3363. 1:57:44already existing row. Now let's have a
  3364. 1:57:46look quickly to the syntax of the
  3365. 1:57:48updates. It start with the keyword
  3366. 1:57:49updates and then we have to specify the
  3367. 1:57:51table name and after that we're going to
  3368. 1:57:53use sit in order to specify what are the
  3369. 1:57:56new values for the columns. So you have
  3370. 1:57:58to write down for each column that you
  3371. 1:57:59want to update a new value and you
  3372. 1:58:01separate the columns of course using a
  3373. 1:58:03comma. Now after that we have to specify
  3374. 1:58:05as well a wear condition. So it's like
  3375. 1:58:07the queries you say where and then you
  3376. 1:58:09write a condition and if you don't do
  3377. 1:58:11that and you don't use the wear clause
  3378. 1:58:14what going to happen you will be end up
  3379. 1:58:16updating all the rows inside your table.
  3380. 1:58:19So that's why we need always the wear
  3381. 1:58:20clause. All right. So that's all about
  3382. 1:58:22the syntax. Let's go back to SQL in
  3383. 1:58:24order to update our data. Okay. So let's
  3384. 1:58:26have the following task and it says
  3385. 1:58:28change the score of customer 6 to zero.
  3386. 1:58:30So that means we have to go and modify
  3387. 1:58:32the data of the customer ID equal to
  3388. 1:58:34six. So now first I would like to go and
  3389. 1:58:36have a look to our data. So select star
  3390. 1:58:38from customers and now the task is
  3391. 1:58:41targeting this customer over here and we
  3392. 1:58:43would like to replace the null to zero.
  3393. 1:58:46Now how we can go and update this
  3394. 1:58:48information inside the table? We can use
  3395. 1:58:50the update command. So what we going to
  3396. 1:58:52do? We're going to start writing update
  3397. 1:58:54and after that we have to specify the
  3398. 1:58:56table name. So what we are updating? We
  3399. 1:58:58are updating the customers and then
  3400. 1:59:00we're going to tell the database to set
  3401. 1:59:02the value of the score to a zero. So we
  3402. 1:59:05would like to update and change the
  3403. 1:59:06value from null to a zero. And now here
  3404. 1:59:09comes something very risky. Don't
  3405. 1:59:10execute this query yet. If you do that,
  3406. 1:59:12what's going to happen? The database
  3407. 1:59:14going to go to the table customers and
  3408. 1:59:16replace all those values of all
  3409. 1:59:18customers to zero. So it's going to go
  3410. 1:59:20and update the whole table and this is
  3411. 1:59:22of course very risky. That's why in the
  3412. 1:59:24update command we have to give a wear
  3413. 1:59:26condition a filter in order to target
  3414. 1:59:29only specific row or the rows that you
  3415. 1:59:31want really to modify. In this case we
  3416. 1:59:33want to change only one row. So what we
  3417. 1:59:36have to do is to go and specify the work
  3418. 1:59:38condition like we have done in the
  3419. 1:59:40select query. Nothing new, right? So
  3420. 1:59:42we're going to say where the customer ID
  3421. 1:59:45is equal to six. And with that SQL will
  3422. 1:59:47not go and update everything. First it's
  3423. 1:59:49going to filter the data and then
  3424. 1:59:51updates. And now before I execute just
  3425. 1:59:53to make sure I go and check which data
  3426. 1:59:55going to be affected. So it's very
  3427. 1:59:56simple you go and select star from table
  3428. 1:59:59customers and then I go and take the
  3429. 2:00:01exact where and put it in my query and
  3430. 2:00:04then I select the whole thing and
  3431. 2:00:06execute. And now if this query gives me
  3432. 2:00:08the data that should be modified then
  3433. 2:00:11I'm doing the update command correctly.
  3434. 2:00:13And in this case we are targeting only
  3435. 2:00:15one customer. This is the customer
  3436. 2:00:17number six. And with that I feel really
  3437. 2:00:19confident with my update. So what we can
  3438. 2:00:21do since I'm going to use this later I'm
  3439. 2:00:23going to put the whole thing in a
  3440. 2:00:24comment and if I execute now only the
  3441. 2:00:26update going to be executed. So let's go
  3442. 2:00:29and do that. Now very important to check
  3443. 2:00:31the message you can see one row is
  3444. 2:00:33affected which is really good because if
  3445. 2:00:35I see here 10 rows is affected that
  3446. 2:00:38means everything is updated. Now let's
  3447. 2:00:40go and check the data. I'm going to go
  3448. 2:00:43and remove the wear here and check the
  3449. 2:00:44whole table. Now you can see we still
  3450. 2:00:46have the old scores only Anna has now
  3451. 2:00:49score zero instead of null. So this is
  3452. 2:00:51how I usually update the data. You have
  3453. 2:00:53to do it very carefully. Now let's move
  3454. 2:00:55to another task. It's going to say
  3455. 2:00:57change the score of the customer number
  3456. 2:00:5910 to zero and update the country to UK.
  3457. 2:01:03So now this time we are targeting the
  3458. 2:01:04user number 10. As you can see she
  3459. 2:01:06doesn't have the country and score. And
  3460. 2:01:08the task wants us to change the score to
  3461. 2:01:11a zero and the country to UK. So now how
  3462. 2:01:13we going to do it? We're going to use
  3463. 2:01:14the exact same command but with
  3464. 2:01:16different condition. So the ID this
  3465. 2:01:18times is equal to 10 and the score is to
  3466. 2:01:21zero. But now we have to change as well
  3467. 2:01:23the country. Now if you want to do
  3468. 2:01:25multiple updates, you're going to have
  3469. 2:01:27here a comma after the score and the new
  3470. 2:01:29line and let's say country equal and
  3471. 2:01:32then we're going to add UK. So select
  3472. 2:01:34the whole thing and let's go and
  3473. 2:01:36execute. So again it is affecting only
  3474. 2:01:39one row. This is really good. And if you
  3475. 2:01:41go and check the table search for Sara,
  3476. 2:01:43you can see in one update we have
  3477. 2:01:45updated two columns the country and as
  3478. 2:01:48well the score. So with that we have
  3479. 2:01:50solved the task. It's very simple. Now
  3480. 2:01:51moving on to the second task. It says
  3481. 2:01:53update all customers with a null score
  3482. 2:01:56by setting their score to a zero. So
  3483. 2:01:59this time we are not speaking about one
  3484. 2:02:01specific customer. We are talking about
  3485. 2:02:03updating the data for a subset of
  3486. 2:02:05customers. So now imagine you have like
  3487. 2:02:07hundreds of customers and you are making
  3488. 2:02:09one update command for each customer.
  3489. 2:02:11It's going to be really wasting of time.
  3490. 2:02:12Now instead of that we can specify a
  3491. 2:02:15condition that targets multiple
  3492. 2:02:17customers and we're going to do the
  3493. 2:02:19update for those customers in one go. So
  3494. 2:02:21now let's see how we're going to do it.
  3495. 2:02:22We are talking only about replacing the
  3496. 2:02:24nulls with a zero. So we don't need the
  3497. 2:02:27country. So set score equal to zero. But
  3498. 2:02:30now we will not be specific for the ids.
  3499. 2:02:32Now we have to make a new condition.
  3500. 2:02:34It's going to say like this where score
  3501. 2:02:36is null. Now of course in the course we
  3502. 2:02:38have a full dedicated chapter about the
  3503. 2:02:40nulls and here all what we are doing is
  3504. 2:02:42we are searching for scores that is
  3505. 2:02:44equal to null. But we cannot write an
  3506. 2:02:46equal we have to write it like this is
  3507. 2:02:48null. Of course before we update
  3508. 2:02:50anything we have to go and test it in a
  3509. 2:02:52query. So select star from customers
  3510. 2:02:55where score is null. Let's go and
  3511. 2:02:56execute. Now as you can see we have two
  3512. 2:02:59customers where the score is null. So
  3513. 2:03:01that means this condition is targeting a
  3514. 2:03:04subset of customers and we're going to
  3515. 2:03:06do now the updates for multiple rows for
  3516. 2:03:08this subset. So that means we can run
  3517. 2:03:11this query. Let's go and execute it. Now
  3518. 2:03:13you can see two rows are affected. So
  3519. 2:03:16that means multiple rows got affected
  3520. 2:03:19got updated. So now if you go and query
  3521. 2:03:21our table customers you can see we don't
  3522. 2:03:24have any nulls inside the scores and we
  3523. 2:03:26have replaced all the nulls with a zero.
  3524. 2:03:28And of course you can do the same thing.
  3525. 2:03:30you can go and make an update command in
  3526. 2:03:33order to replace all the nulls in the
  3527. 2:03:35country to maybe something unknown or
  3528. 2:03:37any default value that you want. So this
  3529. 2:03:39is how you can update multiple rows in
  3530. 2:03:41one
  3531. 2:03:45go. All right my friends. So with that
  3532. 2:03:47we have learned how to insert new rows
  3533. 2:03:50to our tables and as well how to update
  3534. 2:03:52the content of already existing row. Now
  3535. 2:03:54the last thing or command that we can do
  3536. 2:03:57to the data inside the table that we can
  3537. 2:03:59go and remove rows from our table and we
  3538. 2:04:02can do that using the command delete. So
  3539. 2:04:04if you use delete SQL going to go and
  3540. 2:04:07start removing already existing rows
  3541. 2:04:09inside your table. All right. Now for
  3542. 2:04:11the syntax of the delete it's going to
  3543. 2:04:13be very simple. We're going to say
  3544. 2:04:14delete from and then we're going to
  3545. 2:04:16write the table name. And here comes
  3546. 2:04:18something very important. We have to add
  3547. 2:04:20a wear condition. And it's like the
  3548. 2:04:22update. If you don't do that, if you
  3549. 2:04:23don't include where condition, what
  3550. 2:04:25going to happen? You will end up
  3551. 2:04:27deleting all the rows inside the table.
  3552. 2:04:29So the syntax is very simple. Let's go
  3553. 2:04:31back to scale in order to delete some
  3554. 2:04:33data. Okay. So now we have the following
  3555. 2:04:35task. Delete all customers with an ID
  3556. 2:04:38greater than five. So now we have to go
  3557. 2:04:40and delete all the customers that we
  3558. 2:04:41recently added. So how we going to do
  3559. 2:04:43it? It's very simple. We're going to say
  3560. 2:04:44delete from. So that means I want to
  3561. 2:04:47delete something from a table. And we
  3562. 2:04:49have to specify the table name. It's
  3563. 2:04:51going to be the customers. So the syntax
  3564. 2:04:52is very simple. Now my friends, this is
  3565. 2:04:54more risky than updates because if you
  3566. 2:04:57execute it like this, don't do that yet.
  3567. 2:04:59Wait, what's going to happen? All the
  3568. 2:05:01data of the customers going to be
  3569. 2:05:02deleted. So you will get an empty table
  3570. 2:05:05and we will not do that. So now we're
  3571. 2:05:07going to do exactly like the update
  3572. 2:05:08command. We're going to specify the work
  3573. 2:05:10clause. So it says the ID should be
  3574. 2:05:12greater than five. So that means ID
  3575. 2:05:15higher than five. So with that we are
  3576. 2:05:17defining a subset of the data that
  3577. 2:05:19should be deleted, not everything. And
  3578. 2:05:21if we check in the updates, we have here
  3579. 2:05:22to do a double check before deleting
  3580. 2:05:24anything. So again what we do, we select
  3581. 2:05:27star from table customers and we're
  3582. 2:05:30going to go and copy the work condition
  3583. 2:05:32in order to test what going to be
  3584. 2:05:34deleted. So it's going to be all the
  3585. 2:05:35customers that is higher than five. And
  3586. 2:05:37with that I'm making sure that my delete
  3587. 2:05:40command is correct which is from what I
  3588. 2:05:41see here is correct. So those five
  3589. 2:05:44customers should be deleted. So now
  3590. 2:05:45let's go and delete those customers. And
  3591. 2:05:48now very important to read the message.
  3592. 2:05:50It says five rows affected. So that
  3593. 2:05:52means five customers got deleted. And
  3594. 2:05:54this is better than 10 of course. So
  3595. 2:05:56let's go and check what customers left.
  3596. 2:05:59So we have 1 2 3 4 5. Those are the
  3597. 2:06:01original customers. And everything else
  3598. 2:06:03got deleted. And with that we have
  3599. 2:06:05solved the task. And this is how we can
  3600. 2:06:06delete data from tables. Be very
  3601. 2:06:09careful. Always test before doing the
  3602. 2:06:11delete command. Okay. So now we have the
  3603. 2:06:13following task. And it says delete all
  3604. 2:06:15data from table persons. So that means
  3605. 2:06:18we have to go and drop everything from
  3606. 2:06:20the table persons. But we don't want to
  3607. 2:06:22delete the table. We just want to delete
  3608. 2:06:24the data inside the table now. So now
  3609. 2:06:26what we're going to do, we're going to
  3610. 2:06:27write delete from. And now we have to
  3611. 2:06:29specify the table persons. And if you
  3612. 2:06:31execute it, what's going to happen? SQL
  3613. 2:06:33going to go and drop all the data in the
  3614. 2:06:35persons. But in SQL, we have more
  3615. 2:06:37interesting command. If you want to
  3616. 2:06:39delete everything from the table
  3617. 2:06:40persons, we have that truncate.
  3618. 2:06:42Truncate. It is exactly like delete from
  3619. 2:06:44persons. It's going to go and make the
  3620. 2:06:46whole table empty. But why I like to use
  3621. 2:06:48truncate because it is way faster than
  3622. 2:06:51deletes. If you have large tables, the
  3623. 2:06:52delete command going to be really slow
  3624. 2:06:54because with the delete there is like a
  3625. 2:06:56lot of things happening behind the
  3626. 2:06:57scenes. There is like logs and
  3627. 2:06:59protocols. But if you are using trunk,
  3628. 2:07:01the database going to skip all those
  3629. 2:07:03extra stuff and it's going to be very
  3630. 2:07:05fast. So if you want to delete all the
  3631. 2:07:07data from table, you can do it like this
  3632. 2:07:09if it's like small table. But what I
  3633. 2:07:10usually do, I go and write truncate and
  3634. 2:07:14then table. we're going to get the same
  3635. 2:07:16effect and with that I'm saying reset
  3636. 2:07:18everything make the table empty. So
  3637. 2:07:20let's go and execute it and now with
  3638. 2:07:21that you will not get the number of
  3639. 2:07:23deleted rows and that's why it's
  3640. 2:07:25truncate it's way faster. It is not
  3641. 2:07:27protocoling anything it's not logging
  3642. 2:07:29anything it just go and delete all the
  3643. 2:07:31data without any extra steps. So this is
  3644. 2:07:34how we can delete all the data from a
  3645. 2:07:36table but the table still exists. Okay
  3646. 2:07:38my friends, so with that you have
  3647. 2:07:39learned the basics on how to manipulate
  3648. 2:07:41your data inside the database the data
  3649. 2:07:43manipulation language DML and with that
  3650. 2:07:45I can tell you we have covered the
  3651. 2:07:47basics of SQL. So with that we have
  3652. 2:07:50covered the beginner level. Now in the
  3653. 2:07:52next chapters we will be in the
  3654. 2:07:53intermediate level and the first thing
  3655. 2:07:55that you're going to learn in the
  3656. 2:07:56intermediate level you will learn how to
  3657. 2:07:58filter your data and we're going to
  3658. 2:07:59cover many operators that you can use
  3659. 2:08:01inside the workclass. So let's go.
  3660. 2:08:08All right. So now let's have an overview
  3661. 2:08:09about all different operators in SQL. So
  3662. 2:08:12the first group of operators we have the
  3663. 2:08:13comparison operators. They are the
  3664. 2:08:15easiest one where all what we have to do
  3665. 2:08:17is to compare two values and we have
  3666. 2:08:19like six different variants and how to
  3667. 2:08:20do that. Now to the next one we have the
  3668. 2:08:23logical operators. We use it in order to
  3669. 2:08:25combine multiple operators. And moving
  3670. 2:08:27on to the next one we have the range
  3671. 2:08:29operator. Here we have only one, the
  3672. 2:08:31between. We're going to use it in order
  3673. 2:08:32to check whether a value falls within a
  3674. 2:08:35specific range. Now moving on to the
  3675. 2:08:37next one, we have the membership
  3676. 2:08:38operator. And here we have two things.
  3677. 2:08:40We have the in operator or not in. Here
  3678. 2:08:42all what you have to do is to check
  3679. 2:08:44whether a value is in a list or not. And
  3680. 2:08:46the last category that we have is the
  3681. 2:08:48search operator. And here as well we
  3682. 2:08:50have only one operator that like we use
  3683. 2:08:52it in order to search for a specific
  3684. 2:08:54thing in a text. So my friends, we're
  3685. 2:08:56going to go through all those operators
  3686. 2:08:58one by one. Okay. So now let's go and
  3687. 2:09:00deep dive into the first category the
  3688. 2:09:02comparison operators and we're going to
  3689. 2:09:04cover all those stuff. So what is
  3690. 2:09:05exactly comparison
  3691. 2:09:10operator? Okay. So what is exactly
  3692. 2:09:12comparison operators? It is very simple.
  3693. 2:09:14We want to compare two things and there
  3694. 2:09:16is a lot of things that we can compare
  3695. 2:09:18in SQL. But the formula for that going
  3696. 2:09:20to be always like this. So we have the
  3697. 2:09:22first expression and then operator and
  3698. 2:09:24then we have another expression and this
  3699. 2:09:27going to form something called
  3700. 2:09:28condition. So here we have a lot of
  3701. 2:09:30variance. We can compare one column to
  3702. 2:09:32another column. So for example, you can
  3703. 2:09:34go and compare the first name with the
  3704. 2:09:36last name. So both of the expressions
  3705. 2:09:38are columns here. Another scenario, you
  3706. 2:09:41want to compare a column with a value, a
  3707. 2:09:43static value. Like for example, you say
  3708. 2:09:46the first name must be equal to a value
  3709. 2:09:49like John. So now we are comparing a
  3710. 2:09:51column with a value. It's not anymore
  3711. 2:09:53two columns. Now we have another
  3712. 2:09:55scenario where we want to apply a
  3713. 2:09:57function to a column and then compare
  3714. 2:09:59the results to maybe a value. So for
  3715. 2:10:01example, we apply the upper function to
  3716. 2:10:03the first name and then this must be
  3717. 2:10:06equal to a value like John with all the
  3718. 2:10:08letters in the uppercase. And one more
  3719. 2:10:10thing that you can compare you can write
  3720. 2:10:12an expression in one of the sides like
  3721. 2:10:15for example you can say if we multiply
  3722. 2:10:17price with the quantity it must be equal
  3723. 2:10:20to 1,000 for example. So here we have an
  3724. 2:10:23expression. We have multiple columns
  3725. 2:10:25included in one sides and the output of
  3726. 2:10:27this expression must be equal to 1,000.
  3727. 2:10:29And now the last one is going to be a
  3728. 2:10:31little bit more advanced and we're going
  3729. 2:10:32to cover that of course in other
  3730. 2:10:33chapter. We can include a whole query
  3731. 2:10:36the complete query to one of the sides
  3732. 2:10:38and we call this a subquery. So in one
  3733. 2:10:40of the sides you're going to write a
  3734. 2:10:42whole query select from where whatever
  3735. 2:10:45you want and you go and compare the
  3736. 2:10:47result of this query to for example a
  3737. 2:10:49value or a column. So as you can see in
  3738. 2:10:51a scale we can compare a lot of things
  3739. 2:10:53together. Either comparing the columns
  3740. 2:10:55together or a column with a value or we
  3741. 2:10:57use a function or an expression or even
  3742. 2:11:00a whole query. So this is how we build
  3743. 2:11:02conditions in SQL. Okay my friends. So
  3744. 2:11:05let's see how the conditions works in
  3745. 2:11:06SQL. So we have our data the name the
  3746. 2:11:09country the score and let's say that we
  3747. 2:11:11have built a condition where it says the
  3748. 2:11:13country must be equal to the USA. So
  3749. 2:11:15this is very simple comparison operator
  3750. 2:11:17and this is the condition that we are
  3751. 2:11:20using inside the work clause. So once
  3752. 2:11:22you apply this filter to your data what
  3753. 2:11:24going to happen? SQL going to go row by
  3754. 2:11:26row evaluating whether it is meeting the
  3755. 2:11:28condition. If it's not fulfilling the
  3756. 2:11:30condition then SQL going to remove it
  3757. 2:11:32from the results. But if it is
  3758. 2:11:33fulfilling the condition it's going to
  3759. 2:11:35keep it. So now we are comparing the
  3760. 2:11:37values of column together with a static
  3761. 2:11:39value the USA. So we're going to compare
  3762. 2:11:41whatever value we get from the country
  3763. 2:11:43together with the USA. So now let's see
  3764. 2:11:45how is going to apply this filter to our
  3765. 2:11:47data for the first customer Maria. Now
  3766. 2:11:50you can see the value inside the country
  3767. 2:11:51is Germany. So Isql now going to go and
  3768. 2:11:54compare Germany to USA since it is not
  3769. 2:11:57equal. Then is going to understand okay
  3770. 2:11:59Maria is not fulfilling the condition.
  3771. 2:12:02So it is false and is going to go and
  3772. 2:12:04remove this customer from the results.
  3773. 2:12:06So she is not fulfilling the condition.
  3774. 2:12:08Moving on to the next one to Joan. Now S
  3775. 2:12:10is going to take the value inside the
  3776. 2:12:12country the USA it is equal to USA. So
  3777. 2:12:15that means John is fulfilling the
  3778. 2:12:17condition and Isl going to be happy
  3779. 2:12:18about it. So it is true and this means
  3780. 2:12:21is going to keep Joan in the final
  3781. 2:12:23results. Now moving on to George the
  3782. 2:12:25value is UK not equal to USA. He is not
  3783. 2:12:27fulfilling the condition. Is going to go
  3784. 2:12:29and remove him from the final result.
  3785. 2:12:31Same thing for Martin. Germany is not
  3786. 2:12:34equal to USA. Is going to remove this
  3787. 2:12:36customer as well. And to the last one
  3788. 2:12:38bit better you can see the value is USA.
  3789. 2:12:40So USA equal USA. The condition is
  3790. 2:12:42fulfilled. SQL is happy about it and
  3791. 2:12:44going to leave the customer in the
  3792. 2:12:45output. So now if you go and apply this
  3793. 2:12:47condition using the comparison operator
  3794. 2:12:50to your data only two customers going to
  3795. 2:12:52be left in the output. This is exactly
  3796. 2:12:54how the conditions and the comparison
  3797. 2:12:56operators works in SQL. Okay. So now
  3798. 2:12:58let's start with the first operator.
  3799. 2:13:00It's very simple. We have the equal.
  3800. 2:13:02It's going to checks if the two values
  3801. 2:13:04are equal. That's very simple. Let's
  3802. 2:13:06have an example. Okay. So now we have
  3803. 2:13:07this task. It says retrieve all
  3804. 2:13:09customers from Germany. So this is very
  3805. 2:13:11basic. We're going to go and select and
  3806. 2:13:12we're going to select all the columns
  3807. 2:13:14since we don't have any specifications
  3808. 2:13:15from the table customers. And if you go
  3809. 2:13:17and execute it, you will get all the
  3810. 2:13:19customers. But we don't need that only
  3811. 2:13:21the customers that comes from Germany.
  3812. 2:13:23So we have to go and apply a condition
  3813. 2:13:25using the wear clause country equal to
  3814. 2:13:28the value Germany. So make sure you are
  3815. 2:13:31writing it exactly like in the database
  3816. 2:13:33otherwise it will not work. So let's go
  3817. 2:13:35and execute and with that we are getting
  3818. 2:13:37only the customers from Germany. So it
  3819. 2:13:39is very simple and this is why we use
  3820. 2:13:41the equal operator. Okay. So now moving
  3821. 2:13:43on to the next one again very simple. If
  3822. 2:13:45you want to check if two values are not
  3823. 2:13:48equal we can use the not equal operator.
  3824. 2:13:50So let's have an example. Okay. So now
  3825. 2:13:52we let's have the opposite task. It says
  3826. 2:13:54retrieve all customers who are not from
  3827. 2:13:57Germany. So this is very simple. We are
  3828. 2:13:59saying here who are not they are not
  3829. 2:14:02equal to Germany. So we can use the not
  3830. 2:14:05equal operator in order to get these
  3831. 2:14:07customers. So with that as you can see
  3832. 2:14:09after executing we are getting all the
  3833. 2:14:12customers country is not equal to
  3834. 2:14:14Germany and there's like another way on
  3835. 2:14:16how to do the not equal doing it like
  3836. 2:14:18this we'll get the same results. All
  3837. 2:14:19right my friends moving on to the next
  3838. 2:14:21one. We can check if a value is greater
  3839. 2:14:24than another value. So we use the
  3840. 2:14:26greater operator. Let's have an example.
  3841. 2:14:28Okay. So now the next task it says
  3842. 2:14:30retrieve all customers with a score
  3843. 2:14:33greater than 500. Now we want to filter
  3844. 2:14:36the data based on the score. So we're
  3845. 2:14:38going to say where score and now the
  3846. 2:14:41task says greater than 500. We're going
  3847. 2:14:44to use the operator greater than 500.
  3848. 2:14:46It's very simple. So with that we will
  3849. 2:14:48get only the customers where the score
  3850. 2:14:51is higher than 500. So for example Maria
  3851. 2:14:54it's not fulfilling the condition. The
  3852. 2:14:56same thing for the Peter and as well for
  3853. 2:14:58Martin it must be greater than 500. So
  3854. 2:15:01if you go executed you will get only
  3855. 2:15:03those two customers because they are
  3856. 2:15:05greater than 500. Okay, moving on to the
  3857. 2:15:09next one. This time we're going to check
  3858. 2:15:10if a value is greater than or equal to
  3859. 2:15:13another value. So it is like mix between
  3860. 2:15:15the greater than and the equal. If one
  3861. 2:15:17of them is fulfilled then the value
  3862. 2:15:19going to meet the condition. So let's
  3863. 2:15:21have an example for that. Now, if the
  3864. 2:15:22task says retrieve all customers with a
  3865. 2:15:25score of 500 or more, this time we're
  3866. 2:15:28going to go and include the customers
  3867. 2:15:30where their score is equal as well to
  3868. 2:15:32500 or higher. So, we're going to have a
  3869. 2:15:34similar condition based on the score and
  3870. 2:15:36the 500's value, but this time we're
  3871. 2:15:38going to say greater or equal to 500.
  3872. 2:15:41So, if you go now and execute it, this
  3873. 2:15:44time we're going to see the customer
  3874. 2:15:45Martin with the score of 500. So, in
  3875. 2:15:48this scenario, we're going to use
  3876. 2:15:49greater or equal. All right. Right. So
  3877. 2:15:51now let's keep moving. The next one is
  3878. 2:15:53as well very simple. We're going to
  3879. 2:15:54check this time if a value is less than
  3880. 2:15:57another value. So we're going to use the
  3881. 2:15:59less operator. Let's have an example.
  3882. 2:16:01Now moving on to another simple task.
  3883. 2:16:03Retrieve all customers with a score less
  3884. 2:16:06than 500. So this time we want all the
  3885. 2:16:08customers with a lower score. And we're
  3886. 2:16:10going to use exactly the opposite. It's
  3887. 2:16:12going to be the score is less than 500.
  3888. 2:16:14And again here it is not equal, right?
  3889. 2:16:16So if you go and execute, you will get
  3890. 2:16:18all the customers with a low scores. he
  3891. 2:16:21will not get to Martin because Martin is
  3892. 2:16:23equal to 500. So with that we have
  3893. 2:16:25solved the task. We have all the
  3894. 2:16:26customers with the score less than 500.
  3895. 2:16:29Okay my friends, now moving on to the
  3896. 2:16:31last one. I think you already got it. So
  3897. 2:16:33we're going to check whether a value is
  3898. 2:16:35less than or equal to another value. So
  3899. 2:16:38you can go and combine the less operator
  3900. 2:16:40together with the equal and if one of
  3901. 2:16:42them is fulfilled then the value going
  3902. 2:16:44to meet the condition. So let's have an
  3903. 2:16:46example for that. This time we are
  3904. 2:16:48retrieving all customers with a score of
  3905. 2:16:50500 or less. So the query going to be
  3906. 2:16:52very similar but we are saying it is
  3907. 2:16:55less or equal to 500. So we are
  3908. 2:16:57including the value in our condition.
  3909. 2:17:00And with that as you can see we still
  3910. 2:17:01have our two customers where we have the
  3911. 2:17:04score less than 500 but we have now as
  3912. 2:17:06well Martin with a score of 500. Okay my
  3913. 2:17:09friends. So with that we have covered
  3914. 2:17:11the first group the comparison
  3915. 2:17:13operators. Now we're going to move on to
  3916. 2:17:14the next group. We're going to speak
  3917. 2:17:16about the logical operators and here we
  3918. 2:17:17have three and or not. So let's start
  3919. 2:17:20with the first one. What is exactly and
  3920. 2:17:26operator. Okay. So now what is the
  3921. 2:17:28definition of the and it says all
  3922. 2:17:31conditions must be true. So all the
  3923. 2:17:33conditions that you have in the wear
  3924. 2:17:34clause must be true in order to keep the
  3925. 2:17:37row in the results. So let's understand
  3926. 2:17:39what this means. things going to get
  3927. 2:17:40more complicated where you can have not
  3928. 2:17:43only one condition but you might have
  3929. 2:17:45multiple conditions in your query. So
  3930. 2:17:47here we're going to add a second
  3931. 2:17:48condition where we're going to say not
  3932. 2:17:50only the country must be equal to USA
  3933. 2:17:53but also the score must be higher than
  3934. 2:17:55500. So now you have two conditions and
  3935. 2:17:58you have to put them in the wear clause.
  3936. 2:18:00Now you have to combine those conditions
  3937. 2:18:02using the logical operator and here we
  3938. 2:18:04have two options two operators the and
  3939. 2:18:06operator and the or operator. In this
  3940. 2:18:09scenario, if you say and then SQL is
  3941. 2:18:12very restrictive. Both of the conditions
  3942. 2:18:14must be true in order to keep the row in
  3943. 2:18:17the results. So now let's see how this
  3944. 2:18:18going to work. Now for the first row and
  3945. 2:18:20for the first condition you can see the
  3946. 2:18:22country is Germany and it is not
  3947. 2:18:24fulfilling the first condition. So this
  3948. 2:18:27going to be false. And as well if you
  3949. 2:18:28check the second condition for the first
  3950. 2:18:30row you can see the score is 350. So
  3951. 2:18:32that means this customer is as well not
  3952. 2:18:34fulfilling even the second condition. So
  3953. 2:18:37both of the conditions is false and it's
  3954. 2:18:39going to go I remove this customer from
  3955. 2:18:41the results. Now to the next one John
  3956. 2:18:43you can see John is fulfilling the first
  3957. 2:18:45condition because the country is equal
  3958. 2:18:46to USA and as well fulfilling the second
  3959. 2:18:49condition. His score is 900 and this is
  3960. 2:18:52higher than 500. So now SQL going to be
  3961. 2:18:54very happy about it because both of them
  3962. 2:18:56is true and this is the only way in
  3963. 2:18:58order to keep the row in the output
  3964. 2:19:00because we are using the operator and so
  3965. 2:19:03John going to stay in the output. Now
  3966. 2:19:04moving on to George. He is not
  3967. 2:19:06fulfilling the first condition. But now
  3968. 2:19:08the second condition is fulfilled. His
  3969. 2:19:10score is 750 and this is higher than
  3970. 2:19:12500. So now it's like 50/50 right. In
  3971. 2:19:15one side it's false but the other side
  3972. 2:19:17is true. But this is not enough for the
  3973. 2:19:19ant operator. Both of them should be
  3974. 2:19:21true in order to keep the result in the
  3975. 2:19:22output. That's why SQL going to remove
  3976. 2:19:24this row. Now moving on to Martin. He is
  3977. 2:19:26not fulfilling both of the conditions.
  3978. 2:19:28So SQL going to go I remove it from the
  3979. 2:19:30results. And now for the last one. Peter
  3980. 2:19:33is fulfilling the first condition. the
  3981. 2:19:35country is equal to USA but the second
  3982. 2:19:37condition is sadly not fulfilled so we
  3983. 2:19:39have the score zero not higher than 500
  3984. 2:19:42again we have the same scenario it's
  3985. 2:19:4350/50 and this is not enough for the ant
  3986. 2:19:46operator that's why SQL going to go I
  3987. 2:19:48remove it so as you can see if you use
  3988. 2:19:50an and operator a lot of rows going to
  3989. 2:19:52be removed if one of the condition is
  3990. 2:19:55not met so the ant operator is very
  3991. 2:19:57restrictive both of the conditions must
  3992. 2:19:59be fulfilled to keep the row in the
  3993. 2:20:01results so this is exactly how the and
  3994. 2:20:04operator works. Okay. So now we have the
  3995. 2:20:05following task. Retrieve all customers
  3996. 2:20:07who are from USA and have a score
  3997. 2:20:10greater than 500. So here we are like
  3998. 2:20:12combining multiple conditions and let's
  3999. 2:20:15go and do it step by step. So the first
  4000. 2:20:16thing that we have to go and select the
  4001. 2:20:18data from the correct table. So select
  4002. 2:20:20star from customers and with that we are
  4003. 2:20:22getting all the customers from the
  4004. 2:20:24table. Now the first condition we need
  4005. 2:20:26the customers that come from USA. So we
  4006. 2:20:28need only those two customers and in
  4007. 2:20:31order to do that as we learned we can go
  4008. 2:20:32and use the wear clause and the
  4009. 2:20:34condition going to be country equal to
  4010. 2:20:37USA. So if you go and execute we will
  4011. 2:20:39get those two customers. Nothing is new.
  4012. 2:20:42We have used the compression operator
  4013. 2:20:44equal. But we are not done yet. We have
  4014. 2:20:46another condition from those two
  4015. 2:20:48customers. We need only the customers
  4016. 2:20:50where their score is higher than 500. So
  4017. 2:20:53now by looking to those two customers
  4018. 2:20:54you can see we see that the bitter here
  4019. 2:20:57does not have a score higher than 500
  4020. 2:20:59and we don't want to see that in the
  4021. 2:21:01results. So now what we have to do we
  4022. 2:21:02have to go and write a condition for
  4023. 2:21:04this one over here. So this is based
  4024. 2:21:06this time on the scores not on the
  4025. 2:21:08country. So the score should be greater
  4026. 2:21:11than 500. Now as you can see we have the
  4027. 2:21:14first condition for the first one here
  4028. 2:21:16and the second condition for the second
  4029. 2:21:18requirement. Now the question how to
  4030. 2:21:20connect those two conditions. So here we
  4031. 2:21:22have two options and or and to be honest
  4032. 2:21:25this is very simple the task says it
  4033. 2:21:27customer should fulfill both of the
  4034. 2:21:29conditions should be from USA and as
  4035. 2:21:31well at the same time greater than 500.
  4036. 2:21:34So it is very simple real and so with
  4037. 2:21:37that we have connected both of those
  4038. 2:21:39conditions and if you go and query it
  4039. 2:21:41you will get only one customer that is
  4040. 2:21:43fulfilling our conditions. So from all
  4041. 2:21:46customers we have only one customer
  4042. 2:21:48that's fulfilled this condition that
  4043. 2:21:50comes from USA and at the same time the
  4044. 2:21:52score of this customer is higher than
  4045. 2:21:55500. So this is how we use the ant
  4046. 2:21:57operator in order to connect two
  4047. 2:21:59conditions. Okay my friends. So that's
  4048. 2:22:01all for the ant operator. Let's speak
  4049. 2:22:03now about the or
  4050. 2:22:08operator. All right. Now the or operator
  4051. 2:22:11it says at least one condition must be
  4052. 2:22:13true. So it is less restrictive than the
  4053. 2:22:16and it is enough to have one condition
  4054. 2:22:18true in order to keep the row in the
  4055. 2:22:20results. Let's understand exactly what
  4056. 2:22:22this means. Okay. So now we have the
  4057. 2:22:23same scenario. We have two conditions
  4058. 2:22:25and in SQL you have to connect them
  4059. 2:22:27either using the and operator or the or
  4060. 2:22:30operator. In this scenario we're going
  4061. 2:22:32to talk about the or operator. And as we
  4062. 2:22:34said at least one of the conditions must
  4063. 2:22:36be fulfilled in order to leave the
  4064. 2:22:38record in the results. So let's see
  4065. 2:22:40what's going to happen here. Now the
  4066. 2:22:41first customer Maria she is not
  4067. 2:22:44fulfilling the first condition and as
  4068. 2:22:46well the second condition. So both of
  4069. 2:22:48them is false and this is the only
  4070. 2:22:50scenario where SQL going to remove the
  4071. 2:22:52record from the results because it is
  4072. 2:22:54not fulfilling the minimum at least one
  4073. 2:22:57of them should be true. Both of them is
  4074. 2:22:58false then SQL going to go and remove
  4075. 2:23:00this row. Now moving on to the next one
  4076. 2:23:02to John. John is from USA and has higher
  4077. 2:23:05score than 500. Both of the conditions
  4078. 2:23:08is green. So both of them is true and
  4079. 2:23:10this is more than enough to keep the row
  4080. 2:23:12in the output. That's why we will see
  4081. 2:23:14John in the outputs. Now moving on to
  4082. 2:23:16the third one, George. George is not
  4083. 2:23:18fulfilling the first condition because
  4084. 2:23:20UK is not equal to USA. But John this
  4085. 2:23:22time is fulfilling the second condition.
  4086. 2:23:25So we have here true and since we have
  4087. 2:23:27at least one true, this is good enough
  4088. 2:23:29to keep the record in the output. So you
  4089. 2:23:31will see George in the results. Now
  4090. 2:23:33moving on to Martin. He is not
  4091. 2:23:35fulfilling the first condition as well
  4092. 2:23:37not fulfilling the second condition.
  4093. 2:23:39Both of them is false and this is not
  4094. 2:23:41enough to keep the result in the output.
  4095. 2:23:43So that's why it's still going to go and
  4096. 2:23:45remove it. Now moving on to the last
  4097. 2:23:46one. Peter he is fulfilling the first
  4098. 2:23:48condition but not the second condition
  4099. 2:23:50but still everything is fine because he
  4100. 2:23:52is fulfilling at least one condition. So
  4101. 2:23:55we have the minimum and it's still going
  4102. 2:23:56to leave it in the output. So as you can
  4103. 2:23:58see the or operator is not restrictive
  4104. 2:24:00like the and operator. It's enough to
  4105. 2:24:02have one true in order to keep the data
  4106. 2:24:04in the output. And this is exactly how
  4107. 2:24:06the or operator works. Now let's see the
  4108. 2:24:08second task. Retrieve all customers who
  4109. 2:24:11are either from USA or have a score
  4110. 2:24:14greater than 500. So it is a very
  4111. 2:24:16similar task. We have two conditions. So
  4112. 2:24:18we need the customers that are either
  4113. 2:24:20from USA. So it is based on this country
  4114. 2:24:23equal to USA. And the second condition
  4115. 2:24:25is the score is greater than 500. But
  4116. 2:24:28this time we are very relaxed. either
  4117. 2:24:30this condition is fulfilled or the
  4118. 2:24:32second one. So instead of having and we
  4119. 2:24:35will be using the operator or. So it is
  4120. 2:24:37enough to fulfill one of those
  4121. 2:24:38conditions. And if you go and execute
  4122. 2:24:40now as you can see we are getting more
  4123. 2:24:42results because it is easier to fulfill
  4124. 2:24:44the conditions. So we can see those
  4125. 2:24:46three customers either fulfilling the
  4126. 2:24:48first condition or the second one. All
  4127. 2:24:51right my friends. So that's all for the
  4128. 2:24:52or operator and we're going to move to
  4129. 2:24:54the last one in this group the not. So
  4130. 2:24:56what do we mean with the not operator?
  4131. 2:25:02Okay. So now what is this operator not?
  4132. 2:25:04It is a reverse operator. It's going to
  4133. 2:25:07go and exclude the matching values. So
  4134. 2:25:10what this exactly means? Let's have a
  4135. 2:25:11very simple example. All right. So now
  4136. 2:25:13the net operator is not like the or and
  4137. 2:25:16the ands. This operator will not go and
  4138. 2:25:18combine two conditions. So you can use
  4139. 2:25:21it with only one condition. And let's
  4140. 2:25:22say that our current condition is like
  4141. 2:25:24this. The country must be equal to USA.
  4142. 2:25:26So this is like a comparison operator.
  4143. 2:25:28And if you apply it to your data, as we
  4144. 2:25:30learned, it's going to leave only two
  4145. 2:25:31customers, John and Peter, because they
  4146. 2:25:34fulfill the conditions and all other
  4147. 2:25:35customers will be removed because they
  4148. 2:25:38don't fulfill the condition. So nothing
  4149. 2:25:39crazy so far. But now if you go and
  4150. 2:25:41apply the not operator to the condition,
  4151. 2:25:44what going to happen? You're going to
  4152. 2:25:45reverse the whole truth. So you are
  4153. 2:25:47saying if this condition is fulfilled,
  4154. 2:25:50it must be removed from the final
  4155. 2:25:52results. So it is switching everything.
  4156. 2:25:54We want to see the customers that is not
  4157. 2:25:57fulfilling the condition. So now let's
  4158. 2:25:59see what can happen if you apply the not
  4159. 2:26:01operator together with the condition. We
  4160. 2:26:02can see that the first customer is not
  4161. 2:26:04fulfilling the condition which is great
  4162. 2:26:06thing. This is exactly what we want. We
  4163. 2:26:08want the customer that is not fulfilling
  4164. 2:26:10the condition. That's why going to be
  4165. 2:26:12happy about it and SQL going to make it
  4166. 2:26:14true and leave it in the output. So
  4167. 2:26:17Maria is fulfilling the whole thing. She
  4168. 2:26:19is not meeting the condition. So SQL
  4169. 2:26:22going to leave it at the output. Now for
  4170. 2:26:23the next one. So this customer is
  4171. 2:26:25fulfilling the condition and that is not
  4172. 2:26:27a good thing. So SQL going to go and
  4173. 2:26:29this time remove John from the results
  4174. 2:26:31because he is fulfilling the condition.
  4175. 2:26:33And moving on to George. So George is
  4176. 2:26:36not fulfilling the condition which is
  4177. 2:26:38amazing. So that's why SQL going to keep
  4178. 2:26:40this time George in the output. The same
  4179. 2:26:42thing for Martin. Martin is not
  4180. 2:26:44fulfilling the condition. So Isl going
  4181. 2:26:46to keep the customer and better he is
  4182. 2:26:48fulfilling the condition. So SQL going
  4183. 2:26:50to go and remove this customer from the
  4184. 2:26:52output. So as you can see we have
  4185. 2:26:54reversed everything right. The not
  4186. 2:26:56operator going to make the true false
  4187. 2:26:58and the false true. Okay. So this is how
  4188. 2:27:00it works. Now let's go back to SQL in
  4189. 2:27:02order to practice. Okay. The next task
  4190. 2:27:05it says retrieve all customers with a
  4191. 2:27:07score not less than 500. So this sounds
  4192. 2:27:11really funny. As usual we're going to go
  4193. 2:27:12and select star from customers. And now
  4194. 2:27:16we have to filter the data based on this
  4195. 2:27:18condition. So the score is not less than
  4196. 2:27:21500. Well, you can go and say well the
  4197. 2:27:23score is higher, greater or equal to
  4198. 2:27:27500, right? And with that it is not less
  4199. 2:27:30than 500. So if you go and execute it,
  4200. 2:27:32we just solve the task, right? We get
  4201. 2:27:34all the customers that are not less than
  4202. 2:27:36500. Or you can go and use the not
  4203. 2:27:38operator to make things more funnier. So
  4204. 2:27:41you go over here and say it is not and
  4205. 2:27:44then you switch it. So you make like
  4206. 2:27:46this. So the score is less than 500. But
  4207. 2:27:49as we use here not then we twisted
  4208. 2:27:51everything. So we are saying the score
  4209. 2:27:54is not less than 500. And if you execute
  4210. 2:27:56it you will get the exact same results.
  4211. 2:27:59Convert the truth. If you remove it and
  4212. 2:28:01execute you will get everything that is
  4213. 2:28:03less than 500. But if you put the nut
  4214. 2:28:06you will convert the whole logic. So if
  4215. 2:28:08you go and execute you are not getting
  4216. 2:28:10the scores that are less than 500. So
  4217. 2:28:12this is really nice. This is how you use
  4218. 2:28:14the nut operator. Okay my friends. So
  4219. 2:28:16with that we have covered everything
  4220. 2:28:17about the logical operators. Now we're
  4221. 2:28:19going to move to the third group. We're
  4222. 2:28:21going to talk about the range operator.
  4223. 2:28:23And here we have only one the between.
  4224. 2:28:25So what is exactly between
  4225. 2:28:30operator? Okay. So what is between? It's
  4226. 2:28:32going to go and check if a value falls
  4227. 2:28:35within a specific range. So you have a
  4228. 2:28:37range and you are checking whether your
  4229. 2:28:39value is in the range or outside the
  4230. 2:28:41range. So let's understand exactly what
  4231. 2:28:43this means. Okay. So now in order to
  4232. 2:28:45build a range you need two things. You
  4233. 2:28:47need the lower boundary for the range
  4234. 2:28:49and you need as well the upper boundary.
  4235. 2:28:52Once you have two boundaries then you
  4236. 2:28:54have a range and everything between
  4237. 2:28:56those two boundaries going to be true
  4238. 2:28:59and everything outside those boundaries
  4239. 2:29:01going to be false. So now for example
  4240. 2:29:03let's say that we have the lower
  4241. 2:29:04boundary 100 and the upper boundary 500.
  4242. 2:29:07And there is one thing that you have to
  4243. 2:29:08understand about the between the
  4244. 2:29:10boundaries are inclusive. So that means
  4245. 2:29:12if a value is exactly 100 or exactly 500
  4246. 2:29:16then it's going to considered as a true.
  4247. 2:29:18So it is considered to be inside the
  4248. 2:29:20range. Now if you apply this filter to
  4249. 2:29:22our data where we say the score must be
  4250. 2:29:25between 100 and 500 going to go and do
  4251. 2:29:28the following. So for the first customer
  4252. 2:29:30Maria is going to go and check whether
  4253. 2:29:32her score is inside the boundaries. So
  4254. 2:29:35as you can see 300 is between 100 and
  4255. 2:29:37500. So she is in the green area and
  4256. 2:29:40that's why Isque going to be happy about
  4257. 2:29:41it and leave the customer in the
  4258. 2:29:43outputs. Now moving on to John. John has
  4259. 2:29:45900. As you can see 900 is greater than
  4260. 2:29:48500. So this value is going to be
  4261. 2:29:50outside the boundaries on the right side
  4262. 2:29:52and this means the score of John is not
  4263. 2:29:54in the range. That's why he is not
  4264. 2:29:56fulfilling the condition and SQL going
  4265. 2:29:58to go and remove this customer from the
  4266. 2:30:00results. Now moving on to George 750.
  4267. 2:30:03The same thing outside the range. SQL
  4268. 2:30:05will not accept it and remove this
  4269. 2:30:07customer from the final results. Now
  4270. 2:30:09moving on to Martin his score is 500 and
  4271. 2:30:12this is exactly at the boundary. So if
  4272. 2:30:14it's like 5001 it's going to be outside.
  4273. 2:30:17So since between is inclusive then SQL
  4274. 2:30:20going to accept it and Martin considered
  4275. 2:30:22to be in the range and fulfilling the
  4276. 2:30:24condition. So SQL going to keep him in
  4277. 2:30:25the final result. Now here are speaking
  4278. 2:30:27about better he has zero score and this
  4279. 2:30:30is less than 100. So in the left side
  4280. 2:30:32not in the range. So not fulfilling the
  4281. 2:30:34condition and SQL going to go and remove
  4282. 2:30:36him. This is exactly how between works
  4283. 2:30:38in SQL. It's very simple. Okay. So now
  4284. 2:30:40we have the following task and it says
  4285. 2:30:42retrieve all customers whose score falls
  4286. 2:30:45in range between 100 and 500. So let's
  4287. 2:30:48start as usual by selecting all data
  4288. 2:30:51from customers and execute it. Now the
  4289. 2:30:54task says everything. We need all
  4290. 2:30:55customers in a range. So we have a lower
  4291. 2:30:58value and a higher value. So in order to
  4292. 2:31:00do that as usual we're going to use the
  4293. 2:31:02where and then we're going to specify
  4294. 2:31:04the column that we want to filter on. So
  4295. 2:31:06it's going to be the score and since we
  4296. 2:31:07have like two boundaries we can go and
  4297. 2:31:09use the function between and we start
  4298. 2:31:11with the first boundary the lowest
  4299. 2:31:12boundary. So it is the 100 and 500 the
  4300. 2:31:17high boundary the upper boundary. So
  4301. 2:31:19between 100 and 500. So now let's go and
  4302. 2:31:23execute it. And with that we get only
  4303. 2:31:25those two customers because they are
  4304. 2:31:27between this window. Now there is
  4305. 2:31:29another way in how to solve this task by
  4306. 2:31:31not using between. We can go and use the
  4307. 2:31:34comparison operator together with a
  4308. 2:31:36logical operator and. So let me show you
  4309. 2:31:38how we can do that. I'm going to go and
  4310. 2:31:40copy the whole thing. And now we're
  4311. 2:31:41going to write two conditions. So first
  4312. 2:31:43the score should be higher or equal to
  4313. 2:31:46100 because the boundaries is inclusive
  4314. 2:31:49and the other one the score is less or
  4315. 2:31:52equal to 500. So this is the upper
  4316. 2:31:55boundary. So with that we have the two
  4317. 2:31:56conditions and we can go and connect
  4318. 2:31:58them using the and operator. So it's
  4319. 2:32:00like very similar to the between we have
  4320. 2:32:02an and between the upper and the lower
  4321. 2:32:04boundaries but we are using the
  4322. 2:32:06comparison operators. So it is higher or
  4323. 2:32:09equal to 100 and lower or equal to 500.
  4324. 2:32:12If you go and run this query you will
  4325. 2:32:14get exactly same results. Now if you ask
  4326. 2:32:16me which method is my favorite I'm going
  4327. 2:32:18to go with this method and I will skip
  4328. 2:32:20the between because each time to be
  4329. 2:32:22honest for me I forget about the between
  4330. 2:32:24whether the boundaries are inclusive or
  4331. 2:32:26exclusive. But if I read the script I am
  4332. 2:32:29going to see exactly that those
  4333. 2:32:30boundaries are inclusive because we have
  4334. 2:32:32here the equals. So I really prefer
  4335. 2:32:34using the compressor operator together
  4336. 2:32:36with the and then using between. So it's
  4337. 2:32:38up to you if you memorize it then go
  4338. 2:32:40with the between. But for me I'm going
  4339. 2:32:42to go with the compression operators.
  4340. 2:32:44Okay my friends. So that's all about the
  4341. 2:32:45between and the range operator. Now
  4342. 2:32:47let's move to another group. We have the
  4343. 2:32:49membership operator. So here we have
  4344. 2:32:51like two. We have the in and the not in.
  4345. 2:32:53So let's understand what this exactly
  4346. 2:32:59means. Okay. So what is in operator?
  4347. 2:33:01It's going to go and check if a value
  4348. 2:33:03exist in a list. So you have a list of
  4349. 2:33:06values and you are checking whether your
  4350. 2:33:07value is a member of your list. So let's
  4351. 2:33:10have very simple example in order to
  4352. 2:33:11understand what this means. Okay. So now
  4353. 2:33:13how this works exactly what you have to
  4354. 2:33:15do is to go and make a list of values.
  4355. 2:33:18So let's say that I have a list and
  4356. 2:33:19there I have specified two values
  4357. 2:33:21Germany and USA. So those two are the
  4358. 2:33:24members of this list. Now if you use the
  4359. 2:33:26n operator it's going to go and check
  4360. 2:33:28the value of countries whether it is in
  4361. 2:33:30the list or not. So let's do it one by
  4362. 2:33:32one. For the first customer Maria her
  4363. 2:33:34country is Germany and Germany is member
  4364. 2:33:37of the list. So it's going to be happy
  4365. 2:33:39and going to leave Maria in the final
  4366. 2:33:41results. Now moving on to John. John
  4367. 2:33:43comes from USA. USA is member of the
  4368. 2:33:45list. So he is fulfilling as well the
  4369. 2:33:47condition and you're going to see John
  4370. 2:33:49in the final results. Now we come to
  4371. 2:33:50George. George comes from UK and UK is
  4372. 2:33:53not member of our list. And SQL going to
  4373. 2:33:56go and remove this customer from the
  4374. 2:33:58final results not fulfilling the
  4375. 2:33:59condition. Now for the last two, Martin
  4376. 2:34:01and Peter, their country is a member of
  4377. 2:34:03the list and SQL going to go and leave
  4378. 2:34:05those customers in the final results. So
  4379. 2:34:07as you can see it's very simple. Or what
  4380. 2:34:09you have to do is to define the members
  4381. 2:34:10of a list and use the n operator and if
  4382. 2:34:13the value is a member of this list it's
  4383. 2:34:15going to be true otherwise it's going to
  4384. 2:34:17be false. Now of course the other
  4385. 2:34:18operator going to be exactly the
  4386. 2:34:20opposite where we say not in the list.
  4387. 2:34:23So we are searching for values that are
  4388. 2:34:25not in this list. So as we are using not
  4389. 2:34:27it's going to go and reverse completely
  4390. 2:34:29the truth. And if you apply this you
  4391. 2:34:31will get in the result only one
  4392. 2:34:33customer. you will get George and the
  4393. 2:34:35result because the country is UK and UK
  4394. 2:34:38is not a member of the list. So if you
  4395. 2:34:40use not together with the in operator
  4396. 2:34:42you will get exactly the opposite
  4397. 2:34:44effect. So this is how the in and the
  4398. 2:34:46not in operator works in SQL. Let's go
  4399. 2:34:48back to scale in order to practice that.
  4400. 2:34:50Okay. So now we have this task and it
  4401. 2:34:52says retrieve all customers from either
  4402. 2:34:54Germany or USA. Okay. So let's try to
  4403. 2:34:57solve this task. This going to be a
  4404. 2:34:59little bit tricky. So select star from
  4405. 2:35:02customers as usual and execute it. So
  4406. 2:35:04now we need in the results only customer
  4407. 2:35:06that comes either from Germany or USA.
  4408. 2:35:09So that means this customer over here
  4409. 2:35:11should be excluded from the result
  4410. 2:35:12because he come from UK. So how we going
  4411. 2:35:14to write it? It's going to be like this
  4412. 2:35:16maybe. So the first one going to be the
  4413. 2:35:19country is equal to Germany or the
  4414. 2:35:22country is equal to USA right something
  4415. 2:35:25like this. So if you go and execute it,
  4416. 2:35:27you will get in the output only the
  4417. 2:35:28customers that are either from Germany
  4418. 2:35:30or USA. And with that we have solved the
  4419. 2:35:32task, right? Well, there is another way
  4420. 2:35:34in order to solve this task which is
  4421. 2:35:36more clear and shorter using the n
  4422. 2:35:38operator. So now how we going to do it?
  4423. 2:35:40Let's go and get the whole thing in
  4424. 2:35:43another query. And now instead of having
  4425. 2:35:45equals and ors and so on, we're going to
  4426. 2:35:48use the in operator and then we're going
  4427. 2:35:50to have like two parentheses and then
  4428. 2:35:51inside it we're going to have a list of
  4429. 2:35:53values. So it's going to be the Germany
  4430. 2:35:55and then the second value going to be
  4431. 2:35:57USA like this. So we are saying country
  4432. 2:36:00should be in this list Germany or USA
  4433. 2:36:03and if it is like one of those values
  4434. 2:36:05then the condition is fulfilled. So now
  4435. 2:36:07if you go and execute this one over here
  4436. 2:36:09you will get the exact same results. So
  4437. 2:36:12my friends, if you notice that you are
  4438. 2:36:13repeating yourself in the wear condition
  4439. 2:36:15and you are just changing the value of
  4440. 2:36:17the condition, it is based on the same
  4441. 2:36:19column and you are connecting them using
  4442. 2:36:21the or then there is something wrong and
  4443. 2:36:23always think on this scenario to use the
  4444. 2:36:25in operator because this can be really
  4445. 2:36:28ugly once you have a lot of values. So
  4446. 2:36:30imagine in our database we have a lot of
  4447. 2:36:32countries and your query going to be
  4448. 2:36:34like something like this. So you are
  4449. 2:36:36keep repeating country equal or country
  4450. 2:36:38equal and so on. Instead of that you're
  4451. 2:36:40going to have a really nice list of
  4452. 2:36:42countries in one go. So this is as you
  4453. 2:36:44can see here it is easier to extend and
  4454. 2:36:47as well has better performance. So as
  4455. 2:36:49you can see we are repeating the same
  4456. 2:36:51thing but we are just changing the value
  4457. 2:36:53and we are connecting all those
  4458. 2:36:54conditions using the or in this scenario
  4459. 2:36:56go and use the in operator. All right my
  4460. 2:36:59friends. So that's all for the
  4461. 2:37:00membership operators. Now we're going to
  4462. 2:37:02speak about the last one the search
  4463. 2:37:04operator. And here we have only one the
  4464. 2:37:06like. And each time we're going to say
  4465. 2:37:07like, I'm going to remind you to like
  4466. 2:37:09this course. So let's
  4467. 2:37:13go. Okay. So now what is like operator?
  4468. 2:37:16You can use it in order to search for a
  4469. 2:37:19pattern in your text. So if you have
  4470. 2:37:21like a text or characters and you are
  4471. 2:37:23searching for a specific pattern inside
  4472. 2:37:25the text. So let's have an example in
  4473. 2:37:27order to understand exactly what this
  4474. 2:37:28means. Okay. So now if you don't have
  4475. 2:37:30yet cafe, go grab one because you have
  4476. 2:37:33to focus for this one. Now what we have
  4477. 2:37:34to do is to define a pattern in is
  4478. 2:37:36scale. In order to build a pattern we
  4479. 2:37:38have like two special characters. If you
  4480. 2:37:40use a percentage you are saying
  4481. 2:37:42anything. So I'm going to accept
  4482. 2:37:44anything. So it could be no characters
  4483. 2:37:46at all or only one character or many
  4484. 2:37:48characters. So I'm saying anything. Now
  4485. 2:37:50if you use an underscore you are
  4486. 2:37:52expecting to have exactly one thing like
  4487. 2:37:55one character or one number. So it is
  4488. 2:37:57exactly one. I know this sounds
  4489. 2:37:59complicated but with an example you can
  4490. 2:38:00understand this. And I can tell you the
  4491. 2:38:02percentage is way more famous than the
  4492. 2:38:05underscore. I rarely really use the
  4493. 2:38:07underscore. So now let's say that I
  4494. 2:38:09build the pattern like this. I say the
  4495. 2:38:11first character must be M and then
  4496. 2:38:13percentage. So here I'm saying in my
  4497. 2:38:15text the first character must be an M
  4498. 2:38:18and after the first character I really
  4499. 2:38:20don't care. It could be any character,
  4500. 2:38:22any number whatever. So this is the
  4501. 2:38:24pattern and now let's have few values in
  4502. 2:38:26order to say whether it's true or false.
  4503. 2:38:27So now if you have the value Mariam. So
  4504. 2:38:29now you can see the first character is
  4505. 2:38:31an M which is perfect. This is exactly
  4506. 2:38:34our pattern. The first character must be
  4507. 2:38:36an M. And then after the M we got like
  4508. 2:38:38four characters. So whatever it is
  4509. 2:38:40totally fine. We can say Maria is
  4510. 2:38:42fulfilling our pattern. And this is
  4511. 2:38:44exactly what we are searching for. This
  4512. 2:38:47value is fulfilling the condition. Okay.
  4513. 2:38:48Now moving on to the next value we have
  4514. 2:38:50m a. So here again the first character
  4515. 2:38:53is an M which is perfect. And after that
  4516. 2:38:55we have only one character a. Well we
  4517. 2:38:57have say percentage. So it could be
  4518. 2:38:59anything one character multiple
  4519. 2:39:00characters a number or whatever. So
  4520. 2:39:02that's why this value can match our
  4521. 2:39:04pattern and we will see it in the
  4522. 2:39:06outputs. Now moving on to the next value
  4523. 2:39:08we have only one m which is as well
  4524. 2:39:10totally fine because we are saying the
  4525. 2:39:12first character must be an M and then
  4526. 2:39:14followed with anything. Now moving on to
  4527. 2:39:16the last scenario we have Emma. Now this
  4528. 2:39:18is a problematic because the first
  4529. 2:39:20character is an E and in our pattern we
  4530. 2:39:23say it must start with M. So we don't
  4531. 2:39:25have that in this word. The first
  4532. 2:39:27character is an E. That's why this value
  4533. 2:39:29is not fulfilling our pattern and SQL
  4534. 2:39:32going to remove this value from the
  4535. 2:39:33final results. So this is exactly what
  4536. 2:39:35going to happen if you have this pattern
  4537. 2:39:37and those values. Now let's have another
  4538. 2:39:39scenario where you say you know what it
  4539. 2:39:41could start with anything but for me it
  4540. 2:39:43is very important the last two
  4541. 2:39:45characters it must be an I and N. So we
  4542. 2:39:48could start with anything but the last
  4543. 2:39:50two must be an I and N. So let's take
  4544. 2:39:52this value Martin going to go and check
  4545. 2:39:54immediately the last two characters. So
  4546. 2:39:56you can see we have an I and N and the
  4547. 2:39:59first part marks it is fine. It could be
  4548. 2:40:01anything. So this value is fulfilling
  4549. 2:40:03the condition because the last two
  4550. 2:40:05characters is an I and N. Now moving on
  4551. 2:40:07to the next one we have vin. So v i n
  4552. 2:40:10the last two characters is as well
  4553. 2:40:12exactly what we are searching for. It is
  4554. 2:40:14fulfilling the condition and we have
  4555. 2:40:15before it like only v. So we say
  4556. 2:40:17anything with a percentage. Right? Now
  4557. 2:40:19one more we have in. So it is as well
  4558. 2:40:22fulfilling the condition because before
  4559. 2:40:23it we don't have anything. So en is
  4560. 2:40:26fulfilling as well the condition. The
  4561. 2:40:28percentage is always saying anything.
  4562. 2:40:30Now moving on to the last scenario we
  4563. 2:40:31have Jasmine. They are not the last two
  4564. 2:40:33characters. The last two characters is
  4565. 2:40:36an N and E and this is not matching our
  4566. 2:40:39pattern and this why this value is not
  4567. 2:40:41fulfilling our pattern and you will not
  4568. 2:40:43see it in the results. So with that you
  4569. 2:40:44can understand how we can search for
  4570. 2:40:46something in a text using the like
  4571. 2:40:48operator. Let's keep going. Now let's
  4572. 2:40:50say that I have a percentage at the
  4573. 2:40:51start and percentage at the end and in
  4574. 2:40:54between I have only one character an R.
  4575. 2:40:56If you define it like this you are
  4576. 2:40:58saying if there is an R anywhere it is
  4577. 2:41:01good enough whether it's beginning or at
  4578. 2:41:03the end or in between then the condition
  4579. 2:41:06is fulfilled. So if you have Maria you
  4580. 2:41:07can see we have an R in the middle. So
  4581. 2:41:10in the left side we have two characters
  4582. 2:41:11on the right side we have two characters
  4583. 2:41:13doesn't matter the main thing we have an
  4584. 2:41:15R somewhere. So this going to be
  4585. 2:41:16fulfilling the condition. Now moving on
  4586. 2:41:18to better we have an R at the end and
  4587. 2:41:20that is totally fine cuz we say at the
  4588. 2:41:22right side it could be anything. So we
  4589. 2:41:24have an R somewhere that's why it's
  4590. 2:41:26going to fulfill the condition. Now we
  4591. 2:41:28have another case where we say Ryan we
  4592. 2:41:30have an R at the start. So we don't have
  4593. 2:41:32anything before and we have after that
  4594. 2:41:34like three characters which is totally
  4595. 2:41:36fine. So we don't really care about the
  4596. 2:41:38position of the R. It is totally
  4597. 2:41:40acceptable to have an R anywhere. And if
  4598. 2:41:42you have only an R that is as well good
  4599. 2:41:44enough. You don't have anything before.
  4600. 2:41:46you don't have anything after and that's
  4601. 2:41:48okay. But if you have a word like Alice,
  4602. 2:41:50we don't have any R inside it. So that's
  4603. 2:41:52why this is the only case where you say
  4604. 2:41:54we don't have here an R and it's going
  4605. 2:41:57to remove this value from the results.
  4606. 2:41:59And this way of searching of something
  4607. 2:42:00is very famous. You don't care about the
  4608. 2:42:02words before this word and after the
  4609. 2:42:04word, right? So if you are searching for
  4610. 2:42:06any word, you're going to say percentage
  4611. 2:42:08before and percentage after. Now I know
  4612. 2:42:11that we want to practice with the
  4613. 2:42:12underscore. So let's say that I have two
  4614. 2:42:14underscores and then the character B and
  4615. 2:42:16then a percentage. So here what I'm
  4616. 2:42:18saying there should be something in the
  4617. 2:42:20first position. There should be as well
  4618. 2:42:22something in the second position. Then
  4619. 2:42:24the third position should be the
  4620. 2:42:26character B must be exactly at this
  4621. 2:42:28position and after that it could be
  4622. 2:42:30anything. So we really don't care. I
  4623. 2:42:31know this is a little bit complicated.
  4624. 2:42:33Let's have an example. So we have the
  4625. 2:42:34value alert. Now we can see the first
  4626. 2:42:36position we have something the A. Then
  4627. 2:42:39the second position we have as well
  4628. 2:42:40something the L. So so far we are good
  4629. 2:42:42at the pattern and then the third
  4630. 2:42:44position we have B. So we have complete
  4631. 2:42:46match and the rest the ERT whatever. So
  4632. 2:42:49with that Albert is matching our
  4633. 2:42:51pattern. Moving on to the next one rope.
  4634. 2:42:53You can see the first character we have
  4635. 2:42:54something which is good. We have the R.
  4636. 2:42:57Then the second character we have an O.
  4637. 2:42:59So it's not empty. We have something.
  4638. 2:43:01And then the third one we have exactly
  4639. 2:43:03B. And after that we don't have anything
  4640. 2:43:05which is fine. So again this value going
  4641. 2:43:07to fulfill the condition. So moving on
  4642. 2:43:08to the next one. So it start with an A.
  4643. 2:43:11So we have something in the first
  4644. 2:43:12position. The second position we have as
  4645. 2:43:14well something the B. But now the third
  4646. 2:43:16character it is a problem. It is not P.
  4647. 2:43:18We have an E. So that's why it is not
  4648. 2:43:20following our pattern. And is going to
  4649. 2:43:22go and remove it. Now moving on to last
  4650. 2:43:24example we have an A and an N. So in the
  4651. 2:43:26first position we have something. The
  4652. 2:43:27second one as well. But the third one we
  4653. 2:43:30don't have anything. We don't have a B.
  4654. 2:43:32So that's why it's going to be removed.
  4655. 2:43:33So my friends I know that was a lot.
  4656. 2:43:35This is exactly how you build a pattern
  4657. 2:43:37for the like operator using the
  4658. 2:43:39percentage and the underscore. But the
  4659. 2:43:41percentage is more famous. So this is
  4660. 2:43:43exactly how it works. Let's go back to
  4661. 2:43:45scale in order to have some examples.
  4662. 2:43:47All right, let's start with this task.
  4663. 2:43:48Find all customers whose first name
  4664. 2:43:51starts with a capital M. So let's go and
  4665. 2:43:53start searching for those informations.
  4666. 2:43:55We're going to start as usual. Select
  4667. 2:43:56star from customers. And now we have to
  4668. 2:43:58go and build the filter logic. So we're
  4669. 2:44:01going to say where. Now we are searching
  4670. 2:44:03something in the first name. So we're
  4671. 2:44:05going to say first name. So that means
  4672. 2:44:07it is very important to start with an M
  4673. 2:44:09and then the rest it doesn't matter. So
  4674. 2:44:11we're going to use the like operator in
  4675. 2:44:13order to search. And we're going to have
  4676. 2:44:15our single quotes and we're going to
  4677. 2:44:16start with the M. And it doesn't matter
  4678. 2:44:19what comes after that. So for us it is
  4679. 2:44:21very important that the first character
  4680. 2:44:23is an M. Let's go and execute it. And
  4681. 2:44:26with that we got our two customers Maria
  4682. 2:44:28and Martin. And both of them starts with
  4683. 2:44:30an M. So with that we have solved the
  4684. 2:44:32task. It is very simple. Now we have the
  4685. 2:44:34following task. Find all customers whose
  4686. 2:44:37first name ends with an N. So let's go
  4687. 2:44:40first and select all the customers here.
  4688. 2:44:42And we need all those customers where
  4689. 2:44:44they are having an N at the end. So we
  4690. 2:44:46have John and as well Martin. So how we
  4691. 2:44:49going to do it? The same thing where
  4692. 2:44:50first name like since we are searching
  4693. 2:44:53but here we're going to change the
  4694. 2:44:54expression. So it must ends with an N as
  4695. 2:44:57a last character. So before that it
  4696. 2:44:59doesn't matter whether it is the first
  4697. 2:45:01character. So it could be anything but
  4698. 2:45:03the last character of the word should be
  4699. 2:45:05an N. So that's it. Let's go and
  4700. 2:45:07execute. And with that we got John and
  4701. 2:45:10Martin because the last character is an
  4702. 2:45:12N. It is very simple, right? It is all
  4703. 2:45:14about where we're going to place this
  4704. 2:45:16percentage. Okay. So now we have the
  4705. 2:45:17next task. Find all customers whose
  4706. 2:45:20first name contains an R. So here we
  4707. 2:45:22don't have like specifications whether
  4708. 2:45:24it is at the start or at the end.
  4709. 2:45:26Somewhere there should be an R. So if
  4710. 2:45:28you go and execute first without any
  4711. 2:45:30wear condition you can see here for
  4712. 2:45:31example Maria we have in the middle
  4713. 2:45:33somewhere an R George George as well
  4714. 2:45:36Martin and Peter at the end. So we have
  4715. 2:45:38a lot of names with an R. So how we can
  4716. 2:45:40search for that? We're going to stick
  4717. 2:45:41with the where first name like and here
  4718. 2:45:44our character going to be an R and we're
  4719. 2:45:46going to put before it and after it a
  4720. 2:45:48percentage. So it doesn't matter what is
  4721. 2:45:50before it or after it somewhere there
  4722. 2:45:53should be an R. So let's go and execute
  4723. 2:45:55it. And with that we got all our
  4724. 2:45:57customers where somewhere we have an R.
  4725. 2:46:00As you can see it is very simple. If you
  4726. 2:46:01put it before and after then you are
  4727. 2:46:03open for more results. And this is
  4728. 2:46:05usually used a lot in order to search
  4729. 2:46:07for a value inside your database. All
  4730. 2:46:10right. Now we're going to move to a
  4731. 2:46:11funny one. It kind of says find all
  4732. 2:46:13customers whose first name has an R in
  4733. 2:46:15the third position for some reason. I
  4734. 2:46:17don't know why. So let's go and execute
  4735. 2:46:19our customers here without any filter.
  4736. 2:46:21So it is for us very important to find
  4737. 2:46:23the customers where in the third
  4738. 2:46:25position we have an R like here for
  4739. 2:46:27example Maria the third character is an
  4740. 2:46:29R which is okay but with Peter over here
  4741. 2:46:31it is not the third character so it is
  4742. 2:46:34not fulfilling the condition. So how we
  4743. 2:46:35going to write that? It going to say
  4744. 2:46:37like this where the first name like but
  4745. 2:46:40we have to write it now from the start.
  4746. 2:46:41So the first position going to be an
  4747. 2:46:43underscore the second position going to
  4748. 2:46:45be as well an underscore and now in the
  4749. 2:46:47third position going to have an R. So
  4750. 2:46:49with that we make sure the third
  4751. 2:46:51position and an R and before it we have
  4752. 2:46:53two positions and now afterward it
  4753. 2:46:55doesn't matter what comes after that it
  4754. 2:46:57could be nothing or characters. So if
  4755. 2:46:59you go and execute it like this we will
  4756. 2:47:01get Maria and Martin and we will not get
  4757. 2:47:04Peter because the R is not in the third
  4758. 2:47:06position. So now if you don't do it
  4759. 2:47:08correctly with the underscores let's go
  4760. 2:47:09and remove one of them and execute. You
  4761. 2:47:12will get nothing because we don't have
  4762. 2:47:14any first name where the second position
  4763. 2:47:16is an R. So you have to be very careful
  4764. 2:47:18with this. All right my friends. So this
  4765. 2:47:20is how you search inside your values.
  4766. 2:47:22And with that we have covered all
  4767. 2:47:24different groups of operators that you
  4768. 2:47:26can use inside a wear clause. So with
  4769. 2:47:28that you have learned how to filter your
  4770. 2:47:30data using multiple operators that you
  4771. 2:47:32can use inside the wear clause. So you
  4772. 2:47:35can filter anything now in SQL. Now we
  4773. 2:47:37will move to very interesting topic. You
  4774. 2:47:39will learn how to combine your data from
  4775. 2:47:41multiple tables. And here we have two
  4776. 2:47:43main methods. The first one is SQL joins
  4777. 2:47:45and the second set operators. And they
  4778. 2:47:48are really big topics. So we're going to
  4779. 2:47:49first focus on the SQL joins. And here
  4780. 2:47:52we have a lot of things to cover. So now
  4781. 2:47:54we are talking about the core of SQL. So
  4782. 2:47:56let's
  4783. 2:48:00go. All right. So now we have two
  4784. 2:48:02tables, table A and table B. And the big
  4785. 2:48:05question here is how to combine those
  4786. 2:48:08two tables. What do we want exactly? Do
  4787. 2:48:10you want to combine the rows or the
  4788. 2:48:12columns? And now if you say I would like
  4789. 2:48:14to combine the columns then we are
  4790. 2:48:16talking about joining tables. So we're
  4791. 2:48:19going to use joins in SQL. So now let's
  4792. 2:48:21say that we are joining the table A with
  4793. 2:48:23the table B and we start from the table
  4794. 2:48:25A. So SQL going to take the columns and
  4795. 2:48:27the rows of the table A and SQL going to
  4796. 2:48:30call it the left table because we
  4797. 2:48:32started from there and then we join it
  4798. 2:48:34with the table B and SQL going to call
  4799. 2:48:36the second table as the right table. And
  4800. 2:48:38here what's going to happen? and SQL
  4801. 2:48:39going to take the columns and the rows
  4802. 2:48:41from the right table and put it side by
  4803. 2:48:43side with the columns and rows of the
  4804. 2:48:46table A. So we are like combining the
  4805. 2:48:48columns we are putting them side by
  4806. 2:48:50side. And now if you say you know what I
  4807. 2:48:52don't want to do that I would like to
  4808. 2:48:53combine the rows both of the tables
  4809. 2:48:55having the same columns. I just want to
  4810. 2:48:57stack them. So we are now talking about
  4811. 2:49:00another methods. It is called the set
  4812. 2:49:02operators. So here there is like no left
  4813. 2:49:04and right. So since we started with the
  4814. 2:49:06table A, the SQL going to take the
  4815. 2:49:08columns and the rows of the table A and
  4816. 2:49:10put it in the results. And then it's
  4817. 2:49:11going to go to the second table, table B
  4818. 2:49:13and it's going to take only the rows and
  4819. 2:49:15put it below the rows of the the table
  4820. 2:49:17A. So we are putting the rows beneath
  4821. 2:49:20each others. We are doing like
  4822. 2:49:21appending. So that means as we are using
  4823. 2:49:24the set operators, we are combining the
  4824. 2:49:26rows. Our table going to be longer but
  4825. 2:49:28with the joins we are combining the
  4826. 2:49:30columns side by side and we are getting
  4827. 2:49:32wider table. But now for each methods
  4828. 2:49:34there are different types. So now for
  4829. 2:49:36example in order to do the joints we
  4830. 2:49:38have four very famous types. We can do
  4831. 2:49:40an inner join, full join, left join,
  4832. 2:49:42right join. But of course there are more
  4833. 2:49:44than that but those are the basics. And
  4834. 2:49:46for the set methods we have as well
  4835. 2:49:48types. We have the union, union all
  4836. 2:49:50except and intersect. And for each
  4837. 2:49:53methods there are like different rules.
  4838. 2:49:55In order to join the tables we have to
  4839. 2:49:57define the key columns between the two
  4840. 2:49:59tables. Don't worry we're going to learn
  4841. 2:50:00about that later. This is the
  4842. 2:50:02requirement in order to join tables and
  4843. 2:50:04the requirement of combining tables
  4844. 2:50:06using the set operators the tables in
  4845. 2:50:08your query should has the exact same
  4846. 2:50:10number of columns but here you don't
  4847. 2:50:12need any like key in order to combine
  4848. 2:50:14the tables. So guys if you look at this
  4849. 2:50:16in order to combine two tables first you
  4850. 2:50:19have to decide do I want to combine the
  4851. 2:50:21columns or the rows. So first you have
  4852. 2:50:22to decide in the methods and after that
  4853. 2:50:25you have different types on how exactly
  4854. 2:50:27you're going to go and combine the data
  4855. 2:50:28and of course there are rules that you
  4856. 2:50:30have to follow. Now, of course, we're
  4857. 2:50:31going to go and cover everything in the
  4858. 2:50:32course, but now in this section, we're
  4859. 2:50:34going to learn how we're going to
  4860. 2:50:35combine the tables using the SQL joins.
  4861. 2:50:38So, we're going to go and dive into this
  4862. 2:50:44word. All right. So, now what is exactly
  4863. 2:50:46SQL joins? Now, let's say that we have
  4864. 2:50:48two tables. On the left table, we have
  4865. 2:50:50the customer name. So, we have four
  4866. 2:50:52customers. And on the right table, we
  4867. 2:50:53have the country informations about the
  4868. 2:50:55customer. And now we would like to query
  4869. 2:50:57both of those informations the names and
  4870. 2:51:00the countries. Now in order to query
  4871. 2:51:02those two tables in one query first we
  4872. 2:51:05have to connect them. And in order to
  4873. 2:51:06connect those two tables we need a key a
  4874. 2:51:09column that exist on the left and on the
  4875. 2:51:11right sides. And by looking to this the
  4876. 2:51:14common column here is the ID of the
  4877. 2:51:16customer. Now once we connect those ids
  4878. 2:51:18together we will be able to query those
  4879. 2:51:21tables together and SQL going to start
  4880. 2:51:23matching those ids. So for the ID number
  4881. 2:51:25one, we will get the name Maria and the
  4882. 2:51:28country Germany. And the ID2 is
  4883. 2:51:30connecting John to USA. And now you can
  4884. 2:51:33see the ID3 is not connectable. So we
  4885. 2:51:35cannot connect it to the right side. But
  4886. 2:51:37for the ID4, we can use it in order to
  4887. 2:51:40connect Martin to Germany. So this is
  4888. 2:51:42exactly what happens if you join two
  4889. 2:51:44tables. You connect those two tables
  4890. 2:51:46using a common column, a key like the
  4891. 2:51:48ID. And once we have matching value, we
  4892. 2:51:51can connect the two rows together. So
  4893. 2:51:53this is what we mean with SQL
  4894. 2:51:58joins. Now you might ask why do we need
  4895. 2:52:01actually joins? Well, the first and very
  4896. 2:52:03important reason is to recombine your
  4897. 2:52:05data. So now usually in databases the
  4898. 2:52:07data about something like the customers
  4899. 2:52:10could be spreaded into multiple tables.
  4900. 2:52:12Like we could have table called
  4901. 2:52:14customers, another one where we have the
  4902. 2:52:16customer addresses and a third table
  4903. 2:52:18where you can find the orders of the
  4904. 2:52:20customers and maybe another one where
  4905. 2:52:22you can find the reviews of the
  4906. 2:52:24customers. So as you can see the data of
  4907. 2:52:26the customers is spreaded into like four
  4908. 2:52:28tables. Now how about I would like to
  4909. 2:52:30see all the data about the customers in
  4910. 2:52:32one results. So I would like to see the
  4911. 2:52:34complete big picture about our
  4912. 2:52:36customers. What we can do, we can go and
  4913. 2:52:39connect those four tables using the SQL
  4914. 2:52:42joins. And once we do that in one query,
  4915. 2:52:45I will be able to combine all those
  4916. 2:52:47tables in one big results. And this is
  4917. 2:52:49the most important reason why we use SQL
  4918. 2:52:52joins in order to combine all the data
  4919. 2:52:54about specific topic in order to see the
  4920. 2:52:57big picture. Now, another reason why we
  4921. 2:52:59use SQL joins is to do data enrichment.
  4922. 2:53:02It is where I want to get an extra data
  4923. 2:53:04and extra information. So let's say that
  4924. 2:53:06you are querying the table customers and
  4925. 2:53:08this is your main table the master
  4926. 2:53:10table. So you are able to see all the
  4927. 2:53:12data that you need but sometimes what
  4928. 2:53:14happens you would like to get an extra
  4929. 2:53:16information from another table like for
  4930. 2:53:18example the zip codes of the countries.
  4931. 2:53:20So you would like the help of another
  4932. 2:53:22table we call it a reference table or
  4933. 2:53:24sometimes lookup table where there is
  4934. 2:53:26like one extra information that you
  4935. 2:53:28would like to add it to your master
  4936. 2:53:30table to the primary source of your
  4937. 2:53:32data. So now what we can do we can join
  4938. 2:53:33those two tables in order to enhance our
  4939. 2:53:36table. So we are getting one extra
  4940. 2:53:38relevant informations for the customers
  4941. 2:53:40and this process we call it data
  4942. 2:53:42enrichments. I'm getting an extra data
  4943. 2:53:44for my main table. So this is another
  4944. 2:53:47reason why we use joins. All right. So
  4945. 2:53:49now so far we have used joins in order
  4946. 2:53:51to get the data from two tables. But now
  4947. 2:53:54there is another use case for the SQL
  4948. 2:53:55joins. We use it in order to check the
  4949. 2:53:58existence of your data in another table
  4950. 2:54:01or maybe as well the not existence. So
  4951. 2:54:03let's say that I have a table called
  4952. 2:54:04customers and I'm working with this
  4953. 2:54:06table and doing queries. But now I would
  4954. 2:54:08like to check something. I would like to
  4955. 2:54:10check whether our customers did order
  4956. 2:54:12something. Now in order to check that I
  4957. 2:54:15need the help of another table for
  4958. 2:54:17example the table orders. So that means
  4959. 2:54:19I'm using the table orders only for my
  4960. 2:54:22check. So I don't want to get any extra
  4961. 2:54:24data from the orders in my final
  4962. 2:54:26results. I'm just using the table orders
  4963. 2:54:28and we call in this table a lookup. So
  4964. 2:54:30now what we can do we can connect those
  4965. 2:54:32two tables together. And now based on
  4966. 2:54:34the existence of the customers inside
  4967. 2:54:36the second table the orders either the
  4968. 2:54:39customer going to stay in the final
  4969. 2:54:40results or going to be removed. So that
  4970. 2:54:42means I'm filtering the data based on
  4971. 2:54:44the join. And of course I can check as
  4972. 2:54:46well the net existence. I would like to
  4973. 2:54:48see in the final results all the
  4974. 2:54:50customers that didn't order anything. So
  4975. 2:54:53it is the same scenario. So my friends,
  4976. 2:54:55those are the main three reasons why you
  4977. 2:54:57use SQL joins. First, if you want to
  4978. 2:55:00combine the data from multiple tables in
  4979. 2:55:02one big picture. So I use join in order
  4980. 2:55:04to get the data from different tables.
  4981. 2:55:06The second use case, you are working
  4982. 2:55:08with one table but you would like to get
  4983. 2:55:10an extra information from another table.
  4984. 2:55:12So you are doing it like something
  4985. 2:55:14called data enrichments. And in the
  4986. 2:55:16third scenario, we don't want to combine
  4987. 2:55:18the data. We want just to join it with
  4988. 2:55:20another table in order to do a check to
  4989. 2:55:22check the existence of your records in
  4990. 2:55:24another table. So this is why we need
  4991. 2:55:26joins in
  4992. 2:55:31SQL. Now there is like a lot of
  4993. 2:55:33different possibilities on how to join
  4994. 2:55:35tables, how to join the data. Now in
  4995. 2:55:37order to make it easy to understand,
  4996. 2:55:39we're going to visuals as like two
  4997. 2:55:41circles. So we have the table A and a
  4998. 2:55:43table B. The table A is on the left
  4999. 2:55:45side. We call it the left table. And the
  5000. 2:55:48table B going to be on the right side
  5001. 2:55:49and we call it the right table. The side
  5002. 2:55:51of the tables is very important. Now if
  5003. 2:55:53you combine those two circles, you will
  5004. 2:55:55get three different possibilities. The
  5005. 2:55:57circles going to overlap. And here
  5006. 2:55:59exactly where we can have the matching
  5007. 2:56:01data between the two tables. So the data
  5008. 2:56:04is available on the left and on the
  5009. 2:56:05right. Or another possibility you want
  5010. 2:56:07to get all the data from one of the
  5011. 2:56:09tables. So you can get all the rows from
  5012. 2:56:12one circle. And the third possibility
  5013. 2:56:14you want to get only the unmatching data
  5014. 2:56:16from one table. So if something exists
  5015. 2:56:19in one table but not in the other table
  5016. 2:56:21then we call it unmatching data. So
  5017. 2:56:23those are the three scenarios that you
  5018. 2:56:25have to ask yourself once you are
  5019. 2:56:27combining tables and this can generate a
  5020. 2:56:29lot of join types. So here we have like
  5021. 2:56:31basic SQL joins those are the classical
  5022. 2:56:34one and here depends on the scenario
  5023. 2:56:36whether you want only matching all or
  5024. 2:56:38all the rows from either left or right
  5025. 2:56:40and we have advanced SQL joins where we
  5026. 2:56:43focus on the unmatching data. Now we're
  5027. 2:56:45going to go and cover all those types
  5028. 2:56:46one by one. So we're going to start
  5029. 2:56:48first with the basics and the first
  5030. 2:56:49option that you have is to get all the
  5031. 2:56:52data without joining tables. So let's
  5032. 2:56:54see what this means.
  5033. 2:56:58So what do we mean with no join? Well,
  5034. 2:57:01we want to returns the data from two
  5035. 2:57:03tables without combining them. So
  5036. 2:57:05actually this is not a joint type
  5037. 2:57:07because we are not combining anything.
  5038. 2:57:09We just want to query the data from two
  5039. 2:57:11tables. So that means from the table A
  5040. 2:57:13we want to see all the rows everything
  5041. 2:57:15and from the table B we want to see
  5042. 2:57:17everything as well all the rows. So that
  5043. 2:57:19means we want to see two results and
  5044. 2:57:21there is no need to combine them. So
  5045. 2:57:23let's see the syntax of that. So all
  5046. 2:57:25what you have to do is very simple.
  5047. 2:57:26Select star from table A and then
  5048. 2:57:29semicolon and then start another query.
  5049. 2:57:31Select star from table B. So that's it.
  5050. 2:57:34And of course since we are not combining
  5051. 2:57:35the data there will be no join in the
  5052. 2:57:38syntax. So that's it. Let's go to SQL in
  5053. 2:57:40order to do that. Okay. So now we have
  5054. 2:57:42the following task. It says retrieve all
  5055. 2:57:44data from customers and orders in two
  5056. 2:57:46different results. So that sounds that
  5057. 2:57:49we don't have to go and combine the
  5058. 2:57:50tables together. And all what we can do
  5059. 2:57:52is the following. We can go and select
  5060. 2:57:54the data from the first table like this
  5061. 2:57:57and then we make another query for the
  5062. 2:58:00second table the orders and we don't
  5063. 2:58:03have to go and combine them in one big
  5064. 2:58:05query. We just use a very simple select
  5065. 2:58:07statements in order to retrieve the
  5066. 2:58:09data. So if you go and execute it since
  5067. 2:58:11you have two separate queries you will
  5068. 2:58:12get two results and with that in one
  5069. 2:58:14result you will get all the customers
  5070. 2:58:16and in the other result you will get all
  5071. 2:58:18the orders and the data is not combined
  5072. 2:58:21at all. So this is how you query two
  5073. 2:58:23tables without combining them. So with
  5074. 2:58:25that we are getting all the data without
  5075. 2:58:27joining the tables. Now we're going to
  5076. 2:58:28start talking about the first type of
  5077. 2:58:30join the inner join where we start
  5078. 2:58:32combining the data from two tables. So
  5079. 2:58:34let's
  5080. 2:58:38go. Okay. So now what is exactly an
  5081. 2:58:40inner join? So this type going to return
  5082. 2:58:43only the matching rows from both tables.
  5083. 2:58:46So that means we will see in the output
  5084. 2:58:48only matching rows. So now what do we
  5085. 2:58:50need from the left table? We want only
  5086. 2:58:52the matching data. So we will not get
  5087. 2:58:54the whole circle of A. We will get only
  5088. 2:58:57where we have an overlapping with the
  5089. 2:58:59table B. So we want to see the data from
  5090. 2:59:01A only if it exists in the table B. And
  5091. 2:59:04now what do we need from the table B?
  5092. 2:59:06Exactly the same thing only the matching
  5093. 2:59:08data. So that means I don't want to see
  5094. 2:59:10all the data from B. I want to see only
  5095. 2:59:12the data in B that has a match from the
  5096. 2:59:15table A from the left side. And with
  5097. 2:59:17that you will get only the matching data
  5098. 2:59:19from both tables. Now let's see how we
  5099. 2:59:21can write that in SQL. So it is a usual
  5100. 2:59:24query and always we start with a select.
  5101. 2:59:26So we select for example all the columns
  5102. 2:59:28from and here we specify the table name.
  5103. 2:59:30So it's going to be a. So so far nothing
  5104. 2:59:32new. But now we want to add as well the
  5105. 2:59:34table B in the same query. In order to
  5106. 2:59:36do that we use the keyword join and then
  5107. 2:59:39we say table B the name of the table.
  5108. 2:59:42And since we have like different types
  5109. 2:59:43of joins in SQL, you can specify the
  5110. 2:59:46type of the join before the keyword
  5111. 2:59:48join. And if you don't specify anything,
  5112. 2:59:50the default type is inner join. But my
  5113. 2:59:53friends, the best practices is always
  5114. 2:59:55mention the type. I don't like to skip
  5115. 2:59:57the defaults because in projects maybe
  5116. 2:59:59not everyone is aware of the defaults.
  5117. 3:00:02So don't skip that. Always specify the
  5118. 3:00:04type. So now what we're going to do,
  5119. 3:00:05we're going to put the keyword inner
  5120. 3:00:07before the join. And with that SQL going
  5121. 3:00:09to know how to deal with the rows
  5122. 3:00:11between two tables. But still we are not
  5123. 3:00:13done there. We have to tell SQL how to
  5124. 3:00:16combine the tables. And with that we use
  5125. 3:00:18the keyword on. And after that you
  5126. 3:00:20specify the join condition. And as we
  5127. 3:00:22learned in order to join two tables we
  5128. 3:00:25have to find out a common column in
  5129. 3:00:27order to match the data. Right? And
  5130. 3:00:29usually in scale they are the keys or
  5131. 3:00:31ids. So the condition can be like this.
  5132. 3:00:33the key from the table A must be equal
  5133. 3:00:36to the key from the table B. So this is
  5134. 3:00:38the join condition and using this join
  5135. 3:00:41SQL can go and start matching the data
  5136. 3:00:43from the left table and the right table.
  5137. 3:00:45And there is one thing that is very
  5138. 3:00:47important while you are joining the
  5139. 3:00:49tables you have to understand about the
  5140. 3:00:51order of the tables in your query. Now
  5141. 3:00:53in the inner join the order of the
  5142. 3:00:55tables doesn't really matter. So whether
  5143. 3:00:57you start from A or you start from B it
  5144. 3:00:59doesn't matter because you will get the
  5145. 3:01:01same results. Both of the tables has the
  5146. 3:01:03same priority and it doesn't matter
  5147. 3:01:05where we start whether we say from A
  5148. 3:01:07join B or we say from B join A we will
  5149. 3:01:10get the exact same results. So in the
  5150. 3:01:12inner join you don't have to worry about
  5151. 3:01:14the order of the tables. So that's all
  5152. 3:01:16about the inner join. Now let's go back
  5153. 3:01:18to scale in order to practice. Okay. So
  5154. 3:01:20now we have the following task and it
  5155. 3:01:22says all customers along with their
  5156. 3:01:24orders but only for customers who have
  5157. 3:01:26placed an order. So my friends that
  5158. 3:01:28means we need the data from the
  5159. 3:01:30customers and from the orders from two
  5160. 3:01:32tables and we have to put everything in
  5161. 3:01:34one results. That means we have to join
  5162. 3:01:36two tables. Now let's go and do it step
  5163. 3:01:38by step. So we're going to go and say
  5164. 3:01:40select star from customers and then we
  5165. 3:01:43have to go and join it with the orders.
  5166. 3:01:45We're going to say join orders. Now you
  5167. 3:01:47have to go and specify the join type. Is
  5168. 3:01:50it inner, left, full and so on. Well
  5169. 3:01:52that's depend on the task. It says we
  5170. 3:01:55want all customers but only for
  5171. 3:01:57customers who have placed an order. So
  5172. 3:01:59there is like condition right here. We
  5173. 3:02:01don't want to see everything from the
  5174. 3:02:03customer. We just want to see only the
  5175. 3:02:05matching data only if the customers has
  5176. 3:02:08an order in the orders table. And for
  5177. 3:02:10that we can go and use the inner join.
  5178. 3:02:13Of course if you can leave it like this
  5179. 3:02:14you will get the same effects but I'm
  5180. 3:02:16going to go and specify it like this
  5181. 3:02:17inner join just to make it clear. We are
  5182. 3:02:19speaking about the inner join. And after
  5183. 3:02:21that we have to go and specify the join
  5184. 3:02:23condition. So we have to go and find a
  5185. 3:02:25common column between the customers and
  5186. 3:02:27the orders. So how I usually do it I go
  5187. 3:02:29and explore both of the tables. So I'm
  5188. 3:02:32going to go and select everything from
  5189. 3:02:33customers and as well
  5190. 3:02:35everything from the orders. So let's go
  5191. 3:02:39and execute. Now we're going to start
  5192. 3:02:40searching where do we have a common
  5193. 3:02:42column between those two tables. So we
  5194. 3:02:44have the from the first table first
  5195. 3:02:46name, country score and you don't find
  5196. 3:02:48any of those informations in the second
  5197. 3:02:50table. The only one is the ID. So the ID
  5198. 3:02:53of the customer and the ID of the
  5199. 3:02:55customer you can find it in the orders
  5200. 3:02:57the second column here. So this is the
  5201. 3:02:59common column between those two tables.
  5202. 3:03:01And usually in databases we create ids
  5203. 3:03:04exactly for this in order to connect
  5204. 3:03:05tables. So it's really rarely that we're
  5205. 3:03:08going to use like a country or score or
  5206. 3:03:10first name in order to join tables. We
  5207. 3:03:12usually use the ids. So let's go back to
  5208. 3:03:14our query and use those two columns. So
  5209. 3:03:17it's going to be the ID from the
  5210. 3:03:19customers equal to the customer ID. So
  5211. 3:03:22that's it. With that we have the
  5212. 3:03:23condition we have decided on the type
  5213. 3:03:25and we can go and execute it. Now you
  5214. 3:03:27can see we are getting only three
  5215. 3:03:29customers. Right? If you don't apply the
  5216. 3:03:31inner join we can see that we have five
  5217. 3:03:34customers. So that means actually we
  5218. 3:03:36have two customers without any orders
  5219. 3:03:39any matching data from the other table.
  5220. 3:03:41And as well you can see very nicely we
  5221. 3:03:43have now not only the columns from the
  5222. 3:03:45customers but as well all the columns
  5223. 3:03:48from the orders side by side. So with
  5224. 3:03:50that we have combined the data and as
  5225. 3:03:52well with that we have solved the task
  5226. 3:03:53but we will not leave our query like
  5227. 3:03:55this because it is not really good
  5228. 3:03:56practices. What we have to do is to go
  5229. 3:03:58and select only the columns that really
  5230. 3:04:00make sense in our query because in many
  5231. 3:04:02cases in your tables you will have a lot
  5232. 3:04:04of columns that is not needed like for
  5233. 3:04:06example if you check here you see we
  5234. 3:04:08have the customer ID here and as well
  5235. 3:04:10the customer ID over here. So it's like
  5236. 3:04:12repetition and it's enough to see it
  5237. 3:04:14only once. So what you have to do is to
  5238. 3:04:15go and pick few columns that we want.
  5239. 3:04:18For example, I'm going to start with the
  5240. 3:04:19ID maybe the first name and that's all
  5241. 3:04:22from the first table. Let's go and get
  5242. 3:04:24the order ID and I don't want the
  5243. 3:04:26customer ID again. So from the second
  5244. 3:04:28table I'll get add the sales. So let's
  5245. 3:04:30go and execute it. And with that you can
  5246. 3:04:32see very nicely the customer's name and
  5247. 3:04:34their orders with the sales. And now
  5248. 3:04:36comes something very important.
  5249. 3:04:37Sometimes if you have two tables you
  5250. 3:04:39might have columns that having the same
  5251. 3:04:42names. Like imagine the order ID in the
  5252. 3:04:44table orders it's called ID. So that
  5253. 3:04:46means we have the same name in both
  5254. 3:04:48tables and this kind of makes SQL very
  5255. 3:04:50confused. And here you will get an error
  5256. 3:04:52tells you I really don't know what do
  5257. 3:04:54you mean with the ID. Is it from the
  5258. 3:04:56table customers or from the orders? So
  5259. 3:04:58we have to tell SQL exactly from which
  5260. 3:05:00table did this column come from. So in
  5261. 3:05:02SQL in order to do that what we do
  5262. 3:05:04before the column name you write again
  5263. 3:05:07the table name the customers and then
  5264. 3:05:09you make a dot and now we are telling
  5265. 3:05:11SQL this column the ID it comes from the
  5266. 3:05:14table customers and SQL will not be
  5267. 3:05:16confused about it and it's going to go
  5268. 3:05:18and get the ID from the customers. And
  5269. 3:05:20for the second id you can go over here
  5270. 3:05:22and as well before it you say orders do
  5271. 3:05:25id so that knows okay this ID come from
  5272. 3:05:28the orders and the other one comes from
  5273. 3:05:30the customers and it is always good
  5274. 3:05:32practice especially if you are joining
  5275. 3:05:34tables to always assign for each column
  5276. 3:05:36a table because after a while if you
  5277. 3:05:38open your query and you see okay the
  5278. 3:05:40sales does the sales come from the
  5279. 3:05:42customers or the orders and if you have
  5280. 3:05:44a long list of columns it's going to be
  5281. 3:05:46really confusing so that's why we
  5282. 3:05:47consider it best practices if you always
  5283. 3:05:50assign for each column the table name
  5284. 3:05:52especially if you are doing joins. So
  5285. 3:05:54it's going to be like this. But of
  5286. 3:05:55course if you have like only one table
  5287. 3:05:57it's clear that all the columns in the
  5288. 3:05:59select comes from this table. But since
  5289. 3:06:01here we are dealing with multiple tables
  5290. 3:06:03it is good to show it like this. And of
  5291. 3:06:04course here we don't have the ID. We
  5292. 3:06:05have the order ID and the same thing for
  5293. 3:06:08the join condition. So the ID from here
  5294. 3:06:10comes from the customers and the
  5295. 3:06:12customer ID come from the orders. So now
  5296. 3:06:15it is clear for everyone which column
  5297. 3:06:17come from which table. But now you might
  5298. 3:06:19say you know what each time I have to
  5299. 3:06:21write the customers this is very long
  5300. 3:06:23name and sometimes in real projects
  5301. 3:06:25you're going to see tables that has
  5302. 3:06:26really long name and it's going to be
  5303. 3:06:28really annoying to add it each time
  5304. 3:06:30before each column right so instead of
  5305. 3:06:32that we can go and assign aliases for
  5306. 3:06:35the tables but only for the columns so
  5307. 3:06:37usually we go over here and say as and
  5308. 3:06:39maybe you can go and use only one
  5309. 3:06:41character like the first character C.
  5310. 3:06:43And now instead of saying customers you
  5311. 3:06:45can go over here and say C. The same
  5312. 3:06:46thing for the second column and as well
  5313. 3:06:49over here. And you can use now the C in
  5314. 3:06:51everywhere in your query. The same thing
  5315. 3:06:53for the orders. You can go over here and
  5316. 3:06:54say has O. And now instead of orders you
  5317. 3:06:57say
  5318. 3:06:59O on here. And now it is very easily to
  5319. 3:07:02see those two columns comes from the C
  5320. 3:07:05that means the customers and those two
  5321. 3:07:06columns comes from the O the orders.
  5322. 3:07:09Those are the best practices as you are
  5323. 3:07:10joining tables together in SQL. And of
  5324. 3:07:13course with that we have solved the
  5325. 3:07:14task. And about the order of the tables,
  5326. 3:07:15it doesn't matter where do you start. So
  5327. 3:07:17for example, if you take the orders here
  5328. 3:07:19and put it in the join and get the
  5329. 3:07:22orders in the from. So I just switch the
  5330. 3:07:24tables and execute it, you will get the
  5331. 3:07:26exact same results. So if you are doing
  5332. 3:07:28inner join between two tables, don't
  5333. 3:07:30worry about the order of the tables.
  5334. 3:07:32Okay. So now let's go and instant
  5335. 3:07:33exactly how executed the inner join.
  5336. 3:07:36Okay. So now again here we have our
  5337. 3:07:38query. Then we have the two tables
  5338. 3:07:40customers and orders. And here we have
  5339. 3:07:42the ID where we are joining the data. So
  5340. 3:07:44this is the ID from the table customers
  5341. 3:07:46and this is the customer ID that we have
  5342. 3:07:48in the orders. Now let's see how SQL can
  5343. 3:07:50execute this. So we are saying I would
  5344. 3:07:52like to see the ID and the first name.
  5345. 3:07:54So we will get the ID, the first name
  5346. 3:07:56from the table customers and we would
  5347. 3:07:58like to get the order ID and as well the
  5348. 3:08:02sales from the table orders. So our
  5349. 3:08:04result going to focus on those four
  5350. 3:08:06columns. Now the data should be joined
  5351. 3:08:08between those two tables using the inner
  5352. 3:08:09join and SQL going to start from the
  5353. 3:08:11left table from the customers because we
  5354. 3:08:13say from customers. So it's going to
  5355. 3:08:16start matching the ID from the left
  5356. 3:08:18table with the right table. So it's
  5357. 3:08:19going to say okay is there a match from
  5358. 3:08:21the first record from the first order?
  5359. 3:08:24Well yes it is the same ID and then SQL
  5360. 3:08:27going to say okay that condition is
  5361. 3:08:28fulfilled and we are allowed to see the
  5362. 3:08:30data. So the data will be presented in
  5363. 3:08:33the output. So we're going to have the
  5364. 3:08:35ID Maria and the order ID from Maria and
  5365. 3:08:39the sales of this order. So there is a
  5366. 3:08:41match. Then SQL going to go to the
  5367. 3:08:43second record. Well, we don't have a
  5368. 3:08:45match. The third we don't have match.
  5369. 3:08:47And so on for the last one. So we have
  5370. 3:08:49only one match for this ID. Then SQL
  5371. 3:08:51going to go again to the customers and
  5372. 3:08:53pick the second one and start matching
  5373. 3:08:55again with the first order. Do we have a
  5374. 3:08:57match? Well, no. Then it's going to go
  5375. 3:08:59to the second. Well, now we have a
  5376. 3:09:01match. So SQL going to be happy. the
  5377. 3:09:03condition is fulfilled and we will see
  5378. 3:09:05the results. So we're going to see the
  5379. 3:09:07first name and as well the order
  5380. 3:09:08information for this customer in the
  5381. 3:09:10output. It's going to keep searching. So
  5382. 3:09:13we don't have a match as well here. So
  5383. 3:09:15that's it. Now for the third customer as
  5384. 3:09:17well from the start there match no to
  5385. 3:09:20the second to the third and here we have
  5386. 3:09:21a match. So it's going to go and show
  5387. 3:09:23this informations since there is a
  5388. 3:09:26match. So the customer three George with
  5389. 3:09:28the order from this customer order ID
  5390. 3:09:31and the sales as well in the output. Now
  5391. 3:09:33it's going to go and keep continuing the
  5392. 3:09:35search. Well, we don't have any match.
  5393. 3:09:37Then it's still going to go to the
  5394. 3:09:39fourth customer and start matching. Do
  5395. 3:09:41we have here an ID? Do we have here a
  5396. 3:09:43match? Well, no. Then the second, third,
  5397. 3:09:45and fourth. We don't have any order for
  5398. 3:09:48this ID. There is no match at all. And
  5399. 3:09:50since we are saying inner join then SQL
  5400. 3:09:52will not allow to show the data of this
  5401. 3:09:55customer in the results. There is no
  5402. 3:09:57match and SQL going to totally ignore
  5403. 3:09:59this customer. Then we're going to go to
  5404. 3:10:01the last one and start as well matching
  5405. 3:10:03this ID with the orders. Well, there is
  5406. 3:10:05no match as well. SQL going to go and
  5407. 3:10:07exclude this user from the results. So
  5408. 3:10:10this is exactly how the inner join
  5409. 3:10:12works. it start from the left side and
  5410. 3:10:14start matching the data on the right
  5411. 3:10:16side and only if there is match the
  5412. 3:10:18result going to be presented in the
  5413. 3:10:19output and this is exactly why we are
  5414. 3:10:21getting this results and how the inner
  5415. 3:10:23join works. So now if you look again to
  5416. 3:10:25the reasons why we are joining tables we
  5417. 3:10:27can say we can use the inner join in
  5418. 3:10:29order to recombine the multiple tables
  5419. 3:10:32into one big picture. So the first use
  5420. 3:10:34case and as well we can use the inner
  5421. 3:10:36join in order to filter the data. So
  5422. 3:10:38since we are saying only the matching
  5423. 3:10:40data that means we are filtering the
  5424. 3:10:42data we are checking the existence of
  5425. 3:10:44the records in another table. So you can
  5426. 3:10:46use inner join either to combine data
  5427. 3:10:49from multiple tables or you can use it
  5428. 3:10:51as well only for filtering purposes only
  5429. 3:10:53to check the existence of your rows. So
  5430. 3:10:55this is usually the two use cases of
  5431. 3:10:57inner. All right. So that's all about
  5432. 3:10:59the first type the inner join. Next
  5433. 3:11:01we're going to talk about the left join.
  5434. 3:11:03So we're going to focus on the left
  5435. 3:11:04side. So let's go.
  5436. 3:11:09Okay. So now what is exactly left join?
  5437. 3:11:11This type going to returns all the rows
  5438. 3:11:14from the left table and only the
  5439. 3:11:16matching from the right table. So now if
  5440. 3:11:18you look again to our two circles A and
  5441. 3:11:20B. What do we need from the left table?
  5442. 3:11:22We want to see everything all the rows
  5443. 3:11:25all the data. So that means we will get
  5444. 3:11:27a full circle. And now from the right
  5445. 3:11:29table we want to get only the matching
  5446. 3:11:32data. So that means we don't want to see
  5447. 3:11:34everything from the table B. We want to
  5448. 3:11:36see only the records that has match to
  5449. 3:11:38the table A. So that means my friends
  5450. 3:11:41the left table has here more priority.
  5451. 3:11:43This is the primary source of your data.
  5452. 3:11:46The main source we cannot miss anything.
  5453. 3:11:48This is very important. We want to see
  5454. 3:11:49all the data. But from the table B, it
  5455. 3:11:51is a secondary source of data and we are
  5456. 3:11:54joining it only to get an additional
  5457. 3:11:56data. So I don't want everything. I want
  5458. 3:11:58only the data that has matched to the
  5459. 3:12:00lift table. So this is what we mean with
  5460. 3:12:02a lift join. Now if you look to the
  5461. 3:12:04syntax it's going to be very similar to
  5462. 3:12:05the inner join. So we start from the
  5463. 3:12:07left table the A. Then we say left join
  5464. 3:12:10the right table B and then the same
  5465. 3:12:12condition using keys. So here we just
  5466. 3:12:14switch the type. Instead of inner we
  5467. 3:12:16have now left. But now here with the
  5468. 3:12:18syntax we need to be very careful. The
  5469. 3:12:20order of the tables now is very
  5470. 3:12:22important. You have to start from the
  5471. 3:12:24correct table. So you have to mention
  5472. 3:12:26the left table exactly in the from
  5473. 3:12:28clause and then you join it with the
  5474. 3:12:31right table. So in the join you have to
  5475. 3:12:33specify the right table. If you don't do
  5476. 3:12:35it like this then you will not get all
  5477. 3:12:37the data from a and you will not get the
  5478. 3:12:39results that you are expecting. So this
  5479. 3:12:41is what we mean with the left join.
  5480. 3:12:42Let's go back to scale in order to
  5481. 3:12:44practice. All right. So now we have the
  5482. 3:12:46following task. It says get all
  5483. 3:12:48customers along with their orders
  5484. 3:12:50including those without orders. So again
  5485. 3:12:53here we need the data from two tables
  5486. 3:12:55the customers and orders and we want
  5487. 3:12:57everything in one result. So that means
  5488. 3:12:58we have to go and join the data. And now
  5489. 3:13:00the task says includes those without
  5490. 3:13:03orders. So that means I want to see
  5491. 3:13:05everything the matching data and the
  5492. 3:13:07unmatching data from the table
  5493. 3:13:09customers. And by looking to our query
  5494. 3:13:11this is not working because we are not
  5495. 3:13:13getting everything right. We are getting
  5496. 3:13:14only the customers that has match in the
  5497. 3:13:17table orders. And this is not of course
  5498. 3:13:19fulfilling the task. So now if you read
  5499. 3:13:21the task you can understand the main
  5500. 3:13:23table here is the customers. We are not
  5501. 3:13:25speaking about to see all the orders and
  5502. 3:13:28not missing any order and the orders
  5503. 3:13:29here is only for additional
  5504. 3:13:31informations. So now in order to not
  5505. 3:13:32lose any data for the customers we make
  5506. 3:13:35sure we start from the table customers.
  5507. 3:13:37So that means now the customers on the
  5508. 3:13:39left side and now after that instead of
  5509. 3:13:41inner join this is not good thing for
  5510. 3:13:43this task. We're going to say left join
  5511. 3:13:45and with that we guarantee we will get
  5512. 3:13:47all the data from the customers. Now we
  5513. 3:13:49say left join orders and of course the
  5514. 3:13:52condition going to stay like this. This
  5515. 3:13:54is how we are connecting the two tables.
  5516. 3:13:56So actually that's it. Let's go and
  5517. 3:13:58execute it. And now by looking to the
  5518. 3:14:00result you can see that we have now five
  5519. 3:14:02customers even the customers that didn't
  5520. 3:14:04place any orders. So you can see Martin
  5521. 3:14:06and Peter they don't have any order ID.
  5522. 3:14:09So that means they didn't order
  5523. 3:14:11anything. And as you can see is showing
  5524. 3:14:13us nulls when there is no match. So with
  5525. 3:14:16that we have solved the task. Now my
  5526. 3:14:17friends one more thing as I told you the
  5527. 3:14:19order of the tables is very important
  5528. 3:14:21because the customer is now the left
  5529. 3:14:24table because you start from it and the
  5530. 3:14:26second table the orders is the right
  5531. 3:14:28table. Now if you go and switch them
  5532. 3:14:30like this. So we start from the orders
  5533. 3:14:32and then join it with the customers and
  5534. 3:14:35you go execute it you will not get all
  5535. 3:14:37the customers and of course the task is
  5536. 3:14:39now not solved. So as you can see you
  5537. 3:14:40are getting now completely different
  5538. 3:14:42result if you go and switch the tables.
  5539. 3:14:44So be careful where you start and how
  5540. 3:14:46you join the tables in order to get the
  5541. 3:14:48effects that you want. All right. So now
  5542. 3:14:50I'm going to put everything back like
  5543. 3:14:52before. Now let's go and understand how
  5544. 3:14:54is exactly executed this query. Okay. So
  5545. 3:14:57now again we have the data from
  5546. 3:14:58customers and orders and this time we
  5547. 3:15:00are doing the lift join. So now let's
  5548. 3:15:02see how is going to do it. So going to
  5549. 3:15:04say okay we need the ID and the first
  5550. 3:15:05name and we will get that as well in the
  5551. 3:15:08results and from the right table we need
  5552. 3:15:09only those two informations the order ID
  5553. 3:15:12and the sales in the output. So those
  5554. 3:15:14are the columns that we need. So now SQL
  5555. 3:15:16in the left join going to do it a little
  5556. 3:15:18bit differently. It's going to start as
  5557. 3:15:19well from the lift table from the
  5558. 3:15:21customers. But this time going to go and
  5559. 3:15:24immediately put the result in the output
  5560. 3:15:27without like trying to match anything
  5561. 3:15:29and to check whether the data exist or
  5562. 3:15:30not because it doesn't matter not doing
  5563. 3:15:33any validation whether the customer
  5564. 3:15:35exist in the orders. Since it's lift
  5565. 3:15:37join is still going to show all the data
  5566. 3:15:38from the lift table. So there will be
  5567. 3:15:41like no check. But now as a next step in
  5568. 3:15:43order to get the order ID and the sales
  5569. 3:15:45SQL will start searching. So SQL going
  5570. 3:15:47to go over here and start searching
  5571. 3:15:49where do we have a customer with this
  5572. 3:15:51ID? Well, it's going to be the first
  5573. 3:15:52order. We're going to get the order ID
  5574. 3:15:54and as well the sales informations and
  5575. 3:15:57we will see that in the output. So
  5576. 3:15:59that's it for the first one. Now it's
  5577. 3:16:01going to go to the second row and the
  5578. 3:16:02same thing going to happen immediately.
  5579. 3:16:04The SQL going to go and put the result
  5580. 3:16:06in the output without checking anything.
  5581. 3:16:09And then in order to get the order data,
  5582. 3:16:11it will start searching for this ID. So
  5583. 3:16:14we have it here in the second row. We
  5584. 3:16:15have the order ID and the sales. And
  5585. 3:16:18it's still going to put those results to
  5586. 3:16:19the output. So the search for the third
  5587. 3:16:22one immediately going to put everything
  5588. 3:16:24in the output. And then start searching
  5589. 3:16:27for orders with this ID. We have it over
  5590. 3:16:30here. So this order belongs to the user
  5591. 3:16:32ID number three. So far we are getting
  5592. 3:16:34the same result as the inner joint. But
  5593. 3:16:36we are not done yet. Now exactly count
  5594. 3:16:38the difference this guy going to go and
  5595. 3:16:40get Martin and put it immediately in the
  5596. 3:16:42output and start searching for an order
  5597. 3:16:44with this ID. So do we have any order
  5598. 3:16:47with the ID number four? Well, we don't
  5599. 3:16:49have anything this time. SQL of course
  5600. 3:16:51will not go and exclude the ID number
  5601. 3:16:54four. It's going to leave it. But in SQL
  5602. 3:16:56if there is no match, we still have to
  5603. 3:16:58have something in the output. So SQL
  5604. 3:17:00going to go and say the output going to
  5605. 3:17:03be null like this. We don't know it is
  5606. 3:17:06unknown. And the same thing for the
  5607. 3:17:08sales. So in the lift join if there is
  5608. 3:17:09no match you will see nulls. The same
  5609. 3:17:11thing for the next customer for better.
  5610. 3:17:14So SQL will go and put the result
  5611. 3:17:16immediately in the output and then start
  5612. 3:17:18searching the orders. So do we have
  5613. 3:17:20anything for the ID number five? We
  5614. 3:17:22don't have anything. That's why SQL
  5615. 3:17:25going to go and present nulls as well in
  5616. 3:17:27the output. And that's why you saw nulls
  5617. 3:17:29in the output because those customers
  5618. 3:17:32don't have any orders. So this is
  5619. 3:17:34exactly the effect of the lift join. you
  5620. 3:17:35will get everything from the lift table
  5621. 3:17:37and only the matching stuff on the right
  5622. 3:17:39side and if there is something not
  5623. 3:17:41matching you will get nulls. So that's
  5624. 3:17:43it is this is how scale execute the left
  5625. 3:17:45join okay so now back to this use cases
  5626. 3:17:47of joins if I think about lift join I
  5627. 3:17:50can use it in order to recombine data in
  5628. 3:17:52order to build this big picture and as
  5629. 3:17:54well in the second use case where we use
  5630. 3:17:56it in order to get an extra information
  5631. 3:17:58from another table. So we have a main
  5632. 3:18:00table and secondary table. So we use it
  5633. 3:18:03for both use cases and as well in the
  5634. 3:18:05third use case only with a twist that
  5635. 3:18:07we're going to learn later. So that's
  5636. 3:18:08all about the left join. Now we have
  5637. 3:18:10another type that is exactly the
  5638. 3:18:12opposite of the lift join. We have the
  5639. 3:18:14right join. So now let's understand what
  5640. 3:18:17this
  5641. 3:18:20means. Okay. So now what is exactly
  5642. 3:18:23right join? This is the total opposite
  5643. 3:18:25of the left join. So this tag going to
  5644. 3:18:27returns all the rows from the right
  5645. 3:18:29table and only the matching from the
  5646. 3:18:32left table. So here the main table the
  5647. 3:18:34main focus is the right table. So SQL
  5648. 3:18:36going to get you all the rows everything
  5649. 3:18:38from the table B the right table but
  5650. 3:18:41from the left side we will get only the
  5651. 3:18:43matching data. So that means in the left
  5652. 3:18:45sides you will get only the data that
  5653. 3:18:47has a match on the right side and with
  5654. 3:18:50that the right table going to be the
  5655. 3:18:52primary the main source of your data. So
  5656. 3:18:54it is very important table but the lift
  5657. 3:18:56table is not that important. You are
  5658. 3:18:58just joining it in order to get
  5659. 3:19:00additional data. So again about the
  5660. 3:19:02syntax it's not that crazy. All what you
  5661. 3:19:04have to do is to change the join type.
  5662. 3:19:06So instead of left you say right join
  5663. 3:19:09and again here the order of the tables
  5664. 3:19:11is very important because the side here
  5665. 3:19:13makes a difference. So we start from the
  5666. 3:19:15left table A and then right join it to
  5667. 3:19:18the table B. So it sounds very similar
  5668. 3:19:20to the left join. We are just switching
  5669. 3:19:22things. Now let's go back to scale. in
  5670. 3:19:23order to practice. Okay my friends, so
  5671. 3:19:25now we have the following task and it
  5672. 3:19:27says get all customers along with their
  5673. 3:19:29orders including orders without matching
  5674. 3:19:33customers. So again we have the
  5675. 3:19:35customers and the orders and we are
  5676. 3:19:36doing the join but here the condition is
  5677. 3:19:38different. We want to see all the orders
  5678. 3:19:41even if they don't have a matching
  5679. 3:19:43customer. So that means I would like to
  5680. 3:19:45see everything from the table orders and
  5681. 3:19:47the customers table here is only like
  5682. 3:19:49supporting and helping. So the main
  5683. 3:19:51table that we are focusing on is in the
  5684. 3:19:53orders. We want to see everything and
  5685. 3:19:55from the customers only the matching and
  5686. 3:19:57if you are looking currently to the
  5687. 3:19:59results you can see we are seeing only
  5688. 3:20:01three orders right but in the original
  5689. 3:20:04table if you go back over here you can
  5690. 3:20:06see that we have four orders. So we are
  5691. 3:20:08currently using this query not seeing
  5692. 3:20:11all the orders. So now how we going to
  5693. 3:20:12solve it? If you start from the table
  5694. 3:20:14customers you can say you know what
  5695. 3:20:16instead of left join we're going to say
  5696. 3:20:18right join. And with that you're going
  5697. 3:20:20to guarantee you will get everything
  5698. 3:20:22from the table orders. But now the left
  5699. 3:20:25table the customers is not that
  5700. 3:20:26important and you will see the data of
  5701. 3:20:28the customers only if there is a match.
  5702. 3:20:30So doing the right join like this
  5703. 3:20:32guaranteed to see everything whether
  5704. 3:20:34there is match or no match. Now if you
  5705. 3:20:36go and execute it you can see on the
  5706. 3:20:38right side the order ID and the sales
  5707. 3:20:40and we can see now all the orders and on
  5708. 3:20:42the left side the ID and the first name.
  5709. 3:20:45We are seeing only the customers if they
  5710. 3:20:47did order something. And for the orders
  5711. 3:20:49without a known customer, we are getting
  5712. 3:20:51nulls. So with us, you have solved the
  5713. 3:20:53task using the right join. So now my
  5714. 3:20:55friends, you have to go and solve this
  5715. 3:20:56task to get the exact same results. But
  5716. 3:20:59you are allowed to use only the left
  5717. 3:21:01join. So you are not allowed to use the
  5718. 3:21:03right join. So now go pause the video,
  5719. 3:21:05solve the task and meet you
  5720. 3:21:08[Music]
  5721. 3:21:11soon. Now my friends, in SQL there is
  5722. 3:21:14always alternatives on how to solve a
  5723. 3:21:16task. So now if you want to get all the
  5724. 3:21:18data from B and only the matching from
  5725. 3:21:20A, you can do it like we have done using
  5726. 3:21:22the right join. But if you go and switch
  5727. 3:21:24the sides and you make the table B as a
  5728. 3:21:27left table and the table A as a right
  5729. 3:21:29table, you can do that of course in SQL.
  5730. 3:21:31But you have to switch the join type. So
  5731. 3:21:33instead of right, we have to use left
  5732. 3:21:35now since the B table now on the left
  5733. 3:21:38side and as well you have to switch the
  5734. 3:21:40order. So you start from the B table and
  5735. 3:21:43then you say left join the A table. and
  5736. 3:21:46of course the same join condition. And
  5737. 3:21:47if you do that, you will get the exact
  5738. 3:21:49same result as the left query. So if you
  5739. 3:21:52just switch the tables and as well
  5740. 3:21:54switch the join type, you can get the
  5741. 3:21:56same results. And to be honest, my
  5742. 3:21:58friends, I don't like the right join.
  5743. 3:22:00It's just in the last 10 years, I always
  5744. 3:22:02tend to start from a table and then use
  5745. 3:22:04a left join. And from my point of view,
  5746. 3:22:06the left join is way more famous than
  5747. 3:22:09the right join. And I think I never used
  5748. 3:22:11a query where I'm using a right join. So
  5749. 3:22:14my advice for you always try to skip the
  5750. 3:22:16right join and stick with the left join
  5751. 3:22:18just get the order of the tables in the
  5752. 3:22:20query correct and you will get the same
  5753. 3:22:22results. So with that you know an
  5754. 3:22:23alternative for the right join. Now all
  5755. 3:22:25what you have to do is to go and switch
  5756. 3:22:26the right to left. Uh this is not enough
  5757. 3:22:29because if I go and execute it. So now
  5758. 3:22:31all what I have to do is to go and
  5759. 3:22:33switch the tables like this. So we start
  5760. 3:22:36from the table orders because I want to
  5761. 3:22:38see everything from the orders and then
  5762. 3:22:40lift join it with the customers. And of
  5763. 3:22:42course we don't have to change anything
  5764. 3:22:43here. It doesn't matter the order
  5765. 3:22:45because we have an equal operator here.
  5766. 3:22:47What is very important here is where you
  5767. 3:22:49start from which table and what is the
  5768. 3:22:52table that you are joining with. So if
  5769. 3:22:54you go and execute it, you will get the
  5770. 3:22:56exact same results. So now I'm seeing
  5771. 3:22:58all the orders. I'm not missing anything
  5772. 3:23:00and only the matching customers. And I
  5773. 3:23:03prefer this way solving this task
  5774. 3:23:05instead of using the right join. All
  5775. 3:23:06right. So that's all about the right
  5776. 3:23:08join. Next we're going to combine
  5777. 3:23:10everything. We're going to talk about
  5778. 3:23:11the full join. So let's
  5779. 3:23:16go. Okay. So now what is exactly a full
  5780. 3:23:19join? If you use it, SQL returns
  5781. 3:23:21everything all the rows from both
  5782. 3:23:23tables. So now if you check again our
  5783. 3:23:25circles from the left table, we want to
  5784. 3:23:27get everything all the rows. So you will
  5785. 3:23:30get the whole circle and as well from
  5786. 3:23:32the right table you want to get
  5787. 3:23:33everything all the rows the whole
  5788. 3:23:35circle. So that you want to get
  5789. 3:23:37everything the matching the unmatching
  5790. 3:23:39all the data from left and right. Now
  5791. 3:23:41let's check the syntax. It's going to be
  5792. 3:23:43very simple. The joint type here going
  5793. 3:23:44to be a full join. And the full join it
  5794. 3:23:47is very similar to the inner join. You
  5795. 3:23:49remember the order of the tables is not
  5796. 3:23:51important at all. So there is here no
  5797. 3:23:53main table and secondary table. Both of
  5798. 3:23:55the tables are important and it doesn't
  5799. 3:23:58matter in your query where you start.
  5800. 3:23:59You can start from A full join B or you
  5801. 3:24:02can start from B then full join A. you
  5802. 3:24:04will get the exact same results. It
  5803. 3:24:06sounds simple. Let's go to SQL and
  5804. 3:24:08practice the full join. All right. So
  5805. 3:24:10now we have the following task and it
  5806. 3:24:11says get all customers and all orders
  5807. 3:24:14even if there is no match. So now again
  5808. 3:24:16we need the data from customers and
  5809. 3:24:18orders. But now of course which type
  5810. 3:24:20we're going to use? It says even if
  5811. 3:24:22there is no match but it didn't say no
  5812. 3:24:24match from orders or customers. So you
  5813. 3:24:26can understand from this task we are not
  5814. 3:24:28focusing only on the orders or the
  5815. 3:24:30customers. Both of them are equally
  5816. 3:24:32important and we need all the data. So
  5817. 3:24:34that means we need all the data from
  5818. 3:24:36left, all the data from right and we can
  5819. 3:24:38go and use the full join. So now we have
  5820. 3:24:40this query over here. We are starting
  5821. 3:24:42from customers and then joining to
  5822. 3:24:44orders. But now instead of having left,
  5823. 3:24:46we're going to say full join. So now
  5824. 3:24:48let's go and just execute it. Now if you
  5825. 3:24:50are looking to the left side, you can
  5826. 3:24:52see we are getting all the customers,
  5827. 3:24:54right? So we have our five customers and
  5828. 3:24:56if you are looking to the right, you can
  5829. 3:24:58see all our orders. So with that we have
  5830. 3:25:00everything from left and everything from
  5831. 3:25:02right and the matching data is just side
  5832. 3:25:05by side in the results and if there is
  5833. 3:25:07no match we are getting nulls. So
  5834. 3:25:08actually with that we have solved the
  5835. 3:25:10task and again it doesn't matter how you
  5836. 3:25:12start. You can start from the orders and
  5837. 3:25:14then join it to the customers and you
  5838. 3:25:16will get the exact same results. So you
  5839. 3:25:19are getting exactly the same data. Now
  5840. 3:25:20let's go and understand exactly how is
  5841. 3:25:22executed the full join. Okay again we
  5842. 3:25:25have the data of the customers and the
  5843. 3:25:26orders and our full join. So now we're
  5844. 3:25:28still going to identify those columns
  5845. 3:25:30that we want to see in the results. So
  5846. 3:25:32the ID and the first name, the order ID
  5847. 3:25:34and the sales informations to the
  5848. 3:25:36output. Now it's still going to start
  5849. 3:25:38from the left table since it is started
  5850. 3:25:39with the customers. It's still going to
  5851. 3:25:41take simply everything from the left
  5852. 3:25:43table and present it in the output.
  5853. 3:25:45Since it is full join, we want to see
  5854. 3:25:46all the data from the left side. And now
  5855. 3:25:48start searching for matches from the
  5856. 3:25:50right table. So let's start with the
  5857. 3:25:52first customer. And as usual, we will
  5858. 3:25:54get the order from the customer number
  5859. 3:25:57one. And the same thing for the second
  5860. 3:25:59customer, we have as well here match. So
  5861. 3:26:01we will get as well. It's like that lift
  5862. 3:26:03join. And for the third one, we have as
  5863. 3:26:05well a match. And we're going to have it
  5864. 3:26:07like this. And since we don't have
  5865. 3:26:09orders for those two customers, we will
  5866. 3:26:11get as well nulls in the outputs. So
  5867. 3:26:14scale going to mark it with null. The
  5868. 3:26:16same thing over here. And as well for
  5869. 3:26:18the last customer. So we will get nulls
  5870. 3:26:20for those two customers. And now of
  5871. 3:26:22course SQL will not stop here otherwise
  5872. 3:26:24we will get a left join effect. Now SQL
  5873. 3:26:27going to start looking at the right side
  5874. 3:26:29to find any order that is not in the
  5875. 3:26:31output. So SQL going to see okay the
  5876. 3:26:33first order is in the output. The second
  5877. 3:26:35one is as well in the output. The third
  5878. 3:26:37but the fourth one is not in the
  5879. 3:26:39results. So SQL going to take this
  5880. 3:26:41result and put it in the output. So this
  5881. 3:26:44order has no match at all from the left
  5882. 3:26:46side. And with that if you are looking
  5883. 3:26:48to the right side you can see SQL going
  5884. 3:26:50to be happy because we have all the
  5885. 3:26:52orders from the right table. And of
  5886. 3:26:54course SQL will not leave it like this.
  5887. 3:26:56Instead of that SQL going to show nulls
  5888. 3:26:58on the left side. So there is no ID and
  5889. 3:27:00there is no first name. So this is
  5890. 3:27:02exactly why we got this results. And
  5891. 3:27:04this is how SQL executed the full join.
  5892. 3:27:07Okay. Okay. So now if you are looking to
  5893. 3:27:08the use cases I can say you can use the
  5894. 3:27:10full join in order as well to recombine
  5895. 3:27:13the data from multiple tables if you
  5896. 3:27:15don't want to miss anything from all
  5897. 3:27:17four tables all data the matching and
  5898. 3:27:19unmatching data but I don't use it
  5899. 3:27:21usually for data enrichment for the
  5900. 3:27:23second use case and where we can use the
  5901. 3:27:25full join is in the last use case as
  5902. 3:27:27well but with a little twist that we're
  5903. 3:27:29going to learn later. So this is mainly
  5904. 3:27:31where we can use the full join. All
  5905. 3:27:33right. So with that we have covered the
  5906. 3:27:35basic types of joins inner, left, right
  5907. 3:27:37and full join. Those are the classical
  5908. 3:27:39joins on how to combine two
  5909. 3:27:44tables. Now we're going to start talking
  5910. 3:27:46about the advanced SQL joins. And now
  5911. 3:27:48we're going to cover the first part the
  5912. 3:27:50lift anti- join. So let's see what this
  5913. 3:27:56means. Okay. So now what is exactly a
  5914. 3:27:58lift anti- join? Now in this mechanism
  5915. 3:28:00we want to return rows from the left
  5916. 3:28:03side the left table that has no match in
  5917. 3:28:06the right table. So now by looking to
  5918. 3:28:07our two circles from the left table we
  5919. 3:28:10want to see only the unmatching rows. So
  5920. 3:28:13only rows that exist in table A but it
  5921. 3:28:16don't exist in the table B. So if there
  5922. 3:28:18is like matching data we don't want to
  5923. 3:28:20see it. And now from the right table we
  5924. 3:28:22don't want anything. We don't want any
  5925. 3:28:24data. So that means the only source of
  5926. 3:28:26your data going to be the left table.
  5927. 3:28:28And from the right table we don't need
  5928. 3:28:29any data. We are just joining the tables
  5929. 3:28:31to do a check to filter the data. So now
  5930. 3:28:34for the syntax this can be interesting.
  5931. 3:28:36We don't have a special type called left
  5932. 3:28:38anti- join. At least in the SQL server
  5933. 3:28:40we still can create this effect. Since
  5934. 3:28:42we are saying left we can use the type
  5935. 3:28:44left join and then as usual the join
  5936. 3:28:46condition with the keys. But now if you
  5937. 3:28:48leave it like this you will get the
  5938. 3:28:50effect of the lift join. And we don't
  5939. 3:28:52want that because with the lift join you
  5940. 3:28:53will get the complete circle from the
  5941. 3:28:55lift table. But now in order to remove
  5942. 3:28:57the matching data this overlapping in
  5943. 3:28:59the middle what we can do we can use a
  5944. 3:29:01filter and in order to filter the data
  5945. 3:29:03we use the wear clause. So now in order
  5946. 3:29:06to get rid of the matching data we can
  5947. 3:29:08take the key from the right table and we
  5948. 3:29:11say the key must be null. So if the key
  5949. 3:29:14is null so that means there is no match
  5950. 3:29:16on the right side. And if you do it like
  5951. 3:29:18this you will get the effect of the left
  5952. 3:29:21anti-join only the data in the left that
  5953. 3:29:23has no match on the right. So now let's
  5954. 3:29:26go in scale and create this effect.
  5955. 3:29:28Okay. So now we have the following task
  5956. 3:29:29and it says get all customers who
  5957. 3:29:31haven't placed any order. So now by
  5958. 3:29:33looking to this query clearly we are
  5959. 3:29:35focusing on the table customers but we
  5960. 3:29:37want to see the customers that didn't
  5961. 3:29:39order anything. So they are in our
  5962. 3:29:41database but the customers are inactive.
  5963. 3:29:44Now there are like different ways on how
  5964. 3:29:45to solve this task but we're going to
  5965. 3:29:47solve it using the joins. Now let's go
  5966. 3:29:49and start by just writing a very simple
  5967. 3:29:51query where we are selecting everything
  5968. 3:29:54from the table customers. Now you can
  5969. 3:29:56see this is our five customers. And now
  5970. 3:29:58I want to check which of those customers
  5971. 3:30:00didn't order anything yet. Now since we
  5972. 3:30:02are talking about the orders, we can go
  5973. 3:30:04and join it with the table orders. So
  5974. 3:30:06we're going to say lift join the table
  5975. 3:30:08orders as all and then we're going to go
  5976. 3:30:10and connect the tables using the ids
  5977. 3:30:12with the customer ID. So now if you go
  5978. 3:30:15and execute it now we are still seeing
  5979. 3:30:17all the customers because we are using
  5980. 3:30:19the lift join and now we can see the
  5981. 3:30:21orders informations of each customer and
  5982. 3:30:23you can see immediately those two
  5983. 3:30:25customers didn't order anything because
  5984. 3:30:28we are seeing here nulls right so they
  5985. 3:30:30are empty there is no orders now we can
  5986. 3:30:32use this information in order to filter
  5987. 3:30:35the data I just want to see Martin and
  5988. 3:30:37Peter so what you can do we can go and
  5989. 3:30:39say where and all what you have to do is
  5990. 3:30:42to take the key that we are using in
  5991. 3:30:43order to join in the tables this is this
  5992. 3:30:45one over here and say this must be null
  5993. 3:30:48so is null so if you see it like this
  5994. 3:30:51that means you want to see the data if
  5995. 3:30:53the customer ID is null so let's go and
  5996. 3:30:56execute it perfect now you are getting
  5997. 3:30:58the customers who haven't order anything
  5998. 3:31:01and this is exactly the effect that we
  5999. 3:31:03wanted the left anti-join we are getting
  6000. 3:31:05the data from the left side where there
  6001. 3:31:08are no match on the right side so you
  6002. 3:31:10have always to do it in two steps first
  6003. 3:31:12join the data as you normally do using
  6004. 3:31:14the classical joins the lift join and
  6005. 3:31:17then the second step you go and use a
  6006. 3:31:19filter using the wear clause if you do
  6007. 3:31:21it like this you can check for not
  6008. 3:31:23existence and with that we are getting
  6009. 3:31:25the effect of the left anti-join so
  6010. 3:31:27that's it okay so now if you are looking
  6011. 3:31:29to this picture I think you already know
  6012. 3:31:31where we use the lift anti- join we're
  6013. 3:31:33going to use it only in the last use
  6014. 3:31:34case where we are checking the existence
  6015. 3:31:37so if you use the lift join together
  6016. 3:31:38with the where you can check for the
  6017. 3:31:40notexistence of your data in another
  6018. 3:31:42table so This is exactly for this
  6019. 3:31:44scenario. All right. So that's all about
  6020. 3:31:46the left anti- join. Now we're going to
  6021. 3:31:48speak about the exact opposite of that.
  6022. 3:31:50We will cover the right anti- join. So
  6023. 3:31:53it's going to be very similar but we are
  6024. 3:31:55just switching sides. So let's
  6025. 3:31:59go. Okay. So now what is exactly the
  6026. 3:32:02right anti- join? Well, it is the
  6027. 3:32:04opposite of the left anti- join. So we
  6028. 3:32:06want to return the rows from the right
  6029. 3:32:09table that has no match in the left
  6030. 3:32:11table. So again if you are looking to
  6031. 3:32:13our two circles. Now what is important
  6032. 3:32:15is the right table. We want to see only
  6033. 3:32:17the unmatching rows from the right
  6034. 3:32:20table. So only the rows that exist in B
  6035. 3:32:23but not in A. And from the left table we
  6036. 3:32:25don't need anything. So no data is
  6037. 3:32:27needed and that means the only source of
  6038. 3:32:29data comes from the right table and you
  6039. 3:32:32are using the left table as a filter as
  6040. 3:32:34a lookup just in order to check the
  6041. 3:32:36existence. So now the syntax of that
  6042. 3:32:38going to be very similar to the left
  6043. 3:32:39anti- join. So we don't have a special
  6044. 3:32:41type called right anti-join. We have to
  6045. 3:32:44use the classical one the right join.
  6046. 3:32:46But if you do that you will get
  6047. 3:32:47everything from the right table. And now
  6048. 3:32:49in order to get rid of the matching data
  6049. 3:32:51in the middle we use a filter. We use
  6050. 3:32:53the wear clause where we say we are
  6051. 3:32:55interested only on the unmatching data.
  6052. 3:32:58So we take the key from the left table
  6053. 3:33:00and we say the key from left is null.
  6054. 3:33:02And if you do that you will get rid of
  6055. 3:33:04any matching data. Is null means there
  6056. 3:33:06is no match. And again here the same
  6057. 3:33:08thing the order of the tables is very
  6058. 3:33:10important since here we are talking
  6059. 3:33:12about sides and you have to do it
  6060. 3:33:14correctly. Okay. So now the task says
  6061. 3:33:16get all orders without matching
  6062. 3:33:19customers. So now it is exactly the
  6063. 3:33:21opposite. We want to see all the orders
  6064. 3:33:23that don't have a valid customer. So
  6065. 3:33:25this is really bad scenario. You have in
  6066. 3:33:27your business orders without a valid
  6067. 3:33:29customers. So let's see how we can
  6068. 3:33:30discover that using SQL joins. Now as
  6069. 3:33:32you can see we are focusing completely
  6070. 3:33:34on the orders. It's not the customers
  6071. 3:33:36anymore. And we want to see only the
  6072. 3:33:38orders where there is no match with the
  6073. 3:33:39customers. So now again here we have two
  6074. 3:33:41steps. The first step we're going to go
  6075. 3:33:43and do the normal join. So using either
  6076. 3:33:45the left or the right join. Now by
  6077. 3:33:47looking to this query you can leave it
  6078. 3:33:49like this where you can start from the
  6079. 3:33:50customers. But if you want to fully
  6080. 3:33:52focus on the orders you have to switch
  6081. 3:33:54this from left to right. And with that
  6082. 3:33:56you will get all the orders and only the
  6083. 3:33:58matching customers. And let's go and
  6084. 3:34:00remove this workloads from here first.
  6085. 3:34:01So I'm just adding comments. And with
  6086. 3:34:03that SQL going to totally ignore this
  6087. 3:34:06line of code. So let's go and execute
  6088. 3:34:08it. Now you can see we are getting all
  6089. 3:34:09the orders right and data from customers
  6090. 3:34:12only if there is a match. And now of
  6091. 3:34:14course this is not the task. We don't
  6092. 3:34:15want to see all the orders. We want to
  6093. 3:34:17see only the orders where we don't have
  6094. 3:34:19a match from the customers. So if you
  6095. 3:34:21look to this those three orders they are
  6096. 3:34:24okay. They are totally fine. We are
  6097. 3:34:25finding customers for them. So they have
  6098. 3:34:27valid customers. But this order here is
  6099. 3:34:30really bad. So there is no valid
  6100. 3:34:31customer for this order and now our task
  6101. 3:34:34to show only this type of orders in the
  6102. 3:34:36result. Now what we have to do we have
  6103. 3:34:38to use the workclass in order to get
  6104. 3:34:40exactly the effects. So this time we're
  6105. 3:34:42going to say if the ID of the customer
  6106. 3:34:44here. So here we're going to say the ID
  6107. 3:34:46of the customer from the table customers
  6108. 3:34:49must be null. So we're going to remove
  6109. 3:34:50this here and take the key join from the
  6110. 3:34:53customer and we are saying this ID must
  6111. 3:34:56be null. So let's go and execute it.
  6112. 3:34:58Perfect. With us we have solved the task
  6113. 3:35:00and we are getting the effect of the
  6114. 3:35:02right anti- join and we are getting now
  6115. 3:35:04those orders that don't have any
  6116. 3:35:06customers. So we have solved the task.
  6117. 3:35:08Now my friends you have to go and solve
  6118. 3:35:10this task without using the right join
  6119. 3:35:13but still you have to get the same
  6120. 3:35:14effects. You want to get exactly those
  6121. 3:35:16orders without customers. So pause the
  6122. 3:35:19video and go solve the task.
  6123. 3:35:23[Music]
  6124. 3:35:26Now again as you know me I don't like
  6125. 3:35:28the right joins. We can create the same
  6126. 3:35:30effects if you switch the sides of the
  6127. 3:35:32table. So if you say the B table now on
  6128. 3:35:34the left side and the A on the right
  6129. 3:35:36side then we will get the same effect if
  6130. 3:35:38you go and switch the type of join from
  6131. 3:35:41right to left and you go just switch the
  6132. 3:35:43tables. So you start from the B table
  6133. 3:35:45since it's on the left side and then
  6134. 3:35:47join it with the A. And we still say of
  6135. 3:35:49course in our work condition where the
  6136. 3:35:51data from A is null. So there is no
  6137. 3:35:53match. So if you do this you will get
  6138. 3:35:55the exact same results like the lift
  6139. 3:35:57query by using the lift join and just
  6140. 3:35:59switching the tables. So you will get
  6141. 3:36:01the same results and with that you know
  6142. 3:36:03that in scale we have always
  6143. 3:36:04alternatives. I hope that you are done.
  6144. 3:36:06So it's very simple what you're going to
  6145. 3:36:07do. We're going to go and switch the
  6146. 3:36:09joins and since the orders is the main
  6147. 3:36:12table we're going to start first from
  6148. 3:36:14the table orders. So we are putting it
  6149. 3:36:16on the left side and then the right
  6150. 3:36:18table going to be the customers. And of
  6151. 3:36:20course the condition going to stay as it
  6152. 3:36:21is. We want to see the orders where
  6153. 3:36:23there is no customer. So we don't have
  6154. 3:36:25to switch anything here or in the join
  6155. 3:36:28key. So let's go and execute it. With
  6156. 3:36:29that you are getting the same exact
  6157. 3:36:31results. Since we are using here the
  6158. 3:36:33star, it's always starts from the left
  6159. 3:36:35table and show the data from the right
  6160. 3:36:37table. But still the result is valid. We
  6161. 3:36:39are getting this type of orders without
  6162. 3:36:42matching customers. And I prefer this
  6163. 3:36:44way. All right. So now with that we have
  6164. 3:36:45the left, the right and now of course
  6165. 3:36:47what is next? We will get the full. So
  6166. 3:36:50let's speak about now the full anti-join
  6167. 3:36:52in SQL. Let's
  6168. 3:36:56go. Okay. So now what is exactly a full
  6169. 3:36:59anti- join? Well, this time we don't
  6170. 3:37:01have sides. We want to return only the
  6171. 3:37:03rows that don't match in either tables.
  6172. 3:37:06So what this means? If you are looking
  6173. 3:37:08to the left circle, we want only the
  6174. 3:37:10unmatching rows. So we don't want the
  6175. 3:37:12whole circle. We want only the data that
  6176. 3:37:14exist in A but it don't exist in B on
  6177. 3:37:18the right table. Sounds like the left
  6178. 3:37:19ant join but since we are saying full
  6179. 3:37:21then you have to do the same thing on
  6180. 3:37:23the right side as well. So on the right
  6181. 3:37:24table we want only the unmatching rows.
  6182. 3:37:27So we want to see in the result the data
  6183. 3:37:29that is in B but don't have a match from
  6184. 3:37:32A. So it's exactly the opposite. And if
  6185. 3:37:34you look to this then that means we want
  6186. 3:37:36to see only the unmatching data and this
  6187. 3:37:38is exactly the opposite effect of the
  6188. 3:37:41inner join. In the inner join we were
  6189. 3:37:43interested only on the matching data
  6190. 3:37:45only when there is like overlapping. But
  6191. 3:37:47now with the full anti-join it is
  6192. 3:37:48exactly the opposite. We don't want to
  6193. 3:37:50see the matching data. We want to see
  6194. 3:37:52everything else the unmatching data. So
  6195. 3:37:54how we going to write this query? Again
  6196. 3:37:56here we don't have a special type called
  6197. 3:37:58full anti-join. We will use the help of
  6198. 3:38:00the classical full join. So the basic
  6199. 3:38:02one. So you start from a full join b and
  6200. 3:38:05then the same key. But now what is
  6201. 3:38:06interesting is about the where
  6202. 3:38:08condition. Now we have like two
  6203. 3:38:09conditions right? So now in order to get
  6204. 3:38:11all data from A that has no match in B,
  6205. 3:38:14you have to make a filter where you say
  6206. 3:38:16the key from the B table must be null.
  6207. 3:38:18And now since we want the exact same
  6208. 3:38:20thing from the right table, we want all
  6209. 3:38:22the data in B that has no match in A.
  6210. 3:38:24You have to say as well the key from the
  6211. 3:38:27A table must be null. So now we have
  6212. 3:38:29here like two conditions. And in SQL if
  6213. 3:38:31you have like two conditions in the work
  6214. 3:38:33clause, you have here two options either
  6215. 3:38:35use and operator or the over operator.
  6216. 3:38:38So now the one that we're going to use
  6217. 3:38:40here is the or operator. So either the
  6218. 3:38:42key from right is empty or the key from
  6219. 3:38:44left is empty. If you do it like this,
  6220. 3:38:46you will get the effect of the full
  6221. 3:38:49anti- join. And of course since here
  6222. 3:38:50both sides are equal then the order of
  6223. 3:38:53the tables as well here is not that
  6224. 3:38:55important. So you can say from A full
  6225. 3:38:57join B or from B full join A. It doesn't
  6226. 3:39:00matter. So now let's go back to scale in
  6227. 3:39:02order to create this effect. Okay.
  6228. 3:39:04Instead we have the following task and
  6229. 3:39:05it says find customers without orders
  6230. 3:39:08and orders without customers. So if you
  6231. 3:39:10are looking to this this means we want
  6232. 3:39:12to see only the unmatching data from
  6233. 3:39:14customers and as well from orders. There
  6234. 3:39:17is no main table and secondary table.
  6235. 3:39:19Both of them are equally important. So
  6236. 3:39:21now since we are talking about the
  6237. 3:39:22unmatching data and the anti-join we
  6238. 3:39:24have to do it in two steps. The first
  6239. 3:39:26step we're going to do the classical
  6240. 3:39:27join and then we focus on the wear
  6241. 3:39:29clause. So let me remove the wear clause
  6242. 3:39:31to make it as a comment. Now since we
  6243. 3:39:33want the data from left and right, we're
  6244. 3:39:35going to go and use the full join. So
  6245. 3:39:36let's go and execute it. Now you can see
  6246. 3:39:38we are getting the effect of the full
  6247. 3:39:40join. We are getting all the orders and
  6248. 3:39:42as well all the customers. But now we
  6249. 3:39:44are interested only on the strange cases
  6250. 3:39:47where they are like orders without
  6251. 3:39:49customers like this one here and as well
  6252. 3:39:51customers without orders. So that means
  6253. 3:39:53the first three rows they are not really
  6254. 3:39:55interesting for us because it is boring.
  6255. 3:39:57We have here matching data and this is
  6256. 3:40:00totally fine but we are not focusing on
  6257. 3:40:02that now. We are focusing only if there
  6258. 3:40:04is like missing data from left or from
  6259. 3:40:06right. As you notice I'm saying or and
  6260. 3:40:09this is very important because we're
  6261. 3:40:10going to use the or operator. So now
  6262. 3:40:11let's focus on getting this scenario
  6263. 3:40:13over here. We want to get an order
  6264. 3:40:15without a customer. So that means the
  6265. 3:40:17customer ID must be null. And we have it
  6266. 3:40:20already here. So we are saying where the
  6267. 3:40:22ID of the customer is null. So if I go
  6268. 3:40:25and execute it, I will get only one
  6269. 3:40:27records only this one over here. But as
  6270. 3:40:29well I want to get the opposite
  6271. 3:40:31scenario. So in this scenario, the
  6272. 3:40:33customer ID must be null. So we're going
  6273. 3:40:36to say or the customer
  6274. 3:40:38ID in the orders is null or we can do it
  6275. 3:40:42like side by side like this. Either the
  6276. 3:40:44right side is null or the left side is
  6277. 3:40:47null. So if you go and execute it, you
  6278. 3:40:49will get the effect of the full
  6279. 3:40:50anti-join. And with that we are finding
  6280. 3:40:52the customers without orders and orders
  6281. 3:40:55without customers. I think this is
  6282. 3:40:57really fun and as well really easy. So
  6283. 3:40:59this is how we do the full anti- join.
  6284. 3:41:01All right. So now if you are looking to
  6285. 3:41:02the use cases we use the full anti- join
  6286. 3:41:04again exactly for the last use case in
  6287. 3:41:07order to check the existence. So if you
  6288. 3:41:09combine the full with the where you can
  6289. 3:41:11check the existence or the notexistence
  6290. 3:41:13of your data in another table. So this
  6291. 3:41:16is exactly the scenario for that.
  6292. 3:41:21Okay, my friends, now we have a bonus
  6293. 3:41:23section where I'm going to challenge you
  6294. 3:41:25to solve the following task without
  6295. 3:41:27using an inner join. So, it says, "Get
  6296. 3:41:29all customers along with their orders,
  6297. 3:41:31but only for customers who have placed
  6298. 3:41:34an order, but without using an inner
  6299. 3:41:37join." So, pause the video now and go
  6300. 3:41:39and solve this
  6301. 3:41:40[Music]
  6302. 3:41:42task. Okay, so now let's see how we're
  6303. 3:41:44going to solve this. We want the
  6304. 3:41:46customers, the orders, blah blah blah.
  6305. 3:41:48But we want only the customers who have
  6306. 3:41:50placed an order. Previously, we have
  6307. 3:41:52used the inner join in order to solve
  6308. 3:41:53this task. But this time, we are not
  6309. 3:41:55allowed to use it. So, let's go and
  6310. 3:41:57solve it. This is how I'm going to do
  6311. 3:41:58it. Select star from table customers.
  6312. 3:42:01Can't give it the alias. So, now I'm
  6313. 3:42:03getting all the customers, but I am
  6314. 3:42:05interested only the customers who have
  6315. 3:42:07placed an order. So, as we know before
  6316. 3:42:09there's like two customers didn't order
  6317. 3:42:11anything, and we don't want to see them
  6318. 3:42:13in the final results. Now how we will
  6319. 3:42:15get that? Well, we can use the help of
  6320. 3:42:17the table orders in order to check the
  6321. 3:42:19existence of our customers there. And of
  6322. 3:42:21course, I'm not allowed to use the inner
  6323. 3:42:23join. So I'm going to go and use a left
  6324. 3:42:24join with a table orders and then
  6325. 3:42:27combine them as usual. Nothing new with
  6326. 3:42:29the customer ID. So now let's go and
  6327. 3:42:31execute it. As you can see, we are doing
  6328. 3:42:33it step by step. You don't have to rush
  6329. 3:42:35everything in one go. So you start
  6330. 3:42:37simple, check the results and decide on
  6331. 3:42:39the next step. So now by looking at
  6332. 3:42:41these results I want to get those three
  6333. 3:42:43customers because they have ordered
  6334. 3:42:45something and we are seeing data about
  6335. 3:42:47their orders and I don't want to get in
  6336. 3:42:49the result the last two. So again we
  6337. 3:42:51still can use the customer ID from the
  6338. 3:42:53right table in order to decide which
  6339. 3:42:56data going to stay in the result and
  6340. 3:42:57which data should be filtered. We're
  6341. 3:42:59going to go and use the wear clause and
  6342. 3:43:01then the key from the orders and this
  6343. 3:43:03time we're going to say is not null. I
  6344. 3:43:06know we didn't learn yet about the not
  6345. 3:43:08and the logical operators but using the
  6346. 3:43:11not null it means there should be data
  6347. 3:43:13inside the column it must not be null if
  6348. 3:43:16you do it like this and execute you will
  6349. 3:43:18get the exact effect as the inner join.
  6350. 3:43:21So as you can see as you are joining the
  6351. 3:43:22tables using the left join you can
  6352. 3:43:25control what you want to see using the
  6353. 3:43:27wear clouds using the filter and this is
  6354. 3:43:29how you can solve this task without
  6355. 3:43:30using an inner join. Okay, so with that
  6356. 3:43:33we have covered all those three
  6357. 3:43:34scenarios in order to find the
  6358. 3:43:36unmatching data. Left, right, full and
  6359. 3:43:38joints. Now we can speak about one crazy
  6360. 3:43:41join. We call it the cross join. This
  6361. 3:43:43one is totally different from all other
  6362. 3:43:45types that we have learned. So let's
  6363. 3:43:47understand exactly what is the cross
  6364. 3:43:49join. Let's
  6365. 3:43:53go. So now what is exactly a cross join?
  6366. 3:43:56Now in some scenarios we want to combine
  6367. 3:43:59every row from the left, every row from
  6368. 3:44:02the right. So that means I want to see
  6369. 3:44:04all the possible combinations from both
  6370. 3:44:06tables. So we are doing something called
  6371. 3:44:08like cartesian join. So now if you look
  6372. 3:44:10at our two circles, we want everything
  6373. 3:44:13from A and as well everything from B. So
  6374. 3:44:16that means I want to see everything from
  6375. 3:44:18A combined with everything with B. So in
  6376. 3:44:20this example, we have two rows in A and
  6377. 3:44:22three rows in B. If you do a cross join,
  6378. 3:44:25you will get six possible combinations
  6379. 3:44:27by just multiplying the number of rows
  6380. 3:44:29between A and B. So be careful using the
  6381. 3:44:31cross join. If you use it, you will get
  6382. 3:44:33like crazy number of rows in the results
  6383. 3:44:35and you're going to make the database
  6384. 3:44:37really busy finding out the result for
  6385. 3:44:39you. So now about the syntax, it's going
  6386. 3:44:40to be the easiest. So you start as usual
  6387. 3:44:42from one of those tables, the A for
  6388. 3:44:44example, and then you say cross join B.
  6389. 3:44:47So now my friends, if you look at this,
  6390. 3:44:48you can see it's not like the previous
  6391. 3:44:50joins that we have done. We have always
  6392. 3:44:52before talked about unmatching rows,
  6393. 3:44:54matching rows and so on. But here we
  6394. 3:44:56don't care at all about whether the data
  6395. 3:44:58is matching or not. I just want to see
  6396. 3:45:00all the possible combinations
  6397. 3:45:02everything. So since we don't care about
  6398. 3:45:04matching the two tables, we don't have
  6399. 3:45:06to specify any condition. So there is no
  6400. 3:45:08need to use the keyword on because we
  6401. 3:45:11don't need any condition. So that's it.
  6402. 3:45:12You just say cross join B and the magic
  6403. 3:45:15can happen. So this is a cross join.
  6404. 3:45:16Let's go to SQL to try that. Okay. So
  6405. 3:45:19now we have the following task. It says
  6406. 3:45:20generate all possible combinations of
  6407. 3:45:23customers and orders. So that means we
  6408. 3:45:25want everything with everything using
  6409. 3:45:27the cross join and this going to be very
  6410. 3:45:29simple. So we're going to start with
  6411. 3:45:31select star from whatever table. So you
  6412. 3:45:33can start from the customers and then
  6413. 3:45:35you say cross join orders. That's it.
  6414. 3:45:39Very simple. Let's go and execute it. So
  6415. 3:45:41now as you know we have five customers
  6416. 3:45:42and four orders. And if you multiply
  6417. 3:45:44them you will get in the results 20
  6418. 3:45:46rows. So now we are getting everything
  6419. 3:45:48with everything. even if the data is not
  6420. 3:45:51matching at all. So you can see for
  6421. 3:45:53example the orders here. So this is one
  6422. 3:45:55order that belongs only to one customer
  6423. 3:45:57the customer ID one. So it is an order
  6424. 3:46:00from actually Maria but still we are
  6425. 3:46:02seeing this same order with the other
  6426. 3:46:04customers since we want to combine
  6427. 3:46:06everything with everything. So there are
  6428. 3:46:07no rules. The same thing for the next
  6429. 3:46:09set. So this is the second order
  6430. 3:46:11actually belongs to John but we are
  6431. 3:46:13seeing this order with all customers. So
  6432. 3:46:15that's it. This is how the cross join
  6433. 3:46:18works. And now you might ask me why we
  6434. 3:46:19have this. It makes no sense, right?
  6435. 3:46:21Well, my friends, I rarely use it. But
  6436. 3:46:23sometimes if I want to generate like
  6437. 3:46:25test data or maybe if you have like for
  6438. 3:46:27example table called colors and table
  6439. 3:46:29called products and you would like to
  6440. 3:46:30see all the combinations between the
  6441. 3:46:33products and the colors. So in some
  6442. 3:46:35scenarios it makes really sense to see
  6443. 3:46:36all your products together with all the
  6444. 3:46:38colors without any matching conditions
  6445. 3:46:41or whatever. So there are like few
  6446. 3:46:42scenarios for the cross join if you are
  6447. 3:46:44like doing simulations or testing. So
  6448. 3:46:47this is how we do the cross join. Okay.
  6449. 3:46:49So that's all about the cross join. And
  6450. 3:46:51with that we have covered the four
  6451. 3:46:53advanced types of joins. Now if you look
  6452. 3:46:55at this you might ask okay how I'm going
  6453. 3:46:57to choose between all those types. So
  6454. 3:46:59you might ask me okay bar how you do it?
  6455. 3:47:01Well I'm going to show you now my
  6456. 3:47:02decision tree that I usually follow in
  6457. 3:47:05order to choose the correct type.
  6458. 3:47:10So now if I'm combining two tables and I
  6459. 3:47:13want to see in the results only the
  6460. 3:47:15matching data between two tables then I
  6461. 3:47:17go and use the inner join. We don't have
  6462. 3:47:19any other type for that. So that's
  6463. 3:47:21simple but now if I want to see
  6464. 3:47:23everything all the data I don't want to
  6465. 3:47:25miss anything after joining two tables
  6466. 3:47:27then I take different path and here I
  6467. 3:47:29ask myself is there like one side more
  6468. 3:47:31important than the other am I interested
  6469. 3:47:33in all data from one table from one side
  6470. 3:47:36like here we have like a main table or a
  6471. 3:47:39master table then I go and use the lift
  6472. 3:47:41join but if I want to see all the data
  6473. 3:47:43from all tables in my query everything
  6474. 3:47:45so there is no one table more important
  6475. 3:47:47than other then I go with the full join
  6476. 3:47:50So this is another path and now the
  6477. 3:47:52third path if I'm interested to see only
  6478. 3:47:54the unmatching data. So I'm doing some
  6479. 3:47:57kind of checkups and so on. And here
  6480. 3:47:59again the same thing do I want to see
  6481. 3:48:00the unmatching data from only one side.
  6482. 3:48:02There is like one table that is
  6483. 3:48:04important then I go and use the lift
  6484. 3:48:06anti- join. So I want to see the
  6485. 3:48:08unmatching data from one table and I'm
  6486. 3:48:11using the other table only for the
  6487. 3:48:12check. But in my query if both of the
  6488. 3:48:15tables are important there is no main
  6489. 3:48:17table and secondary table both are
  6490. 3:48:19important then I go and use the full
  6491. 3:48:21anti- join. So actually that's it. This
  6492. 3:48:23is the decision tree that I follow
  6493. 3:48:25usually as I'm writing a query. And you
  6494. 3:48:27might ask me how about the right join.
  6495. 3:48:30Well as you know me I don't have it at
  6496. 3:48:31all in my decision tree. So I don't use
  6497. 3:48:34it at all. Now by looking to this I can
  6498. 3:48:36tell you if I check most of the queries
  6499. 3:48:38that I write very often I use the left
  6500. 3:48:41join. So I can tell you this is my
  6501. 3:48:42favorite way on how to join tables. So
  6502. 3:48:45let me show you exactly
  6503. 3:48:49why. Usually I write queries in order to
  6504. 3:48:52do data analyzes. So in data analytics
  6505. 3:48:54you have always like starting points.
  6506. 3:48:56You have like a topic that you are
  6507. 3:48:58analyzing like the customer. So you have
  6508. 3:49:00always like a master table. So I always
  6509. 3:49:02start with the main table of my
  6510. 3:49:04analysis. So in my query I start from
  6511. 3:49:06this table from table A the main table.
  6512. 3:49:09And then what happens? The data is not
  6513. 3:49:11enough in this table. I need some extra
  6514. 3:49:13data that comes from another table like
  6515. 3:49:15the table B. So the table B is only here
  6516. 3:49:18like an additional data to the master
  6517. 3:49:20table. So I go and use the lift join in
  6518. 3:49:23order to connect the table B and then I
  6519. 3:49:25find another interesting information in
  6520. 3:49:27another table in table C. So same things
  6521. 3:49:29happens. I go and join the tables using
  6522. 3:49:31the lift join and so on. So I keep
  6523. 3:49:33connecting multiple tables to this main
  6524. 3:49:36table in the middle. And my query going
  6525. 3:49:38to look like this. always doing lift
  6526. 3:49:40joins with multiple tables. Now, of
  6527. 3:49:42course, you might say, "Yeah, but
  6528. 3:49:43sometimes you would like to see only the
  6529. 3:49:44matching data and so on. So, it makes
  6530. 3:49:47sense only to use the inner join." Well,
  6531. 3:49:49in order to do that, I can control
  6532. 3:49:50everything that I want to see in the
  6533. 3:49:52final results using the wear clause. So,
  6534. 3:49:55in the wear clause, I define exactly
  6535. 3:49:57what I want to see in the final result.
  6536. 3:49:59So, with that, I get like more
  6537. 3:50:00flexibility on whether I want to see the
  6538. 3:50:02matching, unmatching data and so on like
  6539. 3:50:04we done in the lift and join, right? So
  6540. 3:50:06as I'm analyzing data I tend very
  6541. 3:50:09frequently having this setup where I
  6542. 3:50:11start from the main table and I lift
  6543. 3:50:13join all other tables and with the word
  6544. 3:50:15conditions I control the final results.
  6545. 3:50:17So this is how I connect multiple tables
  6546. 3:50:20together. So now if I want to visual
  6547. 3:50:21this in like circles it's going to look
  6548. 3:50:23like this. We have the circle A. So this
  6549. 3:50:25is the master table the starting point.
  6550. 3:50:27I want to see all the data from table A
  6551. 3:50:30and I live join it then with another
  6552. 3:50:32table B and from table B I want to see
  6553. 3:50:34only the matching data. So it's like the
  6554. 3:50:36lift join. Now what going to happen? I'm
  6555. 3:50:38going to go and add another table. So
  6556. 3:50:40another circle the circle C. And from
  6557. 3:50:42the circle C, we want to see only the
  6558. 3:50:44matching data. And of course you can
  6559. 3:50:46keep adding circles to this. But it's
  6560. 3:50:48going to be always the same thing. And
  6561. 3:50:49in your circle going to has only the
  6562. 3:50:51matching data. So now as we learned we
  6563. 3:50:53can use joins in order to combine
  6564. 3:50:55multiple tables to get a complete big
  6565. 3:50:57picture about topic like the customers.
  6566. 3:50:59I would like to see everything about the
  6567. 3:51:01customers in the final results. So
  6568. 3:51:02either you're going to do it like me
  6569. 3:51:04where you start from the main table and
  6570. 3:51:05then go and lift join all other tables
  6571. 3:51:08or maybe you say you know what there is
  6572. 3:51:10no main table about the customer's data
  6573. 3:51:12all the tables are equally important
  6574. 3:51:14then you can go and join all those
  6575. 3:51:16tables using the inner join if you are
  6576. 3:51:18interested only on the match data so
  6577. 3:51:20what can happen if you have again those
  6578. 3:51:22circles from the A you need only the
  6579. 3:51:24matching data from B you need as well
  6580. 3:51:26only matching data and as well from the
  6581. 3:51:28third circle so you are interested only
  6582. 3:51:30on the overlapping between all all three
  6583. 3:51:32tables. So you will get only this
  6584. 3:51:34section where you have overlapping
  6585. 3:51:36between all three tables. So this is of
  6586. 3:51:38course another way on how to join
  6587. 3:51:40multiple tables. Okay. So now my friends
  6588. 3:51:42let's go back to scale in order to
  6589. 3:51:44practice how to join multiple tables.
  6590. 3:51:46Okay. So now let's have a task. This
  6591. 3:51:48going to be a little bit challenging. We
  6592. 3:51:49will be doing multi- joins using the
  6593. 3:51:52sales DB. Retrieve a list of all orders
  6594. 3:51:54along with the related customer product
  6595. 3:51:57and employee details. And for each order
  6596. 3:52:00display the following. We want to see
  6597. 3:52:01the order ID, the customer name, the
  6598. 3:52:04product name, sales price, salesperson
  6599. 3:52:07name. So there is a lot of things that
  6600. 3:52:08is going on. And the first thing that
  6601. 3:52:10you're going to notice it does now we
  6602. 3:52:11are using different database. We will be
  6603. 3:52:14not using the my database, we're going
  6604. 3:52:16to go and use the sales DB. So this is
  6605. 3:52:18the first thing that we have to do. So
  6606. 3:52:20instead of using my database, so we say
  6607. 3:52:23use sales DB and then execute it. We are
  6608. 3:52:26now connected to the sales DB. So this
  6609. 3:52:28is the first thing. So now if you are
  6610. 3:52:30reading this task there are a lot of
  6611. 3:52:31tables that are involved. We need the
  6612. 3:52:33orders, we need the customers, products
  6613. 3:52:36and employees. So there are like four
  6614. 3:52:38tables needed in this task and we need
  6615. 3:52:41different stuff from each table. So now
  6616. 3:52:43how I think about it well it is mainly
  6617. 3:52:45focusing on the table orders right? So
  6618. 3:52:47we need all the orders we cannot miss
  6619. 3:52:50any order here. So this sounds for me
  6620. 3:52:52this is the main table and then it says
  6621. 3:52:55along with that we need other
  6622. 3:52:56informations. So that means the other
  6623. 3:52:58tables are not that important like the
  6624. 3:53:00orders. So this gives me feeling about
  6625. 3:53:02what is the main table and this going to
  6626. 3:53:04be my starting points. So let's start
  6627. 3:53:06from that from the table orders. So
  6628. 3:53:08select star from and here you have to
  6629. 3:53:10pay attention that this database has
  6630. 3:53:13always a schema. It's called if you look
  6631. 3:53:15to the left side sales dot the table
  6632. 3:53:17name. So we have to write that now in
  6633. 3:53:19our query. So we're going to write it
  6634. 3:53:21over here sales dot and then the table
  6635. 3:53:23name orders. Let's go and execute it.
  6636. 3:53:25Now I know this is the first time that
  6637. 3:53:27you are querying this table. We have a
  6638. 3:53:29lot of informations here and as well we
  6639. 3:53:31have a lot of ids. Those ids going to
  6640. 3:53:33help us of course on joining our data
  6641. 3:53:36with the other tables. So what do we
  6642. 3:53:37need from here? We need the order ID. So
  6643. 3:53:39we have it over here. We're going to get
  6644. 3:53:42the order ID. This time the naming
  6645. 3:53:44convention is different. We don't have
  6646. 3:53:46like underscores and comm. We have
  6647. 3:53:48different type of namings. So be careful
  6648. 3:53:50with that. So what else do we need? We
  6649. 3:53:52need the sales. So if you go to the
  6650. 3:53:53right side over here, we have column
  6651. 3:53:55gold sales and we're going to go and
  6652. 3:53:57include it to the results. Now all the
  6653. 3:53:59other informations are actually not
  6654. 3:54:01needed, but I need those ids in order to
  6655. 3:54:04join it with the other tables. So now
  6656. 3:54:06what I'm going to do, I'm going to go
  6657. 3:54:07and give it an alias and all. So now I'm
  6658. 3:54:09going to go and assign it for each
  6659. 3:54:10column. This comes from the orders and
  6660. 3:54:13as well the same thing for the sales. So
  6661. 3:54:15that's it for now. And if I go and
  6662. 3:54:17execute it, I will get the orders and
  6663. 3:54:19the sales. All right, so that's all for
  6664. 3:54:20the first table. Let's go now and see
  6665. 3:54:22what do we need. We need the customer's
  6666. 3:54:24name. Well, actually we don't have this
  6667. 3:54:26piece of information in the orders. So
  6668. 3:54:28all what you have to do is to go and
  6669. 3:54:29explore in the other tables in order to
  6670. 3:54:31find this column. So how I usually do I
  6671. 3:54:34go and explore the tables like this. So
  6672. 3:54:36I write a symbol select from each
  6673. 3:54:39tables. So the customers. So now I go
  6674. 3:54:42and repeat this for each table inside
  6675. 3:54:44the database. So we have the customers,
  6676. 3:54:47employees, we have an orders, the orders
  6677. 3:54:52archive and as well the products. So now
  6678. 3:54:56I start exploring the table. So if I go
  6679. 3:54:58to the customers over here, we can see
  6680. 3:55:00we have here five customers and we can
  6681. 3:55:02see the names of the customers. So we
  6682. 3:55:04see the first name and the last name and
  6683. 3:55:06this is exactly what I need for my
  6684. 3:55:08query. Now of course we have to go and
  6685. 3:55:09connect this table with the orders. So
  6686. 3:55:12we need a common column. Usually it's
  6687. 3:55:13going to be the ID. So here we have the
  6688. 3:55:15customer ID and if you go and query the
  6689. 3:55:18orders you can find here as well the
  6690. 3:55:20customer ID. Now if you are working in
  6691. 3:55:21big projects you're going to have a lot
  6692. 3:55:23of tables and exploring each one of them
  6693. 3:55:25going to be really hard. So now of
  6694. 3:55:26course if you have like in the project
  6695. 3:55:28hundreds of tables it's going to be
  6696. 3:55:29really hard to explore each table. So
  6697. 3:55:31instead of that a good project a good
  6698. 3:55:33database usually has an entity
  6699. 3:55:35relationship model er model like the one
  6700. 3:55:38that we have for the course. And here
  6701. 3:55:40you can find easily the tables that you
  6702. 3:55:42have inside your database and as well
  6703. 3:55:44the relationship between them and this
  6704. 3:55:46is very important especially if you want
  6705. 3:55:49to join tables. So now by just looking
  6706. 3:55:50quickly to this diagram I can understand
  6707. 3:55:53okay there is an ID called customer ID
  6708. 3:55:56inside the table orders and it is like a
  6709. 3:55:59foreign key to the primary key the
  6710. 3:56:01customer ID. So that means if I want to
  6711. 3:56:03connect the orders with the customers I
  6712. 3:56:05have to use that customer ID. So as you
  6713. 3:56:07can see this is really nice
  6714. 3:56:08documentations and I can quickly
  6715. 3:56:09understand how to join the tables. So
  6716. 3:56:11now back to our query. Now what I'm
  6717. 3:56:13going to do I'm going to say lift join.
  6718. 3:56:15So with that I guarantee all the orders
  6719. 3:56:18going to be presented in the output and
  6720. 3:56:19I will see always 10 orders. So now
  6721. 3:56:21let's join it with the table customers
  6722. 3:56:23sales dot customers and let's give it an
  6723. 3:56:26alias like this. And now we're going to
  6724. 3:56:28build the joining condition. So it's
  6725. 3:56:30going to be the customer ID from the
  6726. 3:56:32table orders equal to the customer ID
  6727. 3:56:35from the table customers. So that SQL
  6728. 3:56:37understand how to match the two tables.
  6729. 3:56:40And now the two tables are connected and
  6730. 3:56:42I can get the informations now from the
  6731. 3:56:44customers. So see let's go and get the
  6732. 3:56:46first name and as well the last
  6733. 3:56:49name. So now let's go and execute it. So
  6734. 3:56:52now as you can see we have customers for
  6735. 3:56:54each order which is really nice. So with
  6736. 3:56:56that we got the customer name and the
  6737. 3:56:58order ID. Now the next one we need the
  6738. 3:57:00product name. So either you're going to
  6739. 3:57:02go here and start exploring. I think it
  6740. 3:57:04is inside the table products. And here
  6741. 3:57:06you can see we have the product. This is
  6742. 3:57:09the name of the products. And if you
  6743. 3:57:11check our ER diagram, you can see we can
  6744. 3:57:13connect the table orders with the
  6745. 3:57:15products using the product ID. So we
  6746. 3:57:18have the product ID in the left and as
  6747. 3:57:20well in the right. And now we can go and
  6748. 3:57:22build this join as well over here. So
  6749. 3:57:24again I go with a lift join. I don't
  6750. 3:57:26want to lose anything from the table
  6751. 3:57:27orders sales products and we give it an
  6752. 3:57:31alias P. Now the condition for that here
  6753. 3:57:34you have to be very focused. You want to
  6754. 3:57:36get the product from the orders. So you
  6755. 3:57:39say O dot product id equal to the
  6756. 3:57:43product ID from the table products. So
  6757. 3:57:46as you can see in the joins we are
  6758. 3:57:47always joining with the table orders.
  6759. 3:57:49Right? We are not trying to join for
  6760. 3:57:51example the customers with the products.
  6761. 3:57:53Always we are joining with the main
  6762. 3:57:55table. So with that we have connected
  6763. 3:57:57the third table and we can get the
  6764. 3:57:59information that we need. So we need the
  6765. 3:58:01products as I'm going to go and rename
  6766. 3:58:03it products name. So let's go and
  6767. 3:58:07execute it. And with that my friends I'm
  6768. 3:58:09getting now the product informations
  6769. 3:58:10from the table products. So we have the
  6770. 3:58:13sales as well and we need the price. So
  6771. 3:58:15if you go to the products you can see we
  6772. 3:58:17have as well price information. I forgot
  6773. 3:58:19about it. So let's go and get it as well
  6774. 3:58:21from the same table. price. So let's go
  6775. 3:58:24and execute it. And with that we have as
  6776. 3:58:26well the prices. Now the last column it
  6777. 3:58:28says we want to get the saleserson name.
  6778. 3:58:31So the name of the employee right now if
  6779. 3:58:33you go and explore as well we have here
  6780. 3:58:35employees table and execute it. You can
  6781. 3:58:37see we have here the name and the last
  6782. 3:58:39name of the employees and we have an ID.
  6783. 3:58:42So now we need this ID as well in the
  6784. 3:58:44orders. So you can see we have the
  6785. 3:58:46product ID, the customer ID. We already
  6786. 3:58:48used those two. But we have here one
  6787. 3:58:50more extra ID called the salesperson ID.
  6788. 3:58:52Of course, it is not called employee ID.
  6789. 3:58:54So here you might be a little bit
  6790. 3:58:56skeptical about it. That's why we have
  6791. 3:58:58to go and check again our ER diagram.
  6792. 3:59:00And as you can see the employee ID from
  6793. 3:59:02the employees, it is connected to the
  6794. 3:59:05salesperson ID. So that I have better
  6795. 3:59:07feeling about it and I understand. Okay,
  6796. 3:59:09I can connect the orders with the
  6797. 3:59:10employees using the salesperson ID. So
  6798. 3:59:13let's go and do that. I'm going to say
  6799. 3:59:15lift join. So as you can see I'm just
  6800. 3:59:17doing left joins sales dot employees as
  6801. 3:59:21e and the condition again very important
  6802. 3:59:24always the first table is included in
  6803. 3:59:26the join condition and here we're going
  6804. 3:59:28to say the sales person ID is equal to
  6805. 3:59:31the employee ID. So with that we have
  6806. 3:59:34connected as well the employees and we
  6807. 3:59:36will get as well the first name and the
  6808. 3:59:39last name. So perfect that's it. Let's
  6809. 3:59:42go and execute it. And as you can see
  6810. 3:59:44guys, now we are getting the name of the
  6811. 3:59:46salesperson. Now here comes an issue. As
  6812. 3:59:48you are joining multiple tables and you
  6813. 3:59:50are getting columns from different
  6814. 3:59:52tables, what can happen? You might
  6815. 3:59:53encounter this scenario where you have
  6816. 3:59:55the same names in multiple tables. So
  6817. 3:59:58now as you can see we have the first
  6818. 3:59:59name last name from the employees and as
  6819. 4:00:01well we have the first name last name
  6820. 4:00:02from the customers and it's going to be
  6821. 4:00:04really hard from the result to
  6822. 4:00:05understand what are we talking about? Is
  6823. 4:00:07it the customers? Is it the employee?
  6824. 4:00:09That's why in this scenario if you have
  6825. 4:00:10the same names we have to go and start
  6826. 4:00:13giving aliases. So for the first one
  6827. 4:00:15we're going to say customer first name
  6828. 4:00:18and as well for the last name we're
  6829. 4:00:20going to say customer last name. Same
  6830. 4:00:22thing for the employee. So let's say
  6831. 4:00:25employee first name or we can call it
  6832. 4:00:28the saleserson whatever employee last
  6833. 4:00:31name. So if you go and execute it now
  6834. 4:00:34it's going to be more clear. Here we are
  6835. 4:00:36talking about the name of the customer
  6836. 4:00:38and here we are talking about the name
  6837. 4:00:40of the employee. And again one more
  6838. 4:00:42thing if you are not using aliases it's
  6839. 4:00:43going to be an issue. So for example if
  6840. 4:00:45you go over here and you don't use the
  6841. 4:00:47table name before the column. So if I go
  6842. 4:00:49and remove it and execute it you will
  6843. 4:00:52see I'm getting an error. Now SQL can't
  6844. 4:00:54understand what are you talking about.
  6845. 4:00:56Is it the first name of the customer or
  6846. 4:00:58from the employees because you are not
  6847. 4:01:00specific about it. So you have to tell
  6848. 4:01:02SQL to which table belong this column.
  6849. 4:01:04It's very important to use a table name
  6850. 4:01:06or the alias before the column name.
  6851. 4:01:09Especially if you have the same column.
  6852. 4:01:11So now we will not get an error. And
  6853. 4:01:13with that we have solved the task. You
  6854. 4:01:14have really to pay attention about the
  6855. 4:01:17join keys. The condition you have to do
  6856. 4:01:19it correctly cuz as you can see now we
  6857. 4:01:21have a lot of tables and a lot of
  6858. 4:01:22columns and sometimes happens an issue
  6859. 4:01:24where you specify the wrong columns or
  6860. 4:01:27the joins and the result can makes at
  6861. 4:01:29all no sense. So always double check are
  6862. 4:01:31you using the correct keys in order to
  6863. 4:01:33join the tables. So with that you have
  6864. 4:01:35solved the task and this is exactly how
  6865. 4:01:37I join tables. I have always a starting
  6866. 4:01:39point from an important table and
  6867. 4:01:42everything else going to be left joined
  6868. 4:01:44and in my results if I want to remove
  6869. 4:01:46any scenario then I go and use the wear
  6870. 4:01:49clause. So this is how I join multiple
  6871. 4:01:51tables. Okay my friends. So with that
  6872. 4:01:53you have learned now everything about
  6873. 4:01:55how to join the tables in SQL and this
  6874. 4:01:57is very important to understand. Now
  6875. 4:01:59moving on to the second method on how to
  6876. 4:02:01combine your data from multiple tables.
  6877. 4:02:03We have the set operators. So we're
  6878. 4:02:05going to go and cover how to combine the
  6879. 4:02:07rows from multiple tables. So let's
  6880. 4:02:12go. All right, my friends. So now as we
  6881. 4:02:15learned before, in order to combine two
  6882. 4:02:17tables we have two methods. If you want
  6883. 4:02:19to combine the columns, we use the
  6884. 4:02:21joins. And we have learned all those
  6885. 4:02:23different types on how to combine data
  6886. 4:02:25using join. So we have covered this
  6887. 4:02:27section. But now if we want to combine
  6888. 4:02:28the rows of two tables, we can use the
  6889. 4:02:31set operators. And here we have four
  6890. 4:02:33different types. We have union, union
  6891. 4:02:35all, except and intersects. So now we're
  6892. 4:02:38going to go and deep dive into this word
  6893. 4:02:40on how to combine the rows of tables
  6894. 4:02:42using the set operators. And now of
  6895. 4:02:44course in this course we're going to
  6896. 4:02:45cover everything. So let's
  6897. 4:02:49go. All right. So now let's have a look
  6898. 4:02:52to the syntax of the set operators.
  6899. 4:02:54Okay. So now let's see that we have the
  6900. 4:02:55following query. we are selecting the
  6901. 4:02:57data from the customers. So this is our
  6902. 4:02:59first query or our first select
  6903. 4:03:01statements and we have another one which
  6904. 4:03:03is very similar where we are selecting
  6905. 4:03:05the informations from the employees and
  6906. 4:03:08this is our second select statement. So
  6907. 4:03:10now what we can do we can put between
  6908. 4:03:12those two queries a set operators like
  6909. 4:03:15for example the union. We can use of
  6910. 4:03:17course any other set operators like the
  6911. 4:03:18union all intersects except and so on.
  6912. 4:03:22So as you can see the syntax is very
  6913. 4:03:24simple. We have two different queries
  6914. 4:03:26and we just put between them the set
  6915. 4:03:28operator. So this is how the syntax of
  6916. 4:03:30the set operators looks like. All right
  6917. 4:03:32friends. So now we're going to talk
  6918. 4:03:33about the rules of the set operators.
  6919. 4:03:35And we're going to start with the rule
  6920. 4:03:37number one the SQL clauses. In each
  6921. 4:03:39individual select statements or query.
  6922. 4:03:41We can use almost all the SQL clauses
  6923. 4:03:44like where join group by having. But
  6924. 4:03:47there is only one exception with the
  6925. 4:03:49order by. Order by you can use it only
  6926. 4:03:51once and only at the end of the entire
  6927. 4:03:54query. So that means we cannot use order
  6928. 4:03:57by in each select statements or in each
  6929. 4:03:59query. We can use it only once and only
  6930. 4:04:02at the ends of the entire query. All
  6931. 4:04:04right. So about the syntax again here we
  6932. 4:04:05have our two select statements and in
  6933. 4:04:08between them we have the set operators.
  6934. 4:04:10So now in each query we can go and use
  6935. 4:04:12multiple stuff like the join where group
  6936. 4:04:15by having. So we can make each query
  6937. 4:04:18complex as we want. So everything is
  6938. 4:04:21allowed but not the order by the order
  6939. 4:04:24by must be always placed at the end of
  6940. 4:04:26the entire query. So if you want to sort
  6941. 4:04:28the result by the first name, you have
  6942. 4:04:30to use the order by exactly at the end.
  6943. 4:04:33So we are not allowed to use order by in
  6944. 4:04:36each query. Okay. Moving on to the rule
  6945. 4:04:38number two. The number of columns. The
  6946. 4:04:40number of columns in each query must be
  6947. 4:04:42the same. Okay. Okay. So now in order to
  6948. 4:04:44understand this rule, let's have this
  6949. 4:04:46very simple example. We're going to go
  6950. 4:04:47and select the first name and the last
  6951. 4:04:50name from the table sales customers. So
  6952. 4:04:54this is our first query, our first
  6953. 4:04:55select statements and let's say that I
  6954. 4:04:58have another one and we want to select
  6955. 4:05:00the first name last name but this time
  6956. 4:05:02from another table, the employees. So
  6957. 4:05:04with that we have our two queries and I
  6958. 4:05:06would like now to go and combine them
  6959. 4:05:08into one result. So we're going to go
  6960. 4:05:10and use the set operator union. Let's go
  6961. 4:05:13and execute it. So now as you can see in
  6962. 4:05:14the result we will get the first name
  6963. 4:05:16and last name from two tables the
  6964. 4:05:18customers and employees. And it is
  6965. 4:05:20working because we are fulfilling the
  6966. 4:05:21rule where it says the number of columns
  6967. 4:05:24must be the same in both queries. So how
  6968. 4:05:26many columns do we have in the first
  6969. 4:05:28query? We have two right and as well in
  6970. 4:05:30the second query we have two columns. So
  6971. 4:05:32that's why everything is working. So now
  6972. 4:05:34let's go and break the rule by adding
  6973. 4:05:36another column to the first query. So
  6974. 4:05:38let's say that I would like to have the
  6975. 4:05:40customer ID as well in the first query
  6976. 4:05:42and with that as you can see in the
  6977. 4:05:44first query we have three columns but in
  6978. 4:05:46the second we have only two. So let's go
  6979. 4:05:49and execute it. Now as you can see in
  6980. 4:05:51the result we will get an error where it
  6981. 4:05:52says if you are using union intersect
  6982. 4:05:54and all those set operators you must
  6983. 4:05:57have an equal number of columns between
  6984. 4:05:59queries. So this is the rule you have to
  6985. 4:06:02have the same number of columns in order
  6986. 4:06:03to repair it. So I'm going to do I'm
  6987. 4:06:05just going to remove the customer ID.
  6988. 4:06:06Okay. So here again we have two columns
  6989. 4:06:08and the second one as well two columns
  6990. 4:06:10and everything going to be working.
  6991. 4:06:12Okay. Moving on to the rule number
  6992. 4:06:13three. The data types of columns in each
  6993. 4:06:15query must match must be compatible in
  6994. 4:06:19matching. In order to check that what
  6995. 4:06:21we're going to do we're going to go to
  6996. 4:06:22the object explorer to the left side.
  6997. 4:06:24Let's go and browse the customers and
  6998. 4:06:26the columns. And as you can see we have
  6999. 4:06:28here the first name and last name with
  7000. 4:06:30the same data type. We have the vchar.
  7001. 4:06:32And if you go to the employees, you can
  7002. 4:06:34see as well the first name, last name
  7003. 4:06:36having varchar. So the first column is
  7004. 4:06:38varchchar from the first query and as
  7005. 4:06:40well for the employees and as well the
  7006. 4:06:43last name from the customers having the
  7007. 4:06:45same data type as the last name from
  7008. 4:06:47employees. So the data type is matching.
  7009. 4:06:50Now let's go and break this rule.
  7010. 4:06:52Instead of having the first name, I
  7011. 4:06:54would like to go and use the customer
  7012. 4:06:56ID. So now let's check the customer ID
  7013. 4:06:58on the left side. It is an int, an
  7014. 4:07:00integer. But the first name is
  7015. 4:07:03invarchar. So here we have a mismatch
  7016. 4:07:05between data types. Let's go and try to
  7017. 4:07:07execute it. So now we are getting an
  7018. 4:07:09error where it says SQL is trying to
  7019. 4:07:10convert the value Frank to an integer.
  7020. 4:07:13So what this means the first query is
  7021. 4:07:15always controlling everything the names
  7022. 4:07:17and as well the data types. So here we
  7023. 4:07:19have an integer and now scale is trying
  7024. 4:07:22as well to convert the first name values
  7025. 4:07:24to an integer and of course it will not
  7026. 4:07:26work because we have here characters
  7027. 4:07:28inside and it cannot convert characters
  7028. 4:07:30to an integer. So we have a mismatch
  7029. 4:07:32between data types between the customer
  7030. 4:07:34ID and the first name and that's why we
  7031. 4:07:36will get an error. The second column we
  7032. 4:07:38don't have an issue because it is
  7033. 4:07:40varchar in the first table and as well
  7034. 4:07:42for the second table. So now in order to
  7035. 4:07:44repair it either select a first name in
  7036. 4:07:46the first query or we can go over here
  7037. 4:07:48and say employee ID and with that if I
  7038. 4:07:52execute it we will not get any errors
  7039. 4:07:54because the employee ID is as well an
  7040. 4:07:56integer and we have a match in the data
  7041. 4:07:58types. So as you can see it's not enough
  7042. 4:08:00to have the same number of columns. You
  7043. 4:08:02have to have as well matching data types
  7044. 4:08:04between those two queries. Okay, let's
  7045. 4:08:06move to the next rule. Rule number four,
  7046. 4:08:08the order of columns. The order of
  7047. 4:08:10columns in each query must be as well
  7048. 4:08:12the same. Okay, so let's understand what
  7049. 4:08:14this means. Now we have here again the
  7050. 4:08:16same example where we are selecting the
  7051. 4:08:18ID and last name from customers and we
  7052. 4:08:20are combining it using union with the
  7053. 4:08:22employee ID and last name from the
  7054. 4:08:24employees. And as you can see everything
  7055. 4:08:25is working because we have the same
  7056. 4:08:27number of columns and we have a matching
  7057. 4:08:29data types. So now let's go and break
  7058. 4:08:31it. What I'm going to do I'm just going
  7059. 4:08:33to switch between those two columns. So
  7060. 4:08:35first I'm selecting the last name and
  7061. 4:08:37then the customer ID. So again I have
  7062. 4:08:39the same number of columns and the ID is
  7063. 4:08:42integer matching the ID of the employee
  7064. 4:08:44and the last name having the same data
  7065. 4:08:46type. So let's go and execute it. So
  7066. 4:08:49here again SQL going to throw an error
  7067. 4:08:51and says SQL is trying to convert the
  7068. 4:08:52value go back to an integer. So it's
  7069. 4:08:55like character to integer. It will not
  7070. 4:08:56work. So what happened here? I have here
  7071. 4:08:58the same informations. I have an ID and
  7072. 4:09:00last name and ID and last name. Well,
  7073. 4:09:02SQL doesn't work like this. SQL going to
  7074. 4:09:04go and map the first column from the
  7075. 4:09:06first query with the first column with
  7076. 4:09:08the second query. So it's going to go
  7077. 4:09:09and map last name to employee ID. And
  7078. 4:09:12since they have different data types,
  7079. 4:09:13SQL going to throw an error. So SQL
  7080. 4:09:16doesn't understand or don't know how to
  7081. 4:09:17map let's say the ID with the ID and
  7082. 4:09:20since they have different data types SQL
  7083. 4:09:21going to go and throw an error. So as
  7084. 4:09:23you can see here we have the same
  7085. 4:09:25informations between customers and
  7086. 4:09:27employees but they don't have the same
  7087. 4:09:29order. So SQL cannot go and map the
  7088. 4:09:32informations because of the names of the
  7089. 4:09:33columns. It's going to go and simply
  7090. 4:09:35just mapping the columns like this. The
  7091. 4:09:38first column from the first query with
  7092. 4:09:39the first column from the second query.
  7093. 4:09:42So as you can see in this rule you must
  7094. 4:09:44have the same order of the columns.
  7095. 4:09:46First the ID and then the last name and
  7096. 4:09:50with that it's going to work again. All
  7097. 4:09:52right moving on to the rule number five.
  7098. 4:09:54The column aliases column names that we
  7099. 4:09:56see in the output in the result is
  7100. 4:09:58defined and determined by the column
  7101. 4:10:00names of the first query the first
  7102. 4:10:03select statements. So that means the
  7103. 4:10:05first query is responsible of naming the
  7104. 4:10:07columns in the output. Okay. So let's
  7105. 4:10:10understand what this rule means. Again
  7106. 4:10:11we have the same example. The customer
  7107. 4:10:13ID, last name from customers, union,
  7108. 4:10:15employee ID, last name from employees.
  7109. 4:10:17So if you check closely the output, you
  7110. 4:10:19can see that in the output we have the
  7111. 4:10:21customer ID and not the employee ID.
  7112. 4:10:24Even though we have the ids from the
  7113. 4:10:26employee ID, but as you can see the
  7114. 4:10:28first query is controlling the naming of
  7115. 4:10:31the output. So since the first column
  7116. 4:10:34called the customer ID, you will see it
  7117. 4:10:36in the output as a customer ID. So the
  7118. 4:10:38naming of the like the next queries will
  7119. 4:10:41be totally ignored. So that's why if you
  7120. 4:10:43want to give aliases to the output,
  7121. 4:10:46you're going to go and do it only for
  7122. 4:10:47the first query. So for example, I go
  7123. 4:10:49over here and say instead of having
  7124. 4:10:51customer ID, I would like to call it as
  7125. 4:10:53an ID. So now if I go and execute it, as
  7126. 4:10:56you can see in the output, we will get
  7127. 4:10:58an ID. So I don't have to go and in each
  7128. 4:11:00query give this alias. So I don't have
  7129. 4:11:03to go over here and say yeah you are as
  7130. 4:11:05well the ID because it's enough to
  7131. 4:11:07define it from the first query. So
  7132. 4:11:09there's no need to give the same names
  7133. 4:11:12in the next queries. Let's take another
  7134. 4:11:14example where we would like to have an
  7135. 4:11:15alias for the last name. So I would like
  7136. 4:11:17to have it like this last name and let's
  7137. 4:11:21go and do it in the second query. So
  7138. 4:11:24last name let's go and execute it. So
  7139. 4:11:27now as you can see in the output, we
  7140. 4:11:29still have last name and there's no
  7141. 4:11:31underscore because this is totally
  7142. 4:11:33ignored from SQL. This is not the first
  7143. 4:11:36query. The first query says you are last
  7144. 4:11:38name without underscore. So again if you
  7145. 4:11:41want to do that we go over here. Let me
  7146. 4:11:42just get it and put it in the first
  7147. 4:11:45query. Let's go and execute it. So my
  7148. 4:11:47friends, the first query is very
  7149. 4:11:48important in order to give the names for
  7150. 4:11:51the output. So if you want to do aliases
  7151. 4:11:53and to rename stuff, do it only on the
  7152. 4:11:55first query. And as well the first query
  7153. 4:11:57controls the data types. All right. Now
  7154. 4:11:59to the last rule matching the correct
  7155. 4:12:02informations. If in your query you
  7156. 4:12:03fulfill all other rules and you don't
  7157. 4:12:05have an error in the SQL that doesn't
  7158. 4:12:08mean that your result is accurate and
  7159. 4:12:10correct. You are the only one that is
  7160. 4:12:12responsible of mapping the informations
  7161. 4:12:14between queries correctly because SQL
  7162. 4:12:17doesn't understand the content and the
  7163. 4:12:19informations of your tables of your
  7164. 4:12:21queries. And if you don't match the
  7165. 4:12:23informations correctly between the
  7166. 4:12:24queries, you will get inaccurate and
  7167. 4:12:27wrong results in the output. Okay. So
  7168. 4:12:29now back to our example. Let's say I
  7169. 4:12:30would like to get the first name and as
  7170. 4:12:34well the last name from the customers
  7171. 4:12:36and the same informations from the
  7172. 4:12:38employees. Let's go and execute it. Now
  7173. 4:12:40as you can see it's very nice where we
  7174. 4:12:42are getting the first name, last name
  7175. 4:12:43from both tables in one result and we
  7176. 4:12:46are fulfilling all the requirements in
  7177. 4:12:48SQL. Same numbers, same data types and
  7178. 4:12:50so on. Now let's go and make incorrect
  7179. 4:12:52results. So what I'm going to do, I'm
  7180. 4:12:53just going to swap the first name and
  7181. 4:12:56last name in the second query. So first
  7182. 4:12:58last name and then the first name. So
  7183. 4:13:01let's go and execute it. So now as you
  7184. 4:13:03can see we will get results because we
  7185. 4:13:04are fulfilling all other rules because
  7186. 4:13:07we have the same number of columns and
  7187. 4:13:09as well we have matching data types. So
  7188. 4:13:11the first one is character the first
  7189. 4:13:13name and the last name is as well
  7190. 4:13:14character. So SQL will just present the
  7191. 4:13:17result as you define it. But the result
  7192. 4:13:20is completely wrong because now we have
  7193. 4:13:22if you check the first column here the
  7194. 4:13:24first name. So here we can see last
  7195. 4:13:26names inside the first names. For
  7196. 4:13:28example, Brown and Baker those are last
  7197. 4:13:30names but we can see them inside the
  7198. 4:13:32first name. And the same thing in the
  7199. 4:13:34last name. We now we can see first names
  7200. 4:13:36inside it. Mary, Carol, they are all
  7201. 4:13:39first names. So as you can see the
  7202. 4:13:41result has really bad data quality. We
  7203. 4:13:42are now mixing stuff and it doesn't
  7204. 4:13:44makes any sense. But SQL will not know
  7205. 4:13:47that because SQL doesn't know the
  7206. 4:13:49information the content of your data.
  7207. 4:13:52It's just mapping the data types. So
  7208. 4:13:54first name is varchchar the last name as
  7209. 4:13:56well vchar. Everything is fine and you
  7210. 4:13:59will get the results. So my friends you
  7211. 4:14:01are responsible of having the same
  7212. 4:14:03informations mapped between the two
  7213. 4:14:05queries and not having an error from a
  7214. 4:14:07skill doesn't mean that we have now
  7215. 4:14:09correct results. So pay attention to the
  7216. 4:14:11informations that you are mapping
  7217. 4:14:13between the two queries. All right. So
  7218. 4:14:15those are the rules of the set
  7219. 4:14:17operators. So the first one is that the
  7220. 4:14:19order by can only be used once at the
  7221. 4:14:21end of the entire query and all queries
  7222. 4:14:24must have the same number of columns,
  7223. 4:14:26the matching data types, the same order
  7224. 4:14:29of columns and the first query always
  7225. 4:14:31control the names and the aliases of the
  7226. 4:14:34result set and as well the data type.
  7227. 4:14:36And the last rule is that make sure that
  7228. 4:14:38you are mapping the correct informations
  7229. 4:14:41to each others between queries. So those
  7230. 4:14:43are the rules of the set
  7231. 4:14:48operators. Okay. So what is union? Union
  7232. 4:14:51going to go and return all distinct
  7233. 4:14:53unique rows from both queries. So that
  7234. 4:14:56means it's going to go and combine
  7235. 4:14:57everything and all the rows going to be
  7236. 4:14:59presented at the output. So since it
  7237. 4:15:02says all distinct unique rows that means
  7238. 4:15:05union going to go and remove all
  7239. 4:15:07duplicates from the combined result set.
  7240. 4:15:10So union going to make sure that each
  7241. 4:15:12row going to appear only once. All
  7242. 4:15:14right. So now let's have this very
  7243. 4:15:15simple example. We have two sets of
  7244. 4:15:17data. We have the customers where we
  7245. 4:15:19have five customers with the first names
  7246. 4:15:22and as well we have another set called
  7247. 4:15:23employees and we have as well the first
  7248. 4:15:25names of the employees and we have five
  7249. 4:15:28employees. And now if you take a look to
  7250. 4:15:29the first names you can see that we have
  7251. 4:15:31the same persons as a customers and as
  7252. 4:15:33well as employees. We have given and
  7253. 4:15:36marry in both sets of data. So now how
  7254. 4:15:38is k going to execute union it's going
  7255. 4:15:40to go and return everyone from customers
  7256. 4:15:43and everyone from the employees. But now
  7257. 4:15:45since we have given and married twice in
  7258. 4:15:47the output we're going to have them only
  7259. 4:15:49once. So this is how the union works. It
  7260. 4:15:51going to go and return everyone from two
  7261. 4:15:53sets but without duplicates. All right.
  7262. 4:15:55So now we have the following task and it
  7263. 4:15:57says combine the data from employees and
  7264. 4:15:59customers into one table. So that means
  7265. 4:16:02in one table we want to combine all
  7266. 4:16:04informations from employees and
  7267. 4:16:05customers. So which informations do we
  7268. 4:16:08need? This is the first question that I
  7269. 4:16:09usually ask myself. So in order to do
  7270. 4:16:11that first we have to explore the data.
  7271. 4:16:13So select star from sales customers and
  7272. 4:16:18then semicolon. Then I'm going to write
  7273. 4:16:20another query select star from sales and
  7274. 4:16:24employees and semicolon. So now why I'm
  7275. 4:16:27using two different semicolons because
  7276. 4:16:29I'm telling SQL we have now two separate
  7277. 4:16:31queries. They have nothing to do with
  7278. 4:16:32each others. And if you go and execute
  7279. 4:16:35it like this. And now in the output you
  7280. 4:16:36can see we got two result grids. The
  7281. 4:16:39first result grid is for the first query
  7282. 4:16:41and the second one for the second query.
  7283. 4:16:44So they have nothing to do with each
  7284. 4:16:45others. I just want to explore those two
  7285. 4:16:47tables in order to understand how I'm
  7286. 4:16:48going to map those informations. So now
  7287. 4:16:50if we check those two tables you can see
  7288. 4:16:52that both of them has ids. So we can map
  7289. 4:16:55those informations right. Both of them
  7290. 4:16:57has as well first name last name. So
  7291. 4:17:00that means I can go and map the first
  7292. 4:17:02name and last name together. Now in the
  7293. 4:17:04customers we have country but we don't
  7294. 4:17:07have this informations in the employee.
  7295. 4:17:09So we have to go and ignore it. And we
  7296. 4:17:11have as well here score where we don't
  7297. 4:17:13have a score for the employees. That
  7298. 4:17:15means I can go and map three
  7299. 4:17:17informations between the customers and
  7300. 4:17:19employees. Now of course we can go and
  7301. 4:17:21think do we need really the ids because
  7302. 4:17:23it doesn't make really any sense to have
  7303. 4:17:24the ids in the tables. It's not anymore
  7304. 4:17:27unique because we have here the custom
  7305. 4:17:28ID one and employee one. So I think we
  7306. 4:17:31can go and ignore it. So the only really
  7307. 4:17:33two informations that is useful to map
  7308. 4:17:35is the first name and last name. So now
  7309. 4:17:37let's go and add those two informations.
  7310. 4:17:39So we need the first name, last name and
  7311. 4:17:42the same informations as well from the
  7312. 4:17:44employees. But now we want everything to
  7313. 4:17:46be in one query. That's why I'm going to
  7314. 4:17:48go and remove the semicolons. And now we
  7315. 4:17:51have to go and use set operators between
  7316. 4:17:52those two queries. And now in order to
  7317. 4:17:54combine the data we have two options
  7318. 4:17:56either union or union all in this
  7319. 4:17:58example it doesn't mention anything
  7320. 4:18:00about duplicates and so on. I would like
  7321. 4:18:02to go with the union in order to remove
  7322. 4:18:04the duplicates if there is any. So
  7323. 4:18:06that's it. Let's go and execute it. Now
  7324. 4:18:09as you can see in the output we have
  7325. 4:18:10only one result because we have only one
  7326. 4:18:12big query. And now we have the first
  7327. 4:18:14names and last names from the customers
  7328. 4:18:16and employees. And now one more thing
  7329. 4:18:18about the order of the queries. It
  7330. 4:18:20doesn't matter whether we start with the
  7331. 4:18:21employees or with the customers. we will
  7332. 4:18:23get the exact same results but pay
  7333. 4:18:25attention to the naming of the columns.
  7334. 4:18:27Always the first query controls the
  7335. 4:18:29names but since now they have the same
  7336. 4:18:31naming so it should not be a problem. So
  7337. 4:18:33if I go and switch those two tables and
  7338. 4:18:36start it again we will get exact same
  7339. 4:18:38results. So now let's understand how
  7340. 4:18:40scale did combine the data using the
  7341. 4:18:43union. Okay. So now we have here the
  7342. 4:18:44results from the first query and the
  7343. 4:18:46second query employees and customers and
  7344. 4:18:48we are combining the data using union.
  7345. 4:18:50The first step in SQL is that it's going
  7346. 4:18:52to go and take the columns from the
  7347. 4:18:54first query which is from the employees.
  7348. 4:18:56So it's going to take the first name
  7349. 4:18:58last name as a column name to the
  7350. 4:19:00results. And now the next that is going
  7351. 4:19:02to go and start combining the rows
  7352. 4:19:04between those two tables. So first going
  7353. 4:19:06to go and take the rows from employees
  7354. 4:19:08and as well going to check whether there
  7355. 4:19:10is duplicates in the data. So as you can
  7356. 4:19:12see we don't have here any duplicates.
  7357. 4:19:13So we're going to have the five
  7358. 4:19:15employees. And now the next step is
  7359. 4:19:17going to start adding rows from the
  7360. 4:19:18second query from the customers very
  7361. 4:19:21carefully without generating any
  7362. 4:19:22duplicates. We don't have it in the
  7363. 4:19:24output. That's why it's still going to
  7364. 4:19:25go and add it to the result. Append it.
  7365. 4:19:28And then the next customer we have Kevin
  7366. 4:19:30Brown. As you can see, we have it
  7367. 4:19:31already in the results. That's why will
  7368. 4:19:33not go and add it to the result.
  7369. 4:19:35Otherwise, it's going to go and generate
  7370. 4:19:36duplicates. So it's still going to
  7371. 4:19:38ignore this customer. The same thing for
  7372. 4:19:40Mary. We have Mary as well in the
  7373. 4:19:42results. So it's going to skip it. And
  7374. 4:19:44then we're going to go to the mark. As
  7375. 4:19:45you can see, we don't have mark in the
  7376. 4:19:47results. That's why SQL going to go and
  7377. 4:19:49take this customer and put it in the
  7378. 4:19:51output. And then the last one, we have
  7379. 4:19:53Anna. We don't have Anna in the results.
  7380. 4:19:55That's why SQL can go and as well add it
  7381. 4:19:57to the results. And now with this, SQL
  7382. 4:19:59did combine the rows between those two
  7383. 4:20:01tables. And we have here eight persons.
  7384. 4:20:03So as you can see, SQL is combining the
  7385. 4:20:05data, but very carefully not generating
  7386. 4:20:07any duplicates. All right. So that's it.
  7387. 4:20:09This is how the union operator works.
  7388. 4:20:15Okay. So now union all union union all
  7389. 4:20:17going to go and return all rows from
  7390. 4:20:19both queries. So it's very similar to
  7391. 4:20:21union. It going to go and combine all
  7392. 4:20:23the rows and everything going to be
  7393. 4:20:25presented in the combined result set.
  7394. 4:20:27But the big difference to the union all
  7395. 4:20:30will not remove any duplicates. It is
  7396. 4:20:32the only set operators that doesn't
  7397. 4:20:35remove duplicates and it going to show
  7398. 4:20:37all the rows as it is. So if you have a
  7399. 4:20:40row 10 times from the query, you will
  7400. 4:20:42find it as well in the output 10 times.
  7401. 4:20:44Now you might ask me when to use union
  7402. 4:20:46and when to use union all. I'm going to
  7403. 4:20:48say that there is one big difference
  7404. 4:20:50between them is that union all has way
  7405. 4:20:53better performance and it's faster than
  7406. 4:20:55the union. And that's because union all
  7407. 4:20:58doesn't perform additional steps like
  7408. 4:21:00removing duplicates. So my friends that
  7409. 4:21:02means if you know already that in my
  7410. 4:21:04queries there is no duplicates. I know
  7411. 4:21:06my tables. I know my queries. There's no
  7412. 4:21:08duplicates. Don't use union and always
  7413. 4:21:11use union all because you will get
  7414. 4:21:13better performance. Another scenario for
  7415. 4:21:15the union all is that I would like to
  7416. 4:21:16see the duplicate. I'm doing data
  7417. 4:21:18quality checks and I would like to see
  7418. 4:21:19whether there is duplicate after I
  7419. 4:21:22combine multiple queries. So in this
  7420. 4:21:24situation I go and use as well the union
  7421. 4:21:26all. Now we have again the same example.
  7422. 4:21:28We have the customers and employees and
  7423. 4:21:30we have as well the same persons Kevin
  7424. 4:21:32and Mary as customers and as well as
  7425. 4:21:34employees. So now if you want to combine
  7426. 4:21:36the data using union all it going to
  7427. 4:21:38return all rows including duplicates. So
  7428. 4:21:41that means SQL going to go and execute
  7429. 4:21:43union all like this it going to return
  7430. 4:21:45everything from customers and everything
  7431. 4:21:47from employees and Kevin and Mary going
  7432. 4:21:50to be presented twice in the output. So
  7433. 4:21:52as you can see union all is returning
  7434. 4:21:54all the rows as it is from the two
  7435. 4:21:57result sets and if there's duplicates in
  7436. 4:21:59the sets we will get as well duplicate
  7437. 4:22:01in the output. So Kevin going to be
  7438. 4:22:02existing twice in the output and marry
  7439. 4:22:05as well twice. So this is how the union
  7440. 4:22:07all works. All right. So now we have
  7441. 4:22:08very similar SQL task and it says
  7442. 4:22:10combine the data from employees and
  7443. 4:22:12customers into one table including
  7444. 4:22:15duplicates. So it's exactly like the
  7445. 4:22:17last task but this time in the task we
  7446. 4:22:19are saying include duplicates. So we
  7447. 4:22:21cannot go and use union. We have now to
  7448. 4:22:23go and use union all. We will have the
  7449. 4:22:25exact same query. So we are selecting
  7450. 4:22:27the employees first last name and as
  7451. 4:22:29well customers first last name. And now
  7452. 4:22:31instead of using union, we're going to
  7453. 4:22:33go and use union all. So all what we
  7454. 4:22:35have to do is that to go over here and
  7455. 4:22:36say union all. So now pay attention to
  7456. 4:22:39this. As you can see in the union
  7457. 4:22:40previously, we got eight records or
  7458. 4:22:43eight persons from the output. So now
  7459. 4:22:46let's go and execute it and check the
  7460. 4:22:48results. Now as you can see we got now
  7461. 4:22:4910 persons instead of eight. And that's
  7462. 4:22:51because we have five customers and five
  7463. 4:22:54employees and we have duplicates inside
  7464. 4:22:56the data. We have two duplicates. Now if
  7465. 4:22:57you check we have here Mary and as well
  7466. 4:22:59over here we have Mary and same goes for
  7467. 4:23:01given we have given over here and as
  7468. 4:23:03well here. So we have duplicates inside
  7469. 4:23:05the data and SQL just combine the two
  7470. 4:23:07tables. Okay. So now we're going to
  7471. 4:23:08understand how SQL execute union all in
  7472. 4:23:10order to combine data. All right. Again
  7473. 4:23:12we have the two results from queries. We
  7474. 4:23:14have the employees and customers and SQL
  7475. 4:23:16going to do the same steps. First going
  7476. 4:23:17to go and get the column names from the
  7477. 4:23:19first query and put it in the output.
  7478. 4:23:21It's still going to go and take all the
  7479. 4:23:23employees and put it in the output
  7480. 4:23:25without checking anything. So that means
  7481. 4:23:27if there is duplicates in the data, it's
  7482. 4:23:29going to be presented as well in the
  7483. 4:23:30output. It's very simple. Now it's going
  7484. 4:23:33to go to the second step and as well
  7485. 4:23:34take all the customers and append it
  7486. 4:23:37into the output like this. So that's it.
  7487. 4:23:40It's very fast. It's going to go and
  7488. 4:23:42just combine all the rows from the
  7489. 4:23:44employees and all the rows from the
  7490. 4:23:45customers. And with that, we're going to
  7491. 4:23:46get that 10 persons. And as you can see,
  7492. 4:23:48we have duplicates in the data. So we
  7493. 4:23:50have marry twice and given as well
  7494. 4:23:52twice. And that's why union all is the
  7495. 4:23:54fastest. It doesn't have any extra steps
  7496. 4:23:56or checks. Just taking all rows from all
  7497. 4:23:59queries and put it in the output. All
  7498. 4:24:01right. So as you can see it's very
  7499. 4:24:02simple, right? So that's all for the
  7500. 4:24:04union
  7501. 4:24:08all. Okay. So what is except sometime we
  7502. 4:24:11call it minus in other databases but in
  7503. 4:24:13SQL server we call it except. So it's
  7504. 4:24:15going to go and return a distinct rows
  7505. 4:24:17from the first query that are not found
  7506. 4:24:20in the second query. So from this
  7507. 4:24:22definition we can understand that the
  7508. 4:24:24order of the queries can affect the
  7509. 4:24:26final result. There is a first query and
  7510. 4:24:29a second query. So it is the only set
  7511. 4:24:31operator where you have to pay attention
  7512. 4:24:33to the order of the queries. And as well
  7513. 4:24:35it's like the others. It's going to go I
  7514. 4:24:37remove the duplicates from the result
  7515. 4:24:39set. All right. Again we have this very
  7516. 4:24:40simple example. We have two sets, five
  7517. 4:24:42customers, five employees and there is
  7518. 4:24:44the same persons as a customer and as
  7519. 4:24:47employees Kevin and Mary. So now we're
  7520. 4:24:48going to go and combine those two sets
  7521. 4:24:50using the excepts or sometime we call it
  7522. 4:24:52minus. So it says it's going to return
  7523. 4:24:54unique rows in the first table that are
  7524. 4:24:56not in the second table. So what going
  7525. 4:24:58to happen? What is the first table?
  7526. 4:25:00Let's say the customers on the left
  7527. 4:25:01side. So here we have five persons.
  7528. 4:25:03Joseph, Mark, Anna, Kevin and Mary. So
  7529. 4:25:06now the rule is we need the customers
  7530. 4:25:08that are not employees. So it's safe for
  7531. 4:25:11Joseph, Mark and Anna because they are
  7532. 4:25:13not existing in the second set. That's
  7533. 4:25:16why SQL going to return those three
  7534. 4:25:18values. But now for the two customers
  7535. 4:25:20given and marry here there is an issue.
  7536. 4:25:22Given and marry they are members of the
  7537. 4:25:24second set. The second table the
  7538. 4:25:26employees. That's why SQL going to go
  7539. 4:25:28and exclude them from the output because
  7540. 4:25:31they are not fulfilling the rule. So in
  7541. 4:25:33the output we will get only three
  7542. 4:25:35customers and all the values from
  7543. 4:25:37employees and the common values between
  7544. 4:25:39customers and employees will be excluded
  7545. 4:25:42from the output. So this is how the
  7546. 4:25:45except works. All right. So let's have a
  7547. 4:25:47very simple skill task and it says find
  7548. 4:25:49the employees who are not customers at
  7549. 4:25:52the same time. Okay. So let's see how
  7550. 4:25:53we're going to solve that. We're going
  7551. 4:25:55to stay with the same queries as usual.
  7552. 4:25:56We have the employees and the customers
  7553. 4:25:59but instead of having union all we're
  7554. 4:26:00going to use the set operator except. So
  7555. 4:26:03now since we are using except we have to
  7556. 4:26:04make sure that the order of the queries
  7557. 4:26:06are correct. So the first query is the
  7558. 4:26:09employees which is correct because we
  7559. 4:26:11have to find the employees who are not
  7560. 4:26:14customers at the same time. So we are
  7561. 4:26:15focusing on the employees. The first
  7562. 4:26:17table is correct and the second table is
  7563. 4:26:20customers. If the task says find the
  7564. 4:26:22customers who are not employees at the
  7565. 4:26:24same time then we have to go and switch
  7566. 4:26:26it. We have first to query the
  7567. 4:26:28customers. So now everything is correct.
  7568. 4:26:30Let's go and execute it. And now in the
  7569. 4:26:32output we see three employees who are
  7570. 4:26:34not customers at the same time. So we
  7571. 4:26:36have Carol, Frank and Michael. But as we
  7572. 4:26:38know we have five employees Kevin and
  7573. 4:26:40Mary. They are not here in the result
  7574. 4:26:41because they are customers as well. So
  7575. 4:26:44now let me show you what can happen if I
  7576. 4:26:46just switch those informations. So we
  7577. 4:26:48start with customers and then with
  7578. 4:26:50employees. Let's go and execute it. As
  7579. 4:26:52you can see, we're going to get
  7580. 4:26:53completely different results. Now we are
  7581. 4:26:55getting customers informations. And now
  7582. 4:26:57in the output, we got three customers
  7583. 4:26:59who are not employees at the same time.
  7584. 4:27:01This is not what we want from this task.
  7585. 4:27:03So if you do it like this, it's going to
  7586. 4:27:05be incorrect. So pay always attention
  7587. 4:27:07here to the order of that query. So now
  7588. 4:27:09let's go and correct it. So we're going
  7589. 4:27:10to have first employees and then
  7590. 4:27:12customers. Let's execute it. And now
  7591. 4:27:14let's go and understand how SQL execute
  7592. 4:27:17the except operator. All right. So again
  7593. 4:27:19we have the results from the two queries
  7594. 4:27:20or from two tables and now we are doing
  7595. 4:27:23except between them. So let's see how is
  7596. 4:27:25going to execute it. It's going to take
  7597. 4:27:26as usual first the names from the first
  7598. 4:27:29query from the employees and put it in
  7599. 4:27:31the output. And now SQL going to present
  7600. 4:27:33data only from the first query in the
  7601. 4:27:36output. And it going to go and use the
  7602. 4:27:38customers only as a check. So SQL will
  7603. 4:27:41not put any data or rows from the
  7604. 4:27:43customers. It will just use the second
  7605. 4:27:45query as a lookup in order to check the
  7606. 4:27:47data. So, it's going to start with the
  7607. 4:27:49first employee, Frankly. Do we have
  7608. 4:27:52Frankly in the customers? Well, no, we
  7609. 4:27:54don't have it. That's why it's going to
  7610. 4:27:56accept it and put it in the output. And
  7611. 4:27:58then in the next step, it's still going
  7612. 4:28:00to go to the second employee and check.
  7613. 4:28:02As you can see, we have it already in
  7614. 4:28:03the customers. So, SQL going to go and
  7615. 4:28:05ignore it. It's not allowed to be in the
  7616. 4:28:07output. The same thing for Mary. We have
  7617. 4:28:10it as well in the customers. That's why
  7618. 4:28:12it will not be presented in the output.
  7619. 4:28:14So Michael, we don't have a Michael in
  7620. 4:28:17customers. That's why it can be
  7621. 4:28:19presented in the output. And as well for
  7622. 4:28:21Carol, the same thing. We don't have
  7623. 4:28:23Carol as a customer and we're going to
  7624. 4:28:25have it in the output. So as you can
  7625. 4:28:28see, we will get data only from the
  7626. 4:28:29first table and the second table only
  7627. 4:28:31going to be used in order to check the
  7628. 4:28:33informations from it. So we don't have
  7629. 4:28:35in the output any customers, it's only
  7630. 4:28:36employees. So now let's check quickly
  7631. 4:28:38what going to happen if we switch the
  7632. 4:28:39tables. So now we have the customers as
  7633. 4:28:41the first table. SQL going to take the
  7634. 4:28:43columns from the first table and it's
  7635. 4:28:45going to start presenting the customers
  7636. 4:28:47informations in the output and going to
  7637. 4:28:49go and use the employees only as a
  7638. 4:28:51lookup. So do we have Joseph? We don't
  7639. 4:28:53have it in the employee. And then Kevin
  7640. 4:28:56and Mary we have it already in the
  7641. 4:28:58employees and Mark and Anna are not part
  7642. 4:29:01of the employees that's why can go and
  7643. 4:29:04present the results in the output like
  7644. 4:29:06this. So now as you can see SQL is
  7645. 4:29:07focusing on the table customers and we
  7646. 4:29:09are getting data from the customers not
  7647. 4:29:11from the employees. Employees is only as
  7648. 4:29:13a check. So with that we understand the
  7649. 4:29:15order of the queries is very important
  7650. 4:29:17for the exceptions. We will get
  7651. 4:29:18different results if we have different
  7652. 4:29:20order. All right. So that's all for the
  7653. 4:29:22except
  7654. 4:29:26operator. Okay. So what is intersect?
  7655. 4:29:29Intersect going to go and return only
  7656. 4:29:31row that are common in both queries.
  7657. 4:29:34It's something very similar to the inner
  7658. 4:29:36join and as well here it's going to go
  7659. 4:29:38and remove duplicates. So there will be
  7660. 4:29:39no duplicates in the output. All right.
  7661. 4:29:41Again we have this very simple example
  7662. 4:29:42where we have five customers and five
  7663. 4:29:44employees and now we're going to combine
  7664. 4:29:46them using the intersect. So what
  7665. 4:29:48intersect does it going to go and return
  7666. 4:29:50common rows between two tables. So how
  7667. 4:29:53SQL going to execute it? It's very
  7668. 4:29:55simple. SQL going to go and search for
  7669. 4:29:57the common values. So what are the
  7670. 4:29:59common values? It's given and marry and
  7671. 4:30:02SQL going to return only those two
  7672. 4:30:04values given and marry and all others
  7673. 4:30:06going to be excluded from the results.
  7674. 4:30:09It's very simple, right? It's going to
  7675. 4:30:10go and return only the common values and
  7676. 4:30:12this is how the intersect works in SQL.
  7677. 4:30:15Okay, let's have this simple task and it
  7678. 4:30:16says find the employees who are also
  7679. 4:30:19customers. So we're going to have the
  7680. 4:30:20same queries employees and customers but
  7681. 4:30:23instead of having except we're going to
  7682. 4:30:24go and use intersect. Since we are
  7683. 4:30:27finding the common informations between
  7684. 4:30:29the employees and customers it's very
  7685. 4:30:31simple and straightforward. Let's go and
  7686. 4:30:33execute it. And with that we're going to
  7687. 4:30:34get the Kevin and Mary. This is the two
  7688. 4:30:37persons that are at the same time
  7689. 4:30:39employees and customers. And of course
  7690. 4:30:41here we don't have to pay attention to
  7691. 4:30:42the order of the queries. It's going to
  7692. 4:30:44be the same if we say find the customers
  7693. 4:30:46who are also employees. So if you go and
  7694. 4:30:48just switch for example the customers
  7695. 4:30:50with employees you will see that we will
  7696. 4:30:53get the exact same results. So it
  7697. 4:30:55doesn't matter which query is first
  7698. 4:30:56again pay attention to the first query
  7699. 4:30:58that define the names. So now let's
  7700. 4:31:00understand how is scale execute
  7701. 4:31:01intersects behind the scenes. Okay again
  7702. 4:31:04our two tables and now we are doing
  7703. 4:31:05intersects. So as usual SQL going to go
  7704. 4:31:08and take the columns from the first
  7705. 4:31:09query and now we're going to go and find
  7706. 4:31:11the common data between those two
  7707. 4:31:13results. So it's going to do it row by
  7708. 4:31:15row. So we have the employee Frank. Do
  7709. 4:31:16we have it as a customer? No. So it will
  7710. 4:31:19not be in the output. Given brown, we
  7711. 4:31:21have it in the employees and as well as
  7712. 4:31:23a customer over here. So that's why we
  7713. 4:31:25will get it in the output. The same
  7714. 4:31:27thing for Mary. So we have Mary as
  7715. 4:31:29employee and as well as customer. So
  7716. 4:31:31we're going to have it in the output.
  7717. 4:31:33Michael and Carol, they are not
  7718. 4:31:35customers. They are only employees.
  7719. 4:31:37That's why we will not get it in the
  7720. 4:31:38output. The same thing goes for the
  7721. 4:31:40customers. Joseph, we don't have Mark.
  7722. 4:31:42We don't have Anna because they are not
  7723. 4:31:44employees. So with that we're going to
  7724. 4:31:46get only the common informations between
  7725. 4:31:48the two tables or two queries and it
  7726. 4:31:50doesn't matter whether we start with
  7727. 4:31:51customer or with employees we will get
  7728. 4:31:53at the end the same information. All
  7729. 4:31:55right so that's all it's very simple
  7730. 4:31:57right this is how the intersect works in
  7731. 4:31:59SQL.
  7732. 4:32:04All right friends, so now we come to the
  7733. 4:32:05part where I'm going to show you how I
  7734. 4:32:07usually use the set operators in my
  7735. 4:32:10projects for data analyszis or for data
  7736. 4:32:12engineering. So here are the most
  7737. 4:32:14important use cases for the set
  7738. 4:32:16operators. All right, the first use case
  7739. 4:32:18is combining similar tables before doing
  7740. 4:32:20data analyzes. In some scenarios, we
  7741. 4:32:23want to generate a report and we end up
  7742. 4:32:25writing similar queries on top of
  7743. 4:32:27similar tables and we go at the end and
  7744. 4:32:29join all the results from the queries in
  7745. 4:32:32order to present the final report. And
  7746. 4:32:34now instead of doing that what we can do
  7747. 4:32:36first we can go and combine all the
  7748. 4:32:38similar informations into one table and
  7749. 4:32:40then we can do on top of it a query a
  7750. 4:32:42data analyzes in order to generate a
  7751. 4:32:44report and we can do that using the
  7752. 4:32:47union or union all. Let's have few
  7753. 4:32:49examples. So let's say that we have four
  7754. 4:32:51tables employees, customers, suppliers
  7755. 4:32:53and students. So as you can see all of
  7756. 4:32:55them are sharing the same informations.
  7757. 4:32:57They hold data about persons. So now
  7758. 4:33:00let's say that you are generating a
  7759. 4:33:01report that requires all the individuals
  7760. 4:33:04in the organization in the database. So
  7761. 4:33:06what you're going to end up doing is
  7762. 4:33:08writing SQL query for the employees,
  7763. 4:33:10another one for customers and as well
  7764. 4:33:13for the suppliers and the students. And
  7765. 4:33:15then you're going to go and merge all
  7766. 4:33:16the results from those queries into the
  7767. 4:33:19final report. Now the issue with this
  7768. 4:33:21setup is that you are having a lot of
  7769. 4:33:23queries, a lot of similar queries. So
  7770. 4:33:25you have it here four times. And now
  7771. 4:33:27what might happen is that you go and
  7772. 4:33:29change the logic of the first two
  7773. 4:33:31queries and you forget later to do it
  7774. 4:33:33for the other two and you will get
  7775. 4:33:35really inconsistent data in the reports.
  7776. 4:33:37So instead of that what we can do we can
  7777. 4:33:39go and use the set operators in order to
  7778. 4:33:42combine first all those tables in one
  7779. 4:33:45big table. So what we're going to do
  7780. 4:33:46we're going to go and use a union in
  7781. 4:33:48order to combine those four tables into
  7782. 4:33:51the table persons. So we're going to
  7783. 4:33:53have it like this. So we will get all
  7784. 4:33:54the rows from the employees and put it
  7785. 4:33:56in the persons all the rows from the
  7786. 4:33:58customers from the suppliers and as well
  7787. 4:34:01from the students and put everything in
  7788. 4:34:03one big table that holds all the
  7789. 4:34:06informations about the individuals that
  7790. 4:34:07we have inside our database. And now the
  7791. 4:34:10next step after we combine the data now
  7792. 4:34:12we write an SQL query in order to
  7793. 4:34:14analyze this new big table and the
  7794. 4:34:17result going to be presented in the
  7795. 4:34:19reports. And now of course the advantage
  7796. 4:34:21here is that we have only one SQL query
  7797. 4:34:23for the data analyzers on top of this
  7798. 4:34:26table instead of having it four times.
  7799. 4:34:28And now if you go and change the logic
  7800. 4:34:30of the SQL query, it going to be applied
  7801. 4:34:32automatically on all the data that we
  7802. 4:34:34have in the database. And we have done
  7803. 4:34:36already this example where we have
  7804. 4:34:37combined the data between the employees
  7805. 4:34:39and customers. Another scenario where we
  7806. 4:34:41have to combine data before doing any
  7807. 4:34:42reporting. That's sometimes the database
  7808. 4:34:45developers tend to divide a table one
  7809. 4:34:47big table into multiple small tables in
  7810. 4:34:50order to optimize the performance. For
  7811. 4:34:52example, here splitting the orders by
  7812. 4:34:54the year. We have orders 2022 2023. Now
  7813. 4:34:58again here if you want to generate a
  7814. 4:34:59report in order to analyze the orders
  7815. 4:35:02over the years over the time either
  7816. 4:35:04you're going to go and make a query for
  7817. 4:35:06each of those tables or you're going to
  7818. 4:35:08go first combining all those tables into
  7819. 4:35:11one table called orders. So what we're
  7820. 4:35:13going to do we're going to use a union
  7821. 4:35:15between all those tables in order to
  7822. 4:35:17generate one central table called the
  7823. 4:35:19orders. So all the rows from the first
  7824. 4:35:21table and all rows from the next table.
  7825. 4:35:25next one and the last one. So, we're
  7826. 4:35:27going to put everything in one big table
  7827. 4:35:30and once we have the orders, we're going
  7828. 4:35:31to go and write analytical skill query
  7829. 4:35:34on top of the orders in order to
  7830. 4:35:36generate the report. So, as you can see,
  7831. 4:35:39it's very important step in order to
  7832. 4:35:40prepare the data before doing data
  7833. 4:35:42analyszis. Okay. So now let's have the
  7834. 4:35:44following SQL task and it says the
  7835. 4:35:46orders are stored in separate tables. We
  7836. 4:35:49have the orders and orders archive. Now
  7837. 4:35:51combine all orders data into one report
  7838. 4:35:54without duplicates. Okay. So by looking
  7839. 4:35:56to the task we have to combine two
  7840. 4:35:58tables orders and orders archive. So
  7841. 4:36:00either union or union all. But since the
  7842. 4:36:02task says without duplicates that means
  7843. 4:36:05we have to go with the union. But now
  7844. 4:36:07before we combine any data we have first
  7845. 4:36:09to understand the content of the orders
  7846. 4:36:11and the orders archive in order to map
  7847. 4:36:13the columns correctly. So first we have
  7848. 4:36:15to go and explore the two tables. So
  7849. 4:36:18let's start with selecting the data from
  7850. 4:36:21orders everything semicolon and as well
  7851. 4:36:24from the second table sales orders
  7852. 4:36:28archive and as well semicolon. So let's
  7853. 4:36:31go and execute it. So now in the output
  7854. 4:36:33we get two results because we have two
  7855. 4:36:35separate queries. The first result is
  7856. 4:36:37for the orders and the second one is for
  7857. 4:36:39the orders archive. Let me just make it
  7858. 4:36:42a little bit bigger. And now as you can
  7859. 4:36:44see we have almost identical tables. So
  7860. 4:36:47as you can see we have the order ID,
  7861. 4:36:48product ID, customer ID. So everything
  7862. 4:36:51looks like identical and of course we
  7863. 4:36:53can go and check that using the object
  7864. 4:36:55explorer on the left side. So we have
  7865. 4:36:57here the orders and those are the
  7866. 4:37:00columns. And if you go to the orders
  7867. 4:37:02archive, you can see that we have the
  7868. 4:37:06exact same columns. So that means we can
  7869. 4:37:08go and map all columns from orders with
  7870. 4:37:10the all columns of orders archive. So
  7871. 4:37:12let's go and do that. So I'm just going
  7872. 4:37:14to remove all semicolons and then we're
  7873. 4:37:16going to go and use the union. So now we
  7874. 4:37:18have everything in one query. Let's go
  7875. 4:37:21and execute it. Now we will get in the
  7876. 4:37:23output one single results, one single
  7877. 4:37:25table with all informations from orders
  7878. 4:37:28and orders archive. So we have all
  7879. 4:37:30orders now in one table and everything
  7880. 4:37:33currently is matching. So with that we
  7881. 4:37:35have solved the task. We have one result
  7882. 4:37:36with all orders. We don't have any
  7883. 4:37:38duplicates since we are using union and
  7884. 4:37:41we have combined the data. But now we
  7885. 4:37:42have one issue with that. This solution,
  7886. 4:37:45this query is quick and dirty and
  7887. 4:37:47actually it's not following the best
  7888. 4:37:49practices. So now the best practices
  7889. 4:37:50here is to list clearly all the columns
  7890. 4:37:54in each query without using star. All
  7891. 4:37:56right. So now let's go and do that. Now
  7892. 4:37:57we need a list of all columns from the
  7893. 4:38:00table orders and the table orders
  7894. 4:38:01archive. And since we have a lot of
  7895. 4:38:03columns, what we're going to do, we go
  7896. 4:38:04to object explorer, right click on the
  7897. 4:38:07table name, and then let's go select the
  7898. 4:38:09top thousand rows. So let's click on
  7899. 4:38:11that. And now we're going to get a very
  7900. 4:38:13simple select statements where we have
  7901. 4:38:15all the column names from the table
  7902. 4:38:17orders. This is what I usually do if I
  7903. 4:38:19need all the columns in the my select
  7904. 4:38:21statements. So let's go and copy it and
  7905. 4:38:23go back to our query. Then let's go
  7906. 4:38:26replace the first star with those
  7907. 4:38:29columns. And we're going to do the same
  7908. 4:38:30thing as well for the orders archive
  7909. 4:38:33since they have the same names. So let's
  7910. 4:38:35go and do that as well. So let me just
  7911. 4:38:37make this smaller in order to see the
  7912. 4:38:39query. So now we have a select for the
  7913. 4:38:42table orders with all columns and as
  7914. 4:38:45well a select with all columns for the
  7915. 4:38:47table orders archive. So let's go and
  7916. 4:38:49execute it. And of course now we're
  7917. 4:38:50going to go and get the same results.
  7918. 4:38:52Now you might ask why we are doing this.
  7919. 4:38:54Why didn't we stick with the star? It's
  7920. 4:38:56quick. It's simple. Well for the
  7921. 4:38:58following reason. So now currently the
  7922. 4:39:00status is that everything is matching.
  7923. 4:39:02We have 100% identical tables. But what
  7924. 4:39:05happened with the time is that we do
  7925. 4:39:07development in our solution and we might
  7926. 4:39:09go and change the schema of the table
  7927. 4:39:11orders. So we might rename stuff, we
  7928. 4:39:14might add new columns or maybe switch
  7929. 4:39:16the columns. So this means the table
  7930. 4:39:19order with the time will not be anymore
  7931. 4:39:21identical with the archive. And this is
  7932. 4:39:23of course a problem if you are mapping
  7933. 4:39:25the data blindly using the star. So now
  7934. 4:39:28let me show you what I mean. Let's say
  7935. 4:39:29that in this table we are developing the
  7936. 4:39:32orders and we just switch those two
  7937. 4:39:34columns in the schema for some reason.
  7938. 4:39:37So now we have the product ID first and
  7939. 4:39:39then the order ID. So let's go and
  7940. 4:39:42execute it. Now if you are using star
  7941. 4:39:44you will not notice this informations.
  7942. 4:39:46But if you are using script you're going
  7943. 4:39:47to see immediately that here we have
  7944. 4:39:49first the order ID and then product ID.
  7945. 4:39:52And here we have the opposite. So it's
  7946. 4:39:54more clear listing the columns than
  7947. 4:39:57using the star. And now as you can see
  7948. 4:39:58in the output you can see that we have a
  7949. 4:40:01problem that here we have order ids and
  7950. 4:40:04then suddenly we have something like the
  7951. 4:40:07product ID. So we're going to have
  7952. 4:40:08incorrect data which leads to incorrect
  7953. 4:40:10analyzes. So here the best practices to
  7954. 4:40:12not use the star and to clearly list all
  7955. 4:40:15the columns. Now one more technique that
  7956. 4:40:17I usually use once I'm combining data is
  7957. 4:40:19that I add the source of the data inside
  7958. 4:40:22the query. So what I mean with that now
  7959. 4:40:24you can see that we have here two orders
  7960. 4:40:26with the order ID one they are not
  7961. 4:40:29duplicates they are completely different
  7962. 4:40:30informations and that's because they
  7963. 4:40:32come from different tables. So what I
  7964. 4:40:34usually do I go and add the source of
  7965. 4:40:36each record it's really nice information
  7966. 4:40:38for the analytics for the users to
  7967. 4:40:40understand where these records come
  7968. 4:40:42from. So how we going to do that? We're
  7969. 4:40:44going to have for example on the first
  7970. 4:40:46column the following word let's say
  7971. 4:40:49orders and we're going to call it let's
  7972. 4:40:51say that's source table and we're going
  7973. 4:40:54to do the same thing as well in the
  7974. 4:40:57second query. Right? So the source table
  7975. 4:40:59here is not the orders it's the orders
  7976. 4:41:02archive. So I'm just adding a static
  7977. 4:41:04columns to my query in order to see the
  7978. 4:41:07source of the table. So now we have here
  7979. 4:41:09two different values. And let's go and
  7980. 4:41:12execute it. And now you see we have
  7981. 4:41:13created a new column called source table
  7982. 4:41:15where it has only two values. We have
  7983. 4:41:17the orders and the orders archive. Let's
  7984. 4:41:19go and sort the data by the order ID. So
  7985. 4:41:22order by order ID. So let's go and
  7986. 4:41:25execute it. And now you can see it very
  7987. 4:41:27clearly. The first order order ID one
  7988. 4:41:30comes from the table orders and the
  7989. 4:41:32second one comes from the orders
  7990. 4:41:34archive. So this is really nice
  7991. 4:41:35information that you can add to your
  7992. 4:41:37data once you are combining multiple
  7993. 4:41:38tables. So that's all about this use
  7994. 4:41:40case on how to combine data between
  7995. 4:41:42different
  7996. 4:41:46tables. All right. Now we have another
  7997. 4:41:48use case for the set operators. It's
  7998. 4:41:50more for data engineers. We can use the
  7999. 4:41:52except in order to find the delta
  8000. 4:41:55between two batches of data. For
  8001. 4:41:57example, data engineers build data
  8002. 4:41:59pipelines in order to load daily new
  8003. 4:42:02data from the source systems to a data
  8004. 4:42:04warehouse or a data lake. Now, in those
  8005. 4:42:06data pipelines, we have to build a logic
  8006. 4:42:09in order to identify what are the new
  8007. 4:42:11data that is generated from the source
  8008. 4:42:13system in order to insert it in the data
  8009. 4:42:16warehouse. One way to do it is to use
  8010. 4:42:17the set operator except in order to
  8011. 4:42:20compare the current data with the
  8012. 4:42:22previous load. Let's have a very simple
  8013. 4:42:24example. So in the day number one we
  8014. 4:42:26have two customers one and two. So what
  8015. 4:42:28going to happen in this day we're going
  8016. 4:42:29to go and load those two customers into
  8017. 4:42:31the data warehouse. So in the data
  8018. 4:42:33warehouse we will get as well one and
  8019. 4:42:35two. So this is for the first day
  8020. 4:42:36nothing is crazy. We just load the data
  8021. 4:42:38as it is. Now for the second day we will
  8022. 4:42:41get the new data from the source system
  8023. 4:42:42and it's going to look like this. So now
  8024. 4:42:44if you check the second day you can see
  8025. 4:42:45that we have again the customer number
  8026. 4:42:47one we have already loaded to the data
  8027. 4:42:49warehouse. So we have it as the previous
  8028. 4:42:52day but we have a new customer ID number
  8029. 4:42:55three. So now in order to load only the
  8030. 4:42:57new data we don't need to load again the
  8031. 4:42:59customer number one. What we can do? We
  8032. 4:43:02can do an accept between the day number
  8033. 4:43:05two with the previous load with the day
  8034. 4:43:07number one. So now if we simply do an
  8035. 4:43:09accept between those two sets we're
  8036. 4:43:11going to go and identify the new data
  8037. 4:43:14that is existing in the source system
  8038. 4:43:16which is only the record number three.
  8039. 4:43:18So now what going to happen if we do
  8040. 4:43:19except between day two and day one we
  8041. 4:43:22will get one record the new record that
  8042. 4:43:24we're going to go and insert it inside
  8043. 4:43:26our data warehouse. So as you can see
  8044. 4:43:28this set operator except is very
  8045. 4:43:30powerful in order to compare two sets
  8046. 4:43:32and not only for data analysis we can
  8047. 4:43:34use it as you can see for data
  8048. 4:43:35engineering in order to identify what is
  8049. 4:43:38the new data that is generated from the
  8050. 4:43:40sources in order to insert it inside our
  8051. 4:43:43data warehouse.
  8052. 4:43:48Okay, one more use case for the set
  8053. 4:43:49operators that I personally use a lot in
  8054. 4:43:51my project is that if you are doing data
  8055. 4:43:54migrations, you can use the accept in
  8056. 4:43:56order to check the data quality and more
  8057. 4:43:59specifically we can use it in order to
  8058. 4:44:00check the data completeness. Okay, so we
  8059. 4:44:03have the following scenario where we are
  8060. 4:44:04doing data migrations between two
  8061. 4:44:06databases. So let's say that we would
  8062. 4:44:07like to move this table from database A
  8063. 4:44:09to database B. So we're going to go and
  8064. 4:44:12load the table to the new database. And
  8065. 4:44:15now what is very important after you
  8066. 4:44:16move the data is that to check whether
  8067. 4:44:18all the records did move from database A
  8068. 4:44:21to database B we are not missing
  8069. 4:44:23anything even one record. So we want to
  8070. 4:44:25do data completeness test and there are
  8071. 4:44:27many methods on how to do this test. One
  8072. 4:44:30of them is to use that set operator
  8073. 4:44:32except. So how we going to do it? We're
  8074. 4:44:33going to do an except between the table
  8075. 4:44:36from database A and the table from
  8076. 4:44:37database B in order to find any record
  8077. 4:44:40that is still in database A which is not
  8078. 4:44:43migrated to the database B. And of
  8079. 4:44:45course the best result is that we will
  8080. 4:44:47not get anything. The result should be
  8081. 4:44:50empty. If we get an empty that means all
  8082. 4:44:52the rows from database A exists in the
  8083. 4:44:55database B. And now of course we are not
  8084. 4:44:57done yet. We want to do the comparison
  8085. 4:44:59but the way around. We want to find any
  8086. 4:45:01new rows that is in database B that we
  8087. 4:45:04don't find in database A. Those two
  8088. 4:45:07tables must be identical. So now what
  8089. 4:45:09we're going to do, we're going to do an
  8090. 4:45:10except but the first table going to be
  8091. 4:45:12from the database B. And then we're
  8092. 4:45:14going to compare it with the database A.
  8093. 4:45:15And we have the same expectation. The
  8094. 4:45:18output should be as well empty. And now
  8095. 4:45:20after doing the except twice for both
  8096. 4:45:22sides and we are getting empty in the
  8097. 4:45:24results. That means those two tables are
  8098. 4:45:27identical and we are not missing
  8099. 4:45:29anything. So this is another amazing use
  8100. 4:45:31case for the set operators in order to
  8101. 4:45:34improve the quality of your data
  8102. 4:45:35migrations and in order to do data
  8103. 4:45:37completeness
  8104. 4:45:41test. Okay. So now let's have a quick
  8105. 4:45:44summary about the set operators. So the
  8106. 4:45:46set operator is going to go and combine
  8107. 4:45:47the rows of multiple queries, multiple
  8108. 4:45:49tables into one single result. And we
  8109. 4:45:52have four different types of the asset
  8110. 4:45:53operators. The first one is the union
  8111. 4:45:56where it's going to go and combine all
  8112. 4:45:57the rows but without including any
  8113. 4:45:59duplicates. The second one we have the
  8114. 4:46:01union all it's very similar. And the
  8115. 4:46:03third one we have the except it's going
  8116. 4:46:05to show all the rows from the first
  8117. 4:46:06query that cannot be found in the second
  8118. 4:46:09query. And the fourth one we have the
  8119. 4:46:11intersect where it's going to show the
  8120. 4:46:12common rows between two queries. And of
  8121. 4:46:15course we have SQL rules in order to use
  8122. 4:46:16the set operators. Both of the queries
  8123. 4:46:18should have the same number of columns,
  8124. 4:46:21the same data types and the order of
  8125. 4:46:23columns. And the last rule, don't forget
  8126. 4:46:25that the first query controls the
  8127. 4:46:27aliases, the name of the columns and the
  8128. 4:46:30data types of the entire result. And we
  8129. 4:46:32have found amazing use cases for the set
  8130. 4:46:34operators. Like for example, using union
  8131. 4:46:36and union all in order to combine
  8132. 4:46:39similar informations into one big table.
  8133. 4:46:41Or we can go and use the amazing except
  8134. 4:46:43operator in order to compare two
  8135. 4:46:46different results in order to find the
  8136. 4:46:48differences between them. And I usually
  8137. 4:46:50use it in order to do data quality
  8138. 4:46:52checks to test the data completeness.
  8139. 4:46:54And another use case as a data engineer
  8140. 4:46:56you can go and implement the except in
  8141. 4:46:58your logic in your data pipelines in
  8142. 4:47:01order to identify what are the new data
  8143. 4:47:03that must be inserted in your system.
  8144. 4:47:05Okay my friends. So with that we have
  8145. 4:47:06learned all the set operators that we
  8146. 4:47:08have inside SQL. And with that you have
  8147. 4:47:10learned how to combine your data from
  8148. 4:47:12multiple tables using SQL. So we are
  8149. 4:47:14done with this chapter. Now we're going
  8150. 4:47:16to go to the right side. So now we're
  8151. 4:47:18going to start talking about the
  8152. 4:47:19functions in SQL. And here we have two
  8153. 4:47:21big families. The first one is the row
  8154. 4:47:24level or the single value functions. And
  8155. 4:47:26the second one we have the aggregate
  8156. 4:47:27analytical functions. So let's start
  8157. 4:47:29with the first one the rowle functions.
  8158. 4:47:31And here we can group them into multiple
  8159. 4:47:33categories. And we will start now with
  8160. 4:47:35the string functions. But first let's
  8161. 4:47:37understand what is exactly functions and
  8162. 4:47:39why do we need them in SQL. So let's
  8163. 4:47:45go. Okay. So what is exactly function
  8164. 4:47:48and why we need it. Now again we have
  8165. 4:47:49our data inside the table. Now there is
  8166. 4:47:52like a lot of stuff that you can do with
  8167. 4:47:53your data. So sometimes you have to
  8168. 4:47:55change the values of your data like
  8169. 4:47:57doing data manipulation or you want to
  8170. 4:47:59do some aggregations and analyzes. So
  8171. 4:48:01maybe you want to analyze your data and
  8172. 4:48:03find insights and maybe build reports
  8173. 4:48:06and sometimes you might find bad data
  8174. 4:48:08inside your tables and you want to clean
  8175. 4:48:09that up. So you want to do data
  8176. 4:48:11cleansing and sometimes you have to do
  8177. 4:48:13data transformations and data
  8178. 4:48:15manipulation on our data in order to
  8179. 4:48:17solve some SQL tasks and in SQL in order
  8180. 4:48:20to solve those tasks we have functions.
  8181. 4:48:22So again what is exactly a function? It
  8182. 4:48:24is a built-in code block that accepts an
  8183. 4:48:27input value. Then the function going to
  8184. 4:48:29go and process this value and it going
  8185. 4:48:31to return a result an output value. So
  8186. 4:48:34you give an input value do some
  8187. 4:48:36transformations and give an output. And
  8188. 4:48:38we can group the functions into two big
  8189. 4:48:40categories. The first one we call it
  8190. 4:48:42single row functions. So you give the
  8191. 4:48:44function only one value and at the
  8192. 4:48:46return you will get as well one value.
  8193. 4:48:48So the input for the function going to
  8194. 4:48:49be only one single value like maria and
  8195. 4:48:52the output of the function going to be
  8196. 4:48:54as well single row value. So one value
  8197. 4:48:56in one value out. And now the other
  8198. 4:48:58category of functions we call it
  8199. 4:49:00multirow functions. So for example if
  8200. 4:49:02you have the function sum this function
  8201. 4:49:04accept multiple rows multiple values
  8202. 4:49:07like it gets 30 10 20 40 the function is
  8203. 4:49:10then going to go and summarize all those
  8204. 4:49:12rows and return in the output only one
  8205. 4:49:14value. The summarization of all those
  8206. 4:49:16values going to be 100. So the input is
  8207. 4:49:18multiple rows and the output is one
  8208. 4:49:21single value. So those are the two main
  8209. 4:49:22categories of functions in scale.
  8210. 4:49:28Now my friends you have to understand
  8211. 4:49:30something about the functions that you
  8212. 4:49:31can go and nest functions together. So
  8213. 4:49:34you can use multiple functions together
  8214. 4:49:36in order to manipulate one value. And
  8215. 4:49:38this technique is not only in SQL in any
  8216. 4:49:40programming language. So let's have this
  8217. 4:49:42example. We have the function left. It's
  8218. 4:49:44going to go and extract like few
  8219. 4:49:45characters. Let's say two characters. So
  8220. 4:49:47the input for this function let's say
  8221. 4:49:49it's Maria. This value going to enter
  8222. 4:49:50the function. The function is going to
  8223. 4:49:52go and extract the first two characters.
  8224. 4:49:54And in the output we will get only two
  8225. 4:49:56characters m a. So this is one function.
  8226. 4:49:58We have an input and output. Now you
  8227. 4:50:00might say you know what we have multiple
  8228. 4:50:02steps on this value. So the first step
  8229. 4:50:04we want to extract the first two
  8230. 4:50:05characters using the lift function. But
  8231. 4:50:07we have a second step. So we want to
  8232. 4:50:09transform this output into a lowercase
  8233. 4:50:12characters. So we have another function
  8234. 4:50:13lower and the input for this second
  8235. 4:50:15function will be the output of the first
  8236. 4:50:17function. So ma it is at the same time
  8237. 4:50:20output and input for another function.
  8238. 4:50:22So the lower function going to take this
  8239. 4:50:24value and convert it into lowerase
  8240. 4:50:26character. So it's like inside the
  8241. 4:50:28factory the materials going to be
  8242. 4:50:29processed into multiple stations and the
  8243. 4:50:31output of one station going to be the
  8244. 4:50:33input for the next station. And this is
  8245. 4:50:35exactly what we can do with the
  8246. 4:50:36functions. So now how we going to build
  8247. 4:50:38that? The first step is to start with
  8248. 4:50:39the first function. So this is simple
  8249. 4:50:41one function. Now for the next step what
  8250. 4:50:44you're going to do on the left side
  8251. 4:50:45you're going to write lower and put the
  8252. 4:50:47whole thing in parenthesis. So now the
  8253. 4:50:49whole thing the first function going to
  8254. 4:50:51be inside another function and with that
  8255. 4:50:53you have nested one function in another
  8256. 4:50:55and of course if you need a third
  8257. 4:50:57function like for example the length
  8258. 4:50:59what you're going to do you're going to
  8259. 4:51:00put the whole thing again between two
  8260. 4:51:02parentheses. So now that means the
  8261. 4:51:03output of the lift going to go to the
  8262. 4:51:05lower and the output of the lower going
  8263. 4:51:07to go to the length. So it is very
  8264. 4:51:09simple and the order of the execution
  8265. 4:51:10for this will start always in the inner
  8266. 4:51:13function. So the lift function going to
  8267. 4:51:14be executed first and then the outside
  8268. 4:51:16function the lower and the last function
  8269. 4:51:18that's going to be executed is the
  8270. 4:51:20length. This is how the nested functions
  8271. 4:51:22works in SQL or in any programming
  8272. 4:51:27language. Now my friends in SQL we have
  8273. 4:51:30a lot of functions that's why we have to
  8274. 4:51:32group them as well into subcategories.
  8275. 4:51:34Like if you are talking about the single
  8276. 4:51:36row functions, we have functions for the
  8277. 4:51:38string values and as well for the
  8278. 4:51:40numeric, the date and time and as well
  8279. 4:51:42functions in order to handle the nulls.
  8280. 4:51:44And if you are talking about the
  8281. 4:51:45multirow functions, here we have
  8282. 4:51:47basically two groups. The first one is
  8283. 4:51:49the simple aggregate functions. Those
  8284. 4:51:51are the basics in order to aggregate
  8285. 4:51:52your data. And we have another advanced
  8286. 4:51:54one. We call it the window functions or
  8287. 4:51:57sometime we call it analytical
  8288. 4:51:58functions. So now if I'm looking to
  8289. 4:52:00those two groups and now my friends it
  8290. 4:52:02is very important to understand those
  8291. 4:52:03functions because using them you can do
  8292. 4:52:05whatever you want with your data and if
  8293. 4:52:07I'm looking to those two groups the
  8294. 4:52:09single row functions those stuff here
  8295. 4:52:11they are functions in order to
  8296. 4:52:13manipulate and prepare the data for the
  8297. 4:52:16second group. So if you are thinking
  8298. 4:52:17about data engineers and data analysts
  8299. 4:52:19the data engineers going to go and
  8300. 4:52:21prepare the data in SQL using the single
  8301. 4:52:23row functions. So you're going to use
  8302. 4:52:25them in order to clean up, transform,
  8303. 4:52:27manipulate your data in order to prepare
  8304. 4:52:29it for the analyzes. And if you are data
  8305. 4:52:32analyst, you will be mostly using the
  8306. 4:52:33aggregate functions in almost every
  8307. 4:52:35task. So I really see it like this. The
  8308. 4:52:37single row functions for data engineers
  8309. 4:52:39and multirow functions for data
  8310. 4:52:41analysts. And my friends, what we're
  8311. 4:52:43going to do in this course, we're going
  8312. 4:52:44to visit each of those subgroups one by
  8313. 4:52:47one, exploring the functions,
  8314. 4:52:49understanding how they work and when
  8315. 4:52:50we're going to use them. So let's start
  8316. 4:52:52with the first group, the string
  8317. 4:52:53functions. And here we're going to learn
  8318. 4:52:55how to manipulate the string values. So
  8319. 4:52:58let's
  8320. 4:53:02go. Okay. So now since we have a lot of
  8321. 4:53:04string functions, I'm going to go and
  8322. 4:53:06divide them into categories based on the
  8323. 4:53:08purpose. So for example, we have a group
  8324. 4:53:10of functions that's going to go and
  8325. 4:53:11manipulate the string values. So we have
  8326. 4:53:13concatenation, upper, lower, replace,
  8327. 4:53:15and so on. And another group where we
  8328. 4:53:17have only one function. It is where we
  8329. 4:53:19can do calculations on the string
  8330. 4:53:20values. And the last group, it is all
  8331. 4:53:22about how to extract something from a
  8332. 4:53:25string value. And here we have three
  8333. 4:53:26functions left, right, substring. So now
  8334. 4:53:28let's go and start with the first group
  8335. 4:53:30about the data manipulation. And the
  8336. 4:53:32first function we have here
  8337. 4:53:36concat. All right. So what is exactly
  8338. 4:53:39concat or concatenation? It's going to
  8339. 4:53:41go and combine multiple string values
  8340. 4:53:43into one value. So if you have multiple
  8341. 4:53:46things you can put everything in one
  8342. 4:53:47value. So let's have a very simple
  8343. 4:53:49example. Okay. So now let's say that you
  8344. 4:53:50have one value called Michael. So here
  8345. 4:53:52you have a first name and you have
  8346. 4:53:54totally separated value for the last
  8347. 4:53:56name another column where you have a
  8348. 4:53:58value like Scott. And now you say you
  8349. 4:54:00know what it makes no sense to have the
  8350. 4:54:01first name separated from the last name.
  8351. 4:54:03I would like to go and combine them in
  8352. 4:54:05one value. So you can go and use the
  8353. 4:54:07concat in order to combine those two
  8354. 4:54:09values or multiple values into one
  8355. 4:54:11single value like Michael Scott.
  8356. 4:54:14I think that pretty much sums it up. So
  8357. 4:54:17it is nicer to see the full name in one
  8358. 4:54:19value instead of having like two columns
  8359. 4:54:21for that. So that's it. This is why we
  8360. 4:54:23need the concatenations. Now let's go
  8361. 4:54:25back to scale in order to try that out.
  8362. 4:54:27Okay. So now we have the following task.
  8363. 4:54:29Show a list of customers first names
  8364. 4:54:31together with their country in one
  8365. 4:54:33column. So that means we have to make a
  8366. 4:54:35list of customers and we have to combine
  8367. 4:54:37two columns in one. So let's start
  8368. 4:54:39writing the query. Select. We need the
  8369. 4:54:41first name, the country from the table
  8370. 4:54:44customers. So first let's go and execute
  8371. 4:54:46this. Now as you can see we have list of
  8372. 4:54:48customers but the issue here the first
  8373. 4:54:50name and the countries those two
  8374. 4:54:52informations are in different columns
  8375. 4:54:54but the task says they should be in one
  8376. 4:54:56column. So now in order to combine those
  8377. 4:54:58two things we have to use the
  8378. 4:54:59concatenate function. So concat. So I'm
  8379. 4:55:02going to start with the first argument.
  8380. 4:55:03It's going to be the first name and then
  8381. 4:55:05the country like this. And we're going
  8382. 4:55:07to give it a name. Let's call it like
  8383. 4:55:09this name country. Now let's go ahead
  8384. 4:55:12and execute it. Now in the output you
  8385. 4:55:13can see we have a new column. It's
  8386. 4:55:15called name country and we have both of
  8387. 4:55:17the informations in one column. So we
  8388. 4:55:19have Maria, Germany, join USA. But it
  8389. 4:55:21doesn't really look good because there's
  8390. 4:55:23like no spacing between them. Now we can
  8391. 4:55:25go and make some separation between them
  8392. 4:55:28by just adding one more thing in between
  8393. 4:55:30like for example maybe a space. So now
  8394. 4:55:33we are concatenating the first name
  8395. 4:55:35together with a space this over here and
  8396. 4:55:38then the country. So let's go and
  8397. 4:55:39execute it. Now as you can see we have
  8398. 4:55:41nice separations between the first name
  8399. 4:55:43and the country. And of course you can
  8400. 4:55:44go and add different separations like
  8401. 4:55:46maybe my notes or underscore and you
  8402. 4:55:48will get the same effect. So with that
  8403. 4:55:50we have a list of customers where we
  8404. 4:55:52have the first name together with the
  8405. 4:55:54country in one column. As you can see
  8406. 4:55:56it's very simple. This is how you
  8407. 4:55:57combine two columns in one. It is really
  8408. 4:56:00nice and easy transformation. Okay. So
  8409. 4:56:01that's all about the concatenation in
  8410. 4:56:03scale. Next we're going to talk about
  8411. 4:56:05two functions. The upper and the
  8412. 4:56:10lower. Okay. So what is upper function?
  8413. 4:56:13It's going to go and converts all the
  8414. 4:56:14characters of a string to an uppercase.
  8415. 4:56:17It's going to make everything
  8416. 4:56:18capitalized. And the lower function is
  8417. 4:56:20exactly the opposite. It's going to go
  8418. 4:56:21and convert everything to a lower case.
  8419. 4:56:24So let's have very simple example for
  8420. 4:56:26those two functions. Okay. So now we
  8421. 4:56:27have like three values with different
  8422. 4:56:29cases. The first one where you have only
  8423. 4:56:31the first character capitalized and the
  8424. 4:56:33rest is lowered and then the same value
  8425. 4:56:35but everything is lowered and a third
  8426. 4:56:37one where you have everything with an
  8427. 4:56:39uppercase. Now if you go and apply the
  8428. 4:56:41function upper to those three values
  8429. 4:56:43what going to happen for the first value
  8430. 4:56:45going to go and turn it into an
  8431. 4:56:47uppercase. So everything going to be
  8432. 4:56:48capitalized not only the first
  8433. 4:56:50character. And now for the second value
  8434. 4:56:52going to turn it as well to completely
  8435. 4:56:54capitalized. So all the characters going
  8436. 4:56:56to change. And for the last value it is
  8437. 4:56:58already capitalized. So in the output
  8438. 4:57:00you will get the same value. So actually
  8439. 4:57:01nothing going to happen for that. So
  8440. 4:57:03this is simply the uppercase. Now let's
  8441. 4:57:05see what can happen if you use the lower
  8442. 4:57:07case. For the first value only the first
  8443. 4:57:09character going to be changed and then
  8444. 4:57:10you will have everything in lower case.
  8445. 4:57:12The second value it is already a
  8446. 4:57:14lowerase value. So if you apply lower
  8447. 4:57:16case nothing going to happen. You will
  8448. 4:57:18get the same value. But for the last one
  8449. 4:57:19everything here is capitalized and if
  8450. 4:57:21you apply lower case all the characters
  8451. 4:57:23going to convert to a lower case. So my
  8452. 4:57:25friends this is very simple. Let's go
  8453. 4:57:27back to your skill in order to practice
  8454. 4:57:29that. Okay. So we have the following
  8455. 4:57:30task and it says transform the
  8456. 4:57:32customer's first name to lowerase. So
  8457. 4:57:35now as you can see the first names here
  8458. 4:57:37the first character is a capital the
  8459. 4:57:39rest is lowerase. So now in this task we
  8460. 4:57:41have to convert the whole thing into
  8461. 4:57:43lower case. So let's go and do that.
  8462. 4:57:45It's very simple. We're going to say
  8463. 4:57:47lower first name and let's go and call
  8464. 4:57:50it low name. So that's it. Let's go and
  8465. 4:57:53execute it. Now if you go and compare
  8466. 4:57:54the lower name with the first name, you
  8467. 4:57:56can see all the characters now in the
  8468. 4:57:59lower case. So that's it for the task.
  8469. 4:58:01We have transformed the first name to
  8470. 4:58:03lower case. All right. The next task is
  8471. 4:58:05exactly the opposite. Transform the
  8472. 4:58:06customer's first name to uppercase. So
  8473. 4:58:09let's go and have a new column. We're
  8474. 4:58:11going to say upper then the first
  8475. 4:58:15name as app name. So that's it. It's
  8476. 4:58:19very simple. Let's go and execute. Now
  8477. 4:58:20you can see in the output we have a new
  8478. 4:58:22column called up name and inside it we
  8479. 4:58:24have the first name but now all the
  8480. 4:58:26characters in upper case. So this is how
  8481. 4:58:29you convert the case to lower or to
  8482. 4:58:31upper in SQL. Okay. So that's all about
  8483. 4:58:33the upper and the lower. Next we're
  8484. 4:58:35going to talk about very interesting
  8485. 4:58:36function. It is the
  8486. 4:58:41trim. So the trim function going to go
  8487. 4:58:44and remove the leading and trailing
  8488. 4:58:46spaces in your string values. So it's
  8489. 4:58:48going to go and get rid of the empty
  8490. 4:58:50spaces at the start and at the end of a
  8491. 4:58:52string value. Let's have very simple
  8492. 4:58:54example. Okay. So now we're going to
  8493. 4:58:55have different scenarios. The first one
  8494. 4:58:56you can have like a value join where you
  8495. 4:58:58don't have any spaces and this is the
  8496. 4:59:00normal case. But sometimes you might
  8497. 4:59:02have it like this where at the start you
  8498. 4:59:04have a leading space. You have an empty
  8499. 4:59:06space or sometimes we call it white
  8500. 4:59:08space. In another scenario the space
  8501. 4:59:10might be at the end of the word. So here
  8502. 4:59:12we call it trailing space and in another
  8503. 4:59:14scenario you might have both of them.
  8504. 4:59:16This is really bad. where at the start
  8505. 4:59:18you have the leading space and at the
  8506. 4:59:20end you have the trailing space. And of
  8507. 4:59:21course you might not have only one
  8508. 4:59:23space, you might have multiple spaces
  8509. 4:59:25depend on how long did the user press
  8510. 4:59:27the space, right? So of course my
  8511. 4:59:29friends spaces are really evil and this
  8512. 4:59:31makes no sense to have it in your data.
  8513. 4:59:33Now what you have to do is to do data
  8514. 4:59:34cleansing. We have to clean up this miss
  8515. 4:59:36and you have the best function in order
  8516. 4:59:38to clean up the data. You have the trim.
  8517. 4:59:40So if you apply trim for the first
  8518. 4:59:42value, nothing going to happen because
  8519. 4:59:44everything is clean and we don't have
  8520. 4:59:45any spaces. Now if you apply it for the
  8521. 4:59:47second case where you have a leading
  8522. 4:59:49space if you do that SQL going to go and
  8523. 4:59:52remove this space. The same thing for
  8524. 4:59:54the trailing space. So if you have space
  8525. 4:59:55at the end the trim function going to
  8526. 4:59:57find it and clean that up. And if you
  8527. 4:59:59have it at the start and at the end then
  8528. 5:00:01it's as well no problem. It's going to
  8529. 5:00:03go and clean that up. And as well the
  8530. 5:00:05trim function can go and clean multiple
  8531. 5:00:07spaces. So if you have like five spaces
  8532. 5:00:0910 spaces at the end or at the start the
  8533. 5:00:11trim function going to go and clean that
  8534. 5:00:13up. So this is how the trim works. And
  8535. 5:00:15now let's go back to our scale in order
  8536. 5:00:16to find out whether we have any spaces.
  8537. 5:00:18Okay. So now we have a very tricky and
  8538. 5:00:21interesting task. It says find the
  8539. 5:00:24customers whose first name contains
  8540. 5:00:26leading or trailing spaces. So now by
  8541. 5:00:29looking to those values we have to find
  8542. 5:00:31any spaces inside the customer's name.
  8543. 5:00:33Now by just looking to this results you
  8544. 5:00:35will not find any white spaces because
  8545. 5:00:38it's really hard to see especially if it
  8546. 5:00:40is like trailing spaces. Now we have to
  8547. 5:00:42write query order to detect any spaces
  8548. 5:00:45in the names. So how we can do that?
  8549. 5:00:48Okay. So now think about it a little bit
  8550. 5:00:49and I can give you a hint. You can use
  8551. 5:00:51the function trim in order to remove any
  8552. 5:00:54white spaces and you have to use it
  8553. 5:00:56inside a wear clause. So what we're
  8554. 5:00:58going to do we're going to say where. So
  8555. 5:00:59now we have to build a condition to
  8556. 5:01:01detect any spaces. So if you are saying
  8557. 5:01:04if the first name is not equal to itself
  8558. 5:01:08first name after applying a trim. So
  8559. 5:01:11after trimming the first name if it is
  8560. 5:01:15not equal to the first name so that
  8561. 5:01:17means there was spaces. So again what is
  8562. 5:01:20going on here? Let's go for Maria. If
  8563. 5:01:22Maria has no nulls if you trim this
  8564. 5:01:24value nothing going to happen. The value
  8565. 5:01:26going to stay exactly like before
  8566. 5:01:28because there is no white spaces. But if
  8567. 5:01:30in Maria there is any space inside it.
  8568. 5:01:33Trimming the value will not be equal to
  8569. 5:01:35the first name if it contains any
  8570. 5:01:37spaces. So if the column is not equal to
  8571. 5:01:40the same column after trimming it that
  8572. 5:01:42means there is spaces. So let's go and
  8573. 5:01:45execute it. And now we can see in the
  8574. 5:01:47output we have one customer John where
  8575. 5:01:49we have this situation. Now if you don't
  8576. 5:01:51believe me or you don't follow me here
  8577. 5:01:53we can have another easier check. So
  8578. 5:01:55let's go and comment this out and let's
  8579. 5:01:57have a look to our first names. Now we
  8580. 5:01:59can go and calculate the length of the
  8581. 5:02:02first name like we have done before. So
  8582. 5:02:05length name and let's go and execute it.
  8583. 5:02:08Now if you can see here Maria we have
  8584. 5:02:09five characters but John we have here
  8585. 5:02:12four characters but the length is five
  8586. 5:02:14and that's because we have somewhere
  8587. 5:02:16space and the space going to count as a
  8588. 5:02:18character. So here there is like
  8589. 5:02:20something wrong right and you can check
  8590. 5:02:21the others as well everything is
  8591. 5:02:23matching but only John we have here an
  8592. 5:02:25issue and now in order to see this more
  8593. 5:02:27clearly we're going to use two functions
  8594. 5:02:29the trim and the length. So first let's
  8595. 5:02:31go and trim the first
  8596. 5:02:33name. And after trimming the values, I'm
  8597. 5:02:36going to calculate the length. So we are
  8598. 5:02:38nesting together the trim and the
  8599. 5:02:41length. And I'm going to call it length.
  8600. 5:02:43Trim name. So let's go and execute it.
  8601. 5:02:47Now we can see the length before
  8602. 5:02:49trimming any value. And we can see the
  8603. 5:02:52length after trimming the values. So you
  8604. 5:02:54can see over here that join before
  8605. 5:02:56trimming is five and after trimming is
  8606. 5:02:59four. So we have here an issue. Now we
  8607. 5:03:01can make things more clear where we can
  8608. 5:03:03go and subtract the length of the first
  8609. 5:03:06name with the length of the first name.
  8610. 5:03:09But first we trim the values. So here we
  8611. 5:03:11can call it maybe a flag or something.
  8612. 5:03:13So let's go and execute it. Now by
  8613. 5:03:15looking to the flag it is really easy to
  8614. 5:03:17now to see if we have a zero then
  8615. 5:03:19everything is fine. We don't have any
  8616. 5:03:21white spaces. But if we have higher than
  8617. 5:03:23zero like here one then this is an
  8618. 5:03:25indicator that we have a white space.
  8619. 5:03:27Either you do it like this where the
  8620. 5:03:29first name is not equal the first name
  8621. 5:03:31after trimming or you use more
  8622. 5:03:33complicated solution where you say where
  8623. 5:03:36and I'm going to remove this from here
  8624. 5:03:38the length of the first name is not
  8625. 5:03:41equal to the length after trimming so
  8626. 5:03:43not equal so if you go and execute it
  8627. 5:03:46you will get exactly again join so this
  8628. 5:03:48is how we detect any empty spaces inside
  8629. 5:03:50our data using the trim function or
  8630. 5:03:53maybe as well using the length but I
  8631. 5:03:55really prefer the first solution it is
  8632. 5:03:56way easier using one function. All
  8633. 5:03:58right, so that's all about how to remove
  8634. 5:04:00the empty spaces using the trim. Next,
  8635. 5:04:02we're going to talk about very important
  8636. 5:04:04function called
  8637. 5:04:08replace. Now the replace function going
  8638. 5:04:11to go and replace a specific character.
  8639. 5:04:13So that means we have something old and
  8640. 5:04:15we want to replace it with something
  8641. 5:04:16new. Let's have a very simple example to
  8642. 5:04:18understand it. All right. So now imagine
  8643. 5:04:19we have a phone number where the data is
  8644. 5:04:21splitted by a dash. Now let's say that I
  8645. 5:04:24don't like to have the dash in my data.
  8646. 5:04:25I would like to have slash like any
  8647. 5:04:27other special character. Now in order to
  8648. 5:04:29replace the dash, we can use the
  8649. 5:04:31function replace. So we have to specify
  8650. 5:04:33for SQL two things. The old value the
  8651. 5:04:36dash with a new value the slash. So if
  8652. 5:04:39you do that in the output it's going to
  8653. 5:04:41go and remove all those dashes between
  8654. 5:04:42the numbers and the replacement going to
  8655. 5:04:44be the dash between them. So it's very
  8656. 5:04:47simple, right? All what you are doing is
  8657. 5:04:48replacing an old value with a new value
  8658. 5:04:51and that's why we call it replace. But
  8659. 5:04:53we can use this function as well in
  8660. 5:04:54order to remove something not only we
  8661. 5:04:57replace and you can do that by not
  8662. 5:04:59specifying anything in the new value
  8663. 5:05:01like just the single quotes and with
  8664. 5:05:03that it's going to be nothing a blank.
  8665. 5:05:05So now what's going to happen is still
  8666. 5:05:06going to go and replace the dash with a
  8667. 5:05:09blank and that means I'm just removing
  8668. 5:05:11the dashes from the output. So if you do
  8669. 5:05:13it you will remove the dash and you will
  8670. 5:05:15get only numbers. So if the replacement
  8671. 5:05:17going to be a blank then that means this
  8672. 5:05:19function will be replacing any value
  8673. 5:05:21that you specify. So this is exactly how
  8674. 5:05:24it works and this is why we use the
  8675. 5:05:26replace function in SQL. Now let's go
  8676. 5:05:28back in order to practice. So let's do
  8677. 5:05:30the same example. This time we're going
  8678. 5:05:31to go and select from a static value. So
  8679. 5:05:33we're going to get 1 2 3 4 5 6 7 8 9 0.
  8680. 5:05:37So if you go and execute it, you can see
  8681. 5:05:39we are getting the phone number. Now
  8682. 5:05:41let's go and remove the dashes from this
  8683. 5:05:43value. So let's have a new line and we
  8684. 5:05:45start with replace. The first thing that
  8685. 5:05:47you have to specify for SQL the value
  8686. 5:05:49itself. So let's go and get the value.
  8687. 5:05:51This is the first argument. The second
  8688. 5:05:53argument going to be the old value. So
  8689. 5:05:55the old value going to be the dash. And
  8690. 5:05:57now the third argument will be the
  8691. 5:06:00replacement. And since we want to remove
  8692. 5:06:02it, we don't want to replace it with
  8693. 5:06:04anything. We will have just single
  8694. 5:06:05quotes and nothing between them. So
  8695. 5:06:07there's no space between those single
  8696. 5:06:09quotes. Now we can go and rename stuff
  8697. 5:06:11like this is the phone. And this is a
  8698. 5:06:13clean phone. Let's go and execute it.
  8699. 5:06:16Now, as you can see in the output of the
  8700. 5:06:18function, we don't have any dashes
  8701. 5:06:20between the numbers. And you can go and
  8702. 5:06:22test stuff. Like for example, I can go
  8703. 5:06:25and add a slash and execute it. You will
  8704. 5:06:27see slashes between them. So you can go
  8705. 5:06:29and try multiple stuff. So this is one
  8706. 5:06:31nice use case for the replace function.
  8707. 5:06:33Now there is another use case for the
  8708. 5:06:35replace function is that sometimes in my
  8709. 5:06:37data file names going to be stored like
  8710. 5:06:40for example, let's say reports.t txt and
  8711. 5:06:43now let's say that I would like to
  8712. 5:06:44change the file format from .txt to CSV.
  8713. 5:06:48Now how we're going to do that we're
  8714. 5:06:49going to go with a new line say replace
  8715. 5:06:51and then the first argument going to be
  8716. 5:06:53the value. So let's take our value from
  8717. 5:06:56here and now what is the old value it's
  8718. 5:06:58going to be the txt and I want to
  8719. 5:07:00replace it with another format with
  8720. 5:07:03another extension. So it's going to be
  8721. 5:07:04the CSV. So we're going to say this is
  8722. 5:07:07the new file name and this is the old
  8723. 5:07:10file name. So let's go and execute it.
  8724. 5:07:13And now as you can see in the output SQL
  8725. 5:07:15did replace the txt with SCSV. This is
  8726. 5:07:18as well where I use the replace function
  8727. 5:07:20in my projects. So my friends the
  8728. 5:07:22replace function is really fun and those
  8729. 5:07:24are two nice use cases for the replace.
  8730. 5:07:26All right. So that's all about the
  8731. 5:07:28replace function in SQL and with that we
  8732. 5:07:30have covered the whole datamations. Now
  8733. 5:07:32in the next group we're going to talk
  8734. 5:07:33about the calculations. And here we have
  8735. 5:07:35only one function the
  8736. 5:07:40length. Now the length function it's
  8737. 5:07:42very simple. It's going to go and count
  8738. 5:07:44how many characters you have in one
  8739. 5:07:46value. So you are calculating the length
  8740. 5:07:48of a value. Let's have very simple
  8741. 5:07:50example to understand it. Okay. So now
  8742. 5:07:52let's say that we have the value Maria.
  8743. 5:07:53If you apply the length function for
  8744. 5:07:55that what's going to happen? It's going
  8745. 5:07:56to go and start counting how many
  8746. 5:07:58characters we have inside this value. So
  8747. 5:08:00the m is 1. a 2 3 4 5 in the output you
  8748. 5:08:04will get the number five. So five is the
  8749. 5:08:07length or the total number of characters
  8750. 5:08:08in this value. Now let's say that you
  8751. 5:08:10have a number like 350. If you go and
  8752. 5:08:12apply the length function still is going
  8753. 5:08:14to go and count how many digits do we
  8754. 5:08:16have. The three is 1 5 2 3. So the total
  8755. 5:08:19length for that going to be three. So
  8756. 5:08:21you can apply it even for numbers and
  8757. 5:08:23not only that you can go and apply it on
  8758. 5:08:25a date value. So let's say that you have
  8759. 5:08:26the following date 2026 1st 23. So SQL
  8760. 5:08:30going to go and count each digit each
  8761. 5:08:32character even the underscores not only
  8762. 5:08:34the numbers underscore is as well a
  8763. 5:08:36digit right? So the total length of this
  8764. 5:08:38date it's going to be 10. So you can
  8765. 5:08:40apply any data type to the links
  8766. 5:08:42function and in the output you will get
  8767. 5:08:44always a number. That's it. This is how
  8768. 5:08:46you can count the number of characters
  8769. 5:08:47in any value. Let's go back to scale in
  8770. 5:08:49order to practice that. Okay. So now we
  8771. 5:08:51have the task calculate the length of
  8772. 5:08:53each customer's first name. So it is
  8773. 5:08:56very simple. We're going to go and apply
  8774. 5:08:57the function length len to the column
  8775. 5:09:01first name and we're going to call it
  8776. 5:09:03length name. So let's go and execute it.
  8777. 5:09:06And with that as you can see we are
  8778. 5:09:07getting in the output numbers and these
  8779. 5:09:09numbers are the number of characters of
  8780. 5:09:12each name of our customers. So this is
  8781. 5:09:14how we calculate the length and that's
  8782. 5:09:16it for this group. Now moving on to the
  8783. 5:09:18next one. It's going to be very
  8784. 5:09:19interesting. Now we're going to talk
  8785. 5:09:20about how to extract something from a
  8786. 5:09:22string value. And here we're going to
  8787. 5:09:24cover now two functions the left and the
  8788. 5:09:29right. Now the lift function going to go
  8789. 5:09:32and extract specific number of
  8790. 5:09:34characters from the start of a string
  8791. 5:09:36value. So if you want to get few
  8792. 5:09:38characters at the beginning of a value,
  8793. 5:09:40you can use the lift. But now the right
  8794. 5:09:42function is exactly the opposite. It's
  8795. 5:09:44going to go and extract specific number
  8796. 5:09:46of characters from the end of string
  8797. 5:09:49value. So if you want few characters
  8798. 5:09:51from the end of your value, you can use
  8799. 5:09:53right. Now in order to apply the left or
  8800. 5:09:55the right function, you have to give SQL
  8801. 5:09:57two things. The value where you want to
  8802. 5:09:59extract a part from it and the number of
  8803. 5:10:01characters, how many characters you want
  8804. 5:10:03to extract and this is the same for the
  8805. 5:10:04left and the right. Now let's say that
  8806. 5:10:06we have again this value Mariam. And now
  8807. 5:10:08if the task says I would like to extract
  8808. 5:10:10the first two characters and since we
  8809. 5:10:12are talking about the starting position,
  8810. 5:10:14we're going to use the lift function.
  8811. 5:10:16And since it says two characters, we're
  8812. 5:10:17going to go with the two. So it's going
  8813. 5:10:19to start counting M is 1, A is two and
  8814. 5:10:22after that it's going to stop and make a
  8815. 5:10:23cut and it's going to go and return the
  8816. 5:10:25two characters M A. So we are counting
  8817. 5:10:27from the left side going to the right
  8818. 5:10:29side. Right now if your task says
  8819. 5:10:32extract the last two characters here we
  8820. 5:10:34are talking about the end position of
  8821. 5:10:36your value and for that we're going to
  8822. 5:10:38use the right function since we are
  8823. 5:10:40approaching from the right side and
  8824. 5:10:42since we want only two characters the
  8825. 5:10:43number of characters going to be two. So
  8826. 5:10:45this time going to start counting from
  8827. 5:10:46the right side moving to the left side.
  8828. 5:10:49So A is one, I is two and that's it.
  8829. 5:10:52Then SQL going to stop and extract only
  8830. 5:10:54those two characters. I A. So if you
  8831. 5:10:56want to extract data at the starting
  8832. 5:10:58position, you use the left. But if you
  8833. 5:10:59want to extract characters from the end
  8834. 5:11:01position of your value, then you use the
  8835. 5:11:04right function. Now let's go back to
  8836. 5:11:05scaler in order to practice. Okay. So
  8837. 5:11:07now we have the following task. Retrieve
  8838. 5:11:09the first two characters of each first
  8839. 5:11:11name. So we just need the first two
  8840. 5:11:13characters. Since we are coming from the
  8841. 5:11:15left side, we can go and use the
  8842. 5:11:17function left. So it's very simple.
  8843. 5:11:19First name and we need only two
  8844. 5:11:22characters. So two. So we're going to
  8845. 5:11:23call it first to character. Let's go
  8846. 5:11:26ahead and execute it. And now you can
  8847. 5:11:28see in the output we have two characters
  8848. 5:11:30MA. Now with John we have only G because
  8849. 5:11:32we have a leading space. Well, you can
  8850. 5:11:35leave it like this or you can transform
  8851. 5:11:36it. And then George we have G and so on.
  8852. 5:11:39So with that we are getting the first
  8853. 5:11:40three characters. Now in order to fix it
  8854. 5:11:42for John what we're going to do we're
  8855. 5:11:43going to say trim first and then apply
  8856. 5:11:46the lift. So with that we are getting
  8857. 5:11:48rid of all white spaces and then we
  8858. 5:11:50apply the lift. So with that everything
  8859. 5:11:52looks perfect. So for John we have jo.
  8860. 5:11:54So this is how we can get the first two
  8861. 5:11:56characters of a column. Now let's move
  8862. 5:11:58to the next one. The task says retrieve
  8863. 5:12:01the last two characters of each first
  8864. 5:12:03name. So this time we need the last two.
  8865. 5:12:05So we are coming from the right side. So
  8866. 5:12:07we're going to do it like this. We're
  8867. 5:12:08going to say
  8868. 5:12:10write first name and then as well too.
  8869. 5:12:14So last two character let's go and
  8870. 5:12:17execute it. And now as you can see in
  8871. 5:12:18the output we have new column where we
  8872. 5:12:20have the last two characters from the
  8873. 5:12:21first name. So we have here I a er and
  8874. 5:12:25for John as well working and that's
  8875. 5:12:26because we don't have any trailing
  8876. 5:12:28spaces but if you have any trailing
  8877. 5:12:30spaces then go and use that trim
  8878. 5:12:32function. All right so that's all for
  8879. 5:12:33the left and right and now we're going
  8880. 5:12:35to go to the last function. we have the
  8881. 5:12:40substring. So the substring going to go
  8882. 5:12:42and extract a part of a string at a
  8883. 5:12:45specified position. So this time we
  8884. 5:12:47don't want something from the beginning
  8885. 5:12:48or the end. We want something like in
  8886. 5:12:51the middle. So we want to specify the
  8887. 5:12:53starting position and we want to extract
  8888. 5:12:55few characters from there. So let's have
  8889. 5:12:57very simple example to understand it.
  8890. 5:12:58Now in order to use the substring you
  8891. 5:13:00need three things. The first one is the
  8892. 5:13:02value itself where you want to extract a
  8893. 5:13:05specific part from it and then you have
  8894. 5:13:07to specify the starting position where
  8895. 5:13:09SQL going to start extracting the
  8896. 5:13:11characters that you want and as well SQL
  8897. 5:13:13needs the links how many characters we
  8898. 5:13:15have to extract. So now let's say that
  8899. 5:13:17we have the following task after the
  8900. 5:13:19second character extract two characters.
  8901. 5:13:22So from reading this you can see we
  8902. 5:13:24specified the starting position this is
  8903. 5:13:26the second character and the length
  8904. 5:13:28going to be the two characters. So let's
  8905. 5:13:30have this example. Well, if you have
  8906. 5:13:31Maria, so now we have to specify the
  8907. 5:13:33starting position. Now we are saying
  8908. 5:13:35after the second character. So the first
  8909. 5:13:37character m is one. Then a is two. After
  8910. 5:13:40two, we got the position number three,
  8911. 5:13:42right? So starting from R. So that means
  8912. 5:13:44we have to specify for SQL three because
  8913. 5:13:47the starting position going to be number
  8914. 5:13:49three. This is after the two. Now we
  8915. 5:13:51want only two characters. So we want the
  8916. 5:13:53R and the I. If you give this to SQL
  8917. 5:13:55Maria starting position three and the
  8918. 5:13:58length two, SQL can go and extract the
  8919. 5:14:00two characters the R I. And this is
  8920. 5:14:03exactly what we want. We want two
  8921. 5:14:04characters after the second position,
  8922. 5:14:06the second character. So with that, we
  8923. 5:14:08didn't extract something from the left
  8924. 5:14:10or from the right. We extracted at
  8925. 5:14:12specific position. And this is exactly
  8926. 5:14:14why we need the substring. Now let's
  8927. 5:14:16make it a little bit more difficult
  8928. 5:14:17where we're going to say after the
  8929. 5:14:19second character extract everything all
  8930. 5:14:22the characters. So not only RA I I would
  8931. 5:14:24like RA I A. So now nothing's changed
  8932. 5:14:26about the starting position. It's going
  8933. 5:14:27to stay at three. But now if you are
  8934. 5:14:29looking to this value and you want to
  8935. 5:14:31extract everything starting from R. That
  8936. 5:14:33means you have to specify the length of
  8937. 5:14:35three. But this is not really good
  8938. 5:14:37because let's have another value in the
  8939. 5:14:39same column. So we have Martin. So the
  8940. 5:14:41starting position going to be as well R.
  8941. 5:14:43And now the lengths going to be
  8942. 5:14:45different. So we have here four
  8943. 5:14:47characters. So now the length is not
  8944. 5:14:48anymore three. It is four. But you have
  8945. 5:14:50to specify something at the end for SQL.
  8946. 5:14:52You can go for four. That's fine for
  8947. 5:14:54Maria as well. But if you have a lot of
  8948. 5:14:56values, it's going to be really hard to
  8949. 5:14:58specify exactly the correct length.
  8950. 5:15:00That's why instead of specifying a
  8951. 5:15:02static number like three or four, we can
  8952. 5:15:05use another function. So now my friends,
  8953. 5:15:07if you use the length function, you will
  8954. 5:15:09get the total number of characters,
  8955. 5:15:11right? So for Maria, you will get five.
  8956. 5:15:13For Martin, you will get six. And those
  8957. 5:15:15numbers are okay to use in the length
  8958. 5:15:17because they are more than what we need.
  8959. 5:15:19And that's totally fine. So if you are
  8960. 5:15:21saying okay for Maria start from the
  8961. 5:15:23third position and cut for me five
  8962. 5:15:25characters SQL going to find only three
  8963. 5:15:27but you will not get an error. So you
  8964. 5:15:29are extracting more than you need and
  8965. 5:15:31you will always get all the characters
  8966. 5:15:32after the starting position. So this is
  8967. 5:15:34a little trick that we use in order to
  8968. 5:15:37make the links dynamic where we cannot
  8969. 5:15:39find one value that we can use in all
  8970. 5:15:41scenarios. And now let's go back to SQL
  8971. 5:15:43in order to practice the substring.
  8972. 5:15:46Okay. So now we have the following task
  8973. 5:15:47and it says retrieve a list of customers
  8974. 5:15:50first names after removing the first
  8975. 5:15:52character. So now don't ask me why but
  8976. 5:15:54for some reason we don't want to see the
  8977. 5:15:56first character of the first names. We
  8978. 5:15:58want to remove it. So how we can do
  8979. 5:16:00that? We cannot use the left or the
  8980. 5:16:01right. We have to go with the substring
  8981. 5:16:04because it is little bit more
  8982. 5:16:05complicated. So substring and let's go
  8983. 5:16:08and get and the first argument going to
  8984. 5:16:10be the value. So it comes from the first
  8985. 5:16:12name and then the second argument is the
  8986. 5:16:14starting position. So where we want to
  8987. 5:16:16start since it is saying I want all the
  8988. 5:16:18characters after the first character. So
  8989. 5:16:21that means we will be starting from the
  8990. 5:16:23position number two. So for example
  8991. 5:16:25Maria here the first character M
  8992. 5:16:27position number one and we want to start
  8993. 5:16:29our substring from the position number
  8994. 5:16:31two. So that was so that was the easy
  8995. 5:16:33part. Now the next one the question is
  8996. 5:16:36how much characters we want to leave. So
  8997. 5:16:38do we leave here like four characters
  8998. 5:16:41like in Maria we have four characters
  8999. 5:16:43but in John we have only three then the
  9000. 5:16:45next one is four and so on. So if you go
  9001. 5:16:48for example with four and let's call it
  9002. 5:16:51sub name. So we make it static. What can
  9003. 5:16:54happen? It's going to work for some
  9004. 5:16:56scenarios like Maria. We have here Ara
  9005. 5:16:58and for better we are getting it. But
  9006. 5:17:01for Martin it is not working. We are not
  9007. 5:17:03getting the last N because it has like
  9008. 5:17:06five characters after the first one. And
  9009. 5:17:08by just looking to the result as you can
  9010. 5:17:10see we have here one issue with John and
  9011. 5:17:12that's because the first character is an
  9012. 5:17:14empty string. So this is really
  9013. 5:17:16annoying. So that's why we use the trim
  9014. 5:17:18first just to get rid of all those white
  9015. 5:17:21spaces. And now you can see it's working
  9016. 5:17:23fine. So we are not getting the J. We
  9017. 5:17:25have everything after the first
  9018. 5:17:26character. So now instead of having this
  9019. 5:17:28static what we're going to do we're
  9020. 5:17:30going to make it variable. So we're
  9021. 5:17:32going to go and use the length of the
  9022. 5:17:35first name. So with that we make sure we
  9023. 5:17:38have enough length to extract. And this
  9024. 5:17:41can work for any value inside the first
  9025. 5:17:43name even if the name is like 20
  9026. 5:17:45characters. So let's go and execute. And
  9027. 5:17:48now you can see for Martin it is now
  9028. 5:17:50working. So we have here like five
  9029. 5:17:51characters after the M. And here we have
  9030. 5:17:53four characters after the M as well. And
  9031. 5:17:56here we have three characters after the
  9032. 5:17:57G. So it is working completely and it is
  9033. 5:18:00full dynamic. So this is the trick by
  9034. 5:18:03using the links together with the
  9035. 5:18:04substring. And as you can see now we are
  9036. 5:18:06using three functions in one go. We have
  9037. 5:18:09the length, we have the trim and we have
  9038. 5:18:11the substring. And this is what happens
  9039. 5:18:12in scale. we use multiple functions
  9040. 5:18:15together in order to solve like complex
  9041. 5:18:17tasks. So this is how you can extract a
  9042. 5:18:20substring from a string. All right. So
  9043. 5:18:23that's all about the substring and with
  9044. 5:18:24that we have covered a lot of very
  9045. 5:18:26important string functions in SQL and
  9046. 5:18:28now you have enough tools in order to
  9047. 5:18:30manipulate the string values in your
  9048. 5:18:32data. Okay my friends. So with that we
  9049. 5:18:34have learned how to manipulate your
  9050. 5:18:35string values inside SQL using the
  9051. 5:18:37string functions. Now we will move to
  9052. 5:18:39the second one. you will learn how to
  9053. 5:18:41manipulate the numbers, the numeric
  9054. 5:18:43values. So let's
  9055. 5:18:48go. Okay. So now let's have this example
  9056. 5:18:513.516. Now let's say that you want to
  9057. 5:18:53apply the function round and you are
  9058. 5:18:55using two decimal places. So what going
  9059. 5:18:57to happen? It's going to go and keep
  9060. 5:18:59only two digits after the decimal point.
  9061. 5:19:01So five and one and the third digit
  9062. 5:19:04after the decimal six. It will decide
  9063. 5:19:06whether the number going to round up or
  9064. 5:19:08stay as it is. And now since six is
  9065. 5:19:10higher than five. So that means SQL
  9066. 5:19:13going to go around the numbers up. So
  9067. 5:19:15instead of having 51 we will get 52. And
  9068. 5:19:18after that the third digit going to
  9069. 5:19:20reset to zero. So in the out you will
  9070. 5:19:22get
  9071. 5:19:233.52. Now let's say that you have done
  9072. 5:19:25round but only for one decimal place.
  9073. 5:19:28Now it's still going to go and keep only
  9074. 5:19:30one decimal place and that is the five.
  9075. 5:19:32And the second digit this time going to
  9076. 5:19:34decide whether we round up or not. And
  9077. 5:19:36now since one is less than five, there
  9078. 5:19:39is no need to round up and the five
  9079. 5:19:40going to stay as it is. It will not turn
  9080. 5:19:42to six. So there is no round up and the
  9081. 5:19:45digits after the five going to reset to
  9082. 5:19:47zero. So we're going to get 3.5. Now
  9083. 5:19:49let's say that you say round zero. So
  9084. 5:19:51that means I don't want to see any
  9085. 5:19:53digits after the decimal point. So now
  9086. 5:19:55SQL going to go and check the first
  9087. 5:19:57digit after the decimal point, the five.
  9088. 5:19:59This one going to decide whether the
  9089. 5:20:01three going to turn to four or not. And
  9090. 5:20:03now since we have five it is good enough
  9091. 5:20:05to round the number because either five
  9092. 5:20:07or above five going to round the
  9093. 5:20:10numbers. So that's why it's going to be
  9094. 5:20:12a round up and SQL going to return at
  9095. 5:20:14the end four and all the digits after
  9096. 5:20:16the decimal points going to be reset to
  9097. 5:20:18zero. So this is exactly how the round
  9098. 5:20:20function works in SQL. So now let's see
  9099. 5:20:22how we can do that in SQL. Okay. So now
  9100. 5:20:25let's go and practice about the number
  9101. 5:20:26functions. So what we're going to do
  9102. 5:20:27we're going to write SQL select but this
  9103. 5:20:29time we will not select any data from
  9104. 5:20:31the database. We going to practice using
  9105. 5:20:33our static value like for example the
  9106. 5:20:35value 3 dot 516. So let's go and execute
  9107. 5:20:39it. So with that I have this decimal
  9108. 5:20:41number. Now let's go and start
  9109. 5:20:43practicing the round function. So now
  9110. 5:20:45let's go and round this number
  9111. 5:20:483.516 and this time we are rounding to
  9112. 5:20:51decimals. So let's go and call it round
  9113. 5:20:54two and let's go and execute it. So as
  9114. 5:20:56you can see in the output we are
  9115. 5:20:57rounding two decimal places and we have
  9116. 5:21:00the two because as we learned the six
  9117. 5:21:02going to go and round it up. Now let's
  9118. 5:21:04go and do the same thing for one. So
  9119. 5:21:07let's round one execute. And as you can
  9120. 5:21:10see in the output we are rounding to one
  9121. 5:21:12decimal. So we have the five and
  9122. 5:21:14everything is zero. And we don't have
  9123. 5:21:16six here because the one is lower than
  9124. 5:21:18five and it will not round up the
  9125. 5:21:20numbers. And let's and round by the
  9126. 5:21:23zero. it is rounding it to an integer to
  9127. 5:21:27the four and all the decimal digits are
  9128. 5:21:29zero and we have four because we have
  9129. 5:21:31five and five going to round up the
  9130. 5:21:33number. So as you can see it is really
  9131. 5:21:35nice and this is how we round numbers in
  9132. 5:21:40SQL. Now there is another number
  9133. 5:21:42function which is really cool called APS
  9134. 5:21:45or the absolute what it going to do it's
  9135. 5:21:47going to go and convert any negative
  9136. 5:21:49number to a positive. So let me show you
  9137. 5:21:51what I mean. Let's go and say we have
  9138. 5:21:53like minus 10. So this is a negative
  9139. 5:21:55number. But if I say APS, so the
  9140. 5:21:57absolute of the minus 10, what I will
  9141. 5:22:00get? I will get a positive number. So
  9142. 5:22:02it's like giving us the absolute of any
  9143. 5:22:04number or in other words, it is like
  9144. 5:22:06converting the negative to a positive.
  9145. 5:22:08And if the number is already positive,
  9146. 5:22:11nothing going to happen. So if I say the
  9147. 5:22:13absolute of the 10, I will get as well a
  9148. 5:22:1510. So this is really nice and cool
  9149. 5:22:17function that is really important in
  9150. 5:22:19order to transform numbers in many
  9151. 5:22:21scenarios like if you have mistakes on
  9152. 5:22:23your database like let's say minus sales
  9153. 5:22:26makes no sense to have sales that is
  9154. 5:22:28minus. So in order to correct the data
  9155. 5:22:29we can use the APS in order to convert
  9156. 5:22:32all the negative numbers to a positive.
  9157. 5:22:34So this is really nice cool and easy
  9158. 5:22:36function to learn. All right my friends.
  9159. 5:22:38So that's all for the numeric functions.
  9160. 5:22:40We have covered two very simple
  9161. 5:22:41functions and now in the next topic we
  9162. 5:22:43have a lot of functions about how to
  9163. 5:22:45manipulate the date and time in SQL. So
  9164. 5:22:47let's
  9165. 5:22:51go. So what is a date? If you take a
  9166. 5:22:54look at calendar and you pick any date,
  9167. 5:22:57for example, August 20th,
  9168. 5:23:002025, this date could represent an event
  9169. 5:23:03like a birth date. Happy birthday.
  9170. 5:23:08Happy birthday.
  9171. 5:23:10or a project deadline at your work and
  9172. 5:23:13mainly it has three components. The
  9173. 5:23:15first part is a fourdigit number
  9174. 5:23:17indicating the year. Then the next
  9175. 5:23:19component it is the month. So normally
  9176. 5:23:22we represent the month with a number
  9177. 5:23:24between 1 and 12. And the last component
  9178. 5:23:26is the day. This is a number between 1
  9179. 5:23:29and 31 depending on the month. Now in
  9180. 5:23:31database we call this structure of those
  9181. 5:23:33three components a date. So this is what
  9182. 5:23:36we mean with dates in SQL. All right.
  9183. 5:23:38All right. So now let's move to the next
  9184. 5:23:39one. What is time? Time refers to a
  9185. 5:23:42specific point within a day. Like for
  9186. 5:23:44example, we have 18:00, 55 minutes, and
  9187. 5:23:4745 seconds. So this structure has as
  9188. 5:23:50well three components. The first one we
  9189. 5:23:52call it the hours. It is as well a
  9190. 5:23:54number between 0 and 23 indicating the
  9191. 5:23:57hour of the day. Then the next one, it
  9192. 5:23:59is the minutes. This is a number between
  9193. 5:24:010 and 59. Moving on to the last
  9194. 5:24:03component, we have the second. This is
  9195. 5:24:05again the same thing a number between 0
  9196. 5:24:08and 59. So now this structure with those
  9197. 5:24:11three components we call it in databases
  9198. 5:24:13and SQL a time. So this is what we mean
  9199. 5:24:15with the time. Now to the last type if
  9200. 5:24:18you go and combine both the date
  9201. 5:24:20together with the time and you put them
  9202. 5:24:22side by side you will get a new
  9203. 5:24:25structure and a new name in the
  9204. 5:24:26databases and we call it usually time
  9205. 5:24:29stamp. This name is used in many
  9206. 5:24:31databases like Oracle, Postgress and
  9207. 5:24:33MySQL. But in the SQL server, we have
  9208. 5:24:35another name for that. We call it date
  9209. 5:24:37time. So again, it's very simple. The
  9210. 5:24:39date time or time stamp has the date
  9211. 5:24:41information together with the time
  9212. 5:24:43information. So here in this example, we
  9213. 5:24:45have six components from left to right
  9214. 5:24:47and here we have like a hierarchy in
  9215. 5:24:49this structure. So we start with the
  9216. 5:24:50highest which is the year. Then we have
  9217. 5:24:53the month, the day and then we continue
  9218. 5:24:55to the hour, minutes and seconds. So
  9219. 5:24:58those are the three different types
  9220. 5:25:00about date and time informations in SQL.
  9221. 5:25:02We have the date alone or the time alone
  9222. 5:25:05or together in the date time. All right,
  9223. 5:25:08let's explore now the data that we have
  9224. 5:25:10inside our database searching for date
  9225. 5:25:12and time informations. Now let's go to
  9226. 5:25:14the table orders and if you go and
  9227. 5:25:16expand it, you will find here two
  9228. 5:25:18columns having the data type dates. So
  9229. 5:25:20we have the order dates with the date
  9230. 5:25:22and as well the shipping date with the
  9231. 5:25:24data type dates. And if you check the
  9232. 5:25:26last column, the creation date, this one
  9233. 5:25:28is date time 2. So now let's go and
  9234. 5:25:30query those informations in order to
  9235. 5:25:32understand the structure. I'm just going
  9236. 5:25:34to select the order ID, the order date,
  9237. 5:25:38and the ship
  9238. 5:25:39date and the creation
  9239. 5:25:43time from sales orders and from is big.
  9240. 5:25:47So let's go and execute it. Now if you
  9241. 5:25:49go and check both order date and ship
  9242. 5:25:51date, you can find that here we have
  9243. 5:25:53only the structure or the informations
  9244. 5:25:55about the date and we have nothing about
  9245. 5:25:57the time. So again here we have a year,
  9246. 5:25:59month and day and that's why they have
  9247. 5:26:01the data type date. Now let's go and
  9248. 5:26:03check the creation time. Not only we
  9249. 5:26:05have the date information but as well we
  9250. 5:26:07have the time information. So it start
  9251. 5:26:09with the date information year, month,
  9252. 5:26:11day and then we have hour, minute and
  9253. 5:26:14seconds and then we have fractions of
  9254. 5:26:16the seconds, milliseconds and so on. So
  9255. 5:26:18this is how the date time or time stamp
  9256. 5:26:20looks like in databases and this is how
  9257. 5:26:22the date looks
  9258. 5:26:27like. All right my friends now in SQL I
  9259. 5:26:30can say that we have three different
  9260. 5:26:32sources in order to query the dates. The
  9261. 5:26:35first one is dates that are stored
  9262. 5:26:37inside our database like we saw here in
  9263. 5:26:40those columns like the order date,
  9264. 5:26:41shipping date, creation time. All those
  9265. 5:26:44are columns that holds this informations
  9266. 5:26:46and they are stored inside our database.
  9267. 5:26:49So this is the first source of dates
  9268. 5:26:50that we can get inside our queries. Let
  9269. 5:26:52me just remove those stuff and let's
  9270. 5:26:54stick with the creation time. So let's
  9271. 5:26:56just execute it. So those are date and
  9272. 5:26:58time informations stored inside our
  9273. 5:27:00database. The second type is a
  9274. 5:27:02hard-coded date string that we can use
  9275. 5:27:05inside our queries. Let me show you an
  9276. 5:27:07example. So now if we go to a new line,
  9277. 5:27:09I can go and define a date like this. So
  9278. 5:27:132025 August 20th. So that in this string
  9279. 5:27:17we have hardcoded a date that is static
  9280. 5:27:20for all rows. Let me just call it
  9281. 5:27:23hardcoded and let's go and execute it.
  9282. 5:27:26Now we can see in the output we're going
  9283. 5:27:27to get a static date for all rows. So
  9284. 5:27:30this going to be the same for all rows
  9285. 5:27:32inside our table. So this value is not
  9286. 5:27:34stored inside our database. This value I
  9287. 5:27:37just added to our query and hardcoded
  9288. 5:27:39it. So sometimes in queries we define
  9289. 5:27:41our dates that's going to be used maybe
  9290. 5:27:43later in calculations and so on. Now the
  9291. 5:27:46third source of getting dates inside our
  9292. 5:27:48query is using the function get date.
  9293. 5:27:51Get date is the first and the most
  9294. 5:27:53important function that we use in SQL.
  9295. 5:27:55It's going to go and return the current
  9296. 5:27:57date and time at the moment of executing
  9297. 5:28:00the query. So let's try that out. I'm
  9298. 5:28:02going to go and get a new line. So get
  9299. 5:28:04dates. It's very simple. It doesn't
  9300. 5:28:06accept any values inside the function.
  9301. 5:28:08So it's going to be empty. So let's call
  9302. 5:28:10it today. All right. Let's go and
  9303. 5:28:12execute it. And of course, we're going
  9304. 5:28:14to get different results because the get
  9305. 5:28:16date now is the date and the time that
  9306. 5:28:18I'm recording this video. So currently
  9307. 5:28:21it is July 18, 2024. And I'm recording
  9308. 5:28:24this around 20 p.m. So as you can see,
  9309. 5:28:26this going to be as well repeated for
  9310. 5:28:28each row. We're going to get always the
  9311. 5:28:30same value. So again, this depend on the
  9312. 5:28:32execution of that query. So during the
  9313. 5:28:34tutorial, you're going to learn a lot
  9314. 5:28:36about the get date and we're going to
  9315. 5:28:37use it in a lot of functions. So those
  9316. 5:28:39are the three different sources of
  9317. 5:28:40getting date information inside your
  9318. 5:28:42query either from a column inside our
  9319. 5:28:44database or hardcoded using a string.
  9320. 5:28:47And the third one is using the get date
  9321. 5:28:49in order to get the current date and
  9322. 5:28:51time informations at the moment of the
  9323. 5:28:54query
  9324. 5:28:58execution. Nice. Now we have a clear
  9325. 5:29:00understanding what is date and time in
  9326. 5:29:02SQL. The next question is how to
  9327. 5:29:04manipulate those informations using SQL
  9328. 5:29:07functions. Okay. Now we have our date
  9329. 5:29:09August 20th, 2025. One of the things
  9330. 5:29:11that we can do with the date is we can
  9331. 5:29:13go and extract different parts of the
  9332. 5:29:16date. For example, we are interested
  9333. 5:29:17only on the year. So we can go and
  9334. 5:29:19extract only the year part. Or if you
  9335. 5:29:21are interested in the month, you can go
  9336. 5:29:23and extract the month and you will get
  9337. 5:29:24August. And of course, we can go and
  9338. 5:29:26extract the day and we will get the 20.
  9339. 5:29:28So this is the first thing that we can
  9340. 5:29:30do. We can extract the parts of the
  9341. 5:29:32dates. Now another thing that we can do
  9342. 5:29:33is we can go and change the date format.
  9343. 5:29:36So instead of having like a small minus
  9344. 5:29:39between those date parts, we can go and
  9345. 5:29:41split them using slash. We can even
  9346. 5:29:43start first with the month August then
  9347. 5:29:4520 the day and then the year but having
  9348. 5:29:48only the short form of the year 25 or we
  9349. 5:29:50can go and change the format where we
  9350. 5:29:52say we don't need any special character
  9351. 5:29:54we just leave it as a space. So as you
  9352. 5:29:56can see we are changing and manipulating
  9353. 5:29:58the format of the date. Another category
  9354. 5:30:00or task we can go and do date
  9355. 5:30:02calculations. So we can go and take our
  9356. 5:30:04date and add to it for example 3 years
  9357. 5:30:07or we can go and find the differences
  9358. 5:30:09between two dates like we are doing a
  9359. 5:30:11subtraction or let's say minus and we
  9360. 5:30:13will get for example 30 days. So we can
  9361. 5:30:16go and add stuff subtract stuff or find
  9362. 5:30:18differences between two dates. It's like
  9363. 5:30:20we are doing calculations on the date.
  9364. 5:30:21Now to the last thing that we can do
  9365. 5:30:23with this date is we can go and test
  9366. 5:30:25this date or validate it whether it is a
  9367. 5:30:28real date that SQL understands. So we
  9368. 5:30:31can put it on the test and at the output
  9369. 5:30:33we're going to get true or false or zero
  9370. 5:30:35and one. So as you can see here we have
  9371. 5:30:36different ways or let's say categories
  9372. 5:30:39on how to manipulate our dates in SQL.
  9373. 5:30:41Now we're going to go and group up the
  9374. 5:30:43different date and time functions under
  9375. 5:30:45four categories. The first category and
  9376. 5:30:47the most important one we have the part
  9377. 5:30:49extraction and here we have around seven
  9378. 5:30:51different functions that we can use in
  9379. 5:30:54order to do this task. Another category
  9380. 5:30:56we have the format and casting. And here
  9381. 5:30:58we have three different functions.
  9382. 5:31:00Underneath this category we have the
  9383. 5:31:01format, convert and cast. And then the
  9384. 5:31:04third category we have the calculations
  9385. 5:31:06of the dates. We have two functions date
  9386. 5:31:08add and date diff. And the last category
  9387. 5:31:10the validation. We have here only one
  9388. 5:31:12function called is dates. So as you can
  9389. 5:31:14see we have a lot of scale functions. We
  9390. 5:31:16have 13 date and time functions that
  9391. 5:31:19we're going to cover in this tutorial on
  9392. 5:31:20how to manipulate the date and time
  9393. 5:31:22informations in SQL. And this is how we
  9394. 5:31:24can group them into four different
  9395. 5:31:26categories. Let's start now with the
  9396. 5:31:28biggest category. We have the part
  9397. 5:31:29extraction. We're going to cover all
  9398. 5:31:31those seven functions in details on how
  9399. 5:31:33to extract
  9400. 5:31:37parts. All right friends, now we're
  9401. 5:31:39going to cover three very easy quick
  9402. 5:31:41functions in SQL to extract the parts of
  9403. 5:31:43the dates. So they are very simple. The
  9404. 5:31:45day function going to return a day from
  9405. 5:31:48a date and in the same way the month
  9406. 5:31:50going to return the month from a date
  9407. 5:31:53and guess what the year going to return
  9408. 5:31:56a year from a date. Okay. So now in
  9409. 5:31:58order to understand how they work we
  9410. 5:32:00have a date like this one 2025 August
  9411. 5:32:0320th. Sometimes you are not interested
  9412. 5:32:05in the whole date. You would like to get
  9413. 5:32:07only a part from this date. So you go
  9414. 5:32:09and use the function day in order to
  9415. 5:32:12extract the two digit 20. Now in other
  9416. 5:32:15scenario you might be interested in the
  9417. 5:32:17month information. So you would like to
  9418. 5:32:19get those two digits 08. So we can use
  9419. 5:32:22the function month in order to extract
  9420. 5:32:25the month information in order to get
  9421. 5:32:27the August. So 08 and one more situation
  9422. 5:32:30where you want to have only the year
  9423. 5:32:32information. So you are interested in
  9424. 5:32:34the four digits 2025. So you can go and
  9425. 5:32:37use the function year in order to
  9426. 5:32:39extract it. So in the output if you
  9427. 5:32:41apply it you will get 2025. So it's very
  9428. 5:32:44simple. This is how those three
  9429. 5:32:45functions work. All right. Now let's
  9430. 5:32:47check the syntax of those three
  9431. 5:32:48functions. It's pretty easy. So we have
  9432. 5:32:50it always like this. A keyword called
  9433. 5:32:52day. This is the function name. And then
  9434. 5:32:54it accept only one parameter. It is the
  9435. 5:32:57date. The same things for the others. We
  9436. 5:32:59have a function called month and it
  9437. 5:33:01accept as well only one parameter the
  9438. 5:33:03date and as well for the year the same
  9439. 5:33:04thing. So the syntax is very
  9440. 5:33:06straightforward. It accept only one
  9441. 5:33:07value the date and we have the function
  9442. 5:33:10name like the name of the part that we
  9443. 5:33:12want to extract. All right. So now let's
  9444. 5:33:14try out those functions. I will be
  9445. 5:33:16working with the column creation time.
  9446. 5:33:18So let's try for example extracting the
  9447. 5:33:20year from the creation time using the
  9448. 5:33:22year function. So it's going to be very
  9449. 5:33:24simple. It's going to be year and then
  9450. 5:33:27creation
  9451. 5:33:28time like this. And let's call it year.
  9452. 5:33:32That's it. Let's go and execute it. Now
  9453. 5:33:34as you can see it's very simple. We have
  9454. 5:33:35only one year 2025 from the creation
  9455. 5:33:38time. So with that as you can see we got
  9456. 5:33:40a new column where we have only the year
  9457. 5:33:42informations inside it. And this
  9458. 5:33:44information come from the creation date.
  9459. 5:33:45So we have only 2025. Now let's go and
  9460. 5:33:48do the same for the month. So we're
  9461. 5:33:50going to have the same thing month
  9462. 5:33:53creation time and let's call it month.
  9463. 5:33:56So let's execute it. Now as you can see
  9464. 5:33:58in the output we got as well the number
  9465. 5:34:00of the month. So we have here January,
  9466. 5:34:02February and March and those information
  9467. 5:34:04as well are extracted from the creation
  9468. 5:34:07time and the same thing using the day
  9469. 5:34:09function. So let's go and use that. So
  9470. 5:34:13creation time and we call it day. So now
  9471. 5:34:17as you can see in the output we have the
  9472. 5:34:19day part from the creation time. So here
  9473. 5:34:22we have 1, 5, 10 and so on and all those
  9474. 5:34:25informations come from the creation
  9475. 5:34:26time. So as you can see those three
  9476. 5:34:28functions are very simple and quick in
  9477. 5:34:30order to extract parts from a date or
  9478. 5:34:33date
  9479. 5:34:33[Music]
  9480. 5:34:37time. All right. So what is date part?
  9481. 5:34:39Date part going to go and return
  9482. 5:34:41specific part of the date as a number.
  9483. 5:34:44All right. So now back to our example.
  9484. 5:34:45We have learned how to extract the day,
  9485. 5:34:47month and year. But of course now in a
  9486. 5:34:50day we have more informations that we
  9487. 5:34:52could extract. Not only those three we
  9488. 5:34:54could extract for example the week right
  9489. 5:34:57the quarter so all those informations
  9490. 5:34:59are as well stored in this dates we
  9491. 5:35:02cannot see it like as a value but inside
  9492. 5:35:05the SQL you can extract the week and
  9493. 5:35:07quarter but we don't have a function
  9494. 5:35:09dedicated for those stuff because they
  9495. 5:35:12are not commonly used like the year and
  9496. 5:35:14month and day but still we can extract
  9497. 5:35:16those information using the date parts
  9498. 5:35:19for example we can say date part and we
  9499. 5:35:22can specify the part as a week and with
  9500. 5:35:24that SQL going to return for this
  9501. 5:35:26example 34 and maybe in other situation
  9502. 5:35:28you are interested in the quarter right
  9503. 5:35:30so you can specify it like this date
  9504. 5:35:33part quarter so we are interested in the
  9505. 5:35:35part of quarter and in the output you
  9506. 5:35:37will get three so this is exactly the
  9507. 5:35:39power of the date part you can go and
  9508. 5:35:42extract way more parts that is available
  9509. 5:35:45in these dates and one more thing to
  9510. 5:35:47notice about the date part year and day
  9511. 5:35:50all of them are always generating the
  9512. 5:35:52output an integer a number. So we have
  9513. 5:35:55the for the quarter 3 for the week 34
  9514. 5:35:58the day 20 2025 and so on. So all of
  9515. 5:36:01those informations are integer. So
  9516. 5:36:03integer is the data type of the output
  9517. 5:36:06of these functions. Okay. So let's have
  9518. 5:36:08a look to the syntax of the data part.
  9519. 5:36:09It start with the function name date
  9520. 5:36:12parts and it accept two parameters. The
  9521. 5:36:14first one is the part that we want to
  9522. 5:36:16extract. So we want to define what do we
  9523. 5:36:18want. We want the month, the day, the
  9524. 5:36:20year and so on. And the second parameter
  9525. 5:36:23is the date itself. So let's have an
  9526. 5:36:25example. We can say date part and we
  9527. 5:36:27would like to extract the month from the
  9528. 5:36:29order dates. So the part is the month
  9529. 5:36:31and the order date is the date that we
  9530. 5:36:33want to extract from. So with that we
  9531. 5:36:35are specifying the part as a month. Now
  9532. 5:36:37in SQL there is another way on how to
  9533. 5:36:40specify the parts. We can go and use
  9534. 5:36:42like an abbreviation of the month. So if
  9535. 5:36:45you specify instead of month instead of
  9536. 5:36:47writing the whole thing you write mm you
  9537. 5:36:49will get the same results. So it's like
  9538. 5:36:51abbreviation and shortcut in order to
  9539. 5:36:53write scripts. But I rarely see that in
  9540. 5:36:55the implementations. I always tend to
  9541. 5:36:56write it completely like this month
  9542. 5:36:58because it's more like standards if you
  9543. 5:37:00are switching between different
  9544. 5:37:01databases. So as you can see it's very
  9545. 5:37:03simple. You have to give SQL two things
  9546. 5:37:05which part you want to extract and the
  9547. 5:37:07date that you want to extract from.
  9548. 5:37:09Okay. So now we're going to go and
  9549. 5:37:10extract different parts from the
  9550. 5:37:11creation time using the date part. Let's
  9551. 5:37:14start for example by extracting the year
  9552. 5:37:16again. So let's go and do that. date
  9553. 5:37:20parts and then we have to specify which
  9554. 5:37:23part we need. So we're going to write
  9555. 5:37:24year like this and then the next one
  9556. 5:37:27going to be the value. So it's going to
  9557. 5:37:29be the creation time. So let's call it
  9558. 5:37:33year and let's say date parts. Let's go
  9559. 5:37:36and execute it. So now at the output you
  9560. 5:37:38can see we got as well again the years
  9561. 5:37:41that is extracted from the creation
  9562. 5:37:42time. So it's going to be identical to
  9563. 5:37:44the year function. So there is no
  9564. 5:37:46differences between them. Both of them
  9565. 5:37:48are integer and it holds the year
  9566. 5:37:50informations. Now we can go and try
  9567. 5:37:52different parts. For example, let's copy
  9568. 5:37:54the whole thing and let's extract for
  9569. 5:37:57example the month. So you can go over
  9570. 5:37:59here and change it to month and let's
  9571. 5:38:02rename it
  9572. 5:38:03execute. So at the output you see we got
  9573. 5:38:06as well the months is identical as well
  9574. 5:38:08to the function month. And the same
  9575. 5:38:10thing for the day. So we are just
  9576. 5:38:13changing the
  9577. 5:38:14parts and in the output we are getting
  9578. 5:38:17the parts. So here we have as well the
  9579. 5:38:19days it is identical to the day
  9580. 5:38:21function. So so far we don't have
  9581. 5:38:22something new from the date part because
  9582. 5:38:24we have it already from the other
  9583. 5:38:26functions. But now we're going to go and
  9584. 5:38:28extract other parts that are not year
  9585. 5:38:30month and day. So for example let's go
  9586. 5:38:33and get the hours. So we have the date
  9587. 5:38:36part and here as a part you say hour and
  9588. 5:38:40let's call it here as well hour. Let's
  9589. 5:38:43go and execute it. Now you can see in
  9590. 5:38:45the output we have a new dedicated
  9591. 5:38:47column that shows only the information
  9592. 5:38:49from the hour. So we have here 12 23 and
  9593. 5:38:52so on. And those informations comes from
  9594. 5:38:54the time and the same thing you can
  9595. 5:38:56define minutes and so on. But now let's
  9596. 5:38:59go and get something interesting like
  9597. 5:39:00the quarter. So let's go and duplicate
  9598. 5:39:05it and instead of hour let's get
  9599. 5:39:07quarter. So this information it's not
  9600. 5:39:09displayed in the creation time but SQL
  9601. 5:39:12can go and extract it. So let's call it
  9602. 5:39:15quarter and let's go and execute it. Now
  9603. 5:39:18as you can see in the output we have one
  9604. 5:39:20new field called quarter and inside it
  9605. 5:39:22everywhere we have a one because all
  9606. 5:39:24those dates are in the range of the
  9607. 5:39:26quarter one. So as you can see this is
  9608. 5:39:28amazing of course for reporting and
  9609. 5:39:30analyzes. Let's go and have something
  9610. 5:39:33else like the week day. So we are over
  9611. 5:39:36here quarter and let's call it week day
  9612. 5:39:40and rename as well this to week day. So
  9613. 5:39:44let's go and execute it. All right. So
  9614. 5:39:45now let's go and get something else like
  9615. 5:39:47for example the week. So I just
  9616. 5:39:50duplicated over here instead of quarter
  9617. 5:39:52let's write week. So I would like to get
  9618. 5:39:54the week number. So let's go and execute
  9619. 5:39:58it. So now in the output as you can see
  9620. 5:39:59we got a dedicated field that show us
  9621. 5:40:01the week number from the creation time.
  9622. 5:40:04So we can see this dates come from the
  9623. 5:40:06week number one. Those two come from
  9624. 5:40:08week number two and so on. So that's it.
  9625. 5:40:11As you can see guys all those
  9626. 5:40:12informations that you are getting from
  9627. 5:40:14the date part are numbers. And now we
  9628. 5:40:16can extract way more informations than
  9629. 5:40:19only the year, month and day. And even
  9630. 5:40:21if those informations are not displayed
  9631. 5:40:23directly in the field itself like the
  9632. 5:40:26quarter, weeks and so
  9633. 5:40:27[Music]
  9634. 5:40:30on. All right. So now we have very
  9635. 5:40:32similar function to the date part. We
  9636. 5:40:34have the date name. So the only
  9637. 5:40:36difference here is that it returns the
  9638. 5:40:38name of the date parts. All right. So
  9639. 5:40:40now back to our example. We have learned
  9640. 5:40:42we can extract different types of parts
  9641. 5:40:44from one date. But we learned as well
  9642. 5:40:47that all of them are numbers. How about
  9643. 5:40:49we would like to extract the name of the
  9644. 5:40:51month. So instead of eight, I would like
  9645. 5:40:53to get the name of the month like
  9646. 5:40:55August. Or instead of the 20, I would
  9647. 5:40:57like to get the day name like here in
  9648. 5:41:00this example, it going to be Wednesday.
  9649. 5:41:02So in order to get the name of the
  9650. 5:41:04parts, we have to use the function date
  9651. 5:41:06name. So for example, if you use the
  9652. 5:41:08function date name using the part month,
  9653. 5:41:11you will not get eight in the output.
  9654. 5:41:13You will get the full name of the month
  9655. 5:41:15August. So as you can see we are getting
  9656. 5:41:17a string a full name and as well the
  9657. 5:41:19same thing if you use date name for the
  9658. 5:41:21week day you will not get 20 like the
  9659. 5:41:24day function you will get the name of
  9660. 5:41:26the day Wednesday and as well here the
  9661. 5:41:28output is string so as you can see it's
  9662. 5:41:30very simple we are using the date name
  9663. 5:41:32in order to get the name of the parts
  9664. 5:41:35and the data type of the output here is
  9665. 5:41:37a string it is not an integer so as you
  9666. 5:41:39can see here we have different types of
  9667. 5:41:41functions that all of them are doing the
  9668. 5:41:43same job we are extracting ing parts
  9669. 5:41:46from one date. Okay. So now by checking
  9670. 5:41:48the data name syntax, it's going to be
  9671. 5:41:51identical to the date part. So we are
  9672. 5:41:53just switching the function name. It
  9673. 5:41:56needs from you to define the part and as
  9674. 5:41:58well the dates. The only difference here
  9675. 5:42:00is that we are getting different data
  9676. 5:42:01type at the output. So here we are
  9677. 5:42:03getting a string instead of integer. All
  9678. 5:42:05right. So now let's check the date name.
  9679. 5:42:07It is very similar to the date part. So
  9680. 5:42:09we're going to have it like this. We're
  9681. 5:42:10going to work as well with the creation
  9682. 5:42:12time. So we're going to say date name
  9683. 5:42:14and then after that we have to define
  9684. 5:42:16the parts. So let's go for example with
  9685. 5:42:18the month and our field is as usual the
  9686. 5:42:21creation time and let's call it month
  9687. 5:42:25date
  9688. 5:42:26name like this. So that's it. Let's go
  9689. 5:42:29and execute it. Now if you go to the
  9690. 5:42:31output over here you can see we have the
  9691. 5:42:33month but this time we don't have
  9692. 5:42:35numbers. We have the full name of the
  9693. 5:42:37month. So we have January, February,
  9694. 5:42:39March instead of having 1 2 3. So this
  9695. 5:42:42is the big difference between the date
  9696. 5:42:44name and date part. Date part you get
  9697. 5:42:45numbers. Date name you get the name of
  9698. 5:42:48the part. So let's do the same thing for
  9699. 5:42:50the day. We would like to get the name
  9700. 5:42:53of the day. So I'm just duplicating it.
  9701. 5:42:55But now in order to get the full name of
  9702. 5:42:57the day, we cannot go with the day.
  9703. 5:42:59We're going to go with the week day as a
  9704. 5:43:02part. So that's it. I will call it week
  9705. 5:43:05day. So let's execute it. Now as you can
  9706. 5:43:07see in the output, we have here a new
  9707. 5:43:10column called week day. And inside it we
  9708. 5:43:12have the name of the day instead of a
  9709. 5:43:14number. So here we have Wednesday,
  9710. 5:43:16Sunday, Friday and so on. So the full
  9711. 5:43:18name of the day go of course with the
  9712. 5:43:20day. Let's go and try that
  9713. 5:43:23out. So this is the day of the month and
  9714. 5:43:27of course the day of the month has no
  9715. 5:43:29name and SQL of course going to return
  9716. 5:43:31the numbers again. So you can see 1 5 10
  9717. 5:43:3320 and so on. But still there is a
  9718. 5:43:35difference between the day from the day
  9719. 5:43:37name and the day from the date parts. In
  9720. 5:43:40the date parts we are getting integers.
  9721. 5:43:43So if you store this information in a
  9722. 5:43:44new table it's going to be stored as an
  9723. 5:43:46integer. But in the date that you are
  9724. 5:43:49getting from the date name it is a
  9725. 5:43:51number but still it can be stored as a
  9726. 5:43:53string value. So the data type of those
  9727. 5:43:56numbers is a string and the data types
  9728. 5:43:58of the day from the date part is an
  9729. 5:44:00integer. And the same thing can happen
  9730. 5:44:02if you extract for example a year. So
  9731. 5:44:04you don't have like a full text of the
  9732. 5:44:06year. So let me just do it like this. So
  9733. 5:44:10if we say a year, you will not get the
  9734. 5:44:13name of the year. You're still getting
  9735. 5:44:15the numbers, the digits, but the data
  9736. 5:44:17type here is a string. So that's it.
  9737. 5:44:19This is the difference between the date
  9738. 5:44:21name and the date parts. For the month
  9739. 5:44:23and weekday, you will get the full name.
  9740. 5:44:25For the other stuff, you will get
  9741. 5:44:26numbers but with the string data type.
  9742. 5:44:29So the most important thing about the
  9743. 5:44:30date name is to present easy to read and
  9744. 5:44:34human readable informations to the
  9745. 5:44:35users. So imagine you are building a
  9746. 5:44:37report called sales by month and then
  9747. 5:44:39you show to the user the muscles as
  9748. 5:44:41numbers 1 2 3 until 12. This is of
  9749. 5:44:43course okay but it is way more nicer if
  9750. 5:44:46you present those informations as a full
  9751. 5:44:48text. So you go with the date name in
  9752. 5:44:50order to show instead of one you show
  9753. 5:44:52January, February, March and the full
  9754. 5:44:54name of the month. And this going to
  9755. 5:44:56look way nicer in reporting for the
  9756. 5:44:58users. So this is the core use case of
  9757. 5:45:00the date
  9758. 5:45:04name. So what is date trunk? Date trunk
  9759. 5:45:07going to go and truncate the date to a
  9760. 5:45:10specific part. So let's understand what
  9761. 5:45:13this means. Okay. Now let's check the
  9762. 5:45:15syntax of the date trunk. It's going to
  9763. 5:45:16be exactly the same like date part and
  9764. 5:45:18date name. So you have to define the
  9765. 5:45:20part and the date that you want to
  9766. 5:45:22extract apart from it. So the only thing
  9767. 5:45:25that is different here we are giving
  9768. 5:45:27different function name. So as you can
  9769. 5:45:29see all those three functions like
  9770. 5:45:31having the same structure you have to
  9771. 5:45:33provide which part you want to extract
  9772. 5:45:35like a month, day, week, hour, minutes
  9773. 5:45:38and so on and the date or date and time
  9774. 5:45:41that you want to extract a part from it
  9775. 5:45:43and of course with the date trunk we are
  9776. 5:45:44getting at the output date or date time.
  9777. 5:45:47Okay. So now let's understand exactly
  9778. 5:45:49how the date trunk works. We have the
  9779. 5:45:51following date time and as we learned we
  9780. 5:45:53have like a hierarchy where we start
  9781. 5:45:55with the highest from the year then we
  9782. 5:45:57move to the month, day, hours, minutes
  9783. 5:46:00and seconds and by looking to this
  9784. 5:46:02information it is very precise. We know
  9785. 5:46:04exact second for this information right?
  9786. 5:46:07So the level of details here is very
  9787. 5:46:09high. We know the seconds of this event.
  9788. 5:46:12So now the date going to allow us to
  9789. 5:46:14change this level of details of this
  9790. 5:46:16information by specifying the level of
  9791. 5:46:18details. Let's take for example if we
  9792. 5:46:20say the date trunk minutes. So we are
  9793. 5:46:23saying we are interested only at the
  9794. 5:46:25minutes level. We are not interesting
  9795. 5:46:26with the seconds. So what can happen?
  9796. 5:46:29Everything between the year and the
  9797. 5:46:31minutes going to be kept. That means all
  9798. 5:46:33those information will not be changed
  9799. 5:46:35but only the seconds going to be
  9800. 5:46:38reseted. We are not interested anymore
  9801. 5:46:40with the seconds. This is very detailed
  9802. 5:46:42for us. So it's going to go and reset
  9803. 5:46:44the seconds to 0 0. So we are saying the
  9804. 5:46:47minimum level is the minutes and we are
  9805. 5:46:50not interested anything like before it
  9806. 5:46:52the seconds let's say now we say you
  9807. 5:46:54know what the minutes is very detailed I
  9808. 5:46:56would like to be at the hours level so
  9809. 5:46:58we specify for the date rank hour so
  9810. 5:47:01here things changed we're going to keep
  9811. 5:47:03the informations now between the year
  9812. 5:47:05and the hours and anything after that
  9813. 5:47:07going to be reseted so now minutes and
  9814. 5:47:10seconds going to be in the range of the
  9815. 5:47:12resets and SQL going to go and reset the
  9816. 5:47:1555 to 0 0 so now the level of details is
  9817. 5:47:19little bit lower now we know only the
  9818. 5:47:21informations until the hours and we are
  9819. 5:47:24not interested about the minutes and the
  9820. 5:47:25seconds and I think you already get it
  9821. 5:47:27if you say date trunk day what's going
  9822. 5:47:30to happen it's going to keep everything
  9823. 5:47:32between year and day and the whole time
  9824. 5:47:35going to be resets so the hours and
  9825. 5:47:38seconds all those information is going
  9826. 5:47:40to reset to 0 0 so now by looking to
  9827. 5:47:43this we don't know anything about the
  9828. 5:47:45time we know only informations about the
  9829. 5:47:47dates and now we can go one more step
  9830. 5:47:49and we say you know what I'm not
  9831. 5:47:50interested about the days I'm doing
  9832. 5:47:52analyszis on the month level so what is
  9833. 5:47:54here kept is only two informations year
  9834. 5:47:57and month and everything below that the
  9835. 5:48:00day and the time going to be reseted but
  9836. 5:48:03this time SQL will not reset the date to
  9837. 5:48:050 0 because there is no date called 0 0
  9838. 5:48:08it start always with the first date so
  9839. 5:48:10it's going to reset to 01 so the dates
  9840. 5:48:13parts and the dates going to reset to 01
  9841. 5:48:15one and the dates parts in the time
  9842. 5:48:17going to reset to 0 0. So now we are at
  9843. 5:48:20the level of the month. Now you can go
  9844. 5:48:22to the last step and you say you know
  9845. 5:48:24what I'm interested only on the years
  9846. 5:48:26and I'm doing only analyzes at this
  9847. 5:48:28level at the highest level. So you can
  9848. 5:48:30go and say date trunk year and now
  9849. 5:48:32what's going to happen going to keep
  9850. 5:48:34only the year and everything below that
  9851. 5:48:37going to be reseted. So between month
  9852. 5:48:39and the seconds everything going to
  9853. 5:48:41resets. So here is scale going to reset
  9854. 5:48:42as well the August 2011. So the only
  9855. 5:48:46value that is kept is the year and
  9856. 5:48:48everything else is reseted. So this is
  9857. 5:48:50the 1st of January and the time is
  9858. 5:48:52completely reseted. So now we are at the
  9859. 5:48:54lowest level of details. We know only
  9860. 5:48:56information about the year and we don't
  9861. 5:48:58care about any other parts. So as you
  9862. 5:49:00can see the date trunk here is not
  9863. 5:49:01really extracting a part here. Date
  9864. 5:49:04trunk is like resetting stuff. So we are
  9865. 5:49:07navigating through the hierarchy of the
  9866. 5:49:09date and time and we are controlling at
  9867. 5:49:11which level we are doing the analyszis.
  9868. 5:49:13So as you can see at the end it's not
  9869. 5:49:15very complicated once you understand how
  9870. 5:49:16it works and it is very useful in
  9871. 5:49:18analyzis. So this is how the date trunk
  9872. 5:49:21works in SQL. Okay, let's have a few
  9873. 5:49:23examples about the date rank together
  9874. 5:49:24with the creation time. So as you can
  9875. 5:49:26see the creation time the level of it is
  9876. 5:49:28the seconds. So we have seconds
  9877. 5:49:30information with the creation time. Now
  9878. 5:49:32I would like to move it to the minutes.
  9879. 5:49:35So let's go and do this date trunk and
  9880. 5:49:38we're going to say let's tr it at the
  9881. 5:49:41minutes level for the creation time. So
  9882. 5:49:45let's call it minute date trunk. So
  9883. 5:49:50let's go and execute it. Now if you go
  9884. 5:49:52and check the output over here and
  9885. 5:49:53compare it to the creation time, you can
  9886. 5:49:55see here we have zeros at the seconds.
  9887. 5:49:58So as you can see we have the seconds
  9888. 5:50:00completely resetted compared to the
  9889. 5:50:02creation time. Now let's say that I'm
  9890. 5:50:04not interested in the time information
  9891. 5:50:06inside the creation time. I would like
  9892. 5:50:08only to get the date. So in order to do
  9893. 5:50:10that, we can use the date trunk where we
  9894. 5:50:12reset to the level of the day. So let's
  9895. 5:50:15go and duplicate it. I'm going to put it
  9896. 5:50:18over here and instead of minutes, let's
  9897. 5:50:20say we have a day and let's go and check
  9898. 5:50:23the output. Now if you go and check the
  9899. 5:50:25result over here you can see all the
  9900. 5:50:27time informations are reseted to zeros
  9901. 5:50:30and we have here only information about
  9902. 5:50:32the date. So we have year month and day
  9903. 5:50:35and everything else is reset it to zero.
  9904. 5:50:37Now of course we can go to the maximum
  9905. 5:50:39where we say I just need the year. So I
  9906. 5:50:42don't need anything else. So let's try
  9907. 5:50:44that out. We're going to take date trunk
  9908. 5:50:46and say year and let's call it year. So
  9909. 5:50:51let's go and execute it. Now if you
  9910. 5:50:53check the output over here you can see
  9911. 5:50:54that everything is reseted beside the
  9912. 5:50:57year. So we have only the year
  9913. 5:50:58information but everything else is
  9914. 5:51:00reseted to the first of January and the
  9915. 5:51:03time is as well is reseted. So as you
  9916. 5:51:05can see the output of the date trunk is
  9917. 5:51:08always as a date time and it help us as
  9918. 5:51:11well to navigate through the hierarchy
  9919. 5:51:13of the day time and we can truncate at
  9920. 5:51:15the level that we want. All right. So
  9921. 5:51:17now we're going to check why data trunk
  9922. 5:51:18is amazing function for data analyszis.
  9923. 5:51:21So let's have this example. We are
  9924. 5:51:23saying select
  9925. 5:51:25creation time and we want to count the
  9926. 5:51:29number of orders based on the creation
  9927. 5:51:31time from our table sales orders and
  9928. 5:51:34we're going to use the group by in order
  9929. 5:51:37to group the data by the creation time.
  9930. 5:51:39So let's go and execute it. Now as you
  9931. 5:51:41can see we're going to get one
  9932. 5:51:42everywhere because the level of details
  9933. 5:51:45the granularity or the creation time is
  9934. 5:51:47very high and that's because here we
  9935. 5:51:49have the seconds and since our data is
  9936. 5:51:51small we will not get like two orders at
  9937. 5:51:53the same seconds. Now in data analytics
  9938. 5:51:55you would like quickly to aggregate the
  9939. 5:51:57data at different granularity like for
  9940. 5:51:59example at the month level. So you can
  9941. 5:52:01do that very quickly using the date
  9942. 5:52:04trunk and you say you know what let's
  9943. 5:52:06say at the month and let's call it
  9944. 5:52:10creation and we're going to have the
  9945. 5:52:12same thing for the group pie. So let's
  9946. 5:52:14go and execute it. So now as you can see
  9947. 5:52:16at the output we have only three rows we
  9948. 5:52:18don't have like 10 rows and that's
  9949. 5:52:20because we have three months. So that
  9950. 5:52:22means we just rolled up to the month
  9951. 5:52:24level instead of the seconds. And we can
  9952. 5:52:26see now in the month of January we have
  9953. 5:52:27four orders, February as well four and
  9954. 5:52:30March we have only two. So now we are
  9955. 5:52:32talking about different level of details
  9956. 5:52:33in the output and granularity. And now
  9957. 5:52:36you might say let's go and aggregate the
  9958. 5:52:37data at different level at the year
  9959. 5:52:39level. So you can just change over here
  9960. 5:52:41the year and execute it. And with that
  9961. 5:52:44now we are at the highest level of
  9962. 5:52:46aggregations. We are at the year level
  9963. 5:52:48and since in our data we have only 2025.
  9964. 5:52:51So we will get the total number of
  9965. 5:52:52orders inside the table and that is 10.
  9966. 5:52:55And this is really amazing in data
  9967. 5:52:56analytics. You can go and quickly change
  9968. 5:52:58the granularity and the level of
  9969. 5:53:00aggregation or details by simply
  9970. 5:53:02defining the level inside the dates. So
  9971. 5:53:05this is why the date rank is amazing. It
  9972. 5:53:07allow us to do analyszis and
  9973. 5:53:09aggregations by zooming in and zooming
  9974. 5:53:15out. Okay. So now we're going to talk
  9975. 5:53:17about the last function in the part
  9976. 5:53:19extraction category. We have the end of
  9977. 5:53:21the month. As the name says, it's going
  9978. 5:53:23to go and return the last day of a
  9979. 5:53:26month. So let's see how end of month
  9980. 5:53:28works. This is very simple. So let's
  9981. 5:53:29take our date 20th August 2025. If you
  9982. 5:53:32go now and apply this function to it,
  9983. 5:53:35what's going to happen? It's going to go
  9984. 5:53:36and change only the day information. So
  9985. 5:53:39instead of 20, it's going to go to the
  9986. 5:53:41last day of the month. So it's going to
  9987. 5:53:43go and change the 20 to 31. The last day
  9988. 5:53:47of the month, August in 2025. Let's take
  9989. 5:53:50another example is the 1st of February
  9990. 5:53:522025. If you apply the end of the month,
  9991. 5:53:55it's going to go and change the day from
  9992. 5:53:58the 1st to 28. The last day of month
  9993. 5:54:01February. So as you can see, it's very
  9994. 5:54:03simple. Let's take another example where
  9995. 5:54:04it is already the last day of the month.
  9996. 5:54:08So we have 31 of March. If you apply the
  9997. 5:54:11end of the month here, what can happen?
  9998. 5:54:13Nothing going to happen. You're going to
  9999. 5:54:14get in return the same value. So this is
  10000. 5:54:17how it works. And as you can see always
  10001. 5:54:18the output of the end of the month going
  10002. 5:54:20to be as well a date. So this is how end
  10003. 5:54:23of month work. It is very simple. All
  10004. 5:54:25right. Now quickly about the syntax of
  10005. 5:54:27the end of the month. It's going to have
  10006. 5:54:28the exact same syntax like the day,
  10007. 5:54:31month, year. It accepts only one
  10008. 5:54:33parameter. It is the date. So we have to
  10009. 5:54:35pass here a date in order to find out
  10010. 5:54:38the end of the month. So let's go and
  10011. 5:54:40find the end of the month of our
  10012. 5:54:41creation time. So end of the month like
  10013. 5:54:45this. And let's have our creation time.
  10014. 5:54:49So let's see the end of month. Let's go
  10015. 5:54:53and execute it. And now in the output
  10016. 5:54:54you can see we have a new column a date
  10017. 5:54:56column. And inside it we have values
  10018. 5:54:58about the end of the month. So for
  10019. 5:55:00example here we have January, January,
  10020. 5:55:01January and so on. So you will see
  10021. 5:55:03always here the end of January and the
  10022. 5:55:05same thing for February and March. So
  10023. 5:55:07that's it. This is really nice function
  10024. 5:55:09in case you need the end of the month of
  10025. 5:55:11each date. Maybe you're creating a
  10026. 5:55:12report or analyzes where you need this
  10027. 5:55:14information. And now you might ask me
  10028. 5:55:16how about to get the first day of the
  10029. 5:55:18month. Is there like any function for
  10030. 5:55:19it? Well, no. But there is a trick in
  10031. 5:55:22order to get the first day of the month
  10032. 5:55:24using another function that we just
  10033. 5:55:26learned. Think about it. How to get the
  10034. 5:55:28days as one everywhere. So we have to
  10035. 5:55:31get here the 1st of January, the 1st of
  10036. 5:55:33February, and the 1st of March. So how
  10037. 5:55:35we can do that? Well, using the date
  10038. 5:55:38trunk. So let me show you how we're
  10039. 5:55:39going to do this. So date
  10040. 5:55:42trunk and we're going to reset at the
  10041. 5:55:44level of month. So we don't need the
  10042. 5:55:47days it going to reset to the first. So
  10043. 5:55:50our field is creation time and this
  10044. 5:55:53going to be the start of month. So let's
  10045. 5:55:57go and execute it. So now as you can see
  10046. 5:55:59in the output we have the start of month
  10047. 5:56:01and you can see we have everywhere here
  10048. 5:56:02a one since we reset it at the level of
  10049. 5:56:05month and this going to give us the
  10050. 5:56:06first day of the month. And now you
  10051. 5:56:08might say you know what here we have a
  10052. 5:56:10lot of zeros how to get it exactly like
  10053. 5:56:11the end of the month and that's because
  10054. 5:56:13the date rank give us date and time
  10055. 5:56:15always. So that means we have to change
  10056. 5:56:17the data type and that we're going to
  10057. 5:56:18learn later using the cast function but
  10058. 5:56:21we can go and do it right now. So we can
  10059. 5:56:23say cast and we want to change the whole
  10060. 5:56:26thing to date. And now that we change
  10061. 5:56:28the data type from date time to date and
  10062. 5:56:31in the output as you can see we have
  10063. 5:56:32only the date information. So now it's
  10064. 5:56:34really amazing that you got two dates.
  10065. 5:56:35The first one is the start of the month
  10066. 5:56:37and the second is the end of the month.
  10067. 5:56:38And those information might be helpful
  10068. 5:56:40if you are generating reporting and you
  10069. 5:56:42need the start and the end of the
  10070. 5:56:43[Music]
  10071. 5:56:46month. So now we come to the part where
  10072. 5:56:49we ask the question why do we need those
  10073. 5:56:51parts? Why do we need to extract the
  10074. 5:56:53date parts from a date? So let's have
  10075. 5:56:56the following use cases. The first use
  10076. 5:56:58case of extracting the part is doing
  10077. 5:57:00data aggregations and reporting.
  10078. 5:57:03Sometimes we are building like reports
  10079. 5:57:04based on our data and sometimes we have
  10080. 5:57:06to aggregate our data by a specific time
  10081. 5:57:09unit like for example we are building a
  10082. 5:57:11reports in order to show the sales by
  10083. 5:57:13year. So we have different years and we
  10084. 5:57:15are aggregating the data based on the
  10085. 5:57:18year or you want to drill down to more
  10086. 5:57:20details where you want to aggregate the
  10087. 5:57:21data by the quarter. So in this report
  10088. 5:57:24we are showing the sales by quarter Q1 2
  10089. 5:57:273 4 or you decide to go in more details
  10090. 5:57:30where you show a report says sales by
  10091. 5:57:32month and then you start aggregating
  10092. 5:57:34your data by the month. So you have
  10093. 5:57:36January, February, March and so on. So
  10094. 5:57:38as you can see we can use those
  10095. 5:57:39different parts in order to aggregate
  10096. 5:57:42the data based on it and these different
  10097. 5:57:44parts can offer us different analyzes
  10098. 5:57:46with different details. So now we have
  10099. 5:57:48the following task and it says how many
  10100. 5:57:50orders were placed each year. So that
  10101. 5:57:53means we have to group up our data by
  10102. 5:57:55the year and we have to count the number
  10103. 5:57:56of orders. Let's go and solve it. So
  10104. 5:57:59let's go with the select. And now what
  10105. 5:58:00do we need? We need the order date. This
  10106. 5:58:04going to indicate when the order is
  10107. 5:58:05placed. So and we have to go and count
  10108. 5:58:09the star. So this going to be number of
  10109. 5:58:11orders. and from our table sales orders
  10110. 5:58:16and we have to group up by the order
  10111. 5:58:19dates. So that's it. Let's go a and
  10112. 5:58:21execute it. So now in the output we are
  10113. 5:58:23getting the number of orders but by the
  10114. 5:58:26order date. So we are still not there.
  10115. 5:58:28We have to have it as a year. So we
  10116. 5:58:31don't need the whole date information.
  10117. 5:58:33We need only the year information. So
  10118. 5:58:35that means we have to go and extract the
  10119. 5:58:37part year. In order to do that we can do
  10120. 5:58:40it like this. So we can go with the year
  10121. 5:58:43and we have it as well in the group I.
  10122. 5:58:46So that's it. Let's go and execute it.
  10123. 5:58:48And with that as you can see we got the
  10124. 5:58:49number of orders for each year. And
  10125. 5:58:51since in our data we have only 2025 we
  10126. 5:58:53will get only one row. So with that the
  10127. 5:58:55task is solved. We are now aggregating
  10128. 5:58:57the data on the level of the year. Now
  10129. 5:58:59let's have another task which is the
  10130. 5:59:01same but only different parts. How many
  10131. 5:59:03orders were placed each month. So we
  10132. 5:59:06have to go and change it to a month.
  10133. 5:59:08It's very simple. We're going to use the
  10134. 5:59:10function month and as well in the group
  10135. 5:59:13by. So let's go and execute it. And now
  10136. 5:59:15as you can see in the output we don't
  10137. 5:59:17have one row. Now we have three rows.
  10138. 5:59:18And that's because we have three months
  10139. 5:59:20inside our data. And for each month we
  10140. 5:59:22will get the total number of orders. So
  10141. 5:59:25for the January we have four, February
  10142. 5:59:27we have four and March we have two
  10143. 5:59:29orders. Now you might say you know what
  10144. 5:59:31I don't want the months as a numbers. I
  10145. 5:59:33would like to have the full name of the
  10146. 5:59:34month. So in order to do that we're
  10147. 5:59:36going to go and use the function date
  10148. 5:59:38name. So let's go and use date name and
  10149. 5:59:41then we have to specify the date part.
  10150. 5:59:43It's going to be the month and the value
  10151. 5:59:45going to be the order date and we have
  10152. 5:59:47to have the same thing as well in the
  10153. 5:59:49group I. So let's go and execute it. Now
  10154. 5:59:52you can see in the output we are getting
  10155. 5:59:53the full name of the month which is
  10156. 5:59:55easier to read. So this is one of the
  10157. 5:59:57use cases why we need to extract parts
  10158. 5:59:59from a date in order to aggregate the
  10159. 6:00:02data on a specific level.
  10160. 6:00:07So now let's have the following task and
  10161. 6:00:09it says show all orders that were placed
  10162. 6:00:12during the month of February. So that
  10163. 6:00:14means we don't need all the orders. We
  10164. 6:00:16need only a subset of the orders based
  10165. 6:00:18on the order dates. Now let's go and
  10166. 6:00:20check the data. So select star first
  10167. 6:00:23from sales orders and let's go and
  10168. 6:00:27execute it. So now with that we have our
  10169. 6:00:2810 orders. Now if you check the order
  10170. 6:00:30date over here you can see that we have
  10171. 6:00:32orders in January, February and March.
  10172. 6:00:35Now we are interested only on the orders
  10173. 6:00:37that were placed in February. So only
  10174. 6:00:39these subsets. So that means we have now
  10175. 6:00:41to filter the data based on the month
  10176. 6:00:43information. So what we're going to do,
  10177. 6:00:45we're going to have a wear clause. And
  10178. 6:00:47now we don't need the whole order date.
  10179. 6:00:49We need only the part month. So we're
  10180. 6:00:51going to go with the month and order
  10181. 6:00:54date and this going to be equal to two.
  10182. 6:00:58Since the output going to be in number.
  10183. 6:01:00So let's go and execute it. Now as you
  10184. 6:01:02can see SQL did filter the data and in
  10185. 6:01:04the output we have only the orders were
  10186. 6:01:07placed in the month of February. So this
  10187. 6:01:09is as well very common use case. Why do
  10188. 6:01:12we need the parts? We use it in order to
  10189. 6:01:14filter the data based on specific part
  10190. 6:01:17of the dates. So as you can see it's
  10191. 6:01:19very quick and easy. And here my
  10192. 6:01:21recommendation is that if you are
  10193. 6:01:22filtering the data always use the
  10194. 6:01:24numbers. So always use a date function
  10195. 6:01:26that gives you a number because it's
  10196. 6:01:28always faster to search for integers
  10197. 6:01:31instead of searching for a character or
  10198. 6:01:34for string. So don't use the date name
  10199. 6:01:36function in order to search or filter
  10200. 6:01:38for the data. It's better to use the
  10201. 6:01:40date part or month, year and day. Since
  10202. 6:01:42you can work with numbers and numbers
  10203. 6:01:44are always faster to retrieve data and
  10204. 6:01:46to filter your
  10205. 6:01:50informations. Okay. So now we have a lot
  10206. 6:01:52of functions and I would like now to do
  10207. 6:01:54a quick recap about the data type of
  10208. 6:01:56their results. So as we learned we have
  10209. 6:01:58functions like day, month, year, date
  10210. 6:02:01bar and the output of all those
  10211. 6:02:04functions going to be integer. It's
  10212. 6:02:06going to be a number. Now we have
  10213. 6:02:07another function the date time. If you
  10214. 6:02:09use it the output of this function going
  10215. 6:02:11to be a string because here we are
  10216. 6:02:13extracting the name of the date part.
  10217. 6:02:15And if you go and use the date trunk you
  10218. 6:02:18will get in the output always date time
  10219. 6:02:20two. So you are getting both the date
  10220. 6:02:22and time. And the last function that we
  10221. 6:02:24learned end of month if you use it in
  10222. 6:02:26the results you will get the data type
  10223. 6:02:28date. So this is really important to
  10224. 6:02:30understand the data type of the output
  10225. 6:02:32so that you don't get any unexpected
  10226. 6:02:34results. All right. So now you might say
  10227. 6:02:36you know what those are a lot of
  10228. 6:02:37functions and like I'm saying they are
  10229. 6:02:39doing the same stuff. We are extracting
  10230. 6:02:41the parts of the dates. So now you might
  10231. 6:02:43ask me how do you decide on when to use
  10232. 6:02:46which function? This is how I usually do
  10233. 6:02:47it. First I ask myself which part I want
  10234. 6:02:50to extract. If I want to extract a date
  10235. 6:02:52or a month then I ask the question do I
  10236. 6:02:55need it as an integer as a number? If
  10237. 6:02:58it's yes then I go and use the day
  10238. 6:03:00function or the month function because
  10239. 6:03:02they are quick and I will get exactly
  10240. 6:03:04what I need. But now if I need the full
  10241. 6:03:06name of the month or the day then I go
  10242. 6:03:09with the function date name. Now moving
  10243. 6:03:11back if I'm interested on the part year.
  10244. 6:03:14So here we don't have a year name or
  10245. 6:03:15something. I'm going to go immediately
  10246. 6:03:17with the function year. But now let's
  10247. 6:03:19say that I don't need the day, month or
  10248. 6:03:21year. I'm interested in other parts like
  10249. 6:03:24the week, the quarter and so on. Only
  10250. 6:03:27for this scenario, I go with the
  10251. 6:03:28function date part. So this is my
  10252. 6:03:31decision process. This is how I decide
  10253. 6:03:33when to use which SQL function in order
  10254. 6:03:36to extract the parts of the
  10255. 6:03:41dates. All right. All right. So now I
  10256. 6:03:43have prepared for you here a list of all
  10257. 6:03:45parts that we can use inside those three
  10258. 6:03:47functions date part date name and date
  10259. 6:03:49trunk. And you can see in this table the
  10260. 6:03:51different outputs using those different
  10261. 6:03:53three functions. So for example if you
  10262. 6:03:55go and use the month with the date part
  10263. 6:03:57you will get eight but for the date name
  10264. 6:03:59you will get August and for the date
  10265. 6:04:01trunk you will get truncated date time
  10266. 6:04:04at the level of the month where you
  10267. 6:04:06reset the days and times. So this is a
  10268. 6:04:08full list of all examples you can go and
  10269. 6:04:10check it. And one more thing that I have
  10270. 6:04:11prepared for you in order to practice
  10271. 6:04:13with all those different parts. I have
  10272. 6:04:15made one big query with all different
  10273. 6:04:17parts. So if you go and download the
  10274. 6:04:19queries of this chapter, you will find
  10275. 6:04:21the following files and let's go now and
  10276. 6:04:23open all date parts. So we're going to
  10277. 6:04:26go inside it and here we have a long
  10278. 6:04:29query. So what we're going to do, we're
  10279. 6:04:30going to select everything and copy it
  10280. 6:04:32and let's go back to our scale and paste
  10281. 6:04:34it. So let me just zoom out and then
  10282. 6:04:38let's go and execute the whole thing. So
  10283. 6:04:41now in my code I have just done a union
  10284. 6:04:43for each possible part. For example for
  10285. 6:04:46the year we have date part date name and
  10286. 6:04:48date trunk and I'm using currently the
  10287. 6:04:50get date. So we are manipulating this
  10288. 6:04:52one and then the output can be presented
  10289. 6:04:54over here. So you can see it like this.
  10290. 6:04:56So if you use the part here for the date
  10291. 6:04:58name you will get 2024. The same thing
  10292. 6:05:01for the date name and this is for the
  10293. 6:05:02date rank. And with that you have all
  10294. 6:05:05possible parts that you can use in SQL
  10295. 6:05:08in one query. So with that you can learn
  10296. 6:05:10what are the outputs for different
  10297. 6:05:12parts. All right. So with that we have
  10298. 6:05:14learned all those functions on how to
  10299. 6:05:16extract the parts of dates. All right.
  10300. 6:05:18Moving to the second category. We're
  10301. 6:05:20going to learn how to do formatting and
  10302. 6:05:22casting for the date informations in SQL
  10303. 6:05:24using three functions.
  10304. 6:05:30So now before we deep dive to the
  10305. 6:05:31formatting and casting I would like you
  10306. 6:05:33to understand what is date format. So
  10307. 6:05:35back to our example we have here the
  10308. 6:05:37date and time informations and we
  10309. 6:05:39understood there is components year
  10310. 6:05:41month day and so on. Now if you check
  10311. 6:05:43the date time there is combination of
  10312. 6:05:45numbers and characters. For example the
  10313. 6:05:472025 is a number but between the month
  10314. 6:05:50and the year there is like a minus
  10315. 6:05:52between them and this is a character. So
  10316. 6:05:54now this is a very specific format and
  10317. 6:05:57in SQL we can have a code for this
  10318. 6:06:00format. So for example let's start with
  10319. 6:06:01the year we have here four digits and we
  10320. 6:06:04can represent it with 4 Y. So Y Y and we
  10321. 6:06:08call those characters as format
  10322. 6:06:11specifiers. So this is how we represent
  10323. 6:06:14the year. Then between the year and the
  10324. 6:06:16month there is like this small minus and
  10325. 6:06:18then the month is two digits and we're
  10326. 6:06:20going to represent it with two big M. So
  10327. 6:06:23m M then between the month and the day
  10328. 6:06:25there is a minus. So we have as well
  10329. 6:06:27minus and then the day going to
  10330. 6:06:28represented with two digits d and then
  10331. 6:06:31we have like a space between the date
  10332. 6:06:33and time and then we start with the
  10333. 6:06:35date. So it start with the hour big h
  10334. 6:06:37and big h because here we have the
  10335. 6:06:39system of 24 and then we have double
  10336. 6:06:41points small m small m. So as you can
  10337. 6:06:44see here the formats are case sensitive.
  10338. 6:06:46So there is a big difference between
  10339. 6:06:48small m and a big m. So a small m
  10340. 6:06:50indicates for a minute and big m
  10341. 6:06:53indicates for a month. So as you can see
  10342. 6:06:55here the case format is case sensitive.
  10343. 6:06:58So two small m means minutes but two
  10344. 6:07:01capital m means month. Then double point
  10345. 6:07:04and small 2s. So now the whole code is
  10346. 6:07:07called the date format. So this is the
  10347. 6:07:10date format representation of this
  10348. 6:07:12value. Now in the world there are
  10349. 6:07:14different representations on how to
  10350. 6:07:16represent a date. So for example in SQL
  10351. 6:07:18we have the international standard
  10352. 6:07:21ISO6801 and the date format is like we
  10353. 6:07:23have learned first it start with the
  10354. 6:07:25year. So four digit for the years minus
  10355. 6:07:28two digit for the month minus two digit
  10356. 6:07:31for the day. So year month day but in
  10357. 6:07:34the USA we have different standards. So
  10358. 6:07:36first it start with the month. So we
  10359. 6:07:38have mm and then after that it is
  10360. 6:07:41followed with the day. So we have then
  10361. 6:07:43the day and after that at the end we
  10362. 6:07:45have the year. So this is the sentence
  10363. 6:07:47format that is used in USA and in Europe
  10364. 6:07:49we have different representations of the
  10365. 6:07:51day. So it start first with the small.
  10366. 6:07:53So it starts with the day then the month
  10367. 6:07:55and then the year. So this is exactly
  10368. 6:07:58the opposite of the international
  10369. 6:07:59standards. So as you can see we don't
  10370. 6:08:01have one standard. We have different
  10371. 6:08:02ways on how we represent dates. But in
  10372. 6:08:05SQL the SQL server is following the
  10373. 6:08:07format of the international standards.
  10374. 6:08:10So SQL server start always with the year
  10375. 6:08:12then month then day. So all dates that
  10376. 6:08:15are used in our SQL database can be
  10377. 6:08:17following this
  10378. 6:08:21format. Okay. So after we understood
  10379. 6:08:24what is date format, now let's talk
  10380. 6:08:25about formatting and casting. So what is
  10381. 6:08:28formatting? Is changing the format of
  10382. 6:08:30value from one to another. So we are
  10383. 6:08:32changing how the data looks like. So for
  10384. 6:08:34example, we have our date. So it's
  10385. 6:08:36following the international standards
  10386. 6:08:37start with year, month, then day. Now we
  10387. 6:08:40can go and change the format using the
  10388. 6:08:42function format where we can go and
  10389. 6:08:44define a different date format like it
  10390. 6:08:46start with the month and then we have
  10391. 6:08:48like slash instead of minus and then the
  10392. 6:08:51day/ year. So in the outer we're going
  10393. 6:08:53to get it like this and even the years
  10394. 6:08:55is only two digits not four. So here we
  10395. 6:08:57are providing for SQL the format that we
  10396. 6:08:59would like to see the data with or you
  10397. 6:09:01can go with other format where you have
  10398. 6:09:03three big M and then four digits for the
  10399. 6:09:05year and between them is just a space.
  10400. 6:09:07So in the output you will get
  10401. 6:09:09abbreviation of the month name and then
  10402. 6:09:11space and the year. So this is one way
  10403. 6:09:13on how to format data. But in the scale
  10404. 6:09:15there is another function that help us
  10405. 6:09:17to format data and that is convert. So
  10406. 6:09:19here we provide not the format itself we
  10407. 6:09:22provide style number. So for example the
  10408. 6:09:24style number six. So it can show it like
  10409. 6:09:26this day space and after that we have
  10410. 6:09:28the abbreviation name of the month and
  10411. 6:09:31then two digits of the year. Or if you
  10412. 6:09:33use another style the 112 then you will
  10413. 6:09:36get the year, month, day without any
  10414. 6:09:38separation between them. And of course
  10415. 6:09:40not only the date and time we can style
  10416. 6:09:42we can style as well numbers and here we
  10417. 6:09:44can use the function format in order to
  10418. 6:09:45change the format of the number. So here
  10419. 6:09:47if you're using the format of numeric
  10420. 6:09:49values then the values will be separated
  10421. 6:09:51with comma or if you use c for the
  10422. 6:09:54currency then you will get the dollar
  10423. 6:09:55sign or if you go and use p then you
  10424. 6:09:58will get the percentage and at the end
  10425. 6:09:59you have the percentage character. So as
  10426. 6:10:01you can see we can as well change the
  10427. 6:10:03format of the numbers but only the
  10428. 6:10:05dates. So this is what we mean by
  10429. 6:10:06formatting we are just changing how the
  10430. 6:10:09value looks like. Now in the other hand
  10431. 6:10:11the casting the casting can go and
  10432. 6:10:13change the data type from one to
  10433. 6:10:16another. So for example if we have the
  10434. 6:10:18value 1 2 3 as a string we can go and
  10435. 6:10:21convert it from the data type string to
  10436. 6:10:23an integer. So in the output we will get
  10437. 6:10:25as well 1 2 3 but as a number or we can
  10438. 6:10:28go and change the data type from dates
  10439. 6:10:30to a string. So in the output it is not
  10440. 6:10:33anymore dates it is a string value or
  10441. 6:10:36the way around we can change the data
  10442. 6:10:38type from a string to a date. So as you
  10443. 6:10:41can see we can change the data type from
  10444. 6:10:43one to another and we can use that using
  10445. 6:10:45two functions. The first one is and the
  10446. 6:10:48most famous one is cast function or in
  10447. 6:10:50SQL server we can use as well the
  10448. 6:10:52convert function in order to change the
  10449. 6:10:55data type. So this is what we mean with
  10450. 6:10:57casting changing the data type from one
  10451. 6:10:59to
  10452. 6:11:03another. All right. So let's start with
  10453. 6:11:05the first function the format. So what
  10454. 6:11:07is format? As the name suggest it
  10455. 6:11:09formats a date or time value. So it's
  10456. 6:11:12like we are changing how the date and
  10457. 6:11:14time looks. Okay. So let's check the
  10458. 6:11:16syntax of the format and here it accepts
  10459. 6:11:19two parameters and the third one is
  10460. 6:11:21optional. So the first one we have to
  10461. 6:11:23provide a value. It could be a date or a
  10462. 6:11:25number. And the second one we have to
  10463. 6:11:27provide the format. So here we are
  10464. 6:11:28specifying the new look the new format
  10465. 6:11:30for this value. Now the third one it is
  10466. 6:11:33optional one. It is the culture. Culture
  10467. 6:11:35means show me the value whether it's
  10468. 6:11:37date, time or number. Show me this value
  10469. 6:11:40in the style of a specific country or
  10470. 6:11:43region. So each country each region has
  10471. 6:11:45different format. So here we can go and
  10472. 6:11:47change it to specific region format. But
  10473. 6:11:50as I said it is optional. Let's have an
  10474. 6:11:52example. So here we are saying go and
  10475. 6:11:54format the order dates using the
  10476. 6:11:56following format. So dd day then slash
  10477. 6:12:00then we have the month then slash then
  10478. 6:12:02the year. So going to go and format this
  10479. 6:12:04with this new format. And as you can see
  10480. 6:12:06here we didn't specify any culture since
  10481. 6:12:07it's optional. Let's see another option
  10482. 6:12:09where we can say you know what I would
  10483. 6:12:11like to have the order date formatted
  10484. 6:12:13with this format but we would like to go
  10485. 6:12:15and add the style of Japan. So we are
  10486. 6:12:17specifying here the code or the style of
  10487. 6:12:20Japan. And of course we can go and use
  10488. 6:12:22the format not only for the date but as
  10489. 6:12:24well for formatting the numbers. So here
  10490. 6:12:26we are specifying the value. The format
  10491. 6:12:29is D. And as well we have activated the
  10492. 6:12:31culture option. We are using the style
  10493. 6:12:33of France. So this is the syntax of the
  10494. 6:12:35format. Using this option is not really
  10495. 6:12:37common. So I rarely see this format or
  10496. 6:12:40someone using it. So the first example
  10497. 6:12:42is the most used one in the projects
  10498. 6:12:45where we have the culture as default or
  10499. 6:12:47we are not using the culture at all. And
  10500. 6:12:49of course if you don't specify anything
  10501. 6:12:51is going to go and use the default
  10502. 6:12:54culture which is enus. So this is all
  10503. 6:12:57about the syntax of the format. All
  10504. 6:12:58right. So now let's have a few examples
  10505. 6:13:00using the format. So we're going to go
  10506. 6:13:02and format the creation time. So we're
  10507. 6:13:04going to do it like this. Format. And
  10508. 6:13:06what we are formatting? We are
  10509. 6:13:07formatting the creation time and now you
  10510. 6:13:10can go and define any specifier you
  10511. 6:13:12want. For example, let's say DD like
  10512. 6:13:15this. So let's go and check the outputs.
  10513. 6:13:18So execute it. Now if you are using DD,
  10514. 6:13:20you will get the day information. So we
  10515. 6:13:24can see if you're using this specifier,
  10516. 6:13:26we are getting two digits about the day.
  10517. 6:13:28So and as well we are getting the
  10518. 6:13:29leading zero. So we are getting the 01
  10519. 6:13:3105 and all those informations are the
  10520. 6:13:34day information. Now let's go and try
  10521. 6:13:35something else. adding one more D. So
  10522. 6:13:39let's have it 3D and here as well. So
  10523. 6:13:42let's go execute it. So now if you check
  10524. 6:13:44the output, we are getting now the name
  10525. 6:13:45of the day. It is not full. So we are
  10526. 6:13:48getting like a short name of the day or
  10527. 6:13:50abbreviated one. So this is sometime
  10528. 6:13:51nice if you are creating like a calendar
  10529. 6:13:53or something. Let's go and add one more
  10530. 6:13:56D. So we're going to have 4 D. And let's
  10531. 6:14:00go and check the result for this one.
  10532. 6:14:02Now in the output we are getting the
  10533. 6:14:04full name of the day. So it's really
  10534. 6:14:06nice. Now we are getting full
  10535. 6:14:08flexibility on how to format our day.
  10536. 6:14:10Okay. So now let's keep playing. Let's
  10537. 6:14:11get something else. I'm just going to go
  10538. 6:14:13and duplicate everything and I will go
  10539. 6:14:16with the month now. So this is 2 M, 3 M
  10540. 6:14:21and 4 M. Let me do it like this. So
  10541. 6:14:26let's go and execute it. Now as you can
  10542. 6:14:28see we are getting the same stuff but
  10543. 6:14:30for the month. So mm we will get the two
  10544. 6:14:32digits and 3m we will get the
  10545. 6:14:34abbreviated name of the month and for m
  10546. 6:14:37we will get the full name of the month.
  10547. 6:14:39So it's like we are extracting the date
  10548. 6:14:41part from the format but of course we
  10549. 6:14:43don't use it like this. We will go and
  10550. 6:14:45write the whole format that we need for
  10551. 6:14:48a date. So for example let's go and
  10552. 6:14:50change this format to the USA format. So
  10553. 6:14:53in order to do it so we're going to go
  10554. 6:14:55over here. So let's say format again the
  10555. 6:14:58creation time. And now we're going to
  10556. 6:15:00write the format of USA. So it's going
  10557. 6:15:02to be mm. Then after that then after the
  10558. 6:15:05month we're going to have like minus
  10559. 6:15:07then day and then after that we're going
  10560. 6:15:09to get the year. So for time year and
  10561. 6:15:12that's it. Let's call it USA format. So
  10562. 6:15:15let's go and excuse it. And now you can
  10563. 6:15:18see in the outut we got a new column
  10564. 6:15:19where we see now the date information
  10565. 6:15:21but as a USA standards. So it start with
  10566. 6:15:24the month then the day and then
  10567. 6:15:26afterward we got the year. And of course
  10568. 6:15:28we can do the same thing in order to
  10569. 6:15:29generate the standard format of Europe.
  10570. 6:15:32So what we're going to do I'll just
  10571. 6:15:34duplicate it. And now the format of that
  10572. 6:15:37going to start with the day then the
  10573. 6:15:39month and then the year. So now if you
  10574. 6:15:42check the output you can see it start
  10575. 6:15:43with day minus then we have the month
  10576. 6:15:46then minus the year. So as you can see
  10577. 6:15:48we are changing the format of the date
  10578. 6:15:50from creation time to something new. All
  10579. 6:15:52right. So now we have the following task
  10580. 6:15:54and it says show creation time using the
  10581. 6:15:57following format. Now we have a very
  10582. 6:15:59weird format. So it start with the word
  10583. 6:16:01day. Then after that we have the
  10584. 6:16:03abbreviation of the day and then
  10585. 6:16:05abbreviation of the month. This is the
  10586. 6:16:07quarter informations. Then the year and
  10587. 6:16:10after that we have the time and we're
  10588. 6:16:12going to say whether it's PM or A.M. So
  10589. 6:16:14it's little bit weird format that you
  10590. 6:16:16don't see it everywhere but still we
  10591. 6:16:18want to practice on how to construct
  10592. 6:16:20such custom format. So let's do it step
  10593. 6:16:22by step. I'm going to go over here and a
  10594. 6:16:24new line. So the first one is like day.
  10595. 6:16:27So we don't have any format for that.
  10596. 6:16:29It's just like characters. So this one
  10597. 6:16:32going to be static for all the format.
  10598. 6:16:34So what we going to do? We're going to
  10599. 6:16:35say with a string this is the day. So
  10600. 6:16:39let's go and execute it. So with that we
  10601. 6:16:41got a static value. Everywhere we have
  10602. 6:16:43the word day. So that's it. And after
  10603. 6:16:46that we have a space. So I'm going to go
  10604. 6:16:47and include it after the day in the
  10605. 6:16:49string. So we have a day then space and
  10606. 6:16:52after that we need the abbreviation of
  10607. 6:16:54the day name. So what we're going to do
  10608. 6:16:56we're going to go first with the plus
  10609. 6:16:57operator in order to concatenate the
  10610. 6:17:00strings. So we need the format function
  10611. 6:17:03for the creation time. And what do we
  10612. 6:17:06need? We need the short name. So it's
  10613. 6:17:09going to be three times the d. Let's go
  10614. 6:17:11and execute it. Let me just say here
  10615. 6:17:13custom formats. So now as you can see in
  10616. 6:17:16the output we have here the day. Then
  10617. 6:17:17afterward we have space and then the
  10618. 6:17:20abbreviation of the name of the day. So
  10619. 6:17:23it looks so far good. Now after that
  10620. 6:17:25what do we need? We need space and then
  10621. 6:17:27the abbreviation of the month. So we can
  10622. 6:17:29go and add all those stuff together with
  10623. 6:17:31the format here. So we don't have to
  10624. 6:17:33create two formats. So space and the
  10625. 6:17:36abbreviation of the month is 3 M. So
  10626. 6:17:39let's go and test it. Great. So now as
  10627. 6:17:41you can see we got the abbreviation of
  10628. 6:17:43the month as well side by side. So we so
  10629. 6:17:46far we have covered this part. Now we
  10630. 6:17:48have to move to the second part. So we
  10631. 6:17:50still need a space and then Q1. Well the
  10632. 6:17:53Q going to be static. So we cannot go
  10633. 6:17:55and extend this format. We have to start
  10634. 6:17:57a new one. So what I'm going to do I'm
  10635. 6:17:59just going to add a plus here and a new
  10636. 6:18:02line. So what do we need? We need first
  10637. 6:18:04a space between the month and the
  10638. 6:18:06quarter. So let's go and add space and
  10639. 6:18:09we need the Q as a static value like
  10640. 6:18:12this. Let me just move it like this. And
  10641. 6:18:14now after that we need this one like
  10642. 6:18:16this right so now we need the quarter
  10643. 6:18:18informations and we don't have format
  10644. 6:18:20for that that's why we have to go and
  10645. 6:18:22use the part extraction functions and
  10646. 6:18:24the one that we're going to use since we
  10647. 6:18:26are using string I will go with the date
  10648. 6:18:28name so quarter and we are extracting
  10649. 6:18:32from the creation time so let's go and
  10650. 6:18:35test it so now in the output you can see
  10651. 6:18:37we have everywhere a Q1 and that's
  10652. 6:18:39because all of those dates are in Q1 all
  10653. 6:18:41right so now we are so far halfway in
  10654. 6:18:43our format Not. So now next what do we
  10655. 6:18:46need? We need like a space and then the
  10656. 6:18:48year information and then the time
  10657. 6:18:50information. So now in order to go and
  10658. 6:18:52get space we're going to do it very
  10659. 6:18:53simply concatenate and we're going to
  10660. 6:18:56have space. Now let's go to a new line
  10661. 6:18:59and in order to get the year I will go
  10662. 6:19:01with the format as well. So format and
  10663. 6:19:03what do we have? We're going to have the
  10664. 6:19:05creation time
  10665. 6:19:07again. So how we going to format it now?
  10666. 6:19:10What do we need? We need the year. So
  10667. 6:19:11it's going to be four times the y and
  10668. 6:19:13after that we have like space and then
  10669. 6:19:15the time information. We still can't do
  10670. 6:19:17that inside the format, right? So we're
  10671. 6:19:19going to have space here. And then next
  10672. 6:19:21what do we have? We have the hours. So
  10673. 6:19:22it's going to be h the small h because
  10674. 6:19:24here we are talking about the pm and am.
  10675. 6:19:27It's not the 24hour system. And then
  10676. 6:19:29after that what do we have? The points
  10677. 6:19:31double points. Then the minutes going to
  10678. 6:19:33be small 2 m. And then after that the
  10679. 6:19:36seconds. So far this is exactly this
  10680. 6:19:38part over here. And now what is missing
  10681. 6:19:40a space and the PM the designator. So in
  10682. 6:19:43order to do that we're going to have a
  10683. 6:19:45space as well and then small 2 * tt. All
  10684. 6:19:48right. So we are almost there. Let's go
  10685. 6:19:51and execute it. Now you can see it is
  10686. 6:19:53working. So we have the year then space
  10687. 6:19:56the hours minutes and space and then we
  10688. 6:20:00have the designator. So this is PM and
  10689. 6:20:03this is A.M. which is correct. So that's
  10690. 6:20:06it. We are done. This is how you can
  10691. 6:20:07create those crazy formats in SQL using
  10692. 6:20:11the help of format or maybe date name or
  10693. 6:20:13maybe some static values like we just
  10694. 6:20:15added here. So I think it's really fun
  10695. 6:20:17formatting the dates in
  10696. 6:20:21SQL. Now one use case for the format
  10697. 6:20:24that I frequently use in my project is
  10698. 6:20:26using it to format the date before doing
  10699. 6:20:29aggregations. So it's like part
  10700. 6:20:31extraction but here we have more
  10701. 6:20:33customizations on how we represent the
  10702. 6:20:35date at the reports. So we can show a
  10703. 6:20:38report like sales by month where we
  10704. 6:20:40display for example the date as
  10705. 6:20:41abbreviation name of the month Jan and
  10706. 6:20:44as well two digits for the year 25. So
  10707. 6:20:46once we change the format like this and
  10708. 6:20:48then do data aggregations we will have a
  10709. 6:20:51nice report about the sales by month. So
  10710. 6:20:53let's have a quick aggregations using
  10711. 6:20:54the format. So, we're going to go and
  10712. 6:20:56say select and now the order date and
  10713. 6:20:59count the number of
  10714. 6:21:01orders from our table sales orders and
  10715. 6:21:06then group by. But now before we start
  10716. 6:21:09using the order date, we have to go and
  10717. 6:21:11format it. And then if you take the
  10718. 6:21:12order date, let's go and execute it. So
  10719. 6:21:15as you can see the level of details is
  10720. 6:21:17very high and we have here 10 rows and
  10721. 6:21:19for each day we have like one order. Now
  10722. 6:21:21we learned we can go and use the date
  10723. 6:21:23part in order to extract one part and
  10724. 6:21:25then aggregate on it. So now instead of
  10725. 6:21:27that we're going to go and use the
  10726. 6:21:28format function. So let's go and change
  10727. 6:21:30the format and it is the order dates.
  10728. 6:21:33And our format going to be like this. So
  10729. 6:21:35three big M and then two digits for the
  10730. 6:21:38year. That's it. And let's call it order
  10731. 6:21:41dates. And we need this as well for the
  10732. 6:21:44order date over here for the group I and
  10733. 6:21:46here a comma. So that's it. Let's go and
  10734. 6:21:48execute it. So in the output as you can
  10735. 6:21:50see over here we have three months and
  10736. 6:21:52here we having the aggregation the
  10737. 6:21:53number of orders for each month. So now
  10738. 6:21:55it's like the date part but now we are
  10739. 6:21:57customizing the format as we want. So we
  10740. 6:22:00can use the format in order to change
  10741. 6:22:02the granularity of the date in order to
  10742. 6:22:04do that
  10743. 6:22:08aggregations. Now I'm going to show you
  10744. 6:22:10a real use case for the formatting in
  10745. 6:22:12real projects. Now our data could be
  10746. 6:22:14stored in different technologies like
  10747. 6:22:16the data could be stored in CSV file or
  10748. 6:22:18we can get our data using an API call or
  10749. 6:22:21in very common scenario our data could
  10750. 6:22:23be stored in database. So now what we
  10751. 6:22:25usually do we go and extract the data
  10752. 6:22:27from these different sources into one
  10753. 6:22:29central storage. It could happen that
  10754. 6:22:31you are getting different formats for
  10755. 6:22:33the dates and of course this is a
  10756. 6:22:34problem for analytics. You cannot
  10757. 6:22:36present different formats for the dates.
  10758. 6:22:37What we're going to do we're going to go
  10759. 6:22:38and clean up the formats into one
  10760. 6:22:41standard format. So that means we have
  10761. 6:22:43to format the incoming data to new
  10762. 6:22:45formats and once we have one standard
  10763. 6:22:47format we can use it in analytics and
  10764. 6:22:50reports. So this is very common use case
  10765. 6:22:52in data preparation and in data cleanup
  10766. 6:22:55by formatting different formats into one
  10767. 6:22:57standard
  10768. 6:23:01format. Now in SQL we have many
  10769. 6:23:04different date and time specifiers and I
  10770. 6:23:07said they are case sensitive and each
  10771. 6:23:09one of them has a different meaning. So
  10772. 6:23:11I prepared for you as well all possible
  10773. 6:23:13specifiers that we can use with the
  10774. 6:23:15formats. Not only that, if you go back
  10775. 6:23:16to the queries that you can find in this
  10776. 6:23:18chapter, you can find here date format.
  10777. 6:23:21So all date formats. If you go inside
  10778. 6:23:23it, you can go and copy the whole query
  10779. 6:23:26and then go back to SQL then execute it.
  10780. 6:23:29You can find here a live example because
  10781. 6:23:31I'm manipulating now the get date. So
  10782. 6:23:34you can find here a list of all possible
  10783. 6:23:37date specifiers that you can use with
  10784. 6:23:38the formats. So I would say go and
  10785. 6:23:40practice with those different date
  10786. 6:23:41formats in order to understand what is
  10787. 6:23:44possible in SQL. So as we learned not
  10788. 6:23:45only we can change the format of the
  10789. 6:23:47date, we can change as well the format
  10790. 6:23:49of the number using the function formats
  10791. 6:23:51and those are the different possibility
  10792. 6:23:53that you can use as a specifier for this
  10793. 6:23:55format in order to change the format of
  10794. 6:23:58the numbers and as well I have prepared
  10795. 6:23:59all those different specifiers in one
  10796. 6:24:02big query. So if you go inside it and
  10797. 6:24:04copy it and then put it in SQL and
  10798. 6:24:06execute it, you will find here all
  10799. 6:24:08different possibilities that we have as
  10800. 6:24:11a specifier to change the format of the
  10801. 6:24:17numbers. All right. So what is convert?
  10802. 6:24:19It's very simple. It's going to go and
  10803. 6:24:21change the value to a different type and
  10804. 6:24:23as well at the same time it helps
  10805. 6:24:25formatting the value. Okay. So let's
  10806. 6:24:27check the syntax of the convert and it
  10807. 6:24:29looks like this. It start with the
  10808. 6:24:31function converts and it accept two
  10809. 6:24:33parameters the data type first since we
  10810. 6:24:36can use this function in order to cast
  10811. 6:24:38the data types. So you can use string
  10812. 6:24:40integer dates and so on and then we have
  10813. 6:24:43to specify the value. So which value
  10814. 6:24:45should be casted. And the last parameter
  10815. 6:24:47it is optional one where you define the
  10816. 6:24:50style the format of the value. Let's
  10817. 6:24:53have this very simple example. We are
  10818. 6:24:54saying convert to the data type integer
  10819. 6:24:57int and the value that should be
  10820. 6:24:59converted is 1 2 3 as a string. So it's
  10821. 6:25:02going to convert it to integer. We are
  10822. 6:25:04saying convert to a vchart and the value
  10823. 6:25:07that should be converted is the order
  10824. 6:25:08date. So the order date should be a
  10825. 6:25:10date. So we're going to convert it from
  10826. 6:25:12date to v charts using the format or the
  10827. 6:25:15style of 34. So here we are specifying a
  10828. 6:25:19style a format for this value. And of
  10829. 6:25:21course it is optional and if you are not
  10830. 6:25:23using anything the default value that's
  10831. 6:25:26going to be used is zero. So this is the
  10832. 6:25:29syntax of the convert in SQL. All right.
  10833. 6:25:31So now we're going to have few examples
  10834. 6:25:32on how to work with the convert. So
  10835. 6:25:34let's go and convert for example string
  10836. 6:25:36to integer. So we're going to say for
  10837. 6:25:38example convert. So what is the target
  10838. 6:25:41data type? It's going to be the integer
  10839. 6:25:43and the value. It's going to be like for
  10840. 6:25:45example 1 2 3. So and let's call it like
  10841. 6:25:48this string to integer and the function
  10842. 6:25:51is convert. So now in the column name as
  10843. 6:25:54you can see I'm using here brackets and
  10844. 6:25:55that's because I'm using like empty
  10845. 6:25:57spaces and so on and with that I will
  10846. 6:25:59get more freedom on how to name things.
  10847. 6:26:01So this is just the name. So this is no
  10848. 6:26:04function or something. Let's go and
  10849. 6:26:06excuse it. Now as you can see it's going
  10850. 6:26:07to work. So we are converting from a
  10851. 6:26:09string value to an integer and the
  10852. 6:26:12output this 1 2 3 here is not string.
  10853. 6:26:15This is the data type of integer. All
  10854. 6:26:17right. So now let's have another example
  10855. 6:26:18where we want to convert from string to
  10856. 6:26:21date. So the target going to be the date
  10857. 6:26:24and the value let's have this value as
  10858. 6:26:27usual and we're going to go and call
  10859. 6:26:30it string to date convert. Okay. So
  10860. 6:26:35let's go and execute it. Now in the
  10861. 6:26:37output we will get this information this
  10862. 6:26:39string as a date. And with that we have
  10863. 6:26:41converted the data type from string to
  10864. 6:26:43dates. Now let's have another example
  10865. 6:26:44where we want to convert the date time
  10866. 6:26:46to a date. As you remember the creation
  10867. 6:26:48time is a date time and we would like to
  10868. 6:26:51have it as only date. So let's go and
  10869. 6:26:53convert and we would like it to be as
  10870. 6:26:56well date but this time it's going to be
  10871. 6:26:58a column called creation time and let's
  10872. 6:27:01give it the name. So we are converting
  10873. 6:27:05date time to dates. But of course here
  10874. 6:27:08we have to go and select. So from sales
  10875. 6:27:11orders that's it. Let's go and execute
  10876. 6:27:14it. Now, as you can see in the output,
  10877. 6:27:15we got only date. I'm going to go and
  10878. 6:27:17select the creation time in the query as
  10879. 6:27:20well. So now, as you can see, the
  10880. 6:27:22creation time was before a date time.
  10881. 6:27:24So, we have the time information as
  10882. 6:27:25well. But if you go and cast it using
  10883. 6:27:28the convert and make it only date. So,
  10884. 6:27:30SQL going to go and convert it to date
  10885. 6:27:32and you're going to lose all the
  10886. 6:27:33informations about the time. So, so far
  10887. 6:27:35what we are doing here is just casting.
  10888. 6:27:37So, we are changing the data type from
  10889. 6:27:39one to another. But in the convert, we
  10890. 6:27:41can do both. We can do casting and
  10891. 6:27:43formatting. So let's see how we can do
  10892. 6:27:45that. I will just get rid of those
  10893. 6:27:47information at the start. So creation
  10894. 6:27:49time. And now we're going to go and
  10895. 6:27:51convert the date time of the creation
  10896. 6:27:54time to a varchar to a string. And as
  10897. 6:27:56well to give it the format of the USA
  10898. 6:27:58standard format. So let's see how we can
  10899. 6:28:00do that. We're going to start with
  10900. 6:28:01convert. We are changing now to var. So
  10901. 6:28:05this is the new data type and the value
  10902. 6:28:08is the creation time. And now if I don't
  10903. 6:28:10give it a style, it's going to stay with
  10904. 6:28:11the standard format, but we would like
  10905. 6:28:13to have the USA standards. So in order
  10906. 6:28:16to do that, we're going to go and add
  10907. 6:28:17the style of the format. So it's going
  10908. 6:28:19to be 32. So that's it. Let's have a
  10909. 6:28:23name like this. So
  10910. 6:28:26USA standard and we are using the style
  10911. 6:28:30of 32. Let's go with that. This is just
  10912. 6:28:32a name again. So it's not a function.
  10913. 6:28:34Let's go ahead and execute it. And now
  10914. 6:28:36in the output we got a new field and the
  10915. 6:28:38data type of this field is a varchar. So
  10916. 6:28:40it's not a date or date time. And as you
  10917. 6:28:42can see the date now is formatted using
  10918. 6:28:45this style the 32 the US standard
  10919. 6:28:47format. So it start with a month then a
  10920. 6:28:50day and then a year. So now let's go and
  10921. 6:28:52do the same thing in order to get the
  10922. 6:28:54standard format in Europe. So I will
  10923. 6:28:56just go and copy the whole thing. I will
  10924. 6:28:59just change the style. So instead of 32
  10925. 6:29:02we're going to go with the 34. And I
  10926. 6:29:04will just change the name as well. So,
  10927. 6:29:08so we are just changing the style. Let's
  10928. 6:29:10go ahead and execute it. Now, as you can
  10929. 6:29:11see, we got the same thing. We have as
  10930. 6:29:13well a v jar and the format now is
  10931. 6:29:15different. So, we have here the day,
  10932. 6:29:18then the month, and then the year. So,
  10933. 6:29:20this is how you work with the convert
  10934. 6:29:21function. You can use it in order to do
  10935. 6:29:23only casting or not only that, you can
  10936. 6:29:26do casting and as well formatting. So,
  10937. 6:29:28you have both things in one function.
  10938. 6:29:34And now if you're talking about which
  10939. 6:29:35styles are available, we have many
  10940. 6:29:37styles that you can use inside the
  10941. 6:29:39convert. So I have prepared for you a
  10942. 6:29:41list of all styles that you can use with
  10943. 6:29:43the convert. So we have styles only for
  10944. 6:29:45the dates and another styles only for
  10945. 6:29:47the time and styles for only date time.
  10946. 6:29:50Now in the download folders you can find
  10947. 6:29:52here one file called all culture
  10948. 6:29:54formats. And here you can find one query
  10949. 6:29:57that I have prepared where you can find
  10950. 6:29:59inside it the different cultures and the
  10951. 6:30:01examples. So let's go and copy it and
  10952. 6:30:03let's go back to scale paste it and
  10953. 6:30:05let's see the results. So now if you
  10954. 6:30:07check the output we got the first column
  10955. 6:30:09is the cultures that is used. So we have
  10956. 6:30:11a lot of cultures like around 17s and
  10957. 6:30:13you can see how the numbers are
  10958. 6:30:14formatted or the date is formatted based
  10959. 6:30:16on this culture. So it's really fun. You
  10960. 6:30:18can check here for example how the
  10961. 6:30:20format in Japan or Korea or France and
  10962. 6:30:23the German one. If you scroll down, you
  10963. 6:30:25can find the Arabic, the Russian and so
  10964. 6:30:27on. So you can see the format of each
  10965. 6:30:29dates is changing based on the culture.
  10966. 6:30:32So I would say have fun. Go and try
  10967. 6:30:34those different cultures formats in
  10968. 6:30:36order to format your numbers or
  10969. 6:30:40dates. So what is the cast function? It
  10970. 6:30:43going to go and convert a value to a
  10971. 6:30:46different data type. So it turns one
  10972. 6:30:48data type to another. All right. So now
  10973. 6:30:50let's check the syntax of the cast. I
  10974. 6:30:52really like this one. It is not typical
  10975. 6:30:54like format or syntax in SQL. So it says
  10976. 6:30:57the cast is the function and then inside
  10977. 6:31:00it we need two things but it's not
  10978. 6:31:02separated like with the comma as we
  10979. 6:31:03learned before with all other functions
  10980. 6:31:05but this time is separated with the
  10981. 6:31:07keyword as. So it's like the natural
  10982. 6:31:09English you are saying cast the value as
  10983. 6:31:12a data type. So you are casting the
  10984. 6:31:14value to a new data type. So let's have
  10985. 6:31:16this very simple example we have here
  10986. 6:31:18cast the value 1 2 3 as integer. So
  10987. 6:31:22previously it is string and it going to
  10988. 6:31:24be converted to integer. So as you can
  10989. 6:31:26see it's very simple. Now in this
  10990. 6:31:27example we are saying cast this value
  10991. 6:31:30this string value as a dates. So
  10992. 6:31:32converted from string to dates. So as
  10993. 6:31:34you can see with the cast we don't have
  10994. 6:31:35here any option of formatting or styling
  10995. 6:31:38the values. So it's only dedicated for
  10996. 6:31:40casting the value from one data type to
  10997. 6:31:43another one. So this is the syntax of
  10998. 6:31:45the cast. It is very straightforward and
  10999. 6:31:47really nice function. Okay. So now let's
  11000. 6:31:49have a few examples about the cast. So
  11001. 6:31:51let's go and convert a value from a
  11002. 6:31:53string to integer. So it's very simple.
  11003. 6:31:55We're going to say cast. So now we need
  11004. 6:31:57the value. So let's go with the 1 2 3.
  11005. 6:32:00So we have here a string. And then we're
  11006. 6:32:01going to say as and then we have to
  11007. 6:32:03define the data type. So the data type
  11008. 6:32:05going to be integer. So that's it. So
  11009. 6:32:07let's give it the name like this string
  11010. 6:32:10to integer. Let's go and execute it. Now
  11011. 6:32:13as you can see we got the value but with
  11012. 6:32:14the data type integer. From string to
  11013. 6:32:16integer. Now let's do the way around. We
  11014. 6:32:19cast from integer to string. So we're
  11015. 6:32:21going to say cast 1 2 3 as var jar and
  11016. 6:32:26we're going to give it a
  11017. 6:32:27name int to string. So let's go and
  11018. 6:32:31execute it. Now in the output we have 1
  11019. 6:32:332 3 but this time it has the data type
  11020. 6:32:36varchar. Now let's go and work with the
  11021. 6:32:38date. So we're going to go and convert a
  11022. 6:32:40value a string value to a date. So our
  11023. 6:32:44value going to be the usual one and we
  11024. 6:32:48want it from string to date. So we're
  11025. 6:32:50going to have the data type as date. So
  11026. 6:32:52let's give it a name string to date.
  11027. 6:32:56Let's go and execute it. Now we're going
  11028. 6:32:58to have this value with the data type
  11029. 6:33:00date. So that's it. Now let's say that I
  11030. 6:33:02would like to have this value but as
  11031. 6:33:04date time. So I will just copy the whole
  11032. 6:33:07thing and go to a new line and say date
  11033. 6:33:10time two. So the name of this going to
  11034. 6:33:13be string to date time. Let's go and
  11035. 6:33:16execute it. Now in the output as you can
  11036. 6:33:17see we are getting not only the date but
  11037. 6:33:20as well we are getting the time
  11038. 6:33:21information. But now since we didn't
  11039. 6:33:23provide SQL with any time information
  11040. 6:33:25SQL going to go and show it as zeros.
  11041. 6:33:27Now let's do one more casting where we
  11042. 6:33:29change the data type from date time to
  11043. 6:33:31date. So now we need our creation
  11044. 6:33:33time but we have to get it from the
  11045. 6:33:36tables. So from sales orders let's go
  11046. 6:33:39and execute it. So now in the output you
  11047. 6:33:41can see the creation time is a date
  11048. 6:33:42time. We have the time information but
  11049. 6:33:44we are not interested about the time
  11050. 6:33:45information. I would like to have this
  11051. 6:33:47field as a date. So it's very simple
  11052. 6:33:49what we're going to do. We're going to
  11053. 6:33:50say cast. Now the value is creation time
  11054. 6:33:55and then the keyword as and we need it
  11055. 6:33:57as a date. So we're going to give it the
  11056. 6:33:59name date time to date. So let's go and
  11057. 6:34:03execute it. Now as you can see in the
  11058. 6:34:04output we got the creation time but only
  11059. 6:34:07with the date information. We don't have
  11060. 6:34:09anything about the time. So we get it as
  11061. 6:34:11a date instead of date time. So that's
  11062. 6:34:14it. This is amazing function SQL and
  11063. 6:34:16it's very simple and we can use it only
  11064. 6:34:18for casting. So only to change the data
  11065. 6:34:20type from one to another. And we cannot
  11066. 6:34:22use this function in order to change the
  11067. 6:34:24format. So if you are casting you will
  11068. 6:34:26get always the standard format from
  11069. 6:34:32SQL. So now let's go and compare our
  11070. 6:34:34functions side by side. So we have our
  11071. 6:34:36three functions. cast, convert and
  11072. 6:34:38format and we can do two things either
  11073. 6:34:41casting or formatting. So by the casting
  11074. 6:34:44for the first function cast we can
  11075. 6:34:45change any type to any other type. So
  11076. 6:34:48there is no restriction at all. The same
  11077. 6:34:49thing for the converts the same thing we
  11078. 6:34:52can convert anything to anything. But
  11079. 6:34:53for the format we can change only to a
  11080. 6:34:56string. So any data type like a date or
  11081. 6:34:58number to a string value because the
  11082. 6:35:01main thing for the format is not
  11083. 6:35:03changing the data type. Now if you are
  11084. 6:35:04talking about changing the format of the
  11085. 6:35:06values, you cannot use the cast function
  11086. 6:35:08in order to change the format. So the
  11087. 6:35:10cast function is only for casting. It
  11088. 6:35:12makes sense. Now about the convert, we
  11089. 6:35:14can use it in order to change the format
  11090. 6:35:17of the date and time. But we cannot use
  11091. 6:35:19it in order to change the number
  11092. 6:35:20formats. And for that we have a
  11093. 6:35:22dedicated function called format. So we
  11094. 6:35:25can use it to change the format of the
  11095. 6:35:26date and time and as well the numbers.
  11096. 6:35:28So those are the main differences
  11097. 6:35:30between those three functions. All
  11098. 6:35:31right. So with those three functions we
  11099. 6:35:33have learned how to do formatting and
  11100. 6:35:35casting on date informations. Now moving
  11101. 6:35:38on to the third group we have the date
  11102. 6:35:40calculations and here we have two
  11103. 6:35:41functions on how to do date calculations
  11104. 6:35:43or mathematical operations on the dates.
  11105. 6:35:48If okay so now we're going to start with
  11106. 6:35:50the first function the date add. So what
  11107. 6:35:53is date add? Date add can allow us to
  11108. 6:35:55add or subtract a specific time interval
  11109. 6:35:59to or from a date. So let's understand
  11110. 6:36:01how the date add work. So here again we
  11111. 6:36:03have our date August 20th 2025. So now
  11112. 6:36:06in some scenarios we would like to add
  11113. 6:36:08years to our dates. So for example let's
  11114. 6:36:11say I would like to add three years to
  11115. 6:36:12our date. So we can do that using the
  11116. 6:36:14date ad. So if you do that in the output
  11117. 6:36:17you will get 2028 August 20th only the
  11118. 6:36:20date part is changed and where we have
  11119. 6:36:22added three years but in other scenarios
  11120. 6:36:25you would like to go and add months. So
  11121. 6:36:27for example let's go and add two months
  11122. 6:36:29to the August. So in the output you will
  11123. 6:36:31get 2025 10 20 with that we have added
  11124. 6:36:34two months and of course we can go and
  11125. 6:36:36add days to our dates. So for example
  11126. 6:36:39we're going to go and add five days to
  11127. 6:36:41our date. So in the output we'll get the
  11128. 6:36:43same year 2025 the same month August but
  11129. 6:36:46only the day will be changed to 25. So
  11130. 6:36:49we have added five days to the original
  11131. 6:36:51dates. And of course we can go and
  11132. 6:36:53subtract dates even though that the
  11133. 6:36:54function called date add. So for
  11134. 6:36:56example, we can go and subtract three
  11135. 6:36:59years from our dates and we will get So
  11136. 6:37:01if you do that, you will get 2022 August
  11137. 6:37:0420th or if you go and subtract two
  11138. 6:37:06months from our dates. So it's going to
  11139. 6:37:08stay the same year 2025. But this time
  11140. 6:37:10instead of August, we will go back to
  11141. 6:37:12June with the same date 20. And the same
  11142. 6:37:14thing going to happen for the days if
  11143. 6:37:16you go and subtract five days. So the
  11144. 6:37:18same year 2025, the same month August,
  11145. 6:37:21but only the days going to be instead of
  11146. 6:37:2320, it's going to be 15. So as you can
  11147. 6:37:25see with the date ad you can manipulate
  11148. 6:37:27the years, the month and the days by
  11149. 6:37:30subtracting or adding new intervals. So
  11150. 6:37:33this is how the date ad works. All
  11151. 6:37:35right. So now let's check the syntax of
  11152. 6:37:36the date ad. And here things little bit
  11153. 6:37:38more complicated. We have to provide
  11154. 6:37:40three informations. The first one is a
  11155. 6:37:42part. What do you want to add? Do you
  11156. 6:37:44want to add years or months or days and
  11157. 6:37:47so on. Then the second one is interval.
  11158. 6:37:50So it's like how many days? How many
  11159. 6:37:52years? How many months? And then the
  11160. 6:37:54last one is the date. This is the date
  11161. 6:37:56that we're going to be manipulating by
  11162. 6:37:57adding or subtracting intervals. Let's
  11163. 6:38:00check the following example. We are
  11164. 6:38:02saying here date add. So what is the
  11165. 6:38:04part here is a year. That means we want
  11166. 6:38:06to manipulate only the year parts. Then
  11167. 6:38:09the interval here is two. So it is
  11168. 6:38:11positive. We want to add two years. So
  11169. 6:38:14it's going to go to each order and start
  11170. 6:38:15adding two years for each date value.
  11171. 6:38:18Now let's check another example. Here we
  11172. 6:38:20are saying date add month. So here we
  11173. 6:38:22want to manipulate the month part. But
  11174. 6:38:24here we are saying minus4 that means we
  11175. 6:38:27want to go and subtract four months from
  11176. 6:38:30each value in the order date. So as you
  11177. 6:38:33can see the value of the interval
  11178. 6:38:34whether it's positive or negative. We
  11179. 6:38:36are controlling here the function
  11180. 6:38:37whether it is subtraction or addition.
  11181. 6:38:40So let's have few examples about the
  11182. 6:38:41date add using our field order dates. So
  11183. 6:38:44for example let's go and add two years
  11184. 6:38:46for each date. So we can do it like this
  11185. 6:38:49date adds. So we are adding years that's
  11186. 6:38:52why we're going to go with the part year
  11187. 6:38:53and how many years we are adding we are
  11188. 6:38:54adding two years. So this is our
  11189. 6:38:56interval and our field our value is the
  11190. 6:39:00order date. So now in the output as you
  11191. 6:39:02can see we got a date but this date is
  11192. 6:39:04always 2 years higher than the order
  11193. 6:39:06date. So everywhere you have see 2027.
  11194. 6:39:09Now let's go and add maybe three months
  11195. 6:39:12for each date. Just going to go and copy
  11196. 6:39:14it and say a month. Let's change the
  11197. 6:39:17interval to three and we're going to
  11198. 6:39:19call it three
  11199. 6:39:21months later. So now if you check the
  11200. 6:39:23output over here we have a new date but
  11201. 6:39:25now the difference between it and the
  11202. 6:39:27order date we have here always three
  11203. 6:39:29months more than the order dates. So for
  11204. 6:39:31example here we have January but in the
  11205. 6:39:34new one we have April and for the next
  11206. 6:39:36one we have February and in the new
  11207. 6:39:38field we have May. So as you can see we
  11208. 6:39:40are adding months over here. So as you
  11209. 6:39:42can see we are adding monthses to our
  11210. 6:39:45original filled order date. Now let's
  11211. 6:39:47say that I would like to go and subtract
  11212. 6:39:4810 days. So let's go and do the same. So
  11213. 6:39:52we're going to have the date add. Since
  11214. 6:39:54we are talking about the days, it's
  11215. 6:39:55going to be the day. We're going to
  11216. 6:39:56subtract 10 days. So minus 10 for the
  11217. 6:40:00order date. So let's call it 10 days
  11218. 6:40:04before. Let's go and execute it. Now we
  11219. 6:40:07got as well a new date. And this date
  11220. 6:40:09has always 10 days before the order
  11221. 6:40:12date. So for example, let's take the
  11222. 6:40:14order number seven. In the order date we
  11223. 6:40:16have 15, but in the new column we have
  11224. 6:40:18five. So we have subtracted 10 days from
  11225. 6:40:22the original filled order dates. So as
  11226. 6:40:24you can see it's very simple to add or
  11227. 6:40:26subtract days, year, months using the
  11228. 6:40:29date
  11229. 6:40:32add. All right. So what is date diff?
  11230. 6:40:35diff stands for difference and date diff
  11231. 6:40:38can going to can allow us to find the
  11232. 6:40:40differences between two dates. All
  11233. 6:40:42right. So let's understand how the date
  11234. 6:40:44diff works in SQL. Now imagine we have
  11235. 6:40:46two dates. We have the order date 2025
  11236. 6:40:50August 20th and the shipping date is the
  11237. 6:40:531st of February in the next year 2026.
  11238. 6:40:56Now we might ask the question how many
  11239. 6:40:58years have passed between the order date
  11240. 6:41:01and the shipping date. So in order to
  11241. 6:41:03answer this question we can use the
  11242. 6:41:05function date diff and we can define the
  11243. 6:41:07part year. If you do it like this it's
  11244. 6:41:09going to subtract those two dates and it
  11245. 6:41:11going to return one. So the date
  11246. 6:41:13difference between those two dates is
  11247. 6:41:15exactly one year. But now if the
  11248. 6:41:17question is how many months are between
  11249. 6:41:19the order date and the shipping dates.
  11250. 6:41:21So here again we can go and use the date
  11251. 6:41:23diff between the order date and the
  11252. 6:41:24shipping date but we use the part month.
  11253. 6:41:27If you do it like this in the output you
  11254. 6:41:29will get three months. And now of course
  11255. 6:41:31if the question is how many days are
  11256. 6:41:34between the order date and the shipping
  11257. 6:41:36dates. So here we can use the function
  11258. 6:41:38date diff where we specify the day
  11259. 6:41:40inside it and in the output you will get
  11260. 6:41:4268. So this is how the date diff works.
  11261. 6:41:45You go and subtract two different dates
  11262. 6:41:47and you will get in the output a number
  11263. 6:41:50how many years how many months how many
  11264. 6:41:52days. So that's it. All right. Now to
  11265. 6:41:54the syntax of the date diff. It accept
  11266. 6:41:56here as well three parameters. So the
  11267. 6:41:58first one is the parts as usual year,
  11268. 6:42:01month, day. And then here we need two
  11269. 6:42:03dates, not only one, we need two. So we
  11270. 6:42:05need the starting dates and the ending
  11271. 6:42:08dates. So that means here we have the
  11272. 6:42:10youngest dates and the end date going to
  11273. 6:42:12be the oldest dates. So for example,
  11274. 6:42:14here we have date diff and we are saying
  11275. 6:42:16find the differences in years between
  11276. 6:42:19the order dates. This is the start date
  11277. 6:42:22and the shipping dates. So which dates
  11278. 6:42:25normally happen? First we have to order
  11279. 6:42:26something. So we have the order date and
  11280. 6:42:28once you order what can happen next is
  11281. 6:42:30the shipping date. That's why the
  11282. 6:42:32shipping date is as an end date. So we
  11283. 6:42:35want to find the differences between
  11284. 6:42:36them in years or of course if you want
  11285. 6:42:38to find the differences between them in
  11286. 6:42:40days we have to go and change the part
  11287. 6:42:42from year to day. So as you can see the
  11288. 6:42:44syntax is very simple and very logical
  11289. 6:42:47right. All right let's have the
  11290. 6:42:48following simple task and it says
  11291. 6:42:49calculate the age of employees. So let's
  11292. 6:42:52see how we can solve that. So we're
  11293. 6:42:53going to go and select first all the
  11294. 6:42:55informations from employees. So sales
  11295. 6:42:58and employees. Okay, let's execute it.
  11296. 6:43:01Now in the employees, we don't have any
  11297. 6:43:03informations about the age, but we have
  11298. 6:43:05the birthday. So we can go and transform
  11299. 6:43:07this birthday to an age. And of course,
  11300. 6:43:10how we calculate the age? We count how
  11301. 6:43:12many years between this year and the
  11302. 6:43:14birthday. So that means we have to go
  11303. 6:43:16and use two functions the date diff and
  11304. 6:43:19the get day in order to have the year of
  11305. 6:43:22the current year. So that means we have
  11306. 6:43:23to go and use the function date diff. So
  11307. 6:43:25let's go and do that. I'm going to go
  11308. 6:43:27first selecting only few informations.
  11309. 6:43:30So employee ID and P date. So let's
  11310. 6:43:34start with the date diff. So if we are
  11311. 6:43:36talking about the age we are calculating
  11312. 6:43:37how many years that's why we're going to
  11313. 6:43:39say as a part going to be the year. So
  11314. 6:43:42what is the starting date is the birth
  11315. 6:43:44date of the person. So it's going to be
  11316. 6:43:46the birth date. And now we need the end
  11317. 6:43:48date. We don't have here anything about
  11318. 6:43:50the end date. The end date going to be
  11319. 6:43:51the current year. So in order to get the
  11320. 6:43:54current year, we're going to go with the
  11321. 6:43:55function get dates. And with that we are
  11322. 6:43:58getting the current date information.
  11323. 6:44:00And this is exactly what we want. So
  11324. 6:44:02let's close it and let's go and call it
  11325. 6:44:04an age. So it's very simple. We are
  11326. 6:44:06counting how many years between the
  11327. 6:44:08birth dates and the current dates. So
  11328. 6:44:11let's go and execute it. So now we are
  11329. 6:44:12getting the ages. As you can see the
  11330. 6:44:14first person is 33, the second one is 52
  11331. 6:44:17and so on. And now you might getting
  11332. 6:44:19different values than I'm getting now.
  11333. 6:44:22And that's maybe you are doing the
  11334. 6:44:23course now in 2025 or 2026 and the
  11335. 6:44:26employees going to be older than now.
  11336. 6:44:28Now we are 2024 and I'm getting those
  11337. 6:44:30ages. So this is how we calculate the
  11338. 6:44:32age using the help of two functions. The
  11339. 6:44:35date diff and the get date. Okay. Okay,
  11340. 6:44:37so now we have another task for the day
  11341. 6:44:39diff and it says find the average
  11342. 6:44:41shipping duration in days for each
  11343. 6:44:44month. So here we have a lot of
  11344. 6:44:45informations. Let's do it step by step.
  11345. 6:44:47Let's first find out the shipping
  11346. 6:44:49durations in days. So let's go and
  11347. 6:44:51select few informations from our table.
  11348. 6:44:53So select order ID. We have the order
  11349. 6:44:57date, ship
  11350. 6:44:59date and I think that's it. So from
  11351. 6:45:03sales orders. So let's go ahead and
  11352. 6:45:06execute it. So now we have our 10
  11353. 6:45:08orders. We have the order date and the
  11354. 6:45:09shipping dates. Now we have to go and
  11355. 6:45:11create a new field called shipping
  11356. 6:45:13duration. So what is the shipping
  11357. 6:45:15duration? It is the number of days
  11358. 6:45:18between the order dates and the shipping
  11359. 6:45:20dates. So how many days it took from the
  11360. 6:45:23order placement until the day of the
  11361. 6:45:26shipping. So that means we have two
  11362. 6:45:27dates and we have to go and find the
  11363. 6:45:29differences between them. We're going to
  11364. 6:45:31go with the function date diff. So now
  11365. 6:45:33since we are saying in days we have to
  11366. 6:45:35go with the part day. So what is the
  11367. 6:45:38start date? The start date is the order
  11368. 6:45:40date. And what is the end date? It's
  11369. 6:45:43going to be the shipping dates like
  11370. 6:45:45this. So I'm going to call it day to
  11371. 6:45:48ship like this. Let's go and execute it.
  11372. 6:45:51So now by checking the result for
  11373. 6:45:52example for the order one it is ordered
  11374. 6:45:54at the 1st of January and it is shipped
  11375. 6:45:57on 5th of January. So between those two
  11376. 6:45:59dates we have around 4 days. So four is
  11377. 6:46:02the shipping duration and if you go to
  11378. 6:46:04the order number three the differences
  11379. 6:46:06between the order date and the shipping
  11380. 6:46:08date we have around 15 days. So with
  11381. 6:46:10that we have solved this part shipping
  11382. 6:46:12duration in days. But now the task says
  11383. 6:46:15we have to find the average duration for
  11384. 6:46:18each month. So that means we have to go
  11385. 6:46:20and select for example the month of
  11386. 6:46:21January and find the average duration.
  11387. 6:46:24So we have to go and do a simple
  11388. 6:46:25aggregation. We're going to go to the
  11389. 6:46:27date if at the start and say average.
  11390. 6:46:29And we're going to close it over here.
  11391. 6:46:31And let's go and rename it average
  11392. 6:46:34shipping. And now we have to aggregate
  11393. 6:46:36by the month. So we don't need the whole
  11394. 6:46:39order dates. We need the month of the
  11395. 6:46:42order date. So like this. We don't need
  11396. 6:46:44of course the order ID, but now we need
  11397. 6:46:47to group up the data using this
  11398. 6:46:49dimension, the month order dates. So
  11399. 6:46:52that's it. Let's go and execute it. So
  11400. 6:46:54now in the output you can see we have
  11401. 6:46:56three months and for each month we have
  11402. 6:46:58the average shipping durations in days.
  11403. 6:47:01So for the first month it is around 7
  11404. 6:47:04days for February is as well 7 days and
  11405. 6:47:07for March we have less duration 5 days.
  11406. 6:47:09So with that we have solved the task. As
  11407. 6:47:11you can see the date diff is very strong
  11408. 6:47:13function in order to do data analytics
  11409. 6:47:16using the dates information. All right.
  11410. 6:47:18Right. So now we have the following task
  11411. 6:47:19and it says find the number of days
  11412. 6:47:21between each order and the previous
  11413. 6:47:24order. So there's a lot of stuff going
  11414. 6:47:25on over here. Let's do it step by step.
  11415. 6:47:28Let's start by selecting the basic
  11416. 6:47:29stuff. So select order ID, order date
  11417. 6:47:34from the table sales orders. Let's go
  11418. 6:47:38and execute it. So we have our 10 orders
  11419. 6:47:40and we have the current order dates. So
  11420. 6:47:42now we have to find the differences
  11421. 6:47:43between two dates. order dates, the
  11422. 6:47:46current one and the previous order
  11423. 6:47:48dates. So in our data, we have the
  11424. 6:47:50current order dates, but we don't have
  11425. 6:47:52the previous order date for each order.
  11426. 6:47:54And in order to calculate the previous
  11427. 6:47:56one, do you remember about the window
  11428. 6:47:58functions? We can go and use the lag in
  11429. 6:48:00order to access a value from a previous
  11430. 6:48:03records. So let's go and do that. The
  11431. 6:48:06order date, I'm just going to call it
  11432. 6:48:07current order dates. And let's go and
  11433. 6:48:10find the previous order dates. So we're
  11434. 6:48:12going to go with the lag of the order
  11435. 6:48:15date because we are interested in the
  11436. 6:48:17value of the order date. Now over we
  11437. 6:48:20have to sort the data. So we're going to
  11438. 6:48:22sort it
  11439. 6:48:24by the order date as well. So this is
  11440. 6:48:27going to help us always to access the
  11441. 6:48:30previous value of the order date. So
  11442. 6:48:32we're going to call it
  11443. 6:48:33previous order date. Let's go and
  11444. 6:48:36execute it and let's check the result.
  11445. 6:48:38For the first order, we don't have
  11446. 6:48:39anything previously. So that's why we
  11447. 6:48:41are getting a null. For the second
  11448. 6:48:43record, the current order date is the
  11449. 6:48:455th of January and the previous one is
  11450. 6:48:48the 1st of January. And this value comes
  11451. 6:48:50from the previous record, the previous
  11452. 6:48:53order. Great. Amazing. So with that we
  11453. 6:48:55have now the two dates, the current date
  11454. 6:48:57and the previous one. And now we can go
  11455. 6:48:59very simply finding the number of days
  11456. 6:49:01between those two dates. And we can do
  11457. 6:49:04using the amazing function date diff. So
  11458. 6:49:07we are interested on the days that's why
  11459. 6:49:09it's going to be the day. So what is the
  11460. 6:49:12starting day? If you check those two
  11461. 6:49:13dates, you can see that the previous
  11462. 6:49:15order date is the starting date. So
  11463. 6:49:18we're going to take the whole thing, the
  11464. 6:49:20whole window function and put it over
  11465. 6:49:22here. So I just moved my picture. So
  11466. 6:49:24here is the previous order dates. And
  11467. 6:49:26now the end date, what's going to be?
  11468. 6:49:28It's going to be the current order date
  11469. 6:49:30which is our order date like this. So
  11470. 6:49:33again, we are finding the number of days
  11471. 6:49:35between the previous dates and the
  11472. 6:49:38current dates. So that's it. Let's close
  11473. 6:49:41it. So I'm just going to call it number
  11474. 6:49:43of
  11475. 6:49:44days. So let's go and execute it. Now of
  11476. 6:49:47course we have here null. So we will get
  11477. 6:49:49as well null in the output. And now you
  11478. 6:49:51can check over here how many days
  11479. 6:49:53between those two dates. We have exactly
  11480. 6:49:55four days. And as well for the next one
  11481. 6:49:57we have around 5 days, 10 days and so
  11482. 6:50:00on. So we have solved the task. We have
  11483. 6:50:02now the number of days between each
  11484. 6:50:04order and the previous order. So this
  11485. 6:50:06type of analyszis is very important in
  11486. 6:50:08the business. We call it time gap
  11487. 6:50:10analyzes and we have done it using the
  11488. 6:50:12help of the window function and as well
  11489. 6:50:14the date function date diff. So date div
  11490. 6:50:17function is amazing function to do data
  11491. 6:50:20analyzes. All right. So with those two
  11492. 6:50:21functions we have learned how to do
  11493. 6:50:23mathematical operations on date
  11494. 6:50:25informations or we can call it date
  11495. 6:50:27calculations. Now moving on to the
  11496. 6:50:28easiest and the last group, we have the
  11497. 6:50:31date validation. And here we have only
  11498. 6:50:33one function, the is
  11499. 6:50:37date. Okay. So what is is date? So the
  11500. 6:50:41is date is very simple. It's going to
  11501. 6:50:42check whether a value is a date. So it
  11502. 6:50:45going to return one if the string value
  11503. 6:50:47is a valid date or zero if it is not a
  11504. 6:50:51valid date. Okay. So let's check quickly
  11505. 6:50:53the syntax of the is date. It's very
  11506. 6:50:55simple. The keyword is date is the
  11507. 6:50:57function name and it accepts only one
  11508. 6:50:59value. So for example you can pass a
  11509. 6:51:00string like this and you can ask SQL is
  11510. 6:51:03it a date. So is date and the value and
  11511. 6:51:06of course for this example you will get
  11512. 6:51:07true or one. So as you can see we are
  11513. 6:51:09passing here a string value and we are
  11514. 6:51:11validating whether it is good enough to
  11515. 6:51:14be a date or as well you can go and
  11516. 6:51:15specify a number like here 2025. So is
  11517. 6:51:19this value a date and of course SQL
  11518. 6:51:21going to accept it and say yeah this is
  11519. 6:51:22a year so you will get as well a one. So
  11520. 6:51:24you can pass as well a number or
  11521. 6:51:26integer. So you are just checking the
  11522. 6:51:28values whether they are suitable enough
  11523. 6:51:30to be a date. So that's all about the
  11524. 6:51:32syntax of the is dates. Okay. So now
  11525. 6:51:33let's have few examples. For example,
  11526. 6:51:35let's go and select and we're going to
  11527. 6:51:36say is date and we will check a value.
  11528. 6:51:39So let's say this value is a string 1 2
  11529. 6:51:423. Let's go and call it date. Check one.
  11530. 6:51:46Let's go and execute it. Now in the
  11531. 6:51:48output it's going to say no, it is not a
  11532. 6:51:50date. And that's why we are getting the
  11533. 6:51:52value zero which is correct because 1 2
  11534. 6:51:543 is not a date. Let's pick another
  11535. 6:51:57value. The same thing is dates. And now
  11536. 6:51:59the value going to be the following. So
  11537. 6:52:022025 August 20. So let's call it date
  11538. 6:52:06check 2. And let's go and execute it.
  11539. 6:52:09Now in the output we will get one. That
  11540. 6:52:11means the value that we have provided is
  11541. 6:52:14a date. And that's why we have a one in
  11542. 6:52:16the output because ESKL is saying this
  11543. 6:52:18is a date. Now let's have another
  11544. 6:52:20example. We're going to take the whole
  11545. 6:52:22thing. So this is a check three and
  11546. 6:52:26remove this from here. But I would like
  11547. 6:52:27to go and change the format. So let's
  11548. 6:52:29say that we start with the day then
  11549. 6:52:31month and then the year. Let's go and
  11550. 6:52:34check. Now in the output you can see it
  11551. 6:52:36is zero because SQL does not understand
  11552. 6:52:38the formats. So we are not following the
  11553. 6:52:40standard format of the database and
  11554. 6:52:42scale and that's why going to say no
  11555. 6:52:44this is not a date. This is like a
  11556. 6:52:46string value. So this means only if the
  11557. 6:52:49value is following the status format SQL
  11558. 6:52:51going to understand this is a date. Now
  11559. 6:52:53let's go and check another thing for
  11560. 6:52:55example let's say is date and let's have
  11561. 6:52:57only the year. So 2025 and let's give it
  11562. 6:53:01the name date check for let's go and
  11563. 6:53:04execute it. Now in the output we will
  11564. 6:53:06get one. So that means is considering
  11565. 6:53:08this value as a date. So that means
  11566. 6:53:11Iskll is smart enough to understand okay
  11567. 6:53:12we have provided a year information and
  11568. 6:53:15is going to accept it and say okay maybe
  11569. 6:53:17this is the 1st of January of 2025. Now
  11570. 6:53:20let's go and do the same thing but for
  11571. 6:53:22the month let's see whether SQL going to
  11572. 6:53:24accept it. So check five and we have the
  11573. 6:53:27month of August. Let's go and check now
  11574. 6:53:30going to say no I don't understand this
  11575. 6:53:32value this is zero. So that mean this
  11576. 6:53:35value is provided is not a date. So by
  11577. 6:53:37checking those results as you can see
  11578. 6:53:39SQL understand only the standard formats
  11579. 6:53:41and it allow you as well to check
  11580. 6:53:43whether a year is a date. So this is how
  11581. 6:53:45the is date works in SQL. And now you
  11582. 6:53:47might ask well when I'm going to do this
  11583. 6:53:49when I'm going to check whether the
  11584. 6:53:51value is a date or not. Let me give you
  11585. 6:53:52this following scenario. Now imagine
  11586. 6:53:54that we have the following date. So we
  11587. 6:53:56have four values as a string. And now if
  11588. 6:53:58you check the data you can see that we
  11589. 6:54:00are following the standard format but
  11590. 6:54:02only one value has an issue. So we have
  11591. 6:54:05here data quality problem. So now what
  11592. 6:54:06we want to do, we want to go and cast
  11593. 6:54:08this string value to a date. We don't
  11594. 6:54:11want this to stay as a string value. We
  11595. 6:54:13would like to have it in the final
  11596. 6:54:15result as a date. So what we usually do
  11597. 6:54:17is that we go and have like subquery on
  11598. 6:54:20top of those values. So like this. So
  11599. 6:54:22now what we're going to do, we're going
  11600. 6:54:23to go and say we would like to go and
  11601. 6:54:25cast the order dates as date. We don't
  11602. 6:54:29want it as a string. And we're going to
  11603. 6:54:31call it order dates from these values.
  11604. 6:54:34So let me just make it like this and
  11605. 6:54:37let's go and execute it. Now SQL going
  11606. 6:54:39to give you an error and say well I
  11607. 6:54:41cannot convert everything to a date
  11608. 6:54:44because you have maybe corrupt data and
  11609. 6:54:46this is of course because of this row.
  11610. 6:54:48So SQL is not able to convert this
  11611. 6:54:51string to a date. But of course now the
  11612. 6:54:53example is very simple. We know that but
  11613. 6:54:55if you have a huge table it's going to
  11614. 6:54:56be really hard to identify those issues.
  11615. 6:54:59But now still I would like to go and
  11616. 6:55:01convert those value here. I don't want
  11617. 6:55:03to get an error. And now if there is
  11618. 6:55:04like some values like here that is
  11619. 6:55:07corrupt and so on this value could be
  11620. 6:55:09null. So how we can force SQL to convert
  11621. 6:55:12the data type from string to date and
  11622. 6:55:14not give us this error. And for this we
  11623. 6:55:17can go and use the help of the function
  11624. 6:55:19is date. Let me show you how I usually
  11625. 6:55:20do it. So let's go and say let's check
  11626. 6:55:23whether the order date is a date. So
  11627. 6:55:26let's have it like this. And now before
  11628. 6:55:28we go and execute, I'm going to make
  11629. 6:55:30this as a comment because if I execute
  11630. 6:55:32it like this, we will get an error. And
  11631. 6:55:34let's go and get the order date in our
  11632. 6:55:36select. So let's go and execute it. Now
  11633. 6:55:38as you can see in the output, we have
  11634. 6:55:40our string value. So they are not yet a
  11635. 6:55:42date. And we have the result of our
  11636. 6:55:44check. So as you can see the first row,
  11637. 6:55:46we are getting a zero. So it's saying
  11638. 6:55:48this value is not a date. But for all
  11639. 6:55:51other values, we are getting one. So
  11640. 6:55:53they are passing the check and they are
  11641. 6:55:54dates. So now what we're going to do
  11642. 6:55:56we're going to go and build a logic
  11643. 6:55:57where we're going to say go and cast the
  11644. 6:56:00value from string to date only if the
  11645. 6:56:03flag or the check is equal to one. So
  11646. 6:56:06that means we can go and use the help of
  11647. 6:56:08the case when statement. Let me show you
  11648. 6:56:10how we can do that. So let's do it step
  11649. 6:56:11by step. We're going to say case win.
  11650. 6:56:14Now we need the check. So is
  11651. 6:56:16dates the order date. So if the output
  11652. 6:56:20of this check is equal to one then you
  11653. 6:56:23are allowed to do the casting. So let's
  11654. 6:56:24go and get the cast as a result of this
  11655. 6:56:28condition and if it's not equal to one
  11656. 6:56:30then it could stay as a null. So let's
  11657. 6:56:32have it as a null if it didn't pass the
  11658. 6:56:34test. So end and we can call it new
  11659. 6:56:36order dates. So now let's go and execute
  11660. 6:56:39it. Now as you can see we are not
  11661. 6:56:41getting error from SQL. So now if you
  11662. 6:56:42check the output for the invalid dates
  11663. 6:56:45we are getting a null. So we are not
  11664. 6:56:47getting an SQL error. And now only if
  11665. 6:56:49these string values are a valid dates
  11666. 6:56:52it's allowed to be casted. So that you
  11667. 6:56:54can go and cast a string value to a date
  11668. 6:56:57even though that you have bad data
  11669. 6:56:58quality and this is very important step
  11670. 6:57:00in order to prepare the data before
  11671. 6:57:02doing analyszis and it help us as well
  11672. 6:57:04to find data quality issues. So for
  11673. 6:57:06example we can go over here and say you
  11674. 6:57:08know what let's go and search for all
  11675. 6:57:10issues. So we're going to go and take
  11676. 6:57:12the is dates. So let's go and get the
  11677. 6:57:14check and I'm going to say let me see
  11678. 6:57:16all string values that are invalid that
  11679. 6:57:19are failing the test. So let me execute
  11680. 6:57:21it. And with that we are getting this
  11681. 6:57:22record. And now imagine we have a lot of
  11682. 6:57:24data. So it's now it's really easy to
  11683. 6:57:27identify those issues by just using the
  11684. 6:57:29S dates. So this is as well amazing way
  11685. 6:57:31in order to identify data quality
  11686. 6:57:33issues. Now of course you might say you
  11687. 6:57:35know what I don't want to see here null.
  11688. 6:57:36Maybe let's get a dummy value. Well it's
  11689. 6:57:39very easy. We can go over here and say
  11690. 6:57:41else. So and we can go and get for
  11691. 6:57:43example very large value something like
  11692. 6:57:46this that is easy to identify. So now
  11693. 6:57:48with that instead of getting nulls
  11694. 6:57:50inside your data you can get such a
  11695. 6:57:52dummy value. So now you understand the
  11696. 6:57:54use case of the is dates and why this
  11697. 6:57:56function is amazing doing data
  11698. 6:58:02cleanup. All right. So with that we have
  11699. 6:58:04covered 13 different date and time
  11700. 6:58:07functions in SQL. So we have learned how
  11701. 6:58:09to extract the date parts using seven
  11702. 6:58:12different functions and we have learned
  11703. 6:58:13as well when to use which one. So they
  11704. 6:58:15are amazing in order to do data
  11705. 6:58:17aggregations and as well filtering. And
  11706. 6:58:19then we have learned how to change the
  11707. 6:58:21date format from one to another and as
  11708. 6:58:23well how to change the data types. And
  11709. 6:58:25then we learned how to do mathematical
  11710. 6:58:27operations on our dates. So how we can
  11711. 6:58:30add or subtract days, years, months from
  11712. 6:58:33a date or the amazing function the date
  11713. 6:58:36diff where we can go and find the
  11714. 6:58:38differences in days or years between two
  11715. 6:58:40days. And the last one we can go and
  11716. 6:58:42validate whether the values that we have
  11717. 6:58:44are dates or not. So as we learned date
  11718. 6:58:47functions are amazing functions in order
  11719. 6:58:49to do data analyzes and reporting. All
  11720. 6:58:51right my friends. So with that we have
  11721. 6:58:53learned a lot of very important SQL
  11722. 6:58:55functions and how to manipulate the date
  11723. 6:58:57and time values in your database using
  11724. 6:58:59SQL. Now in the next section we're going
  11725. 6:59:01to start talking about the null
  11726. 6:59:03functions in order to handle the nulls
  11727. 6:59:05inside your tables. So let's go.
  11728. 6:59:11So what are the nulls? Imagine you are
  11729. 6:59:13filling out a forum and there will be
  11730. 6:59:15usually like fields that are required
  11731. 6:59:17and another fields that are optional. So
  11732. 6:59:20what usually happens? We leave those
  11733. 6:59:21optional fields unanswered. So we don't
  11734. 6:59:24provide any values and we leave it
  11735. 6:59:26empty. And now once we are done filling
  11736. 6:59:28out the form and we click on register,
  11737. 6:59:30the data will be inserted into database
  11738. 6:59:33tables. So now what can happen? The
  11739. 6:59:35fields where you have provided answers
  11740. 6:59:36and values can be filled inside the
  11741. 6:59:38table while the unanswered fields will
  11742. 6:59:41have no value and this is what we call
  11743. 6:59:44in SQL a null. So in databases a null
  11744. 6:59:47means nothing unknown. It is not equal
  11745. 6:59:50to anything. So it is not equal to zero
  11746. 6:59:52or empty string or blank space. A null
  11747. 6:59:55is simply nothing. It tells us there is
  11748. 6:59:58no value and it is missing. It's like
  11749. 7:00:01saying I don't know what this value is.
  11750. 7:00:03So this is what a null means in
  11751. 7:00:08SQL. All right friends, so now we're
  11752. 7:00:11going to do a deep dive into special SQL
  11753. 7:00:13functions on how to handle the nulls
  11754. 7:00:16inside our data. Now in some scenarios
  11755. 7:00:18we have nulls inside our tables and we
  11756. 7:00:21would like to go and remove it and
  11757. 7:00:23replace it with a new value like for
  11758. 7:00:25example 40. And in order to do that in
  11759. 7:00:27scale we have two functions. The first
  11760. 7:00:29one called is a null and the second one
  11761. 7:00:32called coales. But now let's say that we
  11762. 7:00:35have another scenario where we have a
  11763. 7:00:37value inside our table like the 40 and
  11764. 7:00:39we want to go and make it as a null. So
  11765. 7:00:41now we are doing the exact opposite. We
  11766. 7:00:43are replacing the value with a null and
  11767. 7:00:46for that we have the SQL function null
  11768. 7:00:48if. So as you can see with those two
  11769. 7:00:50scenarios we are replacing stuff. So
  11770. 7:00:52from null to value or from value to
  11771. 7:00:55null. So they are really helpful in
  11772. 7:00:57order to manipulate the data inside our
  11773. 7:00:59databases. Now moving on to another
  11774. 7:01:01scenario where we don't want to
  11775. 7:01:02manipulate anything. We want just to
  11776. 7:01:04check. So we don't want to replace or
  11777. 7:01:06convert anything. We want just to check
  11778. 7:01:08in our database whether we have a null
  11779. 7:01:11value. And for that we have a function
  11780. 7:01:13called is a null. But between the is and
  11781. 7:01:15null there is like space. It is
  11782. 7:01:17different than the first function. So if
  11783. 7:01:19you apply is null you're going to get a
  11784. 7:01:21boolean true or false. For this scenario
  11785. 7:01:23you will get true. Or the second option
  11786. 7:01:25you can go and check whether the value
  11787. 7:01:27is not null. So we can use is not null
  11788. 7:01:29and for this example you can get false.
  11789. 7:01:31So in the output we are getting a
  11790. 7:01:33boolean true or false. So those keywords
  11791. 7:01:35are really amazing in order to check
  11792. 7:01:38whether we have nulls inside our data.
  11793. 7:01:40So this is the big picture of all
  11794. 7:01:41functions that we have in SQL in order
  11795. 7:01:43to handle the nulls. So now let's go and
  11796. 7:01:45understand those functions one by one.
  11797. 7:01:52So let's start with the first function
  11798. 7:01:53is null. Is null going to go and replace
  11799. 7:01:56a null with a specific value. Now the
  11800. 7:01:59syntax of the isnull is very simple.
  11801. 7:02:00We're going to use the keyword is a null
  11802. 7:02:03and it accepts two arguments. First the
  11803. 7:02:05value and then the second the
  11804. 7:02:07replacement value. So let's have an
  11805. 7:02:09example. We can go and use the is null
  11806. 7:02:11for the column called shipping address.
  11807. 7:02:13So we are checking the nulls inside it.
  11808. 7:02:15And if SQL encounters any null, it going
  11809. 7:02:18to go and replace it with the value
  11810. 7:02:20unknown. So this going to be like a
  11811. 7:02:22default value for the nulls. So the
  11812. 7:02:24first value is a column and the second
  11813. 7:02:26value is like static. Always going to be
  11814. 7:02:29the unknown if we find any nulls. Now of
  11815. 7:02:32course in other scenarios we don't want
  11816. 7:02:33to have it always like the unknown. We
  11817. 7:02:36would like to use another column to help
  11818. 7:02:38the first one. So let's have this
  11819. 7:02:40scenario. So now with this syntax we are
  11820. 7:02:42checking the values of the shipping
  11821. 7:02:44address and if we find any nulls it's
  11822. 7:02:47going to get the replacement from the
  11823. 7:02:49billing address. So here in this example
  11824. 7:02:51we have two columns. We don't have here
  11825. 7:02:53any static value. We will get the values
  11826. 7:02:55of the billing address only if the
  11827. 7:02:58shipping address is null. So we are
  11828. 7:03:00replacing the nulls using the help of
  11829. 7:03:02other column. And in the first scenario
  11830. 7:03:04we are replacing the nulls with a static
  11831. 7:03:07value the default value. So let's have a
  11832. 7:03:09very simple example in order to learn
  11833. 7:03:11how this works. So what we are doing we
  11834. 7:03:13are checking whether the value is null.
  11835. 7:03:15If it's yes then we're going to go and
  11836. 7:03:17get the value from the replacement and
  11837. 7:03:20if the value is not null then show the
  11838. 7:03:22value itself. So we have the following
  11839. 7:03:24example. We are going to check the
  11840. 7:03:25values from the shipping address and if
  11841. 7:03:28there is nulls then go replace it with
  11842. 7:03:30the default value na. So let's see how
  11843. 7:03:32going to go and execute this very simple
  11844. 7:03:34example. We have two orders. The first
  11845. 7:03:36order we are checking the submit address
  11846. 7:03:39is the value of this address is null.
  11847. 7:03:42Well, no. We have a value a. So that's
  11848. 7:03:44why it's scale going to go and return
  11849. 7:03:46the same value. So in the outputs we
  11850. 7:03:49will get a. So if it's not null, it's
  11851. 7:03:52going to return the same value. So now
  11852. 7:03:53it's going to move to the second order
  11853. 7:03:55and here we have the shipment address as
  11854. 7:03:57a null. So what going to happen here? If
  11855. 7:03:59the value is null, then we going to get
  11856. 7:04:01the replacement value. So what is the
  11857. 7:04:04replacement value is the NA. So that's
  11858. 7:04:07why in the output we will not get a null
  11859. 7:04:09we will get the N A. So if you check the
  11860. 7:04:12result what happens? We're going to get
  11861. 7:04:14the addresses from the shipping address
  11862. 7:04:16but only if we have a null we will get
  11863. 7:04:18like default value. It's very important
  11864. 7:04:20to understand if you are using the
  11865. 7:04:22default value in the output you will
  11866. 7:04:24never get a null. All right. So let's
  11867. 7:04:26have another example for the second
  11868. 7:04:27scenario where we are not using a
  11869. 7:04:29default value we are using a column. So
  11870. 7:04:32we have a supportive column that's going
  11871. 7:04:33to be checked. So in this scenario we
  11872. 7:04:35are saying is null shipping address and
  11873. 7:04:37billing address. So we have two columns
  11874. 7:04:39and of course the logic going to be the
  11875. 7:04:41same right. So we are checking only
  11876. 7:04:43once. Let's see how SQL going to execute
  11877. 7:04:45this example. We have this time three
  11878. 7:04:47orders and we have addresses from the
  11879. 7:04:49shipments and as well from billing. So
  11880. 7:04:51now SQL is always focusing on the
  11881. 7:04:53shipping address since it is the first
  11882. 7:04:55column. So we are not checking the
  11883. 7:04:57billing address at all. So it start with
  11884. 7:04:59the first order. Is it null? Well, no,
  11885. 7:05:01we have the value A. So, we will get it
  11886. 7:05:04as well in the output and SQL will not
  11887. 7:05:07get anything from the billing address.
  11888. 7:05:09So, we will get a. So, that's it for the
  11889. 7:05:11first order. Now, it's still going to go
  11890. 7:05:13to the second order. And this time,
  11891. 7:05:14we're going to have a null. So, now in
  11892. 7:05:16the rule, we are saying if the shipping
  11893. 7:05:18address is a null, go get the value from
  11894. 7:05:21the billing address. So, this time we're
  11895. 7:05:23going to go to the replacement, right?
  11896. 7:05:25So we will get the value C in the output
  11897. 7:05:29because the shipping address is the
  11898. 7:05:31null. Now let's move to the third row.
  11899. 7:05:32As you can see here we have again null.
  11900. 7:05:34So SQL going to go and get the value
  11901. 7:05:37from the billing address. But here in
  11902. 7:05:39this scenario the billing address is as
  11903. 7:05:41well null. That's why we will get the
  11904. 7:05:44value null in the output. So as you can
  11905. 7:05:46see having the replacements values from
  11906. 7:05:48a column there is no guarantee that
  11907. 7:05:51there will be always a value like here
  11908. 7:05:53in the third order it is a null that's
  11909. 7:05:56why we will get null as well in the
  11910. 7:05:58output. So if you think you are using is
  11911. 7:06:00null to replace all the nulls by having
  11912. 7:06:03two columns you might end up as well
  11913. 7:06:05having a null in the output if the
  11914. 7:06:07replacement having nulls. So if you want
  11915. 7:06:09to make sure you don't get any nulls in
  11916. 7:06:12the output you have to go and use a
  11917. 7:06:14static value. So this is how SQL execute
  11918. 7:06:17the
  11919. 7:06:21isnull. All right. So what is coales?
  11920. 7:06:24Coal is going to go and return the first
  11921. 7:06:26null value from a list. All right. So
  11922. 7:06:29now the syntax of the coales is way
  11923. 7:06:31better than the is null. Here it accepts
  11924. 7:06:34like a list of many values. So here for
  11925. 7:06:36example we have value 1 2 3 you can add
  11926. 7:06:39four five as much as you want. So we are
  11927. 7:06:42creating here a list of values to be
  11928. 7:06:44checked. So for example, we still can
  11929. 7:06:46use it like the isnull where we have the
  11930. 7:06:48shipping address where we replace the
  11931. 7:06:50null with a static value the unknown or
  11932. 7:06:53as we learned we can go and use two
  11933. 7:06:54columns shipping address and the billing
  11934. 7:06:56address. So so far it's like the same
  11935. 7:06:58use cases as the is null but now of
  11936. 7:07:00course the kalis is not only limited to
  11937. 7:07:02two we can go and use three. So we are
  11938. 7:07:05saying go check the shipping address if
  11939. 7:07:07it's null then go check the billing
  11940. 7:07:09address. If it is as well null then use
  11941. 7:07:12at the end the default value the static
  11942. 7:07:14one the unknown. So as you can see we
  11943. 7:07:16can use more than two values with the
  11944. 7:07:18coalis. Okay. So now let's understand
  11945. 7:07:19the cowless and how this works. Now the
  11946. 7:07:22workflow is something similar to the
  11947. 7:07:24isnull. So in this example we have two
  11948. 7:07:26columns shipping address and the billing
  11949. 7:07:28address. It's going to consider it as a
  11950. 7:07:30list and it's going to start checking
  11951. 7:07:32from left to right. So it's going to
  11952. 7:07:34check the first value from the shipping
  11953. 7:07:35address whether it's null. If no, it's
  11954. 7:07:38not null then we're going to go and get
  11955. 7:07:40the value one. So we will get the value
  11956. 7:07:42from the shipping address. And if yes,
  11957. 7:07:44it is null then it's going to go and get
  11958. 7:07:47the value two. So we're going to get the
  11959. 7:07:49value from the shipping address. Now we
  11960. 7:07:51have the similar data. We have three
  11961. 7:07:52orders. Let's see how going to execute
  11962. 7:07:54it. So it's going to start with the
  11963. 7:07:55first row and it's going to focus on the
  11964. 7:07:57shipping address. So here the value is
  11965. 7:07:59not null. So we have it as an A. So
  11966. 7:08:02that's why we will get the value one. So
  11967. 7:08:05we will get the value from the shipping
  11968. 7:08:07address and nothing else going to be
  11969. 7:08:09checked. Now moving on to the second
  11970. 7:08:11row. This time the shipping address is
  11971. 7:08:13null. So it's going to go and get the
  11972. 7:08:16value from the second column and it's
  11973. 7:08:18going to be the C. Right? So in the
  11974. 7:08:21output we will get C. Now to the last
  11975. 7:08:23example, we have it as a null and it's
  11976. 7:08:25going to go and get the value from the
  11977. 7:08:27second column and this time we're going
  11978. 7:08:29to get as well a null like the is null
  11979. 7:08:32function. So at the results we are
  11980. 7:08:34getting exactly the same result as
  11981. 7:08:36isnull. So for this scenario it doesn't
  11982. 7:08:38matter whether you use isnull or
  11983. 7:08:40kowalis. So now of course we are still
  11984. 7:08:41not happy with that because I don't want
  11985. 7:08:43to see any nulls in the output and I
  11986. 7:08:46will still need to use the billing
  11987. 7:08:47address instead of any static values. So
  11988. 7:08:50I would like to have everything the
  11989. 7:08:51values from the billing address and as
  11990. 7:08:53well I would like to have at the end a
  11991. 7:08:55default value so that I don't have any
  11992. 7:08:58nulls in the output. So how we going to
  11993. 7:08:59solve it? So now we can use the power of
  11994. 7:09:01the account list where we can include
  11995. 7:09:03multiple values in one function. So what
  11996. 7:09:06we're going to do we're going to have
  11997. 7:09:07the shipping address first then the
  11998. 7:09:09billing address and at the end we're
  11999. 7:09:11going to have the default value. So we
  12000. 7:09:13have now a list of three values and of
  12001. 7:09:15course our workflow going to be a little
  12002. 7:09:17bit bigger. So again here it's going to
  12003. 7:09:19start from the left to the right. So
  12004. 7:09:21first it's going to go and check the
  12005. 7:09:22value one. If it is null then it's going
  12006. 7:09:24to go as well checking the value two.
  12007. 7:09:27And if the value two is as well null, we
  12008. 7:09:29will get the last value. It's going to
  12009. 7:09:31be the value three. So now let's run the
  12010. 7:09:33example again using the new kalis. So
  12011. 7:09:35the first thing we're going to go and
  12012. 7:09:37check the first value which is the
  12013. 7:09:38shipping address for the record number
  12014. 7:09:40one. So now as you can see the value is
  12015. 7:09:42not null. So we have here an a. So what
  12016. 7:09:45going to happen? We're going to get the
  12017. 7:09:46value a as well in the output. So that
  12018. 7:09:49means this one going to be activated and
  12019. 7:09:51we will not check anything else. So that
  12020. 7:09:54means in the output it's going to be
  12021. 7:09:56like this. and the first value is
  12022. 7:09:58returned and everything else will be
  12023. 7:10:00ignored. So, SQL will not check
  12024. 7:10:02anything. So, as you can see, we are
  12025. 7:10:04returning the first null value. So, now
  12026. 7:10:08let's move to the second order. Now,
  12027. 7:10:09we're going to check again the first
  12028. 7:10:10value. Is it null? Well, yes. As you can
  12029. 7:10:13see, we have here a null. So, that means
  12030. 7:10:16we're going to go and activate this path
  12031. 7:10:18over here on the right side. So, now SQL
  12032. 7:10:20will not go blindly putting anything
  12033. 7:10:22from the billing address in the results.
  12034. 7:10:24First SQL has to check it. So SQL going
  12035. 7:10:27to check it whether it's null or not.
  12036. 7:10:29SQL going to go and return it as well in
  12037. 7:10:31the output. And we have activated this
  12038. 7:10:34path. So SQL is returning the value two
  12039. 7:10:37which is the value from the billing
  12040. 7:10:39address. So now let's move to the third
  12041. 7:10:40order. SQL first going to go and check
  12042. 7:10:43the shipping address. Is it null? Well
  12043. 7:10:46yes it is null. So that's why SQL going
  12044. 7:10:48to go and start checking the second
  12045. 7:10:51value. So this time SQL will not return
  12046. 7:10:54the billing address value since it's
  12047. 7:10:56null. It's going to go and return the
  12048. 7:10:58third value. And what is the third
  12049. 7:11:00value? It is our static value the NA. So
  12050. 7:11:03in the output we're going to get the NA
  12051. 7:11:07our default value. So with that as you
  12052. 7:11:09can see in the output we will not get
  12053. 7:11:11any nulls. We are using the default
  12054. 7:11:13value and as well multiple columns. So
  12055. 7:11:15if you check the output, it's always the
  12056. 7:11:17first priority to check the values from
  12057. 7:11:20the first column, the shipping address.
  12058. 7:11:22If it's null, then the second priority
  12059. 7:11:24going to be the billing address. If it's
  12060. 7:11:26null, then the last priority, it's going
  12061. 7:11:29to be the default value. So as you can
  12062. 7:11:30see, SQL is checking the values from
  12063. 7:11:32left to right and it stops immediately
  12064. 7:11:35once it encounters the first not null
  12065. 7:11:38value and return it in the results. So
  12066. 7:11:40this is how the cow works.
  12067. 7:11:46All right. So now let's have a quick
  12068. 7:11:47summary about the differences between
  12069. 7:11:49the kowalis and isnull. So as we learned
  12070. 7:11:51the isnull is limited only to two values
  12071. 7:11:54where the kowalis is amazing where you
  12072. 7:11:56can have a list of multiple values which
  12073. 7:11:59is a great advantage compared to the
  12074. 7:12:01isnull. Now if you are talking about the
  12075. 7:12:02performance the isnull is faster than
  12076. 7:12:05the kawalis. So if you want to optimize
  12077. 7:12:07the performance of your query then go
  12078. 7:12:09with the isnull. Now there is another
  12079. 7:12:11problem with the isnull is that we have
  12080. 7:12:14different keywords for different
  12081. 7:12:15databases. So for Microsoft SQL server
  12082. 7:12:18we use the isnull as we learned but in
  12083. 7:12:21Oracle they have different
  12084. 7:12:22implementations they use the NVL and
  12085. 7:12:24other database like MySQL you have if
  12086. 7:12:28null and all those three functions are
  12087. 7:12:29doing the same but we have different
  12088. 7:12:31implementations for different databases
  12089. 7:12:33but in the other hand the cowis it is
  12090. 7:12:35available in all different databases. So
  12091. 7:12:37here we have like an agreement or
  12092. 7:12:39standards between the databases of using
  12093. 7:12:41the kowalis. So here again this is a
  12094. 7:12:43great advantage for the kowalis because
  12095. 7:12:45if you are writing like scripts and
  12096. 7:12:47someday you want to migrate from one
  12097. 7:12:49database to another. If you are using
  12098. 7:12:50the kowalis you don't have to change
  12099. 7:12:52anything but if you are using the isnull
  12100. 7:12:54then you have to go and adjust your
  12101. 7:12:56queries and scripts with the correct
  12102. 7:12:58functions. That's why I tend always to
  12103. 7:13:01use the kalis and avoid using the
  12104. 7:13:03isnull. Only if it's really necessary
  12105. 7:13:06that I have really bad performance, I go
  12106. 7:13:08and try the isnull. But I usually stick
  12107. 7:13:10with the kowalis. So that is my advice
  12108. 7:13:13for you. Go with the kowalis and stick
  12109. 7:13:15with the standard.
  12110. 7:13:19Now the use cases of the kowalis and the
  12111. 7:13:21isnull are very similar and we mainly
  12112. 7:13:24use them in order to handle the null
  12113. 7:13:27before doing any SQL task. For example,
  12114. 7:13:30we can use them in order to handle the
  12115. 7:13:32null before doing data aggregations. So
  12116. 7:13:35let's understand what this means.
  12117. 7:13:36Imagine that we have three sales. We
  12118. 7:13:38have 15, 25, and a null. Now if you go
  12119. 7:13:41and use an aggregate functions like the
  12120. 7:13:43average, what's going to happen? SQL
  12121. 7:13:45going to calculate it like this. 15 + 25
  12122. 7:13:48divided by two and the average is going
  12123. 7:13:50to be 20. So as you can see here SQL is
  12124. 7:13:53including only the two values 15 and 25
  12125. 7:13:56and ignores totally the null value. So
  12126. 7:13:59in the calculations the null will not be
  12127. 7:14:01included because if SQL does that the
  12128. 7:14:04output going to be as well null. So the
  12129. 7:14:06nulls are totally ignored. Now the same
  12130. 7:14:08thing can happen with the other
  12131. 7:14:09aggregate functions like the sum count
  12132. 7:14:11if you are counting the sales min and
  12133. 7:14:13max. There is only one exception about
  12134. 7:14:16the aggregate function count. If you are
  12135. 7:14:17using it with the star, SQL here is
  12136. 7:14:20considering not the values. SQL going to
  12137. 7:14:22consider the rows. That's why SQL going
  12138. 7:14:24to go and include all those rows and
  12139. 7:14:26find the output going to be three. Now
  12140. 7:14:28in some scenarios, if your business
  12141. 7:14:30understand the null as zero, then you're
  12142. 7:14:32going to have a problem with the result
  12143. 7:14:34of your analyzes if you don't handle the
  12144. 7:14:36nulls. So what we have to do? We have to
  12145. 7:14:38handle the null before doing the
  12146. 7:14:39aggregations. So we have to go and
  12147. 7:14:41replace a null with zero using either
  12148. 7:14:43the isnar or the kowalis. So once you do
  12149. 7:14:46that the calculation going to be changed
  12150. 7:14:48for the average. So it's going to be 15
  12151. 7:14:50+ 25 + 0 divided by 3 and the output
  12152. 7:14:54this time going to be 13.3. So with that
  12153. 7:14:57you're going to get more accurate
  12154. 7:14:58results for the business if they
  12155. 7:15:00understand nulls as zero. All right. So
  12156. 7:15:02now we have the following example. It
  12157. 7:15:03says find the average scores for the
  12158. 7:15:05customers. So let's go and solve it. So
  12159. 7:15:07we're going to go and select the
  12160. 7:15:09customer ID, the score from table
  12161. 7:15:14customers. So let's go and execute it.
  12162. 7:15:16So as you can see, we have four
  12163. 7:15:18customers with score and the last one
  12164. 7:15:19doesn't have any score. So we have it as
  12165. 7:15:21a null. Let's go and calculate the
  12166. 7:15:23average for the score and I would like
  12167. 7:15:27to have the window function in order to
  12168. 7:15:29see the details as well. So this is
  12169. 7:15:31average scores. So let's go and execute
  12170. 7:15:35it. Now of course what is going on here?
  12171. 7:15:37The four values going to be added to
  12172. 7:15:38each others and divided by four and the
  12173. 7:15:40null is totally ignored. Now of course
  12174. 7:15:42the question is what the business
  12175. 7:15:44understand with the null. If it is zero
  12176. 7:15:47then we have inaccurate results. So
  12177. 7:15:50let's go and fix it. Now this time we're
  12178. 7:15:52going to say okay we're going to have
  12179. 7:15:53the average but instead of score we're
  12180. 7:15:55going to handle the nulls first. So we
  12181. 7:15:57have to replace any nulls with zero. We
  12182. 7:16:00can go and use the kowalis or the
  12183. 7:16:02isnull. So I will go with the cabalis
  12184. 7:16:04like this and score if you find any null
  12185. 7:16:09make it zero. So that's it and as well I
  12186. 7:16:12will go with the window function. So
  12187. 7:16:14average scores let's call it two. Now
  12188. 7:16:17let's go and execute it. Now as you can
  12189. 7:16:19see in the output we got 500 and this is
  12190. 7:16:22different than the previous average and
  12191. 7:16:24that's because we have replaced the null
  12192. 7:16:26with zero. Let's just go and display it
  12193. 7:16:29in order to understand it. So I will
  12194. 7:16:31copy it and put it here. So let's call
  12195. 7:16:33it score two and execute it. So now SQL
  12196. 7:16:36is going to summarize all those values
  12197. 7:16:38and divided by five and that's why we
  12198. 7:16:41are getting the 500. So if our business
  12199. 7:16:44understand the null as a zero this
  12200. 7:16:46average going to be more accurate after
  12201. 7:16:49we handle the null. As you can see in
  12202. 7:16:50some scenarios we have to handle the
  12203. 7:16:52nulls before doing any data
  12204. 7:16:54aggregations.
  12205. 7:16:59All right, moving on to the next use
  12206. 7:17:00case for the kowalis and isnull. We can
  12207. 7:17:02use them in order to handle the nulls
  12208. 7:17:05before doing any mathematical
  12209. 7:17:07operations. So let's understand what
  12210. 7:17:09this means using the plus operator. So
  12211. 7:17:11if you do plus operator between two
  12212. 7:17:12numbers like 1 + 5, you are summarizing
  12213. 7:17:15the values and you will get six. And if
  12214. 7:17:17you do the plus operator between string
  12215. 7:17:19values like a + b. So now what we are
  12216. 7:17:22doing, we are doing data concatenations
  12217. 7:17:25and the output going to be a b. So now
  12218. 7:17:27if you go and replace the one with a
  12219. 7:17:29value like zero. So 0 + 5 we will get
  12220. 7:17:32five. Nothing fancy about that. And for
  12221. 7:17:34the strings if you go and replace a
  12222. 7:17:36value with an empty string. So there is
  12223. 7:17:39zero characters between the two quotes
  12224. 7:17:41plus the B. So in the output you will
  12225. 7:17:44get only B. So it's fine and nothing is
  12226. 7:17:46critical. But now we come to the
  12227. 7:17:48problem. If you use a null if you
  12228. 7:17:49replace the one with null in the output
  12229. 7:17:52you will get a null. because you are
  12230. 7:17:54saying okay five plus something that I
  12231. 7:17:56don't know so SQL says okay you are
  12232. 7:17:58summarizing now a value with a no value
  12233. 7:18:01it is unknown so I don't as well know
  12234. 7:18:04what going to be the answer that's why
  12235. 7:18:06going to say it's going to be null just
  12236. 7:18:07don't know what is the answer and the
  12237. 7:18:09same thing can happen with anything else
  12238. 7:18:11like the string so if you're saying null
  12239. 7:18:13plus b and here going to say the same
  12240. 7:18:15thing the null is unknown and the answer
  12241. 7:18:18going to be as well unknown so my
  12242. 7:18:20friends this is very critical in the
  12243. 7:18:22analyzes and working with data. So this
  12244. 7:18:24means we have to handle the nulls before
  12245. 7:18:26doing any mathematical operations. And
  12246. 7:18:28this is not only for the plus operator,
  12247. 7:18:31it's as well for the other operators
  12248. 7:18:32like minus and so on. All right. So now
  12249. 7:18:34let's have the following task. And it
  12250. 7:18:36says display the full name of the
  12251. 7:18:38customers in a single field by merging
  12252. 7:18:41their first and last names and add 10
  12253. 7:18:43bonus points for each customer's score.
  12254. 7:18:46So let's go and solve it. We're going to
  12255. 7:18:48select first the basic informations.
  12256. 7:18:50Let's get the customer ID. What do we
  12257. 7:18:52need? the first name, the last name and
  12258. 7:18:55we need the scores. So that's it from
  12259. 7:18:58sales customers. Let's go and execute
  12260. 7:19:01it. Now the first task is that we have
  12261. 7:19:03to generate a new field called full name
  12262. 7:19:06where we have to go and merge or
  12263. 7:19:08concatenate their first and last names.
  12264. 7:19:10So let's go and do that. We need the
  12265. 7:19:12first name plus and then let's have a
  12266. 7:19:15space between the first and last name
  12267. 7:19:19and then plus let's have the last name
  12268. 7:19:22as
  12269. 7:19:23full name. So let's go and execute it.
  12270. 7:19:27Now if you check the result for the
  12271. 7:19:29first customer it is working. So we have
  12272. 7:19:31Joseph Goldenberg. The same thing for
  12273. 7:19:33the second customer. But for the third
  12274. 7:19:35customer we have here a problem.
  12275. 7:19:37Customer doesn't have any last name but
  12276. 7:19:40she has a first name. So we have here a
  12277. 7:19:42Mary. So the full name here is
  12278. 7:19:44completely null which is not correct.
  12279. 7:19:46For this example we have at least to
  12280. 7:19:48show the first name Mary even though
  12281. 7:19:50that the last name is missing. So the
  12282. 7:19:52result is not really accurate and that's
  12283. 7:19:54because we are doing the plus operator
  12284. 7:19:56between a null and marry. So that means
  12285. 7:19:59we have to go and handle the nulls
  12286. 7:20:01before doing any plus operator. So again
  12287. 7:20:04here we can go with the cowless or the
  12288. 7:20:06isnull. So let's go and create a new
  12289. 7:20:08field using the cowless. So it's going
  12290. 7:20:11to be the last name and now we have to
  12291. 7:20:14define a new value. If it's null so we
  12292. 7:20:17could have like something unknown or we
  12293. 7:20:19could have like an empty string and we
  12294. 7:20:21can do that using two quotes and between
  12295. 7:20:23them there is nothing. So we are using
  12296. 7:20:25an empty string. So let's go and check
  12297. 7:20:28the results. Last name two. So let's go
  12298. 7:20:33and execute it. Now we can see that the
  12299. 7:20:35last name over here for marry it has an
  12300. 7:20:39empty string and it is not anymore a
  12301. 7:20:41null. So now SQL knows okay this is a
  12302. 7:20:44string and there is no characters inside
  12303. 7:20:46it. So with that SQL knows more
  12304. 7:20:48informations and we can go and now
  12305. 7:20:50concatenate those informations. So let's
  12306. 7:20:52go and do that. We're going to take the
  12307. 7:20:54whole thing and replace the last name
  12308. 7:20:57with the kowalis. So let me just remove
  12309. 7:21:00this last name over here and execute it.
  12310. 7:21:03So now as you can see things looks
  12311. 7:21:04better. Now we have in the full name for
  12312. 7:21:06mari only the first name. And of course
  12313. 7:21:09if you don't like it like this you would
  12314. 7:21:10like to have another default value. You
  12315. 7:21:12can go over here and say something like
  12316. 7:21:14in a not available. So let's go and
  12317. 7:21:16execute it. And with that you can see
  12318. 7:21:18immediately uh there is here a missing
  12319. 7:21:20last name. But it doesn't really look
  12320. 7:21:22good. So I will just remove it and go
  12321. 7:21:24with the empty string. We're going to go
  12322. 7:21:26and execute it. So with that we have
  12323. 7:21:28solved the first part of the task where
  12324. 7:21:30we have the full names and we are not
  12325. 7:21:32missing any informations from the first
  12326. 7:21:34name and the last name. Now let's go to
  12327. 7:21:35the second part of the task where we
  12328. 7:21:37have to add 10 bonus points for each
  12329. 7:21:39customer score. So we have to go and add
  12330. 7:21:42a 10 for each score. So let's go and do
  12331. 7:21:44it. I'm going to put it at the end. So
  12332. 7:21:46score + 10 and let's give it the name
  12333. 7:21:51score with bonus. So that's it. Let's go
  12334. 7:21:54and execute it. So now in the output you
  12335. 7:21:56can see it's very easy. We have added a
  12336. 7:21:5810 for each score. So we have increased
  12337. 7:22:01the score points for each customer. But
  12338. 7:22:03now for the last customer Anna you can
  12339. 7:22:05see over here she doesn't have a value
  12340. 7:22:07in the scores and that's why didn't go
  12341. 7:22:10and added 10. So we will get as well a
  12342. 7:22:12null. And of course this might not be
  12343. 7:22:14fair that the last customer is not
  12344. 7:22:16getting any point even though that we
  12345. 7:22:17have increased for all others. So that
  12346. 7:22:19means we have to go and handle the null
  12347. 7:22:21by replacing the null to zero. And only
  12348. 7:22:24after that we're going to add a plus to
  12349. 7:22:26it. So let's go and do that. I'm going
  12350. 7:22:28to add a
  12351. 7:22:30kalis if it is null then go and make it
  12352. 7:22:34zero. And afterward go and add a 10
  12353. 7:22:36points. So let's go and execute it. So
  12354. 7:22:39now as you can see at the results
  12355. 7:22:40everything now is fair where we have a
  12356. 7:22:4310 bonus points for each customers even
  12357. 7:22:45if the customer doesn't have any values
  12358. 7:22:48in the scores like here Anna she has
  12359. 7:22:50like null but still she is getting a 10
  12360. 7:22:52points. So here again as you can see if
  12361. 7:22:54you don't handle the nulls correctly
  12362. 7:22:56before doing the mathematical operations
  12363. 7:22:59you might get unexpected results. So be
  12364. 7:23:01careful with the nulls and handle them
  12365. 7:23:03correctly before adding anything.
  12366. 7:23:09Okay, moving on to the next use case for
  12367. 7:23:11the kowalis and is null. We can use them
  12368. 7:23:13in order to handle the null before doing
  12369. 7:23:16joins. This is little bit advanced use
  12370. 7:23:18case but it's very important to
  12371. 7:23:20understand it. So let's understand why
  12372. 7:23:21this is important. Let's have for
  12373. 7:23:23example two tables table A and table B.
  12374. 7:23:26And in some scenarios we have to go and
  12375. 7:23:28combine those two tables using the
  12376. 7:23:29joins. And now in order to join two
  12377. 7:23:31tables, we have to go and specify the
  12378. 7:23:34keys between the table A and table B in
  12379. 7:23:36order to join on it. So in this example,
  12380. 7:23:38we have two keys in order to join the
  12381. 7:23:40tables. Now here comes the special case.
  12382. 7:23:43If those keys don't have any nulls
  12383. 7:23:45inside it and all the data are filled,
  12384. 7:23:47then your join going to work perfectly
  12385. 7:23:49and you will get the expected results.
  12386. 7:23:51And now you might have a special case
  12387. 7:23:53where there are nulls inside the keys.
  12388. 7:23:55So there are missing values and this is
  12389. 7:23:57a big problem because in the output you
  12390. 7:23:59will get unexpected results and some
  12391. 7:24:01records will be totally missing. So in
  12392. 7:24:04this scenario we have to handle the
  12393. 7:24:05nulls inside the keys before doing the
  12394. 7:24:08joins. Let's have a very simple example
  12395. 7:24:10in order to understand this behavior.
  12396. 7:24:12All right. So now let's have this very
  12397. 7:24:13simple example where we have two tables
  12398. 7:24:15and we want to combine them. So in the
  12399. 7:24:16first table we have a year type orders
  12400. 7:24:19and in the second table we have as well
  12401. 7:24:21year type and we have sales. So now we
  12402. 7:24:23would like to go and combine those two
  12403. 7:24:25tables in order to have all informations
  12404. 7:24:27in one result. Now we can go of course
  12405. 7:24:29and use the inner join between the table
  12406. 7:24:31one and table two and the keys for the
  12407. 7:24:33joins here. As you can see we have the
  12408. 7:24:36year in both of the tables and as well
  12409. 7:24:38the type. So we're going to go and use
  12410. 7:24:40both of those columns as a key for the
  12411. 7:24:42join. So let's do it step by step how
  12412. 7:24:45going to execute this. So we need the
  12413. 7:24:46year type and the results. So it's going
  12414. 7:24:49to go and take those two columns to the
  12415. 7:24:51results and we need the orders and
  12416. 7:24:53sales. So it's going to take as well the
  12417. 7:24:56orders and the sales from the second
  12418. 7:24:58table. So now let's start doing it row
  12419. 7:25:00by row. So the first key going to be
  12420. 7:25:02those two columns. So we have 2024 and
  12421. 7:25:06the type A. So now it's going to start
  12422. 7:25:08searching for those two informations in
  12423. 7:25:10the second table. And as you can see we
  12424. 7:25:12have here a match, right? So the first
  12425. 7:25:15row is as well matching since it's inner
  12426. 7:25:17join it going to present in the output
  12427. 7:25:19only the matching rows from left and
  12428. 7:25:22right. So in the outputs we're going to
  12429. 7:25:24get the whole row from the table one and
  12430. 7:25:27we will get the sales from the table
  12431. 7:25:29two. All right. So that's all for the
  12432. 7:25:31first row. Now let's move to the second
  12433. 7:25:34row over here. So what are the values of
  12434. 7:25:36the keys? We have 20 24 and null. So now
  12435. 7:25:40if you check the matches on the right
  12436. 7:25:42side you can see we have a match here
  12437. 7:25:44right it is logical so it's as well 20
  12438. 7:25:4724 and null so everything is matching
  12439. 7:25:50and we should get it in the result right
  12440. 7:25:52SQL cannot go and use the equal operator
  12441. 7:25:55in order to join tables so even though
  12442. 7:25:58that is logically it makes sense to have
  12443. 7:26:00it at the output but still SQL cannot go
  12444. 7:26:02and compare the nulls that's why this is
  12445. 7:26:05a problem for this combination SQL will
  12446. 7:26:08not find any matching So we will not get
  12447. 7:26:10any informations for the combination of
  12448. 7:26:122024 and null. So for us of course in
  12449. 7:26:15the business this is missing
  12450. 7:26:17informations and as well inaccurate
  12451. 7:26:19results. So we're going to miss this row
  12452. 7:26:22and it's still going to go and jump to
  12453. 7:26:23the third row. So here what are the
  12454. 7:26:25values of the key. We have 20 25 and B.
  12455. 7:26:28Now it's going to go and search it in
  12456. 7:26:30the second table and it's still going to
  12457. 7:26:32find a match over here. So in the
  12458. 7:26:34outputs we're going to get those values.
  12459. 7:26:37The the orders going to be 50, the sales
  12460. 7:26:40300. Now it's going to go to the last
  12461. 7:26:42row and we have here again the same
  12462. 7:26:44problem. We have here 2025 and null. And
  12463. 7:26:48of course if you check the data you will
  12464. 7:26:49say yes we have a matching over here but
  12465. 7:26:52SQL would ignore it. So we have exactly
  12466. 7:26:54the same situation and we will not find
  12467. 7:26:57it at the results. So at the output we
  12468. 7:26:59will get only two rows even though that
  12469. 7:27:01those two tables are like identicals if
  12470. 7:27:04you compare the keys. So with that we
  12471. 7:27:06are losing data at the results and we
  12472. 7:27:08are providing inaccurate results. So my
  12473. 7:27:10friends if you have nulls inside your
  12474. 7:27:13keys what can happen you will lose
  12475. 7:27:15records at the output. So here it's very
  12476. 7:27:18important to handle the nulls inside the
  12477. 7:27:21keys before doing the joins. All right
  12478. 7:27:24so now in order to fix it we're going to
  12479. 7:27:25go and use either the kalis or the
  12480. 7:27:27isnull in the join. So as you can see we
  12481. 7:27:29are not using the type directly. We are
  12482. 7:27:31handling it by replacing the null with
  12483. 7:27:34an empty string. It doesn't matter which
  12484. 7:27:36value you are using. The main thing is
  12485. 7:27:38that you have a value and SQL can go and
  12486. 7:27:41map it. So you could have it as empty
  12487. 7:27:43string or a blank or any default value.
  12488. 7:27:45But I usually go with the empty string
  12489. 7:27:47since it's little bit faster than having
  12490. 7:27:49any other characters. So now what going
  12491. 7:27:51to happen is we're going to go
  12492. 7:27:52everywhere and replace those nulls with
  12493. 7:27:56an empty string. So now we don't have
  12494. 7:27:58any nulls inside our keys and let's go
  12495. 7:28:01and see what can happen. So we're going
  12496. 7:28:02to start with the first row again. Here
  12497. 7:28:04we have a matching from the right table
  12498. 7:28:07and we're going to see the whole records
  12499. 7:28:10in the outputs. So we will get as well
  12500. 7:28:12the sales as 100. And now it's going to
  12501. 7:28:14go to the second row over here. So this
  12502. 7:28:17time we don't have a null. We have 2024
  12503. 7:28:20and an empty string. So now it's going
  12504. 7:28:22to go and search for a match and it's
  12505. 7:28:24going to find it over here. we have as
  12506. 7:28:25well 2024 and an empty string. So now
  12507. 7:28:28what can happen in the outputs we're
  12508. 7:28:30going to get a
  12509. 7:28:32204 but here we will get a null. So we
  12510. 7:28:35will not get an empty string we will get
  12511. 7:28:37a null over here and that's because we
  12512. 7:28:40are handling the null only on the join.
  12513. 7:28:42So as you can see we have here the is
  12514. 7:28:44null type on the join but we don't have
  12515. 7:28:46it on the select. So in the select the
  12516. 7:28:49type going to be like the original data
  12517. 7:28:51and the original data was a null. We are
  12518. 7:28:53just handling the null in the joints
  12519. 7:28:55just in order to let SQL understand how
  12520. 7:28:57to map and match the data. So in this
  12521. 7:29:00example, I'm not changing the values in
  12522. 7:29:02the select. So that's why we will get
  12523. 7:29:03the original value. But the orders we
  12524. 7:29:06will get it 40 and the sales going to be
  12525. 7:29:0920. Now moving on to the third row. I
  12526. 7:29:12think you already get it. So let's going
  12527. 7:29:14to find the match and the sales going to
  12528. 7:29:16be 300. All right. Now we're going to
  12529. 7:29:19move to the last one. And here we have
  12530. 7:29:20the same scenario. So we have 2025 and
  12531. 7:29:23an empty string. So it's not null
  12532. 7:29:25anymore. And SQL going to go and search
  12533. 7:29:27for all those informations and it's
  12534. 7:29:29going to find it over here. So SQL going
  12535. 7:29:31to take this fields over here in the
  12536. 7:29:34type in null not an empty string because
  12537. 7:29:37in the select we didn't handle it. So
  12538. 7:29:39the order going to be 60 and the sales
  12539. 7:29:42going to be 200. So as you can see now
  12540. 7:29:45the result is complete. We successfully
  12541. 7:29:48combined both of those tables in one big
  12542. 7:29:50results using joins but as well using
  12543. 7:29:53the help of the isnull function in order
  12544. 7:29:55to have a complete results and not miss
  12545. 7:29:57any value. So my friends be very careful
  12546. 7:30:00check always the keys whether they have
  12547. 7:30:03nulls or not and if you find nulls go
  12548. 7:30:05immediately and handle it so you don't
  12549. 7:30:07lose any records in the results and you
  12550. 7:30:10get accurate
  12551. 7:30:14analyzes. All right, moving on to the
  12552. 7:30:16next use case for the isnull. We can use
  12553. 7:30:18it in order to handle the nulls before
  12554. 7:30:22sorting the data. So imagine we have the
  12555. 7:30:24following sales 15 25 and null. Now if
  12556. 7:30:27you go and sort the data by the sales
  12557. 7:30:29ascending from the lowest to the highest
  12558. 7:30:32what can happen? SQL going to show the
  12559. 7:30:34nulls at the start and that is not
  12560. 7:30:37because the null is the lowest value
  12561. 7:30:39because null has no value. But SQL show
  12562. 7:30:42it like this. it's going to place it at
  12563. 7:30:43the start and then below it we're going
  12564. 7:30:46to have the lowest value. So it is the
  12565. 7:30:4815 and at the end we're going to have
  12566. 7:30:49the 25. Now if you are doing the exact
  12567. 7:30:52opposite where we are sorting the data
  12568. 7:30:54from the highest to the lowest using
  12569. 7:30:56descending. So what going to happen is
  12570. 7:30:59going to sort it like this. We're going
  12571. 7:31:00to have 25 then 15 and the last thing
  12572. 7:31:03that going to appear in the list going
  12573. 7:31:05to be the null. So here SQL is showing
  12574. 7:31:07the nulls at the end and that is again
  12575. 7:31:10not because nulls are the lowest value
  12576. 7:31:12it has no value but SQL do it like this
  12577. 7:31:15show it at the end. So this is how SQL
  12578. 7:31:17deals with the nulls if you are sorting
  12579. 7:31:19the data. So in order to understand this
  12580. 7:31:21use case let's have the following task.
  12581. 7:31:23So the task says sort the customers from
  12582. 7:31:26the lowest to the highest scores with
  12583. 7:31:29nulls appearing last. All right. So
  12584. 7:31:31let's solve it. This going to be very
  12585. 7:31:33interesting one. So we need the customer
  12586. 7:31:35informations. So let's go and select and
  12587. 7:31:37we need the customer ID and the scores
  12588. 7:31:41from sales customers and let's go and
  12589. 7:31:45execute it. So we have a simple list of
  12590. 7:31:47all customers and their scores. But now
  12591. 7:31:49we have to go and sort the data from the
  12592. 7:31:51lowest to the highest. So we're going to
  12593. 7:31:53go and use the order by clause and we
  12594. 7:31:55need the field score. And since it's
  12595. 7:31:57lowest to the highest that means we need
  12596. 7:31:59to have the ascending and in SQL it is a
  12597. 7:32:02default. So we don't have to go and
  12598. 7:32:03mention it. So let's go and execute it.
  12599. 7:32:05So now as you can see in the results it
  12600. 7:32:07start from the lowest to the highest and
  12601. 7:32:09the first part of our task is solved.
  12602. 7:32:12But now of course we have an issue right
  12603. 7:32:13because we have a null and as we learned
  12604. 7:32:15SQL going to put it at the first place
  12605. 7:32:18on the list. But the task says with
  12606. 7:32:20nulls appearing last. So we really don't
  12607. 7:32:23want to see the nulls at the start. We
  12608. 7:32:25don't worry about it. So we would like
  12609. 7:32:26to have it at the end of the list. So
  12610. 7:32:28that means we have to go and handle the
  12611. 7:32:30nulls before sorting the data. And here
  12612. 7:32:33we have two ways to do it. One way that
  12613. 7:32:36is lazy and the other one is more
  12614. 7:32:38professional. So let me show you first
  12615. 7:32:39the lazy way. We're going to go and
  12616. 7:32:41replace the null with a very big number.
  12617. 7:32:44So for example, what we're going to do,
  12618. 7:32:46we're going to go and use the kowalis
  12619. 7:32:48and we're going to say okay score and
  12620. 7:32:50then let's have a lot of number so that
  12621. 7:32:53we have a really big score. I just want
  12622. 7:32:55to select it in order to see the
  12623. 7:32:56results. So as you can see it's a very
  12624. 7:32:58big number here. So if you take this and
  12625. 7:33:02replace the order by with the new score.
  12626. 7:33:05So that's it. Let's go and execute it.
  12627. 7:33:07So now if you check the results we have
  12628. 7:33:09already solved the task. We have listed
  12629. 7:33:10all the customers from the highest to
  12630. 7:33:12the lowest and the nulls are at the end.
  12631. 7:33:14So now the question why do we call this
  12632. 7:33:16lazy or not professional and that's
  12633. 7:33:18because we are defining a static value.
  12634. 7:33:21And of course for this example it is
  12635. 7:33:22working but we don't know later what's
  12636. 7:33:24going to happen. Maybe things change
  12637. 7:33:26where in this course you're going to get
  12638. 7:33:27a higher value than this and then
  12639. 7:33:29sorting the data will make no sense
  12640. 7:33:31since the null going to be like in
  12641. 7:33:33between values. So who knows your value
  12642. 7:33:36might be a real value inside the data.
  12643. 7:33:38Now let me show you the other way which
  12644. 7:33:40is more professional in order to solve
  12645. 7:33:42this task where we don't play with luck
  12646. 7:33:44at all. So let's go and do that. Let me
  12647. 7:33:46just move this little bit here. I'm
  12648. 7:33:48going to go and create a new logic where
  12649. 7:33:50we're going to say case when if the
  12650. 7:33:52score is null then what's going to
  12651. 7:33:54happen we want the value one otherwise
  12652. 7:33:58the value going to be zero so end so we
  12653. 7:34:01are just creating a flag with zero and
  12654. 7:34:04one if the score is null then we're
  12655. 7:34:06going to get the flag of one if we have
  12656. 7:34:08a value for the score we will get zero
  12657. 7:34:10so let's have it like this and I will
  12658. 7:34:12just go and get rid of this kalis so
  12659. 7:34:16let's go and execute it Now if you check
  12660. 7:34:18our new nice flag you can see we have
  12661. 7:34:20zeros everywhere where we have a value
  12662. 7:34:22in the score but only once we have a
  12663. 7:34:25null we will get the flag of one. So now
  12664. 7:34:27once we got this what we're going to do
  12665. 7:34:29we're going to go and sort our data
  12666. 7:34:30based on this flag and the score even
  12667. 7:34:33though the task is not mentioning
  12668. 7:34:34anything about the flag but we are using
  12669. 7:34:36it in order to force the nulls to be at
  12670. 7:34:39the end of the result. Let me show you
  12671. 7:34:41how we're going to do that. So let me
  12672. 7:34:42just remove all this. So first we want
  12673. 7:34:45to sort the data by our new flag in
  12674. 7:34:48order to make sure that the nulls at the
  12675. 7:34:50end. So we're going to have our flag and
  12676. 7:34:52then afterward we sort the data by the
  12677. 7:34:55score. So let's go and have the score.
  12678. 7:34:58So again what we are doing first sort
  12679. 7:35:00the data by the flag in order to push
  12680. 7:35:02the nulls at the end. And now once all
  12681. 7:35:04those values are equal to each others
  12682. 7:35:07what's going to happen SQL going to go
  12683. 7:35:08and sort the data by the score. So SQL
  12684. 7:35:10going to use the scores in order to sort
  12685. 7:35:12the data and both of them are ascending.
  12686. 7:35:15Let's go and execute it. Now as you can
  12687. 7:35:17see we're going to get exactly same
  12688. 7:35:18results. The values from the lowest to
  12689. 7:35:21the highest and the nulls are at the
  12690. 7:35:23end. And as you can see with the order
  12691. 7:35:25by we didn't use any static values or
  12692. 7:35:28any big numbers. And of course we don't
  12693. 7:35:30need the flag at the select. So we can
  12694. 7:35:31go and remove it. So let's execute it.
  12695. 7:35:33And with that we have solved the task.
  12696. 7:35:35So as you can see we can use those nice
  12697. 7:35:37functions like the cowis or the isnull
  12698. 7:35:40in order to handle the nulls before
  12699. 7:35:42sorting your
  12700. 7:35:46data. So what is the function null if
  12701. 7:35:49null if going to go and compare two
  12702. 7:35:51values and it going to returns a null if
  12703. 7:35:54they are equal otherwise if they are not
  12704. 7:35:56equal it going to returns the first
  12705. 7:35:59value. Okay. Okay. So now the syntax of
  12706. 7:36:01the null if it accepts only two values
  12707. 7:36:04value one and value two. So here again
  12708. 7:36:06of course you can go and use a column
  12709. 7:36:08with a static value like the unknown. So
  12710. 7:36:10we are comparing the values between a
  12711. 7:36:12column and a static value or you can go
  12712. 7:36:15and compare two columns the shipping
  12713. 7:36:17address and the billing address. So
  12714. 7:36:19again here it accepts only two values.
  12715. 7:36:21We cannot have it like the kalis where
  12716. 7:36:23we have a list of multiple values. All
  12717. 7:36:25right. So now let's understand exactly
  12718. 7:36:27what do we mean with the null if. So the
  12719. 7:36:29workflow going to be like this. SQL
  12720. 7:36:30going to go and check two values the
  12721. 7:36:32value one and the value two. And if they
  12722. 7:36:35are equal then SQL going to go and
  12723. 7:36:37return a null. But if the two values are
  12724. 7:36:39not equal going to go and return the
  12725. 7:36:42first value. So it is the one on the
  12726. 7:36:44left side. So by checking the outcomes
  12727. 7:36:46here we will never have a scenario where
  12728. 7:36:48we're going to get the second value.
  12729. 7:36:50That means the second value always used
  12730. 7:36:52as a check. So we are checking against
  12731. 7:36:55this value. So either we're going to get
  12732. 7:36:56the value one or a null. Let's have this
  12733. 7:36:59very simple example. We are saying null
  12734. 7:37:00if price and we are checking whether
  12735. 7:37:03it's equal to minus1. So we are saying
  12736. 7:37:05if the price is equal to minus1 then go
  12737. 7:37:08and replace it with a null because it is
  12738. 7:37:10data quality issue that we have a price
  12739. 7:37:12that is negative. It makes no sense for
  12740. 7:37:14our business. And if it is minus1 then
  12741. 7:37:16it means for us a null. We don't know
  12742. 7:37:18the price of this product. So we will
  12743. 7:37:20correct it using the null if. Let's
  12744. 7:37:22check this very simple example. We have
  12745. 7:37:24two orders. So SQL going to start with
  12746. 7:37:25the first order and check the first
  12747. 7:37:27value. So what is the first value? Is
  12748. 7:37:29the price. So here we have a 90. SQL
  12749. 7:37:32going to go and check is 90 equal to
  12750. 7:37:34minus one. Well, no. That means it's
  12751. 7:37:36going to go and execute this path. So
  12752. 7:37:39that means in the output we will get the
  12753. 7:37:42first value which is 90. So in the
  12754. 7:37:44output we will get a 90. Now let's move
  12755. 7:37:47to the second order. Here we have a
  12756. 7:37:49minus one. So SQL going to check is
  12757. 7:37:51minus one here equal to the minus one
  12758. 7:37:53that we have in the null if well yes. So
  12759. 7:37:56that means SQL going to go and execute
  12760. 7:37:58this path where we were going to get the
  12761. 7:38:00null value in the output and we're going
  12762. 7:38:02to get it like this. So now if you
  12763. 7:38:04compare the result from null if and the
  12764. 7:38:05price you can see we don't have any more
  12765. 7:38:08the minus one. And as you can see now we
  12766. 7:38:10are doing exactly the opposite as
  12767. 7:38:11kowalis and is null. We are replacing a
  12768. 7:38:13real value with a null. Now moving on to
  12769. 7:38:16the second example and this is very
  12770. 7:38:18interesting one in the analytics where
  12771. 7:38:20we can go and use two columns inside the
  12772. 7:38:22null if. So in this example we are
  12773. 7:38:24saying null if original price and
  12774. 7:38:27discount price. So SQL have to go and
  12775. 7:38:29compare the prices between those two
  12776. 7:38:30columns and if they are equal it should
  12777. 7:38:33return a null. And now you might say
  12778. 7:38:34okay in this example why we are doing
  12779. 7:38:36this? Well we can use it in order to
  12780. 7:38:39highlight or flag special cases inside
  12781. 7:38:41our data. And the special case here is
  12782. 7:38:44if the original price is equal to the
  12783. 7:38:47discount price and if those two prices
  12784. 7:38:49are equals that means we have an issue
  12785. 7:38:51in our program or something like went
  12786. 7:38:53wrong as we are inserting data. So let's
  12787. 7:38:55see what's going to happen for the first
  12788. 7:38:57row we're going to go and compare the
  12789. 7:38:59150 from the original price with the
  12790. 7:39:01discount price. So they are not equal
  12791. 7:39:04right. So that means going to go and
  12792. 7:39:06return the original price the 150 in the
  12793. 7:39:09output. So let's move to the second
  12794. 7:39:11order. Here we have the original price
  12795. 7:39:13250 and as well the discount price is
  12796. 7:39:16250. So they are equal and if they are
  12797. 7:39:18equal then we will get a null in the
  12798. 7:39:21output. So as you can see again here we
  12799. 7:39:23are not getting any values from the
  12800. 7:39:25discount. We are using it only for a
  12801. 7:39:26check. So with that we have a quick flag
  12802. 7:39:28like using the nulls as flag in order to
  12803. 7:39:31identify where we have equal values. So
  12804. 7:39:34this is how the null if works.
  12805. 7:39:39All right friends, here we have a very
  12806. 7:39:41nice use case for the null if and that
  12807. 7:39:43is preventing the error of dividing by
  12808. 7:39:46zero. Let's see what this means. Okay,
  12809. 7:39:48let's have the following task and it
  12810. 7:39:50says find the sales price for each order
  12811. 7:39:53by dividing the sales by quantity. So
  12812. 7:39:56let's go and solve it. This should be
  12813. 7:39:57very easy. So we need the order ID. We
  12814. 7:40:02need the sales and the
  12815. 7:40:05quantity from sales orders. Let's go and
  12816. 7:40:10execute it. So now we have 10 orders.
  12817. 7:40:12Those are the sales and the quantity. So
  12818. 7:40:14now it's very easy to calculate the
  12819. 7:40:16price. It's going to be the sales
  12820. 7:40:18divided by quantity and we're going to
  12821. 7:40:21call it price. So let's go and execute
  12822. 7:40:24it. Now as you can see we got an error
  12823. 7:40:26says divide by zero error encountered.
  12824. 7:40:29So that means somewhere we have a zero
  12825. 7:40:31for the quantity and this is a problem.
  12826. 7:40:34Let's go and check the data again. So
  12827. 7:40:35I'm just going to comment the whole
  12828. 7:40:38thing and let's go and execute it. So
  12829. 7:40:40now by checking the result yes we got
  12830. 7:40:42for the order ID 10 here we have
  12831. 7:40:44quantity zero. So it will not work if
  12832. 7:40:46you divide by zero of course. So how we
  12833. 7:40:48can solve it? We can use the magic of
  12834. 7:40:50the null if where we're going to go and
  12835. 7:40:52replace the zero with a null. So getting
  12836. 7:40:55a null is way better than getting an
  12837. 7:40:58error. Right? So let's go and do that.
  12838. 7:41:00I'm just going to remove the comments.
  12839. 7:41:01And here we're going to say null if if
  12840. 7:41:04the quantity equal to the zero value. So
  12841. 7:41:08that's it. Let's go and execute it. Now
  12842. 7:41:10as you can see it is working. And with
  12843. 7:41:12that we are making sure that we are not
  12844. 7:41:15dividing by zero. And that's because we
  12845. 7:41:17replace it with a null. And if you
  12846. 7:41:19divide anything by null you will get a
  12847. 7:41:21null. So if you check the result over
  12848. 7:41:23here the order 10 we got the price of
  12849. 7:41:25null which is correct and for the all
  12850. 7:41:28other values everything is working
  12851. 7:41:29because we have values and we didn't
  12852. 7:41:31replace it with a null that's why we
  12853. 7:41:33have values for the price and this is
  12854. 7:41:36very common use case for the null if we
  12855. 7:41:38can use it in order to prevent dividing
  12856. 7:41:40by
  12857. 7:41:44zero. All right so what is is null? It's
  12858. 7:41:47going to return true if the value is
  12859. 7:41:50null. So it is checking the value if
  12860. 7:41:52it's null it's going to return true
  12861. 7:41:54otherwise it's going to returns a false.
  12862. 7:41:57Now the exact opposite if you go use the
  12863. 7:41:59is not null. So if you use these
  12864. 7:42:01keywords it's going to returns a true if
  12865. 7:42:04the value is not null otherwise if it is
  12866. 7:42:06null it's going to go and return a
  12867. 7:42:08false. Okay. So the syntax for that is
  12868. 7:42:10very simple. It start with a value or
  12869. 7:42:13expression and then after that we're
  12870. 7:42:15going to have the keyword is space null
  12871. 7:42:17and the is not is exactly the same. So
  12872. 7:42:20we have a value then afterwards we have
  12873. 7:42:22the is not null. So we have the not
  12874. 7:42:25operator after that and the is not is
  12875. 7:42:27exactly the same. So we have a value
  12876. 7:42:29then we have the is not the not operator
  12877. 7:42:32then the null. So it's very simple.
  12878. 7:42:34Let's have an example. We are checking
  12879. 7:42:35whether the values of the shipping
  12880. 7:42:37address is null. So we can have it like
  12881. 7:42:39this. Shipping address is null or we can
  12882. 7:42:42check the opposite whether it's not
  12883. 7:42:43null. So the shipping address is not
  12884. 7:42:45null. It's very easy. Okay. So now let's
  12885. 7:42:47understand how this works. we are
  12886. 7:42:49checking the value. So if the value is
  12887. 7:42:52null then return a true if it is not
  12888. 7:42:55null then we return a false. So as you
  12889. 7:42:57can see it never returns the value
  12890. 7:42:59itself or any nulls. So we are getting a
  12891. 7:43:01boolean of true and false. So we are
  12892. 7:43:04creating like a boolean flag in order to
  12893. 7:43:06assist us with the checks. So we have
  12894. 7:43:08this very simple example price is null
  12895. 7:43:10and we have those two rows. So we are
  12896. 7:43:12checking whether the price is null in
  12897. 7:43:14the first order it is not null right
  12898. 7:43:17that's why we will get a false in the
  12899. 7:43:19output and the second order the value is
  12900. 7:43:22null so it is correct that's why we will
  12901. 7:43:25get true now of course if we go and use
  12902. 7:43:27the is not null is going to be exact
  12903. 7:43:29opposite so is the price not null well
  12904. 7:43:33yes it's not null that's why you will
  12905. 7:43:35get a true over here so now for the
  12906. 7:43:37second check it is null right so the
  12907. 7:43:40output going to be false we will get the
  12908. 7:43:43exact opposite. So that's it. It's very
  12909. 7:43:45simple how the isnull and is not null
  12910. 7:43:50works. All right. One very obvious use
  12911. 7:43:53case for is null and is not null is by
  12912. 7:43:56searching for missing informations or
  12913. 7:43:58searching for nulls. And maybe after
  12914. 7:43:59that we can go and clean up our data by
  12915. 7:44:02removing the nulls from our data set.
  12916. 7:44:04Let's have the following task and it
  12917. 7:44:06says identify the customers who has no
  12918. 7:44:09scores. All right, let's go and solve
  12919. 7:44:11it. This is very simple. So let's start
  12920. 7:44:13by selecting star from sales customers.
  12921. 7:44:17So we need everything. Let's go and
  12922. 7:44:19execute it. Now as you can see we have
  12923. 7:44:21our five customers. But the task says we
  12924. 7:44:23have to have all the customers who have
  12925. 7:44:25no score. So that means the result
  12926. 7:44:27should return only the last record since
  12927. 7:44:30the score of Anna is null. So let's go
  12928. 7:44:33and have a wear clause. So where and now
  12929. 7:44:36what do we need? We need the score. Then
  12930. 7:44:38we don't use the equal, we use is null
  12931. 7:44:42like this. So that's it. Let's go and
  12932. 7:44:44execute it. And with that, as you can
  12933. 7:44:45see, it's very simple. We have filtered
  12934. 7:44:47our data and now we can see all the
  12935. 7:44:49customers where the score is null. This
  12936. 7:44:52is a very basic check to understand
  12937. 7:44:54whether our data contains nulls. All
  12938. 7:44:56right, moving on to the next task and it
  12939. 7:44:58says show a list of all customers who
  12940. 7:45:01have scores. So back to our example,
  12941. 7:45:03this time we're going to do exactly the
  12942. 7:45:05opposite. We want a list of all
  12943. 7:45:06customers where we have a value in the
  12944. 7:45:09scores. So what we're going to do, we're
  12945. 7:45:10going to say where score is not null. So
  12946. 7:45:14if you go and execute it, you can see
  12947. 7:45:16we're going to get a clean list where
  12948. 7:45:18all the customers have score. And with
  12949. 7:45:20that, we get rid of all nulls inside the
  12950. 7:45:22score field. And maybe this is helpful
  12951. 7:45:24in order to do further analyzes.
  12952. 7:45:30All right friends, now we come to very
  12953. 7:45:32interesting use case for the isnull and
  12954. 7:45:34that is by introducing a new type of
  12955. 7:45:37joints between tables that's going to
  12956. 7:45:39help us to find the unmatching rows
  12957. 7:45:42between two tables. Let's have a quick
  12958. 7:45:44recap about the joints in SQL in order
  12959. 7:45:46to understand the new types. So
  12960. 7:45:48basically we have two sets or let's say
  12961. 7:45:50two tables the left and the right. And
  12962. 7:45:53if you go and use an inner join what we
  12963. 7:45:55are doing here we are finding only the
  12964. 7:45:57matching rows between the left table and
  12965. 7:45:59the right table. So at the result we
  12966. 7:46:01will get only the matching rows. Now we
  12967. 7:46:04have another type of joints called lift
  12968. 7:46:06outer join. And if you use this type at
  12969. 7:46:09the result you will get all the rows
  12970. 7:46:11from the left table and as well only the
  12971. 7:46:14matching rows from the right table. Now
  12972. 7:46:16we have another type which is exactly
  12973. 7:46:18the opposite the right join. And here
  12974. 7:46:21we're going to get all the rows from the
  12975. 7:46:22right table and only the matching
  12976. 7:46:25informations from the left table. And
  12977. 7:46:27now to the last type that we learned. We
  12978. 7:46:29have the full join where we will get all
  12979. 7:46:31the rows from the left and as well all
  12980. 7:46:33the rows from the right. So we will not
  12981. 7:46:35be missing anything. So those are the
  12982. 7:46:37four basic joints that we have learned
  12983. 7:46:39in SQL. But in SQL we have as well other
  12984. 7:46:42types that are more advanced. But we
  12985. 7:46:44don't have in SQL any keywords for that.
  12986. 7:46:47So the first one called lift anti-join.
  12987. 7:46:51So what we are saying here we need all
  12988. 7:46:53the rows from the left table but this
  12989. 7:46:55time without the matching rows. So all
  12990. 7:46:59the informations that are matching with
  12991. 7:47:01the right table we don't want to see it
  12992. 7:47:03at the results. And as I said we don't
  12993. 7:47:05have here an extra keyword for this type
  12994. 7:47:07of join. But in order to get this effect
  12995. 7:47:09we're going to go and combine the left
  12996. 7:47:11join together with the isnull. And with
  12997. 7:47:13that we're going to get all the data
  12998. 7:47:15from the left side but without anything
  12999. 7:47:17that is matching the right side. And
  13000. 7:47:19this we call it left anti- join. And we
  13001. 7:47:22have another advanced type for the
  13002. 7:47:24joints called the right anti- join. This
  13003. 7:47:26is exactly the opposite. So we are
  13004. 7:47:28saying all the rows from the right table
  13005. 7:47:31without having any matching rows from
  13006. 7:47:34the left table. So all the informations
  13007. 7:47:36on the right side that is not matching
  13008. 7:47:38the left side. So again here we don't
  13009. 7:47:39have a keyword for that. We're going to
  13010. 7:47:41go and work with the right join plus and
  13011. 7:47:44is null. So with that, as you can see,
  13012. 7:47:46we have two new types of joins added to
  13013. 7:47:48our four basic joins. Now this might be
  13014. 7:47:50confusing. Let's have the following task
  13015. 7:47:52in order to understand it. Show a list
  13016. 7:47:54of all details for customers who have
  13017. 7:47:57not placed any orders. All right. So
  13018. 7:47:59let's see how we can create the effect
  13019. 7:48:01of the left anti-join. So let's do it
  13020. 7:48:03step by step. We need here two tables.
  13021. 7:48:06We need the customers and as well the
  13022. 7:48:08orders. So since we are focusing on the
  13023. 7:48:10customers, the lift table going to be
  13024. 7:48:12the customers. So let's go and do that.
  13025. 7:48:15We're going to go and say select star
  13026. 7:48:18from sales customers. This is our first
  13027. 7:48:22table. So we are using the alias of C.
  13028. 7:48:25So let's go and execute it. Now as you
  13029. 7:48:27can see we got the list of all
  13030. 7:48:28customers. So that we have all the
  13031. 7:48:30details for our customers. But now we
  13032. 7:48:32have to go and join it with the orders.
  13033. 7:48:34So in order to do that let's have a new
  13034. 7:48:37line. left join
  13035. 7:48:40sales sales orders and let's have the
  13036. 7:48:44lso and now we have to go and define the
  13037. 7:48:46key for the join so on it's going to be
  13038. 7:48:49the customer ID equal the customer ID in
  13039. 7:48:53the order table so now if you go and
  13040. 7:48:55execute it now what we're going to do
  13041. 7:48:57we're going to go and show the order ID
  13042. 7:49:00from the table orders so order ID just
  13043. 7:49:03to see whether we have a match or not so
  13044. 7:49:05let's have it like this and execute it
  13045. 7:49:07Now let's go and check the results. As
  13046. 7:49:09you can see those four columns comes
  13047. 7:49:12from the table customers and only the
  13048. 7:49:14last column come from the orders. So now
  13049. 7:49:16what is interesting is to check the
  13050. 7:49:18order ID whether we have nulls or not.
  13051. 7:49:21So as you can see for the customer one
  13052. 7:49:23we have everything matching. For the
  13053. 7:49:25customer two as well we have orders the
  13054. 7:49:27three as well for only the last one
  13055. 7:49:30customer ID 5 we have here a null. So
  13056. 7:49:33that means SQL was not able to find any
  13057. 7:49:37order for this customer. So again what
  13058. 7:49:39this means we have only one customer
  13059. 7:49:41Anna where she doesn't have any order
  13060. 7:49:45but all other customers they did have an
  13061. 7:49:48order and that's because we have values
  13062. 7:49:51from the right table. So once we have
  13063. 7:49:53values that means we have matching but
  13064. 7:49:55since here we have a null that means we
  13065. 7:49:58don't have any matching. So now since
  13066. 7:50:00the left anti- joint says we would like
  13067. 7:50:02to have all the data from the left table
  13068. 7:50:05without having any matching from the
  13069. 7:50:07right table. So that means for this
  13070. 7:50:09example we would like to get only this
  13071. 7:50:11customer Anna. And this is exactly as
  13072. 7:50:14well fulfilling our task. The task says
  13073. 7:50:16list all details for customers who have
  13074. 7:50:19not placed any order. All data from
  13075. 7:50:21customers where we don't have matching
  13076. 7:50:24from the orders. Now I think you already
  13077. 7:50:26got it how to get this effect. We're
  13078. 7:50:28going to go and filter the data like the
  13079. 7:50:30following. So we're going to have the
  13080. 7:50:32wear clause and now we need the column
  13081. 7:50:34from the right table from the orders. So
  13082. 7:50:36we're going to go with the customer ID
  13083. 7:50:39comes from the orders. So we're going to
  13084. 7:50:41say oh customer ID is null. And of
  13085. 7:50:47course you can go with the order ID as
  13086. 7:50:48well. You're going to get the same
  13087. 7:50:49effect. But I would like always to use
  13088. 7:50:51the key that we are using with the join.
  13089. 7:50:54So let's go and execute it. And now as
  13090. 7:50:56you can see we got the effect of the
  13091. 7:50:58left anti join and with that as you can
  13092. 7:51:00see we got the customer that we are
  13093. 7:51:01aiming for. So here we have the data
  13094. 7:51:03from the left side that is not matching
  13095. 7:51:05the right side. So the customers who
  13096. 7:51:07have not placed an order and with that
  13097. 7:51:10we have solved the task. So as you can
  13098. 7:51:11see we have implemented the left and
  13099. 7:51:13join by combining the left join together
  13100. 7:51:18with the is null. So this is the power
  13101. 7:51:20of playing with the nulls in SQL.
  13102. 7:51:26Now my friends, there is something that
  13103. 7:51:28is really confuses a lot of developers
  13104. 7:51:30or anyone that is working with data in
  13105. 7:51:33databases and SQL and that is the
  13106. 7:51:36differences between nulls, empty string
  13107. 7:51:39and blank spaces. So the nulls as we
  13108. 7:51:41learned we are saying I don't know what
  13109. 7:51:44the value is it is unknown. But now in
  13110. 7:51:46the other hand the empty string you are
  13111. 7:51:48saying I know the value it is nothing.
  13112. 7:51:52So the empty string is a string value
  13113. 7:51:55which has a zero characters. This is
  13114. 7:51:57totally different than the nulls. The
  13115. 7:51:59nulls we don't know anything about it.
  13116. 7:52:01So now sometimes maybe happens to you as
  13117. 7:52:03you are filling a forum and you come to
  13118. 7:52:05one field you go and by mistake hit a
  13119. 7:52:08space bar and with that you are entering
  13120. 7:52:10space into the field and you just jump
  13121. 7:52:12to the next field without entering any
  13122. 7:52:14other values. So we have now like a
  13123. 7:52:17space character inside the field. This
  13124. 7:52:19is really evil in databases because once
  13125. 7:52:21the user enter a blank space, it's going
  13126. 7:52:24to go and store it as a value inside the
  13127. 7:52:26database and it's going to take storage.
  13128. 7:52:28So it could be one space or many spaces
  13129. 7:52:30depends on how long you press the space
  13130. 7:52:33bar. So the blank space is a string but
  13131. 7:52:36the size is not zero like the empty
  13132. 7:52:38string. We're going to have a size of
  13133. 7:52:40how many spaces you have entered. So
  13134. 7:52:42here it's not like the null. We know the
  13135. 7:52:44value it is string and the character of
  13136. 7:52:46that going to be space. Okay. So let's
  13137. 7:52:48see those three scenarios inside scale.
  13138. 7:52:50Now I have like a dummy data using the
  13139. 7:52:52city statements. Don't worry about it.
  13140. 7:52:54I'm going to teach you all those stuff
  13141. 7:52:55in the next tutorials. So now we have
  13142. 7:52:57here like four rows. The first one with
  13143. 7:53:00a value a. The next one with null. The
  13144. 7:53:02third one with empty string. So as you
  13145. 7:53:05can see there is nothing between those
  13146. 7:53:07two quotes. And the last one we have a
  13147. 7:53:09space between those two quotes. Now
  13148. 7:53:11let's go and query this temporal table.
  13149. 7:53:14So select star from orders and execute.
  13150. 7:53:19So now by looking to the values of the
  13151. 7:53:21categories you can find all the
  13152. 7:53:23scenarios now. So now the first scenario
  13153. 7:53:25is the easiest one where we have a
  13154. 7:53:27normal value. We have here an a. But the
  13155. 7:53:29other three rows we don't have normal
  13156. 7:53:31values. We have like empty stuff. So the
  13157. 7:53:34first one going to be the null. So we
  13158. 7:53:36don't have a value. This is the special
  13159. 7:53:38marker from SQL. It says null. So there
  13160. 7:53:41is no value. And the other two they are
  13161. 7:53:43really confusing. As you can see it's
  13162. 7:53:45really hard by just looking to the data
  13163. 7:53:47or to the results whether it is an empty
  13164. 7:53:50string or a blank space. And this confus
  13165. 7:53:53a lot of developers or anyone working
  13166. 7:53:54with data seeing those results. It's
  13167. 7:53:56really hard to detect the data quality
  13168. 7:53:58issues by just looking at the results.
  13169. 7:54:01So now in this scenario what I do I go
  13170. 7:54:03and calculate the length of each value
  13171. 7:54:06inside my column. So let's go and do
  13172. 7:54:08that. Now we're going to go in the SQL
  13173. 7:54:11server. We're going to go and use the
  13174. 7:54:12function data length and our field going
  13175. 7:54:15to be the category. So let's call it
  13176. 7:54:18category length. So let's go execute it.
  13177. 7:54:22And now let's check the result. The
  13178. 7:54:23first one since we have only one
  13179. 7:54:25character, the length of that is going
  13180. 7:54:26to be one which is correct. And now to
  13181. 7:54:28the next row we have the category null.
  13182. 7:54:30We don't know the value and as well we
  13183. 7:54:33don't know the length of the value,
  13184. 7:54:34right? So that's why we will get a null.
  13185. 7:54:36So now by moving to the next one as you
  13186. 7:54:38can see those two looking really exactly
  13187. 7:54:40the same. But now with the help of the
  13188. 7:54:43length or the data length function we
  13189. 7:54:46can see that the third row or the third
  13190. 7:54:48category value has the length of zero.
  13191. 7:54:51That means it is an empty string and we
  13192. 7:54:54don't have any characters over here that
  13193. 7:54:56is hidden. So with that we are sure this
  13194. 7:54:58is an empty string. But now let's move
  13195. 7:55:00to the last one. Here it is very tricky
  13196. 7:55:02and evil. we have a hidden space inside
  13197. 7:55:05this value and we can understand that by
  13198. 7:55:08the length of this field. So as you can
  13199. 7:55:10see we have here a one that means we
  13200. 7:55:12have here one hidden space inside this
  13201. 7:55:15value and it is not empty string. So
  13202. 7:55:18that means I have here only one space
  13203. 7:55:20let's go and give it another space and
  13204. 7:55:23calculate the length. So as you can see
  13205. 7:55:24we have two spaces and that's why the
  13206. 7:55:26length is two. So don't count on your
  13207. 7:55:29eyes in order to understand the spaces.
  13208. 7:55:31go and calculate the length in order to
  13209. 7:55:34be very precise. So now let's go and
  13210. 7:55:36compare the three scenarios side by
  13211. 7:55:37side. So let's start with the first one
  13212. 7:55:39about the representations in the table.
  13213. 7:55:41The null we're going to see it as a null
  13214. 7:55:43inside the table. The empty string going
  13215. 7:55:45to be like two quotes and nothing
  13216. 7:55:47between them. And the blank space it's
  13217. 7:55:49as well two quotes and between them one
  13218. 7:55:52or many spaces. And now if you are
  13219. 7:55:54talking about the meaning the null means
  13220. 7:55:56unknown. We don't know the value. The
  13221. 7:55:59empty string it is known but it is
  13222. 7:56:02nothing it is empty value. And the third
  13223. 7:56:04one blank spaces it is as well known and
  13224. 7:56:07the spaces are the value. And now if you
  13225. 7:56:09are talking about the data types since
  13226. 7:56:11the null is no value. So we don't have a
  13227. 7:56:14data type for this and it is like a
  13228. 7:56:16special marker in the SQL. And now the
  13229. 7:56:19empty string has a data type. It is a
  13230. 7:56:21string and the size of this string going
  13231. 7:56:24to be zero since we have zero characters
  13232. 7:56:26inside the empty string. Moving on to
  13233. 7:56:28the blank spaces, it is a string since a
  13234. 7:56:30space is a character and it's going to
  13235. 7:56:32be the size of one or many. And now if
  13236. 7:56:35we are talking about the storage, the
  13237. 7:56:36null is the best. They don't consume or
  13238. 7:56:39occupy a lot of storage. While the empty
  13239. 7:56:41string and the blank spaces, they occupy
  13240. 7:56:43here storage and memory and they waste
  13241. 7:56:46the space. So if you are worried about
  13242. 7:56:48the storage, the best option here is a
  13243. 7:56:50null. Now talking about the performance,
  13244. 7:56:52you will get the best performance if you
  13245. 7:56:55are using nulls. Now the empty string is
  13246. 7:56:57as well fast but it is not that fast
  13247. 7:56:59like the nulls. Now the worst option
  13248. 7:57:01here is the blank spaces it is slow. So
  13249. 7:57:04again if the speed is important for you
  13250. 7:57:06you have to have those scenarios as a
  13251. 7:57:08null. So now if you are talking about
  13252. 7:57:09the comparison and you are searching for
  13253. 7:57:11those values if you want to search for
  13254. 7:57:13the null you have to go and use is null.
  13255. 7:57:16But in the other hand if you want to
  13256. 7:57:18search for the empty string and the
  13257. 7:57:19blank spaces you have to go and use the
  13258. 7:57:21operator equal. So that's all those are
  13259. 7:57:24the main differences between the null
  13260. 7:57:26empty string and blank spaces.
  13261. 7:57:31Now you might ask you know what why do I
  13262. 7:57:34have to understand the differences
  13263. 7:57:35between all those stuff the nulls empty
  13264. 7:57:37strings and the blanks everything's like
  13265. 7:57:39empty so why do I care well in new
  13266. 7:57:42projects I'm going to promise you that
  13267. 7:57:44you will be working with sources and
  13268. 7:57:46data that has bad data quality and you
  13269. 7:57:48might encounter all those three
  13270. 7:57:50scenarios in your data and now if you
  13271. 7:57:52don't do any data preparations like
  13272. 7:57:54cleaning up the data handling those
  13273. 7:57:56three scenarios and bringing standards
  13274. 7:57:58to your data and you jump immediately to
  13275. 7:58:01the analyzes without doing all those
  13276. 7:58:02stuff, you will end up providing
  13277. 7:58:04inaccurate results in your reports and
  13278. 7:58:07analyzes which leads to wrong decisions.
  13279. 7:58:10So preparing your data before doing any
  13280. 7:58:12analyszis by cleaning up the data,
  13281. 7:58:14handling those three scenarios and as
  13282. 7:58:16well bringing standards is very
  13283. 7:58:18important step before doing any
  13284. 7:58:21analyszis. So this is how we're going to
  13285. 7:58:23do it together with the stakeholders and
  13286. 7:58:25the users of your reports and analyzes.
  13287. 7:58:28You have to define a clear data
  13288. 7:58:30policies. It's like rules and you have
  13289. 7:58:33to commit yourself during the
  13290. 7:58:34implementations by following those
  13291. 7:58:36rules. And here we have three different
  13292. 7:58:38options. The first one you can go and
  13293. 7:58:40define the data policies like this. Only
  13294. 7:58:42use nulls and empty string but avoid
  13295. 7:58:45using blank spaces. In my project I
  13296. 7:58:48cannot imagine that there is a scenario
  13297. 7:58:51where we need blank spaces. They are
  13298. 7:58:53just evil. Just go get rid of them. All
  13299. 7:58:55right. Right. So with this policy, we
  13300. 7:58:57have to go and get rid of all blank
  13301. 7:58:59spaces inside our data. And in order to
  13302. 7:59:01do that, we have a wonderful function in
  13303. 7:59:02SQL called trim. The trim function in
  13304. 7:59:05SQL going to go and remove the spaces
  13305. 7:59:07from a string from the left side and as
  13306. 7:59:10well from the right side. So all the
  13307. 7:59:12leading spaces and the trailing spaces
  13308. 7:59:14going to be removed. So now if we go and
  13309. 7:59:16apply the trim function on that
  13310. 7:59:17category, what's going to happen? All
  13311. 7:59:19the blank spaces going to be removed and
  13312. 7:59:21it going to be turned into empty string.
  13313. 7:59:24So let's go and do that. It's very
  13314. 7:59:26simple. So we're going to use the trim
  13315. 7:59:28function and we're going to apply it on
  13316. 7:59:30the
  13317. 7:59:31category. Let's go and call it policy
  13318. 7:59:34one. So let's go and execute it. So now
  13319. 7:59:37by just comparing the policy one with
  13320. 7:59:39the category. You see like it's
  13321. 7:59:41identical but it's not. Now in order to
  13322. 7:59:43have a better feeling about this we can
  13323. 7:59:45go and test it using the data length.
  13324. 7:59:47Now let's go again and use the data
  13325. 7:59:49length function. So we're going to use
  13326. 7:59:52it for the whole results and as well I'm
  13327. 7:59:54going to go and use it for the category
  13328. 7:59:56in order to just compare it. So without
  13329. 7:59:59the
  13330. 8:00:03trim so like this. Let's go and execute
  13331. 8:00:06it. Now if you go and check the result
  13332. 8:00:08as you can see here again we have the
  13333. 8:00:09length of two because here we have two
  13334. 8:00:11spaces but with the policy one we have
  13335. 8:00:14zero. So those two values after applying
  13336. 8:00:17the trim function they have the length
  13337. 8:00:20of zero and with that we don't have
  13338. 8:00:22blank spaces. So that means now we are
  13339. 8:00:24sure after applying the trim we have
  13340. 8:00:27either a null or empty string. So let me
  13341. 8:00:29just get rid of all those informations.
  13342. 8:00:32Now I am sure both of them are empty
  13343. 8:00:34string. So as you can see it's very
  13344. 8:00:36simple using only one SQL function you
  13345. 8:00:39are cleaning up the data and bringing
  13346. 8:00:41standards. All right moving on to the
  13347. 8:00:43option two. You can define your data
  13348. 8:00:45policies like this. Only use nulls and
  13349. 8:00:47avoid both empty strings and as well
  13350. 8:00:50blank spaces. So that means in our
  13351. 8:00:52business we don't have anything
  13352. 8:00:54meaningful for the empty string and the
  13353. 8:00:56blank spaces. We can go and use only the
  13354. 8:00:58nulls. Okay. So now let's go and
  13355. 8:01:00implement this rule. We have to go and
  13356. 8:01:01convert a value to a null. So the value
  13357. 8:01:05going to be empty string to a null. And
  13358. 8:01:07as we learned we can go and use the null
  13359. 8:01:09if function in order to get nulls
  13360. 8:01:11instead of values. So let's go and apply
  13361. 8:01:13this policy. But now here we have two
  13362. 8:01:15values the empty string and spaces. Now
  13363. 8:01:18instead of having two rules for that I'm
  13364. 8:01:21going to convert first the blank spaces
  13365. 8:01:23to an empty string like we have done
  13366. 8:01:26here. So I'm going to take the result of
  13367. 8:01:28this function first as a first step and
  13368. 8:01:31afterwards we're going to go and use the
  13369. 8:01:33null if. So we're going to say null if
  13370. 8:01:37for the result of the trim if if you
  13371. 8:01:40find any empty strings convert it to
  13372. 8:01:43null. So that's it policy 2. So as you
  13373. 8:01:46can see in the result we have converted
  13374. 8:01:48those empty spaces and planks to a null.
  13375. 8:01:51So with that we are getting three nulls
  13376. 8:01:53and of course we're going to get the
  13377. 8:01:54value a. And now if you compare those
  13378. 8:01:56three columns side by side you're going
  13379. 8:01:57to see the bully C2 is really easier to
  13380. 8:02:00understand compared to the previous
  13381. 8:02:02ones. Right? So now if you compare the
  13382. 8:02:04policy two now to the policy one, you
  13383. 8:02:05can see it's easier to understand and
  13384. 8:02:08it's easier as well to handle. So again
  13385. 8:02:10it's very easy to do data cleanup with
  13386. 8:02:12only two functions we have now like
  13387. 8:02:14standards inside our data. And now
  13388. 8:02:16moving on to the last option, we can
  13389. 8:02:18define our data policy like this. Use
  13390. 8:02:20only a default value unknown and avoid
  13391. 8:02:24using anything else like nulls, empty
  13392. 8:02:26strings and blank spaces. So that means
  13393. 8:02:29in the analyzes and reports we want to
  13394. 8:02:31see the value unknown and we have to
  13395. 8:02:33handle all those three informations and
  13396. 8:02:35convert them to unknown. So now in order
  13397. 8:02:38to implement the policy three we have to
  13398. 8:02:39go and convert a null with a value a
  13399. 8:02:42default value and here we have two
  13400. 8:02:44options either use the is null or we can
  13401. 8:02:46go and use the kalis and I will go with
  13402. 8:02:49the kowalis so
  13403. 8:02:51kowalis and I'm going to use directly
  13404. 8:02:54the category. So if you find any null
  13405. 8:02:57replace it with the default value
  13406. 8:02:59unknown and let's call it policy 3. So
  13407. 8:03:02let's go and execute it. So now if you
  13408. 8:03:04check the result over here you see that
  13409. 8:03:06we got it only once correct. So we
  13410. 8:03:08replaced the null with the unknown but
  13411. 8:03:10we still have like empty spaces and
  13412. 8:03:12blanks and that's because we rushed
  13413. 8:03:14using the qualis and we skipped the
  13414. 8:03:16other steps. So as you can see preparing
  13415. 8:03:18the data you have to do it slowly step
  13416. 8:03:20by step. So first we have to go and
  13417. 8:03:22convert everything to a null like the
  13418. 8:03:24policy 2. And after that the last step
  13419. 8:03:27we're going to go and use the default
  13420. 8:03:28value. So that means instead of using
  13421. 8:03:30the category we have to go and get the
  13422. 8:03:32result of the policy 2. So let's go and
  13423. 8:03:35copy it and replace the category with
  13424. 8:03:37those two steps and let's go and execute
  13425. 8:03:40it. So now as you can see we have the
  13426. 8:03:42default value for all those three
  13427. 8:03:44scenarios. First we have to trim the
  13428. 8:03:46data in order to remove all the blank
  13429. 8:03:48spaces. The second step, we're going to
  13430. 8:03:50go and replace all the empty strings
  13431. 8:03:53with a null. And with that, we're going
  13432. 8:03:55to get a null for all those three
  13433. 8:03:57scenarios. And finally, we're going to
  13434. 8:03:59go and replace the nulls with a default
  13435. 8:04:02value, the unknown. So, that's it for
  13436. 8:04:04the three policies. And this is the
  13437. 8:04:06different ways in order to clean up the
  13438. 8:04:08data and bring standards before doing
  13439. 8:04:10analyszis. And now you might ask me,
  13440. 8:04:12okay, which one should I use in my
  13441. 8:04:13project? Like if I want to suggest
  13442. 8:04:15something for the users, which one
  13443. 8:04:17should I use? Well, it really depends on
  13444. 8:04:19the business, but I tried always to
  13445. 8:04:21avoid this one, the policy one, because
  13446. 8:04:23it's always confusing and I have always
  13447. 8:04:25explained for the users. So now we are
  13448. 8:04:27left with the two and three. Well, I use
  13449. 8:04:29both of them in different scenarios. I
  13450. 8:04:31normally go with the policy 2 because it
  13451. 8:04:34takes less storage and as well the
  13452. 8:04:36performance of your queries afterward
  13453. 8:04:38going to be really good. So if I'm doing
  13454. 8:04:40data preparations in my ETL before
  13455. 8:04:42inserting it inside a table, I go with
  13456. 8:04:45the policy too. But in other hand, if
  13457. 8:04:47I'm doing a preparation step before
  13458. 8:04:50showing it in a report like in Tableau
  13459. 8:04:52or PowerBI. So if it is like one of the
  13460. 8:04:54last steps before showing the data to
  13461. 8:04:57the users, I go with the policy 3
  13462. 8:04:59because if you present a null inside a
  13463. 8:05:01report, it's going to be really hard to
  13464. 8:05:03read. So having like a word like
  13465. 8:05:05unknown, it's easier to understand.
  13466. 8:05:07Okay, we have here missing data. So
  13467. 8:05:09again if the data preparations is
  13468. 8:05:11exactly before I present the data to the
  13469. 8:05:13users I go with the policy 3 where I use
  13470. 8:05:16default values but if I'm using a data
  13471. 8:05:19preparations before inserting it in the
  13472. 8:05:21database I go with the policy 2 because
  13473. 8:05:24it's going to optimize the storage and
  13474. 8:05:26it's going to be really bad if you go
  13475. 8:05:28with the policy 3 because it's really
  13476. 8:05:30bad to store the whole world each time
  13477. 8:05:32there is no value like the unknown. it's
  13478. 8:05:34gonna take a lot of space and as well
  13479. 8:05:36you're going to get bad performance as
  13480. 8:05:37you are building the queries. That's why
  13481. 8:05:39I tend to store the data using nulls. If
  13482. 8:05:42you present it to the users go and show
  13483. 8:05:44it as a default value. So as you can see
  13484. 8:05:46it's very important to understand the
  13485. 8:05:47differences between the nulls empty
  13486. 8:05:49strings and blanks and how to prepare
  13487. 8:05:51the data by cleaning up the data and
  13488. 8:05:53bringing standards and policies before
  13489. 8:05:55doing any analyszis. So with this we
  13490. 8:05:57have cleared up the confusion between
  13491. 8:05:59those scenarios and if you encounter it
  13492. 8:06:01in your projects you know how to deal
  13493. 8:06:03with
  13494. 8:06:06it. All right. So now let's have quick
  13495. 8:06:09summary about the nulls. Nulls are
  13496. 8:06:11special markers in SQL in order to say
  13497. 8:06:14there is no value. It is missing. It is
  13498. 8:06:16unknown. So nulls are not equal to zero
  13499. 8:06:19or empty string or any blank spaces. And
  13500. 8:06:22using nulls inside our database is going
  13501. 8:06:24to save some storage and as well provide
  13502. 8:06:27a strong performance in your queries.
  13503. 8:06:29And in scale we have different functions
  13504. 8:06:30in order to handle the nulls. So now if
  13505. 8:06:32you want to replace a null with the
  13506. 8:06:34value we can go either with the function
  13507. 8:06:36kowalis or is null or if you want to do
  13508. 8:06:39the opposite where you want to replace a
  13509. 8:06:41value with null you can go use the
  13510. 8:06:43function null if or in other cases we
  13511. 8:06:45want only to check whether there is
  13512. 8:06:47nulls or not we can use the is null or
  13513. 8:06:50is not null. And we have learned as well
  13514. 8:06:52that we have to treat the nulls
  13515. 8:06:54especially before doing any tasks. So
  13516. 8:06:56that means we have to handle the nulls
  13517. 8:06:58before doing for example data
  13518. 8:07:00aggregations like average, sum, max, min
  13519. 8:07:03and so on. And we have to handle the
  13520. 8:07:05nulls as well before doing any
  13521. 8:07:06mathematical operations like using the
  13522. 8:07:08plus operator to concatenate two
  13523. 8:07:11strings. And in some scenarios as we
  13524. 8:07:13learned we have to handle the nulls as
  13525. 8:07:14well before doing joins. And in other
  13526. 8:07:17cases we have as well to handle the
  13527. 8:07:18nulls before sorting the data. And we
  13528. 8:07:21have learned as well by combining the
  13529. 8:07:23joins and the isnull we introduce new
  13530. 8:07:26types of joins like as we learned the
  13531. 8:07:28left anti- join and the right anti-join
  13532. 8:07:31where we exclude the matching rows using
  13533. 8:07:33the isnull and we can use the null
  13534. 8:07:35functions in order to provide standards
  13535. 8:07:38and data policies in our data like using
  13536. 8:07:41the nulls or using a default values like
  13537. 8:07:43the unknown. All right my friends. So
  13538. 8:07:45with that you have learned how to handle
  13539. 8:07:46the nulls inside your data and now we're
  13540. 8:07:48going to move to a very special topic
  13541. 8:07:50called the case statements. This is very
  13542. 8:07:52important tool in order to do data
  13543. 8:07:54transformations. So let's
  13544. 8:07:59go case statements. It can allow you to
  13545. 8:08:02build a conditional logic in your SQL
  13546. 8:08:04query by evaluating a list of conditions
  13547. 8:08:07one by one and return a value when the
  13548. 8:08:10first condition is met. So now let's
  13549. 8:08:12understand the syntax of the case
  13550. 8:08:13statements and what this
  13551. 8:08:18means. Okay. So now let's see the syntax
  13552. 8:08:20step by step. It start with the keyword
  13553. 8:08:23case. This case indicates now we are
  13554. 8:08:25starting a logic a conditional logic in
  13555. 8:08:27SQL. It's like programming languages as
  13556. 8:08:29you start with the if else. So the if is
  13557. 8:08:32the keyword of a logic and the whole
  13558. 8:08:34logic as well ends with another keyword
  13559. 8:08:36called end. So once SQL sees the end. So
  13560. 8:08:39this is the end of the conditional
  13561. 8:08:41logic. So the case is the start and the
  13562. 8:08:43end is the end. So now what we're going
  13563. 8:08:45to have in between is the conditional
  13564. 8:08:47logics right. So the conditional logic
  13565. 8:08:49start with the keyword when. Now we are
  13566. 8:08:51telling SQL we have a condition to be
  13567. 8:08:53evaluated and then we're going to go and
  13568. 8:08:55specify that conditional logic. So now
  13569. 8:08:58we have to tell SQL what can happen if
  13570. 8:09:00this condition is fulfilled. So now we
  13571. 8:09:03have to use another keyword called then.
  13572. 8:09:05So now we are telling SQL show this
  13573. 8:09:07results if the condition is true. So as
  13574. 8:09:10you can see it's very simple. It's like
  13575. 8:09:11the natural language, right? It's like
  13576. 8:09:13in English when the condition one is met
  13577. 8:09:16then show the results. It's very logic,
  13578. 8:09:18right? And now of course we can go and
  13579. 8:09:19add a second condition inside our case
  13580. 8:09:22statements. So we're going to have the
  13581. 8:09:23same setup. When condition two if this
  13582. 8:09:26is true then show the result number two.
  13583. 8:09:28We specify the keyword when then we have
  13584. 8:09:30a second condition. And if this
  13585. 8:09:32condition is true then we tell SQL to
  13586. 8:09:35show another results. And of course it's
  13587. 8:09:37very important to understand in the
  13588. 8:09:38syntax of that SQL going to go and
  13589. 8:09:40process the conditions from the top to
  13590. 8:09:42the bottom. So the first most important
  13591. 8:09:45condition should be at the start. So SQL
  13592. 8:09:47going to first check this condition. If
  13593. 8:09:50it fails and it's not true then it going
  13594. 8:09:52to go and jump to the second condition.
  13595. 8:09:54So the order of the conditions is very
  13596. 8:09:56important in your logic. And now of
  13597. 8:09:58course we can go and add multiple
  13598. 8:09:59conditions depend on the logic using the
  13599. 8:10:02keyword when. And now once we are done
  13600. 8:10:04defining all the conditions we can go
  13601. 8:10:06and specify an else keyword. The else
  13602. 8:10:09can introduce the default value and it
  13603. 8:10:11is optional. You can go and skip it. So
  13604. 8:10:13the value of the else or the default
  13605. 8:10:15going to be used only if all the
  13606. 8:10:18condition failed. So that means all our
  13607. 8:10:20conditions are not true and nothing is
  13608. 8:10:22fulfilled then SQL going to go and use
  13609. 8:10:24the value from the else. So it is the
  13610. 8:10:27default value that's going to be used if
  13611. 8:10:29all conditions are false. So those are
  13612. 8:10:31the keywords that you must use inside
  13613. 8:10:33each case statement. So we have case
  13614. 8:10:35when then and only the else is an
  13615. 8:10:39optional. So you can go and use it or
  13616. 8:10:41skip it. So this is the main structure
  13617. 8:10:43and the syntax of each case
  13618. 8:10:48statement. Now let's have a very simple
  13619. 8:10:50example in order to understand how SQL
  13620. 8:10:53execute the case statements behind the
  13621. 8:10:55scenes. All right, let's have this very
  13622. 8:10:56simple example where we have only one
  13623. 8:10:58condition. So as you can see in the
  13624. 8:11:00syntax, it starts with case and end and
  13625. 8:11:03then we have only one condition and we
  13626. 8:11:05are evaluating here the sales. So the
  13627. 8:11:07condition says if the sales is higher
  13628. 8:11:10than 50 then show as a result the value
  13629. 8:11:13of high. So it's very simple only one
  13630. 8:11:15condition and on the right side we have
  13631. 8:11:16here a flowchart in order to understand
  13632. 8:11:18how the logic is executed. And now what
  13633. 8:11:20we're going to do, we're going to go and
  13634. 8:11:21evaluate those four sales through this
  13635. 8:11:24logic and see what the output going to
  13636. 8:11:26be with the case statement. So let's do
  13637. 8:11:28it one by one. Let's start with the
  13638. 8:11:30first sales. It is 60. So here we're
  13639. 8:11:32going to go and check is 60 higher than
  13640. 8:11:3550. Well, yes. That means this sales is
  13641. 8:11:38meeting this condition and we will get
  13642. 8:11:41true and we're going to get in the
  13643. 8:11:42output the value of high. So here we're
  13644. 8:11:45going to get the value high in the
  13645. 8:11:47output. So that means the first sales is
  13646. 8:11:50fulfilling the requirement the condition
  13647. 8:11:52and SQL going to give us the value from
  13648. 8:11:54this condition. All right. So now SQL
  13649. 8:11:55going to go to the next value and we're
  13650. 8:11:57going to start evaluating the 30. Now
  13651. 8:11:59we're going to ask the same question the
  13652. 8:12:00same condition is 30 higher than 50.
  13653. 8:12:03Well no. So that means in the output for
  13654. 8:12:06this condition we will get false. So we
  13655. 8:12:09will take the path of the false. Now if
  13656. 8:12:11you take the path of the false we will
  13657. 8:12:13not get any value. Right? So that means
  13658. 8:12:15the output going to be a null. So the
  13659. 8:12:18output for the 30 is null. And that's
  13660. 8:12:21because we didn't define in our logic
  13661. 8:12:23anything about the default option. So we
  13662. 8:12:25don't have here an else. And this is
  13663. 8:12:27what going to happen. If you don't use
  13664. 8:12:28else, you will get a null in the output
  13665. 8:12:31for the case statement. So now let's
  13666. 8:12:32move to the next one. It's going to be
  13667. 8:12:34the same thing. So 15 is smaller than
  13668. 8:12:3750. So it's not fulfilling the
  13669. 8:12:39condition. And as well we're going to
  13670. 8:12:41get a null. And for the last one since
  13671. 8:12:43it's null we will get as well a null
  13672. 8:12:45since it will not fulfill the condition.
  13673. 8:12:47So now after evaluating all those sales
  13674. 8:12:49only the first sales is fulfilling that
  13675. 8:12:52condition and that's why we have only
  13676. 8:12:54one value the high. All right. So now
  13677. 8:12:55let's keep moving and adding stuff to
  13678. 8:12:57our case statements. Now we are adding a
  13679. 8:12:59second condition. So it says after
  13680. 8:13:02checking the sales whether it's higher
  13681. 8:13:03than 50 and it fails check again the
  13682. 8:13:06sales whether it's higher than 20. If
  13683. 8:13:08yes then show the value of medium. So
  13684. 8:13:11now in our workflow we are adding a
  13685. 8:13:13second condition to be checked if the
  13686. 8:13:16first one is false. So now let's go and
  13687. 8:13:18evaluate our sales again and check the
  13688. 8:13:20output the first one the 60. So as you
  13689. 8:13:22can see the 60 is higher than 50. So we
  13690. 8:13:25are fulfilling the first requirement
  13691. 8:13:27that's why we will get the value of
  13692. 8:13:29high. So it's same like before. So here
  13693. 8:13:31we're going to get high in the output.
  13694. 8:13:33And now here very important to
  13695. 8:13:35understand one thing is that SQL didn't
  13696. 8:13:37evaluate here in this scenario the
  13697. 8:13:40second condition. So SQL didn't waste
  13698. 8:13:42any time by checking the other
  13699. 8:13:43condition. It skipped everything once it
  13700. 8:13:45get a true from one condition. So this
  13701. 8:13:48is exactly how SQL process the case win.
  13702. 8:13:50It going to check each conditions from
  13703. 8:13:52top to down and once it finds a true
  13704. 8:13:56it's going to stop everything
  13705. 8:13:57immediately and throw the value from
  13706. 8:13:58this condition and it will not evaluate
  13707. 8:14:01any other conditions. So now it's going
  13708. 8:14:03to go and jump to the next value. We are
  13709. 8:14:05at the value of 30. So let's evaluate
  13710. 8:14:07the conditions. Is 30 higher than 50?
  13711. 8:14:10Well, it's not. So it's false. So now
  13712. 8:14:12what can happen is going to go and jump
  13713. 8:14:14to the next condition and start
  13714. 8:14:15evaluating the second one whether it's
  13715. 8:14:17true or false. So now we're going to
  13716. 8:14:19check here. Is 30 higher than 20? Well,
  13717. 8:14:21yes. So it's going to be fulfilled and
  13718. 8:14:24we will get the value of medium. So it's
  13719. 8:14:27going to stop everything and show in the
  13720. 8:14:28output for this value the medium. So
  13721. 8:14:32we're going to get medium here. So in
  13722. 8:14:34this scenario, we have evaluated both of
  13723. 8:14:36the conditions that we have in the case
  13724. 8:14:38statement. Now it's going to go to the
  13725. 8:14:40third one. We have 15. Is 15 higher than
  13726. 8:14:4250? Will no. So we will get to false for
  13727. 8:14:45the first condition. Then it's going to
  13728. 8:14:47go and jump to the second condition and
  13729. 8:14:48check it. Is 15 higher than 20? Will as
  13730. 8:14:52well no. So now what going to happen?
  13731. 8:14:54The false going to be activated over
  13732. 8:14:55here. And we will not get any value as a
  13733. 8:14:58return. So we will get the value of null
  13734. 8:15:01in the output. And now for the last one
  13735. 8:15:03we have null. We will get as well null
  13736. 8:15:05because it will not fulfill any of those
  13737. 8:15:08conditions and that's because we didn't
  13738. 8:15:10define an else in the case statement. So
  13739. 8:15:12if we define these conditions like this,
  13740. 8:15:14we will get the category medium for the
  13741. 8:15:1730. And this is how SQL evaluate
  13742. 8:15:19multiple conditions in the case
  13743. 8:15:21statement. All right. Now we're going to
  13744. 8:15:22go to the final form of our case
  13745. 8:15:24statements and we're going to go and add
  13746. 8:15:26an else. So we're going to have a
  13747. 8:15:28default value. So we are seeing here if
  13748. 8:15:29the sales is not higher than 50 or
  13749. 8:15:31higher than 20 then show a default value
  13750. 8:15:34as low. So that means any sales that is
  13751. 8:15:37equal or smaller than 20 going to get
  13752. 8:15:39the value of low. And now very
  13753. 8:15:41interesting if you check the workflow
  13754. 8:15:42over here you can see that we have now a
  13755. 8:15:45value for each path. So for the first
  13756. 8:15:47condition we're going to get high for
  13757. 8:15:48the second one medium. And if nothing is
  13758. 8:15:51fulfilled we're going to get always the
  13759. 8:15:53value of low. So there is no way in this
  13760. 8:15:55chart to get any nulls. Right? So let's
  13761. 8:15:58go and evaluate again our values. I
  13762. 8:16:00think you already get it. The 60 is
  13763. 8:16:02fulfilling the first requirement and SQL
  13764. 8:16:04going to stop everything immediately and
  13765. 8:16:06just show the value of high. So on the
  13766. 8:16:09right side over here nothing going to be
  13767. 8:16:10evaluated because the first condition is
  13768. 8:16:13true. So here in the output we're going
  13769. 8:16:15to get the value of high. So nothing
  13770. 8:16:17changed like the two previous examples.
  13771. 8:16:19Now it's going to go to the next value.
  13772. 8:16:21We have the 30. So we're going to
  13773. 8:16:23evaluate the first one. It's going to be
  13774. 8:16:24false. The next one it's higher than 20.
  13775. 8:16:28It is true. And that's why is still
  13776. 8:16:30going to show the value of medium. And
  13777. 8:16:32this is as well. We had it in the
  13778. 8:16:34previous example. So medium. So now
  13779. 8:16:37scale going to move to the next one. And
  13780. 8:16:38here things going to get interesting. So
  13781. 8:16:40the value of 15. We're going to evaluate
  13782. 8:16:42the first condition. Is it higher than
  13783. 8:16:4450? Well, no. Is it higher than 20?
  13784. 8:16:46Well, no. So now we are in scenario
  13785. 8:16:48where none of those conditions are true.
  13786. 8:16:51So that's why SQL going to go and
  13787. 8:16:53execute the else. So if you check our
  13788. 8:16:56chart it's going to be false and we will
  13789. 8:16:58get the value of low. So in the output
  13790. 8:17:01we will not get this time a null because
  13791. 8:17:04we have else we will get the value of
  13792. 8:17:06low. The same thing now for the null.
  13793. 8:17:08Null will not fulfill the first
  13794. 8:17:10condition as well the second condition
  13795. 8:17:12and that's why we will get as well the
  13796. 8:17:15value from the else. So here in the
  13797. 8:17:17output we will get as well the value of
  13798. 8:17:19low. So now as you can see if you use an
  13799. 8:17:21else inside the case statements you will
  13800. 8:17:24make sure that there will be no nulls in
  13801. 8:17:26the output. So that you have learned the
  13802. 8:17:28different options that we have inside
  13803. 8:17:30the case statements and how skill
  13804. 8:17:32execute the case behind the
  13805. 8:17:37scenes. All right friends so now we come
  13806. 8:17:40to the part where I'm going to show you
  13807. 8:17:41the most useful use cases of the case
  13808. 8:17:44statements that I usually use in my
  13809. 8:17:46projects. So let's start. The main
  13810. 8:17:48purpose of the case statement is to do
  13811. 8:17:50data transformations. And data
  13812. 8:17:52transformations is very important
  13813. 8:17:53process in each data project. And one
  13814. 8:17:56very important task in data
  13815. 8:17:57transformations is that we can generate
  13816. 8:17:59new informations. We can go and create
  13817. 8:18:01new columns based on the existing data
  13818. 8:18:04that we have in the database using the
  13819. 8:18:06case statements and this of course can
  13820. 8:18:08help us deriving new informations for
  13821. 8:18:10our analyzes without modifying the
  13822. 8:18:12source database only for analytics. So
  13823. 8:18:15my friends, the main purpose of the case
  13824. 8:18:17statement is to do data transformations
  13825. 8:18:20by creating and generating new columns.
  13826. 8:18:22So now let's start with the first use
  13827. 8:18:24case and the most important and famous
  13828. 8:18:26one is we use case statement in order to
  13829. 8:18:29categorize the data. This means we are
  13830. 8:18:31going to group up the data into
  13831. 8:18:33different categories based on certain
  13832. 8:18:35conditions. And now you might ask why
  13833. 8:18:36this use case is important. Well,
  13834. 8:18:39classifying and grouping data is
  13835. 8:18:41fundamental in data analysis and
  13836. 8:18:43reporting because it makes the data
  13837. 8:18:45easier to understand and as well to
  13838. 8:18:47track. But what's more important, it
  13839. 8:18:49going to help us aggregating the data
  13840. 8:18:51based on the categories. All right. So
  13841. 8:18:53now let's have the following task. And
  13842. 8:18:54it says generate a report showing total
  13843. 8:18:58sales for each of the following
  13844. 8:18:59categories. category high if the sales
  13845. 8:19:01is over 50. Category medium if the sales
  13846. 8:19:04is between 20 and 50 and low if the
  13847. 8:19:07sales is 20 or less and sort the
  13848. 8:19:10categories from the highest sales to the
  13849. 8:19:12lowest. Okay, so let's do it step by
  13850. 8:19:14step. And now before we do any data
  13851. 8:19:15aggregations, we have to go and create a
  13852. 8:19:17new column called categories because we
  13853. 8:19:19don't have it in the database. So now
  13854. 8:19:21let's start with very simple select
  13855. 8:19:23statements. So select what do we need?
  13856. 8:19:25Let's take the order ID, the sales and
  13857. 8:19:28that's it for now. So from sales orders
  13858. 8:19:32let's go and execute it. And now we have
  13859. 8:19:34our 10 orders and we have to go and now
  13860. 8:19:36create a new column called categories.
  13861. 8:19:39And we're going to do that using the
  13862. 8:19:40case statements. So let's take a new
  13863. 8:19:43line and we start with case and then
  13864. 8:19:45again a new line in order to define the
  13865. 8:19:47first condition using the when. So the
  13866. 8:19:49first condition is the high where sales
  13867. 8:19:52is over 50. So it's very simple. So when
  13868. 8:19:55the sales is higher than 50, what can
  13869. 8:19:58happen if this is true? We want to show
  13870. 8:20:00the value high. So this is the first
  13871. 8:20:03condition. And then let's move to the
  13872. 8:20:05second one. If the sales is higher than
  13873. 8:20:0920, that means it's less than 50 and
  13874. 8:20:12higher than 20, then we want to see the
  13875. 8:20:15value medium. And now for the last
  13876. 8:20:17category, the low, we don't have to go
  13877. 8:20:19and create a condition for that because
  13878. 8:20:21if those two fails, then that means that
  13879. 8:20:23the sales either equal to 20 or less. So
  13880. 8:20:25what we're going to do, we're going to
  13881. 8:20:26just do a simple else and show the value
  13882. 8:20:29low like this. Let me make this a little
  13883. 8:20:32bit smaller. Now what is missing in our
  13884. 8:20:35case is of course the end. Without it,
  13885. 8:20:37you're going to get an error. So end and
  13886. 8:20:39let's give it a name
  13887. 8:20:40category. So we are ready. Let's go and
  13888. 8:20:43execute it. So now let's check randomly
  13889. 8:20:45stuff. So as you can see here we have
  13890. 8:20:46the sales of 50 it is low which is
  13891. 8:20:49correct and then we have here 60 it's
  13892. 8:20:51above 50 and we have the category high
  13893. 8:20:53and now if you check the order number
  13894. 8:20:54six we have the order 50 it's medium
  13895. 8:20:57because it is not higher than 50 it is
  13896. 8:21:00between 50 and 20. So now as you can see
  13897. 8:21:02we have now classified our orders using
  13898. 8:21:05the category. Now the next step that
  13899. 8:21:07we're going to go and aggregate the
  13900. 8:21:08data. So how we going to do that? We
  13901. 8:21:10will use a subquery. So let's do it like
  13902. 8:21:13this. So we're going to go and select
  13903. 8:21:14and of course we're going to group up
  13904. 8:21:15the data by the category. So we're going
  13905. 8:21:17to go and select that category and we
  13906. 8:21:20need the total sales. That means we're
  13907. 8:21:22going to go and use the function sum for
  13908. 8:21:24the sales and we're going to call it
  13909. 8:21:26total sales. So now we have to nest the
  13910. 8:21:29queries together. So from this is our
  13911. 8:21:33query like this and then we have to
  13912. 8:21:36close it and group by. So we are
  13913. 8:21:39grouping by the category. Okay. So with
  13914. 8:21:42that we are now aggregating the sales by
  13915. 8:21:45that category. It's very simple. Let's
  13916. 8:21:47go and execute it. So now in the result
  13917. 8:21:49we have only three categories. We don't
  13918. 8:21:50have the 10 orders because now we are
  13919. 8:21:52doing data aggregations. So now the
  13920. 8:21:54granularity now on the level of
  13921. 8:21:56category. So now we can see the total
  13922. 8:21:58sales for the high is 2010. The low we
  13923. 8:22:01have 65 and the medium we have 105. And
  13924. 8:22:04of course we are not done yet because in
  13925. 8:22:05the task it says sort the categories
  13926. 8:22:08from the highest sales to the lowest.
  13927. 8:22:10That means we have to go and use an
  13928. 8:22:12order by statement at the end and we're
  13929. 8:22:14going to sort the data by the sales from
  13930. 8:22:16the highest to the lowest. That means
  13931. 8:22:18descending. So that's it. Let's go and
  13932. 8:22:20execute it. And now with that we have
  13933. 8:22:22our reports. Now we are showing the
  13934. 8:22:24total sales by the categories and the
  13935. 8:22:25data is sorted from the highest to the
  13936. 8:22:27lowest. So the highest category is high
  13937. 8:22:30then medium and then the last one is
  13938. 8:22:32low. So my friends as you can see with
  13939. 8:22:34the help of the case win we have created
  13940. 8:22:36the new informations from our data we
  13941. 8:22:38have the category and then we have
  13942. 8:22:39created insights or report based on this
  13943. 8:22:42new informations where we have
  13944. 8:22:44aggregated our data using this new
  13945. 8:22:46information. So the use case of
  13946. 8:22:48categorizing data using case statements
  13947. 8:22:49is fundamental and very important in
  13948. 8:22:52each data
  13949. 8:22:56project. Okay. Okay. So now one more
  13950. 8:22:58thing before we jump to the next use
  13951. 8:22:59case is that there is one rule to follow
  13952. 8:23:01if you are using case statements and
  13953. 8:23:03that is the data types of the result
  13954. 8:23:06must be matching. So what this means if
  13955. 8:23:08we check again our example over here we
  13956. 8:23:10can see that the result of each
  13957. 8:23:12condition is a string. So as you can see
  13958. 8:23:14we have here high, medium and low and
  13959. 8:23:16all of those informations are following
  13960. 8:23:18the same data type. So it is correct. So
  13961. 8:23:20now if I go and break this rule for
  13962. 8:23:22example after this then let's have the
  13963. 8:23:25value two. So now we have a number and
  13964. 8:23:27we have characters. So let's go and
  13965. 8:23:29execute it. And now of course we're
  13966. 8:23:30going to get an error because now SSQL
  13967. 8:23:32is trying to convert the value low to an
  13968. 8:23:35integer which is incorrect. So the data
  13969. 8:23:37types of the output of the result must
  13970. 8:23:40be matching and that's not only include
  13971. 8:23:42the value after the then but also the
  13972. 8:23:45value after the else because this value
  13973. 8:23:48is as well part of the output. So let's
  13974. 8:23:50have here again medium. And now let's go
  13975. 8:23:52and change this to let's say one. So
  13976. 8:23:55let's go and excuse it again. Isl going
  13977. 8:23:57to throw an error because this is an
  13978. 8:23:59integer in number and the others are
  13979. 8:24:01string characters. So this is the rule
  13980. 8:24:03of using the case statement. The data
  13981. 8:24:05types after then and after else must be
  13982. 8:24:07matching. And if you ask me whether
  13983. 8:24:09there is restriction about where you can
  13984. 8:24:11use the case statement in which clauses
  13985. 8:24:13you can use it everywhere in select, in
  13986. 8:24:15joins, from, where, group by, order by,
  13987. 8:24:19everywhere. So there are no restrictions
  13988. 8:24:21and we have only this one rule.
  13989. 8:24:27Okay friends, another use case for the
  13990. 8:24:28case statement. We can use it in order
  13991. 8:24:30to map values. So we can use the case
  13992. 8:24:33statement in order to transform the data
  13993. 8:24:35from one form to another in order to
  13994. 8:24:37make it more readable and more usable
  13995. 8:24:39for analytics. One scenario of mapping
  13996. 8:24:41values is that sometimes the database
  13997. 8:24:43developers stores the data and values
  13998. 8:24:46inside the database as codes and as
  13999. 8:24:48flags. So for example, the status of the
  14000. 8:24:50order could be stored as one and zero
  14001. 8:24:53instead of having inactive and active.
  14002. 8:24:56And this is one technique in order to
  14003. 8:24:57optimize the performance of the database
  14004. 8:24:59for the application because one and zero
  14005. 8:25:01is way faster than storing the whole
  14006. 8:25:04string. But in data analyzes, we usually
  14007. 8:25:06generate a report to be read by human by
  14008. 8:25:08persons. And now instead of showing the
  14009. 8:25:11data as zero and one, it's going to be
  14010. 8:25:12more nicer and readable if you show the
  14011. 8:25:15data as active and inactive. So for
  14012. 8:25:17these scenarios, we're going to go and
  14013. 8:25:18use the case statement in order to
  14014. 8:25:20translate those cryptical and technical
  14015. 8:25:23values into readable terms. Otherwise,
  14016. 8:25:26each one going to consume your report.
  14017. 8:25:27Going to ask you what do you mean with
  14018. 8:25:29the zero and one. Let's have the
  14019. 8:25:30following task and it says retrieve
  14020. 8:25:32employee details with gender displayed
  14021. 8:25:35as full text. Okay. So now let's go and
  14022. 8:25:37solve it. First we're going to go and
  14023. 8:25:38explore few informations. So let's go
  14024. 8:25:41and show the employee
  14025. 8:25:42ID and let's take the first name, last
  14026. 8:25:46name and we need the gender
  14027. 8:25:48informations. So gender from sales
  14028. 8:25:52employees. So that's it. Let's go and
  14029. 8:25:55execute it. So now as you can see in the
  14030. 8:25:57result we got our five employees and now
  14031. 8:25:59the gender informations are stored as
  14032. 8:26:01only one character F and M. And of
  14033. 8:26:04course it's easy to understand that the
  14034. 8:26:05F is female and M is male. but we would
  14035. 8:26:08like to show it in the report as a full
  14036. 8:26:10text. So, female and male instead of
  14037. 8:26:13those abbreviations. So, in order to do
  14038. 8:26:15that, we're going to go and use the case
  14039. 8:26:17statement in order to do the mapping
  14040. 8:26:19between the old value and the new value.
  14041. 8:26:21So, let's go and create a new column
  14042. 8:26:23using the case. So, we're going to have
  14043. 8:26:25here two conditions because we have two
  14044. 8:26:26values. Let's start with the first one.
  14045. 8:26:28So, we're going to have a new line and
  14046. 8:26:30when. So when the gender equals to f
  14047. 8:26:34ladies first then female and now for the
  14048. 8:26:38second value it's going to be exactly
  14049. 8:26:39the same when gender equal to m then
  14050. 8:26:44we're going to have male be careful for
  14051. 8:26:47the case sensitivity of the values. So
  14052. 8:26:49of course we will not end this without
  14053. 8:26:51an else. So else then we can have the
  14054. 8:26:53default value. We're going to have the
  14055. 8:26:55default value not available. It's better
  14056. 8:26:57than having nulls. So what we are
  14057. 8:27:00missing is the end. So we're going to
  14058. 8:27:02have an end over here and we're going to
  14059. 8:27:04call you gender full text. So that's it.
  14060. 8:27:08Let's go and execute it. Now if you
  14061. 8:27:10check the results, we have now done the
  14062. 8:27:12mapping between the old format of the
  14063. 8:27:14value with the new format. So instead of
  14064. 8:27:16m we have males and females. And of
  14065. 8:27:18course we don't have here any nulls.
  14066. 8:27:20That's why we don't have a not available
  14067. 8:27:22in the data. But if you have huge data
  14068. 8:27:24of course you can have somewhere a null
  14069. 8:27:26and then you will get this default
  14070. 8:27:28value. So this is how you can do mapping
  14071. 8:27:30between values very easily using the
  14072. 8:27:32case statements. Okay let's have another
  14073. 8:27:34task for the mapping use case and the
  14074. 8:27:36task says retrieve employee details with
  14075. 8:27:39abbreviated country code. Sometimes as
  14076. 8:27:41we are generating reports maybe using
  14077. 8:27:42PowerBI or Tableau we don't have enough
  14078. 8:27:45spaces in order to use the full name of
  14079. 8:27:48values. So what do we need? We need
  14080. 8:27:50abbreviations. we need short form of the
  14081. 8:27:52values and we can go and use in SQL the
  14082. 8:27:55case statement in order to map the full
  14083. 8:27:57value to an abbreviated value. So it's
  14084. 8:28:00like the previous example but the way
  14085. 8:28:02around. All right. So now let's go and
  14086. 8:28:03solve it. We're going to go and select
  14087. 8:28:04few details like the customer ID. Let's
  14088. 8:28:07take the first name, last name and what
  14089. 8:28:10do we need? We need the country
  14090. 8:28:12information from sales customers. So
  14091. 8:28:15that's it. Let's go and execute it. And
  14092. 8:28:18now as you can see we get our five
  14093. 8:28:19customers and we have the country
  14094. 8:28:21informations as a full name. Now of
  14095. 8:28:23course for the report we need
  14096. 8:28:24abbreviated values from this. So we're
  14097. 8:28:26going to go and map those full names of
  14098. 8:28:28the countries to a short form. But in
  14099. 8:28:30real project you might get big tables
  14100. 8:28:32where you have thousands and millions of
  14101. 8:28:34records. So you cannot just check it
  14102. 8:28:36like this. So how I usually do it I go
  14103. 8:28:38and retrieve a distinct list of all
  14104. 8:28:40values from one column. So I usually go
  14105. 8:28:42and have a separate query for that. So
  14106. 8:28:45we're going to have select distinct
  14107. 8:28:48country from the table sales customers.
  14108. 8:28:51It's just for me to see all the possible
  14109. 8:28:53values inside the database. So now you
  14110. 8:28:55see the second result over here. We have
  14111. 8:28:56only two values Germany and USA. And
  14112. 8:28:58then I can go and map the data
  14113. 8:29:00correctly. So always if you are mapping
  14114. 8:29:02data using the case win you have to
  14115. 8:29:04understand all the possible values that
  14116. 8:29:06you have inside the table. So let's go
  14117. 8:29:08and generate this new informations.
  14118. 8:29:10Let's start with case and then you line
  14119. 8:29:13when country equal to the first value.
  14120. 8:29:16It's going to be Germany. Make sure you
  14121. 8:29:18write it exactly like in the database.
  14122. 8:29:20The first character is capital and the
  14123. 8:29:22rest is small. So what happened? We're
  14124. 8:29:25going to have the abbreviation of
  14125. 8:29:27Germany. It's going to be de. All right.
  14126. 8:29:29So this is for the first value. And then
  14127. 8:29:30let's move to the second one. It's going
  14128. 8:29:32to be country equal to USA. It's already
  14129. 8:29:36abbreviated but maybe we can get only
  14130. 8:29:39two characters.
  14131. 8:29:40So us like this. And now let's go and
  14132. 8:29:43add an else. It's optional but in case
  14133. 8:29:45that we have nulls in the data or we get
  14134. 8:29:47a new value. So else it's not available.
  14135. 8:29:50So na. So that's it. And never forget
  14136. 8:29:53about the end. So end. And the name
  14137. 8:29:56going to be country abbreviation. So
  14138. 8:29:59that's it. Let me just get rid of the
  14139. 8:30:01other query. So the mapping is correct.
  14140. 8:30:04Let's go and execute it. And now if you
  14141. 8:30:06check the results, we got a new column
  14142. 8:30:08called country abbreviation. And as you
  14143. 8:30:10can see now the mapping is working. Here
  14144. 8:30:12we have Germany and we have here DE and
  14145. 8:30:14for the USA we have US. So with that we
  14146. 8:30:17have solved the task and we done the
  14147. 8:30:18mapping correctly between the old value
  14148. 8:30:20and the new
  14149. 8:30:24value. All right friends, now there is
  14150. 8:30:26special case for the syntax of the case
  14151. 8:30:28statements if you are using it for
  14152. 8:30:31mapping values. So now let's go and
  14153. 8:30:32check it. So now let's say that we have
  14154. 8:30:34a lot of different distinct values
  14155. 8:30:35inside the country not only to values
  14156. 8:30:37you have a lot of values and if you are
  14157. 8:30:39mapping the values using the case when
  14158. 8:30:41you're going to end up always writing
  14159. 8:30:42the same thing country equal Germany
  14160. 8:30:45country equal India country equal United
  14161. 8:30:47States and so on. So we are always using
  14162. 8:30:49the column country. So the conditions
  14163. 8:30:51over here using always one column and
  14164. 8:30:54it's always the operator is equal. So
  14165. 8:30:57now only for this scenario we have
  14166. 8:30:59another syntax for the case statements
  14167. 8:31:01and it looks like this. We start with
  14168. 8:31:03the keyword case but after that
  14169. 8:31:05immediately we're going to use the
  14170. 8:31:07column that we want to evaluate and here
  14171. 8:31:09you can use only one column you cannot
  14172. 8:31:11use multiple columns. So now we are
  14173. 8:31:13telling SQL we are now evaluating one
  14174. 8:31:15column the country and then for each
  14175. 8:31:18condition we have the following stuff we
  14176. 8:31:19say when Germany that means when country
  14177. 8:31:22is equal to Germany then de so as you
  14178. 8:31:25can see here we don't have here the
  14179. 8:31:26whole condition we have only a possible
  14180. 8:31:29value that we can see inside the
  14181. 8:31:31country. So we are saying is the value
  14182. 8:31:34country if it's true then show de the
  14183. 8:31:36next one is it India then en United
  14184. 8:31:39States US and so on. So we call this
  14185. 8:31:41syntax a quick form of the case
  14186. 8:31:43statements and on the left side we call
  14187. 8:31:45it full form of the case statements and
  14188. 8:31:47of course the restriction and limitation
  14189. 8:31:50using the quick format is that you can
  14190. 8:31:52use only one column and it's only for
  14191. 8:31:55the equal operator. So that means only
  14192. 8:31:57for these scenarios you can go and use
  14193. 8:31:59the quick format. If things get a little
  14194. 8:32:01bit complicated where you have to mix
  14195. 8:32:03and make complex logic, you cannot use
  14196. 8:32:05the quick formats. So I would say if you
  14197. 8:32:06are sure that the logic will not get
  14198. 8:32:08complicated and you can stay always with
  14199. 8:32:10the same column, you can go with the
  14200. 8:32:12quick format. But I would recommend
  14201. 8:32:13always to go with the full format
  14202. 8:32:15because for one simple reason if you add
  14203. 8:32:17one small logic you have to go and
  14204. 8:32:19rewrite the whole case statements back
  14205. 8:32:22to the full format in order to add any
  14206. 8:32:24small logic. But of course there is
  14207. 8:32:26nothing wrong using the quick form in
  14208. 8:32:28order to do the case statements if the
  14209. 8:32:30logic can stay static and you are sure
  14210. 8:32:32we are using only one column and we are
  14211. 8:32:34just doing mapping. There is no any
  14212. 8:32:36extra logic. Okay. So now let's try this
  14213. 8:32:37quick format for the case statement for
  14214. 8:32:39the previous example. So I will just go
  14215. 8:32:41and copy everything to a new column. So
  14216. 8:32:44I'm just going to rename it to two. And
  14217. 8:32:46now how we going to do it? So it's going
  14218. 8:32:49to be case but this time we're going to
  14219. 8:32:51write country and then inside the wind
  14220. 8:32:54we will have only the values. So no need
  14221. 8:32:57for the condition. So it's going to be
  14222. 8:32:59like this. Let me scroll up. So that's
  14223. 8:33:01it. As you can see it's smaller and
  14224. 8:33:03quicker than writing the whole condition
  14225. 8:33:05each time. So now let's go and execute
  14226. 8:33:08this. And as you can see in the result
  14227. 8:33:09we're going to get identical values. So
  14228. 8:33:11now you know one more trick in the case
  14229. 8:33:13statement.
  14230. 8:33:18All right, moving on to the next use
  14231. 8:33:19case for the case statements. We can use
  14232. 8:33:21it in order to handle nulls. Handling
  14233. 8:33:23nulls means replace a null with a value.
  14234. 8:33:26And as we learned before with the window
  14235. 8:33:27aggregate functions, sometimes nulls
  14236. 8:33:29leads to incorrect calculations and
  14237. 8:33:32results which leads to wrong decision-m.
  14238. 8:33:34We're going to have later a dedicated
  14239. 8:33:36chapter on how to handle nulls in SQL.
  14240. 8:33:38But now we're going to learn how to
  14241. 8:33:39handle nulls using case statements. So
  14242. 8:33:42now let's have the following task and it
  14243. 8:33:43says find the average scores of
  14244. 8:33:46customers and treat nulls as zero and
  14245. 8:33:48additionally provide details such as
  14246. 8:33:50customer ID and the last name. Okay. So
  14247. 8:33:52now let's solve it step by step and
  14248. 8:33:54again we have here details and as well
  14249. 8:33:56we have to do aggregations that means we
  14250. 8:33:57have to go and use the window functions
  14251. 8:33:59and we don't have to forget that we have
  14252. 8:34:01to treat the null so we have to handle
  14253. 8:34:02it. So now let's go and start with very
  14254. 8:34:05simple uh select. So select
  14255. 8:34:08customer ID we need the last name and as
  14256. 8:34:12well we need the scores. So from sales
  14257. 8:34:16customers let's go and execute it. So as
  14258. 8:34:19usual we have our five customers and the
  14259. 8:34:21scores. And here we have a null. Now
  14260. 8:34:22we're going to go and write the window
  14261. 8:34:24function but without handling the nulls
  14262. 8:34:26just in order to see the differences. So
  14263. 8:34:28we need the average function for what
  14264. 8:34:31for the scores. Do we have to now
  14265. 8:34:33partition the data? Well no. So we're
  14266. 8:34:35going to leave it as empty. We need the
  14267. 8:34:37average score of all customers. So
  14268. 8:34:39that's it. Let's go and give it a name
  14269. 8:34:42and then execute it. I think I have here
  14270. 8:34:44mistake. So it is a score not scores. So
  14271. 8:34:46and now as you can see we have the
  14272. 8:34:48average of 625. And as you learned
  14273. 8:34:50before SQL going to go and summarize all
  14274. 8:34:53those four values and divide it by four.
  14275. 8:34:55But our business understand the nulls as
  14276. 8:34:57zero not as missing information. So we
  14277. 8:34:59have to go and handle the null. Let's go
  14278. 8:35:02and create a new column for the scores.
  14279. 8:35:05But this time we're going to go and use
  14280. 8:35:07the case statements. It's going to be
  14281. 8:35:09very simple. So we're going to say when
  14282. 8:35:12the score is null. So in SQL we don't
  14283. 8:35:15write equal null, we say is null. So
  14284. 8:35:18with that we are replacing the nulls
  14285. 8:35:20with zero. Right? So now otherwise what
  14286. 8:35:23can happen? So if it's not null so we
  14287. 8:35:25need the score as it is. We should not
  14288. 8:35:27manipulate anything. So the default
  14289. 8:35:30value is the score itself if the score
  14290. 8:35:32is not null. So now let's go and end it
  14291. 8:35:35and let's call it score clean. So let's
  14292. 8:35:39go and execute it. Now if you check the
  14293. 8:35:41result over here, it's like almost
  14294. 8:35:43identical as the score. So we don't have
  14295. 8:35:45any new values for the scores but only
  14296. 8:35:48the nulls now are zero and all other
  14297. 8:35:50values they are not affected. So we
  14298. 8:35:52didn't touch it. We didn't transform it
  14299. 8:35:54at all. So this is what do we mean with
  14300. 8:35:56handling nulls replacing nulls with
  14301. 8:35:58another value. So now in order to finish
  14302. 8:35:59the task we have to do the average for
  14303. 8:36:01the score clean and not for the original
  14304. 8:36:04score. So how we going to do it? Let's
  14305. 8:36:05go and copy the whole case statements.
  14306. 8:36:07I'm just going to do it in another
  14307. 8:36:09column. So let's have an average and
  14308. 8:36:12inside it we have the case statements
  14309. 8:36:14like this. Let me just sort it like
  14310. 8:36:17this. And now what is missing is the
  14311. 8:36:19over and it's going to be empty. So
  14312. 8:36:23average customer let's call it clean. So
  14313. 8:36:26this is the logic. Let me just make
  14314. 8:36:28everything smaller. So now as you can
  14315. 8:36:30see it's exactly like the previous one
  14316. 8:36:32but instead of using the original score
  14317. 8:36:35now we are using the column that we have
  14318. 8:36:38created. But of course we don't need the
  14319. 8:36:39alias over here. So we have to remove
  14320. 8:36:41it. So it start with case and end. So
  14321. 8:36:44let's go and execute it. And now you can
  14322. 8:36:46see in the output we got a new value for
  14323. 8:36:49the average and it is more accurate for
  14324. 8:36:51the business. So now we have 500.
  14325. 8:36:53Previously we had
  14326. 8:36:54625. So as you can see you have to
  14327. 8:36:56understand what the nulls means in your
  14328. 8:36:58business and handle it correctly.
  14329. 8:37:00Otherwise you will get wrong results. So
  14330. 8:37:02that's it. We use case statements in
  14331. 8:37:04order to handle the nulls inside our
  14332. 8:37:07data.
  14333. 8:37:10Conditional aggregations means we're
  14334. 8:37:12going to go and apply an aggregate
  14335. 8:37:13function in SQL like some average count
  14336. 8:37:16but this time only on a subset of data
  14337. 8:37:19that meet specific conditions. This
  14338. 8:37:22technique is amazing in order to do deep
  14339. 8:37:24dive analyzes or target analyzes on a
  14340. 8:37:27specific subset of the data. So now
  14341. 8:37:29let's have the following SQL task in
  14342. 8:37:30order to understand this use case. The
  14343. 8:37:32task says count how many times each
  14344. 8:37:34customer has made an order with sales
  14345. 8:37:37greater than 30. All right. So, as
  14346. 8:37:39usual, we can do it step by step. So,
  14347. 8:37:41what do we need? We need the orders. So,
  14348. 8:37:43let's get the order ID and as well,
  14349. 8:37:45let's get the customer ID like this and
  14350. 8:37:49the sales from sales orders. Let's go
  14351. 8:37:53and execute it. So now, what else I'm
  14352. 8:37:55going to do with I'm going to go and
  14353. 8:37:57order the data by customer ID. So, let's
  14354. 8:38:00execute it again. Okay. So, now the task
  14355. 8:38:02sounds easy, but it's a little bit
  14356. 8:38:04tricky. We have to count the number of
  14357. 8:38:06orders for each customer where the sales
  14358. 8:38:08is higher than 30. Let's have an
  14359. 8:38:10example. For example, this customer
  14360. 8:38:12number one. So the total number of
  14361. 8:38:13orders is three orders, right? But we
  14362. 8:38:16have to count only the orders where the
  14363. 8:38:17sales is higher than 30. And in this
  14364. 8:38:20example, we have only one order where
  14365. 8:38:22the sales is higher than 30. So it's
  14366. 8:38:24only the order number four. So the count
  14367. 8:38:26for the customer ID number one should be
  14368. 8:38:28one. Now let's check another customer.
  14369. 8:38:30For example, the two. And as you can
  14370. 8:38:32see, we have three orders, but none of
  14371. 8:38:34them have the sales higher than 30. So
  14372. 8:38:37the count should be zero here. So how we
  14373. 8:38:39going to do that? We have to go and flag
  14374. 8:38:41each row whether it's higher than 30 or
  14375. 8:38:44not. So if it's higher than 30, it gets
  14376. 8:38:47the flag of one. If it's less than 30 or
  14377. 8:38:50equal to 30, it's going to get zero. And
  14378. 8:38:52then we're going to go and summarize all
  14379. 8:38:53those flags in order to get the count.
  14380. 8:38:56So let's do it step by step. Let's first
  14381. 8:38:58create the flag. So we're going to go
  14382. 8:39:00and use case and then our condition is
  14383. 8:39:02very easy. We're going to say when. So
  14384. 8:39:04what is the condition? Sales greater
  14385. 8:39:06than 30. So sales is higher than 30.
  14386. 8:39:10Then what can happen? We're going to
  14387. 8:39:11flag it with the one because later we're
  14388. 8:39:14going to go and summarize the one. And
  14389. 8:39:15now else if it's not higher than 30,
  14390. 8:39:18equal to 30 or less. So it's going to
  14391. 8:39:20get zero. All right. So now let's go and
  14392. 8:39:22end it. So let's say sales flag. Now
  14393. 8:39:26let's go and execute it and check the
  14394. 8:39:28results. All right. So now if you check
  14395. 8:39:29the results we got now a very nice flag
  14396. 8:39:31in order to see which orders has sales
  14397. 8:39:34higher than 30. So now for example let's
  14398. 8:39:36take the customer ID number one. As you
  14399. 8:39:38can see only the order number four has
  14400. 8:39:40sales higher than 30 and it's flagged
  14401. 8:39:42with one and all others are zero. Now
  14402. 8:39:45let's take the customer ID number three.
  14403. 8:39:47And as you can see we have now two
  14404. 8:39:49orders where the sales is higher than
  14405. 8:39:5130. And as you can see we have the one
  14406. 8:39:53twice. And now we can use this flag in
  14407. 8:39:55order to do the aggregation. So now if
  14408. 8:39:57you go and summarize the flag for the
  14409. 8:39:59customer id number three we will get two
  14410. 8:40:02and this is the count of orders where
  14411. 8:40:04the sales is higher than 30 right and
  14412. 8:40:06let's take another example the customer
  14413. 8:40:08ID number two we have everywhere zero
  14414. 8:40:10and if we summarize those values we will
  14415. 8:40:12get zero which is the count of orders
  14416. 8:40:14where the sales is higher than 30 which
  14417. 8:40:15is correct so now as you can see first
  14418. 8:40:17we have built an extra column in order
  14419. 8:40:19to help us doing the aggregation and now
  14420. 8:40:21in the next step we're going to go and
  14421. 8:40:23aggregate this column so let's go and do
  14422. 8:40:25that we don't need all those
  14423. 8:40:26informations the order ID we need the
  14424. 8:40:29customer ID because it is the
  14425. 8:40:31granularity for the aggregation and
  14426. 8:40:33let's remove the order by and now let's
  14427. 8:40:36go and group up the data by customer ID
  14428. 8:40:40but of course we need the aggregate
  14429. 8:40:42function so how we going to do it we're
  14430. 8:40:44going to go and summarize the whole flag
  14431. 8:40:46so and now of course we're going to go
  14432. 8:40:48and rename this since now it is an
  14433. 8:40:50aggregated column so we're going to call
  14434. 8:40:52it total orders so now let's go and
  14435. 8:40:55execute it. So now let's go and check
  14436. 8:40:57the result. As you can see, now we have
  14437. 8:40:58our four customers. And for the customer
  14438. 8:41:00ID number one, we got only one order
  14439. 8:41:03higher than 30. The second one has no
  14440. 8:41:05orders higher than 30. The third we have
  14441. 8:41:08two and one. And with that, we have
  14442. 8:41:10solved the task. Now I would like to add
  14443. 8:41:12one more thing to our query in order to
  14444. 8:41:13see the normal aggregations, not the
  14445. 8:41:16conditional aggregations. So usually we
  14446. 8:41:18go and count for example the star in
  14447. 8:41:22order to get the total orders. And let's
  14448. 8:41:24rename the previous one to high sales.
  14449. 8:41:27So let's go and execute it. So we are
  14450. 8:41:29just now doing aggregations without any
  14451. 8:41:32conditions. And now we can see how many
  14452. 8:41:34orders did each customer. So we can see
  14453. 8:41:36that the customer ID number one did
  14454. 8:41:38order three times but only one order
  14455. 8:41:40higher than 30. So this is a normal
  14456. 8:41:42aggregation and this is a conditional
  14457. 8:41:44aggregations using the case
  14458. 8:41:49statements. All right friends. So now
  14459. 8:41:51let's do a recap about the case
  14460. 8:41:53statements. Case statement can go and
  14461. 8:41:54evaluate a list of conditions one by one
  14462. 8:41:57and return a value once the first
  14463. 8:41:59condition is met. And if you are talking
  14464. 8:42:01about the rules of using the case
  14465. 8:42:02statements, we have only one where the
  14466. 8:42:04data types of each condition after the
  14467. 8:42:07then and else must be matching. And now
  14468. 8:42:09if we talk about the use cases of the
  14469. 8:42:11case statements, the main use case is to
  14470. 8:42:13do data transformations and especially
  14471. 8:42:15by creating new columns and deriving new
  14472. 8:42:18informations. So as we saw there are
  14473. 8:42:20amazing use cases for the case
  14474. 8:42:22statements. For example, we can use it
  14475. 8:42:23in order to categorize our data. As we
  14476. 8:42:25learned, we can go and create a new
  14477. 8:42:27groups of data then to be aggregated for
  14478. 8:42:29our reports. And then we saw another use
  14479. 8:42:31case is mapping values. We can use the
  14480. 8:42:34case statement in order to help us
  14481. 8:42:36mapping the cryptical technical values
  14482. 8:42:38that is stored in databases to new
  14483. 8:42:41values which is more readable and more
  14484. 8:42:43friendly to be used. And the next use
  14485. 8:42:45case that we have learned is handling
  14486. 8:42:46the nulls. We can use the case statement
  14487. 8:42:49in order to replace the nulls with value
  14488. 8:42:51to make our aggregations more accurate.
  14489. 8:42:54And the last use case that we have
  14490. 8:42:55learned and I think the most used one in
  14491. 8:42:57my project is doing conditional
  14492. 8:42:59aggregations where we can aggregate a
  14493. 8:43:01subset of data that meets specific
  14494. 8:43:03conditions in order to do focus and
  14495. 8:43:06target analyszis. Okay my friends. So
  14496. 8:43:08with that we have covered all the topics
  14497. 8:43:09and all the functions in order to
  14498. 8:43:11transform single value in SQL the role
  14499. 8:43:14level functions that was very important
  14500. 8:43:16especially for data engineers. So we are
  14501. 8:43:19done with this chapter. Now we are
  14502. 8:43:20moving to very interesting chapter.
  14503. 8:43:22Finally we're going to talk about data
  14504. 8:43:24analytics in SQL and we will be covering
  14505. 8:43:26now the aggregate and the analytical
  14506. 8:43:28functions that we have in SQL. So first
  14507. 8:43:30we're going to start with the basics. So
  14508. 8:43:32we will learn simple functions on how to
  14509. 8:43:34aggregate your data. So let's go.
  14510. 8:43:40Hey my friends. So now we're going to
  14511. 8:43:42talk about the aggregate functions in
  14512. 8:43:44SQL. They are amazing if you are a data
  14513. 8:43:46analyst or data scientist where we
  14514. 8:43:48usually use them in order to uncover
  14515. 8:43:50insights about our data. So the
  14516. 8:43:51aggregate functions they accept multiple
  14517. 8:43:54rows as an input and the output of the
  14518. 8:43:56aggregate function usually is one single
  14519. 8:43:58value. So now we're going to go and
  14520. 8:44:00cover first the basic aggregate
  14521. 8:44:02functions in SQL. So let's go. So now in
  14522. 8:44:04our database we have four orders and we
  14523. 8:44:06have the sales informations for each one
  14524. 8:44:08of them. So now one question that comes
  14525. 8:44:10in our mind what is the total number of
  14526. 8:44:12orders in our business. So how many
  14527. 8:44:14orders do we have? Now in order to do
  14528. 8:44:16that we use the function count because
  14529. 8:44:18what it does it's going to go and count
  14530. 8:44:20the number of rows inside our table. So
  14531. 8:44:22if you apply the count function on this
  14532. 8:44:24data SQL going to go and start counting
  14533. 8:44:26how many rows do we have. So the total
  14534. 8:44:28number is four and in the output we will
  14535. 8:44:30get four. So as you can see we don't
  14536. 8:44:32really care about the content of the
  14537. 8:44:33tables. Scale is just counting how many
  14538. 8:44:36rows. So the number is not based on the
  14539. 8:44:38sales or formations or the orders. So
  14540. 8:44:40this is how the count function works.
  14541. 8:44:42Now we have another question and we say
  14542. 8:44:44I would like to find the total sales in
  14543. 8:44:46our data in our business. So that means
  14544. 8:44:48we have to go and summarize all those
  14545. 8:44:50sales that we have in the order and for
  14546. 8:44:52that we have the sum function. So if you
  14547. 8:44:54go and apply the sum function, it's
  14548. 8:44:56going to go and summarize all the sales
  14549. 8:44:58and return at the end the total sales.
  14550. 8:45:00In this example, it's going to be 80.
  14551. 8:45:01So, as you can see, the aggregate
  14552. 8:45:03function accept multiple rows, multiple
  14553. 8:45:05values, and the output going to be one
  14554. 8:45:07single value, the aggregated value. Now,
  14555. 8:45:10moving on, I would like to understand
  14556. 8:45:11what is the average sales in our
  14557. 8:45:13business. So, it sounds simple. In order
  14558. 8:45:15to do that, we're going to use the
  14559. 8:45:16average function. So, if you apply it on
  14560. 8:45:19the sales, it's going to go and
  14561. 8:45:20summarize all those values and divide it
  14562. 8:45:22by the number of values. So, you will
  14563. 8:45:24get the average of 20. Now comes
  14564. 8:45:26interesting question where you want to
  14565. 8:45:28find what is the highest sales in my
  14566. 8:45:30data. So for that we can use the
  14567. 8:45:32function max. So once you apply it it's
  14568. 8:45:34going to go and start searching for the
  14569. 8:45:36highest value inside our table. So this
  14570. 8:45:38time we are not really aggregating the
  14571. 8:45:40data into something new. It's like
  14572. 8:45:43searching for the highest value between
  14573. 8:45:44multiple values. So in this example we
  14574. 8:45:47will get the 35 as the highest sales.
  14575. 8:45:49Now of course if you want to see the
  14576. 8:45:51lowest sales inside your business you
  14577. 8:45:53can use the min function. And if you go
  14578. 8:45:55and apply it as well, the same thing is
  14579. 8:45:57going to go and start searching for the
  14580. 8:45:58lowest value in the sales. And in this
  14581. 8:46:01example, it's going to be the 10. So as
  14582. 8:46:02you can see guys, the aggregate
  14583. 8:46:03functions is very simple but yet very
  14584. 8:46:05powerful. So it is really useful for
  14585. 8:46:07insights in order to understand how well
  14586. 8:46:09your business is performing. So now
  14587. 8:46:10let's go to SQL in order to try those
  14588. 8:46:12functions. Okay. So now we're going to
  14589. 8:46:14go and analyze the orders table inside
  14590. 8:46:16our database by doing very simple
  14591. 8:46:18aggregations. So let's start with the
  14592. 8:46:20first task. It says find the total
  14593. 8:46:22number of orders. So this time we are
  14594. 8:46:24targeting the table orders. So let's
  14595. 8:46:28just start with the select. So now we
  14596. 8:46:29can see we have like four orders. And
  14597. 8:46:31now we would like to have like one
  14598. 8:46:32number. What we can do? We can go and
  14599. 8:46:34say count star as total number of
  14600. 8:46:38orders. So let's go and execute it. And
  14601. 8:46:41with that we got one number. It is the
  14602. 8:46:43four. This is the total number of
  14603. 8:46:44orders. Now let's move to the second
  14604. 8:46:46task. It says find the total sales of
  14605. 8:46:49all orders. So this time we have to
  14606. 8:46:51summarize all the sales values in one
  14607. 8:46:54big value. So how to do it? We're going
  14608. 8:46:56to use the function sum and this time we
  14609. 8:46:59are targeting the sales and we're going
  14610. 8:47:01to go and call it total sales. So let's
  14611. 8:47:04go and execute it. And with that we have
  14612. 8:47:0680 as the total number of sales. So all
  14613. 8:47:09the sales values are summarized in one
  14614. 8:47:11big value. So as you can see now we are
  14615. 8:47:12exploring the business right? We are
  14616. 8:47:14understanding how many sales, how many
  14617. 8:47:16orders. So this is really the basics of
  14618. 8:47:18analytics in SQL. Now let's go to the
  14619. 8:47:20second task. Let's find the average
  14620. 8:47:22sales of all orders. So we're going to
  14621. 8:47:24have average this time the sales as
  14622. 8:47:29average sales. Again very simple. Let's
  14623. 8:47:31go and execute it. Now the total sales
  14624. 8:47:33is 80 but the average sales is 20. So
  14625. 8:47:36all the values of the sales is
  14626. 8:47:37summarized and then divided by the
  14627. 8:47:39number of orders. So 80 divided by four.
  14628. 8:47:42And with that SQL finding the 20 as an
  14629. 8:47:45average. Now let's go and get
  14630. 8:47:46interesting stuff. Let's go and find the
  14631. 8:47:48highest sales of all orders. So what is
  14632. 8:47:51the highest sales that happens in our
  14633. 8:47:53business? In order to do that, we can
  14634. 8:47:54use the function max sales as highest
  14635. 8:47:59sales. Very nice. Let's go and execute.
  14636. 8:48:02So the highest sales in the database is
  14637. 8:48:0535. And now I think you already know
  14638. 8:48:07what is the next task. Find the lowest
  14639. 8:48:09sales of all orders. So this is exactly
  14640. 8:48:12the opposite. So we're going to go and
  14641. 8:48:13use the min sales as lowest sales. So
  14642. 8:48:18let's go and execute. The lowest sales
  14643. 8:48:20in our business was 10. So my friends,
  14644. 8:48:22as you can see, the aggregate functions
  14645. 8:48:24are really amazing. And if you use it
  14646. 8:48:26like this, you will get like the big
  14647. 8:48:28numbers about our business. But now
  14648. 8:48:29don't forget about the aggregate
  14649. 8:48:31functions. If you combine it with a
  14650. 8:48:33group by then you will be breaking those
  14651. 8:48:36big numbers into something like you are
  14652. 8:48:39aggregating by the customer ID maybe by
  14653. 8:48:42a date by a country. So anything you
  14654. 8:48:45specify with the group by it going to
  14655. 8:48:47breaks those big numbers into smaller
  14656. 8:48:49number based on the column that you are
  14657. 8:48:51using. For example let's go with the
  14658. 8:48:52customer ID over here and let's put it
  14659. 8:48:55at the start as well. And now if you go
  14660. 8:48:58and execute it. So now as you can see in
  14661. 8:49:00the output all those numbers are not
  14662. 8:49:02anymore like big numbers. We drill down
  14663. 8:49:04to more details based on the column that
  14664. 8:49:07we have specified. So now we have for
  14665. 8:49:09each customer the total number of
  14666. 8:49:11orders, the total number of sales, the
  14667. 8:49:13average sales, the highest sales or the
  14668. 8:49:15lowest sales. Of course the data is very
  14669. 8:49:17small and those numbers can be more
  14670. 8:49:19interesting if you have bigger data. So
  14671. 8:49:20if you combine the aggregate functions
  14672. 8:49:22together with the group by, you will
  14673. 8:49:24break those big numbers into more
  14674. 8:49:26details based on the column that you are
  14675. 8:49:28grouping by. So now what you can do, you
  14676. 8:49:30can go and apply those functions as well
  14677. 8:49:32for the customers. There we have a score
  14678. 8:49:35and you can go and find the average
  14679. 8:49:37score, the highest score, the lowest
  14680. 8:49:39score and then you can group up the data
  14681. 8:49:41by the country for example. So pause the
  14682. 8:49:44video and do some aggregations on the
  14683. 8:49:46table customers.
  14684. 8:49:48[Music]
  14685. 8:49:52All right my friends. So with that you
  14686. 8:49:54have learned the basics on how to
  14687. 8:49:55aggregate your data using SQL. Now we're
  14688. 8:49:58going to move to more advanced way on
  14689. 8:49:59how to aggregate your data. We will
  14690. 8:50:01start talking about the window functions
  14691. 8:50:03the analytical functions. So first we're
  14692. 8:50:05going to start talking about what is
  14693. 8:50:07exactly window functions and we're going
  14694. 8:50:08to cover the basics about this topic. So
  14695. 8:50:10let's go.
  14696. 8:50:15window functions or sometimes we call
  14697. 8:50:17them analytical functions. They are very
  14698. 8:50:20important functions in SQL. Everyone
  14699. 8:50:22must know them especially if you are
  14700. 8:50:24doing data analyszis. Each time I write
  14701. 8:50:26SQL script in order to do data
  14702. 8:50:28analytics, I end up using them. So as
  14703. 8:50:30usual, we're going to go and now
  14704. 8:50:31understand the concept behind them and
  14705. 8:50:34then we're going to start practicing. So
  14706. 8:50:36let's
  14707. 8:50:39go. Okay guys, so now let's start with
  14708. 8:50:41the first question. What are SQL window
  14709. 8:50:44functions? They are functions that
  14710. 8:50:46allows you to do calculations like
  14711. 8:50:48aggregations but on top of subset of
  14712. 8:50:51data without losing the level of details
  14713. 8:50:53of the rows. So it is something very
  14714. 8:50:56similar to the group pi but here we have
  14715. 8:50:57special case you don't lose the level of
  14716. 8:51:00details. So now in order to understand
  14717. 8:51:02the definition let's have a very simple
  14718. 8:51:04example. Okay. So now let's understand
  14719. 8:51:05how SQL works with the group by clouds.
  14720. 8:51:08Let's say that we have the very simple
  14721. 8:51:10example. We have four orders. two orders
  14722. 8:51:12for the cabs and two order for the
  14723. 8:51:14gloves. And let's say that I would like
  14724. 8:51:16to see the total sales for each
  14725. 8:51:18products. So now if we decided to use
  14726. 8:51:20the group by what SQL going to do going
  14727. 8:51:22to take the first two orders for the
  14728. 8:51:25caps and put it in one row. So in the
  14729. 8:51:27output we're going to have only one row
  14730. 8:51:29for the caps with the total sales of 40.
  14731. 8:51:32And the same thing going to happen for
  14732. 8:51:33the gloves. So we're going to take the
  14733. 8:51:34two rows of the gloves from the input
  14734. 8:51:36and in the output we're going to have
  14735. 8:51:38only one row for the gloves. So that
  14736. 8:51:40means the number of rows going to be
  14737. 8:51:42depending on the number of products we
  14738. 8:51:44have on our data. We have two products,
  14739. 8:51:46we get two rows. So that means SQL is
  14740. 8:51:49really like smashing or squeezing the
  14741. 8:51:51results in the output. And this is
  14742. 8:51:53exactly what the grouper does to our
  14743. 8:51:55data. It aggregate the rows, aggregate
  14744. 8:51:57the data into different level of
  14745. 8:51:59details. So now on the left side we see
  14746. 8:52:02four rows. On the right side we have two
  14747. 8:52:04rows and with that we are losing some
  14748. 8:52:06details in the results. But still we
  14749. 8:52:08have solved the tasks. So now let's see
  14750. 8:52:10what going to happen if you use window
  14751. 8:52:12function in SQL. Okay. So now we have
  14752. 8:52:13the same data and as with the same task
  14753. 8:52:15we have to find the total sales for each
  14754. 8:52:17product. Now if you use window function
  14755. 8:52:20SQL going to do the following. It going
  14756. 8:52:22to go and execute each rows individually
  14757. 8:52:25from each others. So what going to
  14758. 8:52:27happen it start with the first row the
  14759. 8:52:28order ID one. In the output we're going
  14760. 8:52:31to get as well the same stuff the order
  14761. 8:52:33ID one the same row but we will get the
  14762. 8:52:35total sales for the caps. So here the
  14763. 8:52:38total sales is going to be 10 30 we will
  14764. 8:52:40get 40. Then it's going to jump to the
  14765. 8:52:42second row and it's going to process it
  14766. 8:52:44as well. So in the output we will get
  14767. 8:52:46the order ID two the product caps and as
  14768. 8:52:48well we have the same aggregation since
  14769. 8:52:50we are talking about the same product.
  14770. 8:52:52So we will get 40. Then it's going to go
  14771. 8:52:54to the third order and here we have the
  14772. 8:52:55gloves. So in the output again we have
  14773. 8:52:57the order ID 3 the product gloves and
  14774. 8:53:00the total sales this time going to be 5
  14775. 8:53:02+ 20 so we will get 25 then it goes to
  14776. 8:53:05the last row to the order ID number four
  14777. 8:53:08in the output we're going to get four
  14778. 8:53:09gloves and as well 25. So now we can
  14779. 8:53:12notice that if you use the window
  14780. 8:53:14function you will not lose the level of
  14781. 8:53:16details of your data. So we are doing
  14782. 8:53:18something called rowle calculations. So
  14783. 8:53:21if in input data we have four orders in
  14784. 8:53:23the output we're going to get four
  14785. 8:53:25orders and as well we will get our
  14786. 8:53:27aggregations correctly. So now if you
  14787. 8:53:29compare both of the methods side by side
  14788. 8:53:31we can see that we are solving the same
  14789. 8:53:33task. So we are finding the total sales
  14790. 8:53:35for each products but with the group by
  14791. 8:53:38we are smashing squeezing the results
  14792. 8:53:40from four orders into two rows one row
  14793. 8:53:44for each order. So that means with the
  14794. 8:53:46group by the granularity is changing
  14795. 8:53:48right in the input the order ID is
  14796. 8:53:50controlling the level of details but in
  14797. 8:53:52the output of the group by the product
  14798. 8:53:54is controlling the level of details. So
  14799. 8:53:56we have different granularity but in the
  14800. 8:53:58other hand with the window functions we
  14801. 8:54:00are still able to do aggregations but we
  14802. 8:54:02are not losing the level of details. So
  14803. 8:54:04the granularity of the input going to be
  14804. 8:54:07the same like the output in the results.
  14805. 8:54:09So this is exactly the main difference
  14806. 8:54:11between the group eye and the window
  14807. 8:54:12function. If you want just to do simple
  14808. 8:54:15aggregations, then go with the group by.
  14809. 8:54:17But if you care about the level of
  14810. 8:54:19details and you need to add more details
  14811. 8:54:21to your results, then you can go with
  14812. 8:54:23the window function where you can do
  14813. 8:54:25aggregations plus having more details.
  14814. 8:54:27And now if you go and compare the
  14815. 8:54:29functions between the window and the
  14816. 8:54:30group by, we can find that both of them
  14817. 8:54:32has exactly the same functions for the
  14818. 8:54:34aggregations. So we have the count, sum,
  14819. 8:54:36average, min, max. And here comes
  14820. 8:54:38another difference between the window
  14821. 8:54:40and the group by. The group I has only
  14822. 8:54:42the aggregate functions. So that's it.
  14823. 8:54:44But in the window functions, we have way
  14824. 8:54:46more functions to use for analytics. So
  14825. 8:54:49for example, we have the ranking
  14826. 8:54:50functions. And we have here another
  14827. 8:54:52group of functions for the value or we
  14828. 8:54:54call it analytical functions. So that
  14829. 8:54:56means in the SQL window, we have a lot
  14830. 8:54:58of functions. We can cover a lot of
  14831. 8:55:00analytical use cases and advanced
  14832. 8:55:02complex stuff. But with the group by we,
  14833. 8:55:05we have only the aggregate functions
  14834. 8:55:06only for simple use cases. So this is
  14835. 8:55:09another difference between the group by
  14836. 8:55:10and the window. Group by use it if you
  14837. 8:55:13have simple analyzes, simple
  14838. 8:55:15aggregations, window functions, we're
  14839. 8:55:17going to use it for more advanced data
  14840. 8:55:18analyszis where we're going to cover a
  14841. 8:55:20lot of use cases. All right guys, so now
  14842. 8:55:22we're going to have few tasks in order
  14843. 8:55:23to understand one thing. Why do we need
  14844. 8:55:26scale window functions and why in some
  14845. 8:55:28scenarios group is not enough and we
  14846. 8:55:31have to use scale window functions. So
  14847. 8:55:33let's go. All right. So let's start with
  14848. 8:55:34very simple task. It's going to say find
  14849. 8:55:37the total sales across all orders. So we
  14850. 8:55:40need one value with the total sales.
  14851. 8:55:42Let's see how we can do that. First make
  14852. 8:55:44sure that you are using the database. So
  14853. 8:55:46use sales database in case you have
  14854. 8:55:48closed the clients so that we don't get
  14855. 8:55:51any errors. So now we're going to start
  14856. 8:55:53with the first thing. We're going to go
  14857. 8:55:54and select the sales. You're going to
  14858. 8:55:56find it in the table sales orders. So
  14859. 8:55:59now let's just query the data. And as
  14860. 8:56:01you can see we have 10 orders with 10
  14861. 8:56:03sales. We didn't aggregate anything yet.
  14862. 8:56:06So we have the row data now. So now in
  14863. 8:56:07order to solve the task, we're going to
  14864. 8:56:09use the function sum. So sum of sales
  14865. 8:56:12and we're going to give it new name
  14866. 8:56:14total sales. We don't have to use any
  14867. 8:56:16group by because we don't have to group
  14868. 8:56:18up anything. So that's it. Let's go and
  14869. 8:56:21execute that. And as you can see SQL
  14870. 8:56:22going to return one value 380. This is
  14871. 8:56:25the total sales that we have inside our
  14872. 8:56:27data. And this is the highest level of
  14873. 8:56:30aggregations. So with that we have
  14874. 8:56:32solved the task. We have the total sales
  14875. 8:56:34across all orders. We don't have to
  14876. 8:56:36group up anything. Let's move to the
  14877. 8:56:38next example. Let's say that in the next
  14878. 8:56:40task, this time we want to find the
  14879. 8:56:42total sales but for each products. So
  14880. 8:56:45not for the all orders, for each
  14881. 8:56:47products we want to find the total
  14882. 8:56:49sales. So this time we don't need only
  14883. 8:56:51one value. We need one value for each
  14884. 8:56:54product. In order to do that now, we're
  14885. 8:56:56going to go and use the group by
  14886. 8:56:58function. And we're going to group up by
  14887. 8:57:00the product ID. and group up need as
  14888. 8:57:02well the dimension in the selection. So
  14889. 8:57:05we can do it like this. So that's it.
  14890. 8:57:07Let's go and execute the query. Now as
  14891. 8:57:09you can see in the results we don't have
  14892. 8:57:10one value. We don't have the highest
  14893. 8:57:12aggregations. This time we are drilling
  14894. 8:57:15down to the next level of details. So
  14895. 8:57:17the level of details here is the product
  14896. 8:57:19ID. We have one row for each product. So
  14897. 8:57:22for the first product we have 140. The
  14898. 8:57:25next one 105 and so on. So as you can
  14899. 8:57:27see we are now splitting the data at the
  14900. 8:57:30level of product ID and we went from 10
  14901. 8:57:33orders now in the results we have four
  14902. 8:57:35orders and that's because we have four
  14903. 8:57:37products. So the number of rows at the
  14904. 8:57:40output going to be defined by the
  14905. 8:57:42dimension the product ID and with we
  14906. 8:57:44have solved the task we have the total
  14907. 8:57:46sales for each product. All right guys
  14908. 8:57:48so let's keep progressing in our
  14909. 8:57:49examples. Now the next one going to be a
  14910. 8:57:52little bit advanced where we have the
  14911. 8:57:53same aggregation. Find the total sales
  14912. 8:57:56for each product. Additionally, provide
  14913. 8:57:58details such order ID and the order
  14914. 8:58:01date. So, as you can see, we have
  14915. 8:58:03already solved the first part. We are
  14916. 8:58:05finding the total sales for each
  14917. 8:58:06product. Now, we just have to add some
  14918. 8:58:08additional informations like the order
  14919. 8:58:10ID and the order date. So, let's go over
  14920. 8:58:12here and just add it in our select. So,
  14921. 8:58:14order ID and let's have the order date.
  14922. 8:58:17So, let's go and execute that. Just
  14923. 8:58:19going to make it a little bit bigger.
  14924. 8:58:21So, let's go. But now as you can see SQL
  14925. 8:58:23will not be happy going to throw an
  14926. 8:58:24error and says the stuff that you are
  14927. 8:58:26adding to your select are not included
  14928. 8:58:29in the group by. So as you can see in
  14929. 8:58:31the group buy we have only one dimension
  14930. 8:58:32or one field called the product ID. But
  14931. 8:58:35in our selection we have three
  14932. 8:58:36dimensions the order ID, the order date
  14933. 8:58:39and the product ID. So there is no
  14934. 8:58:41matching between the select and group by
  14935. 8:58:43and SQL will not allow it. And now you
  14936. 8:58:45might say you know what let's add
  14937. 8:58:47everything to the group by. So with that
  14938. 8:58:49we're going to get our aggregation and
  14939. 8:58:50as well we're going to get our details.
  14940. 8:58:52So let's try that. I'm just going to
  14941. 8:58:53zoom out a little bit and instead of
  14942. 8:58:55having the product ID let's add
  14943. 8:58:57everything. So the order ID, order date
  14944. 8:59:00and the product ID. So now we have
  14945. 8:59:02matching and SQL should not throw any
  14946. 8:59:04error. Let's go and execute it. So now
  14947. 8:59:06let's check whether we have solved the
  14948. 8:59:08task. The task has two parts right. We
  14949. 8:59:10have to do the aggregations and to
  14950. 8:59:12provide details. So as you can see we
  14951. 8:59:14have solved the second part. We have the
  14952. 8:59:16details, order ID and order dates. But
  14953. 8:59:18now the first part finding the total
  14954. 8:59:20sales for each product is destroyed
  14955. 8:59:22because if you check the results, we
  14956. 8:59:24have the product ID 101. It has the
  14957. 8:59:26total sales of 10. But in the third
  14958. 8:59:28order, we have it as a 20 for the same
  14959. 8:59:31product. So actually the data is not
  14960. 8:59:33aggregated and that's because we are
  14961. 8:59:34aggregating at different levels and we
  14962. 8:59:36have included way more stuff that we
  14963. 8:59:39don't need for the aggregations. We are
  14964. 8:59:40aggregating at the order ID level. So as
  14965. 8:59:43you can see now we are hitting the
  14966. 8:59:45limits of group by. We cannot provide
  14967. 8:59:47aggregations and as well provide
  14968. 8:59:49additional informations from our data.
  14969. 8:59:51You have to pick one. That's why we have
  14970. 8:59:53to go to the second option where we can
  14971. 8:59:55use the window functions. So let's do
  14972. 8:59:57that. I'm just going to get rid of the
  14973. 8:59:58group by parts and as well all the
  14974. 9:00:01fields. Let's back to the root. So now
  14975. 9:00:03we have the sum of sales and if execute
  14976. 9:00:05this I'm going to get one value. So we
  14977. 9:00:07are at the highest level of
  14978. 9:00:08aggregations. So now we need to use the
  14979. 9:00:10window function. I'm just going to
  14980. 9:00:12remove the name. And now we're going to
  14981. 9:00:14tell SQL this is a window functions
  14982. 9:00:17using over after the aggregations or the
  14983. 9:00:19functions tells SQL we are talking about
  14984. 9:00:22window functions. So let's just execute
  14985. 9:00:23it like this. And with that we got 10
  14986. 9:00:26rows and that's because we have 10
  14987. 9:00:28orders and for each row we have exactly
  14988. 9:00:30the same value. So we have the total
  14989. 9:00:32sales of all orders for each row. So as
  14990. 9:00:35you can see SQL understands this is a
  14991. 9:00:37window function and SQL should not like
  14992. 9:00:40group all the data in one row. It should
  14993. 9:00:42keep exactly the same rows or same
  14994. 9:00:44number of rows like the input. So with
  14995. 9:00:46that we have the window function but we
  14996. 9:00:48have to split the data by the products.
  14997. 9:00:51So now we're going to use the keyword
  14998. 9:00:52partition by it's like the group by but
  14999. 9:00:54another wording products ID the same
  15000. 9:00:57dimension. So with that we have the
  15001. 9:00:59total sales by products as a name. So
  15002. 9:01:02let's go and execute this. So now as you
  15003. 9:01:04can see in the output we still have the
  15004. 9:01:06same number of rows. We have 10 orders.
  15005. 9:01:08We have 10 rows but the result did
  15006. 9:01:10change because now we are aggregating
  15007. 9:01:12the data at the level of product ID. In
  15008. 9:01:14order to understand the results we have
  15009. 9:01:16to add more informations to our select.
  15010. 9:01:18So now let's add the same dimension.
  15011. 9:01:20It's going to be the product ID. I'm
  15012. 9:01:22just going to add it at the front over
  15013. 9:01:23here. So let's select. And as you can
  15014. 9:01:26see now it makes more sense. We have
  15015. 9:01:28those products and they have always the
  15016. 9:01:31exact same uh sales. and as well for the
  15017. 9:01:34next product and so on. And now here
  15018. 9:01:35comes the magic of the window function.
  15019. 9:01:37We can add more informations to our
  15020. 9:01:39select statement without having any
  15021. 9:01:41errors. So now we need additional
  15022. 9:01:43informations like the order ID. So we
  15023. 9:01:45can go over here and say order ID, order
  15024. 9:01:48date, any type of column you can add it
  15025. 9:01:51to your select and let's go and execute.
  15026. 9:01:53So as you can see now we got the result
  15027. 9:01:55even though that those three dimensions
  15028. 9:01:57in the select are not part of the window
  15029. 9:02:00aggregation. So with that we have solved
  15030. 9:02:02the tasks. We have additional
  15031. 9:02:04informations. We have the order ID, the
  15032. 9:02:06order date and as well the first part of
  15033. 9:02:08the task to find the total sales for
  15034. 9:02:10each products. So each of those values
  15035. 9:02:13are the total sales for each product.
  15036. 9:02:15And with that we have solved the tasks
  15037. 9:02:17and this is exactly why we need window
  15038. 9:02:19functions. In real projects things get
  15039. 9:02:21really complicated. You are doing
  15040. 9:02:23different tasks in one query. So you are
  15041. 9:02:25doing aggregations, you are doing some
  15042. 9:02:27other stuff. So just focusing on the
  15043. 9:02:30aggregations is not going to be enough.
  15044. 9:02:31You have always to add additional
  15045. 9:02:33informations to your query. So as you
  15046. 9:02:35can see we use group eye to do simple
  15047. 9:02:36analyszis but as things get complicated
  15048. 9:02:39in the analytics we use the window
  15049. 9:02:41functions in order to show the
  15050. 9:02:43aggregations and as well add additional
  15051. 9:02:45informations. So as you can see we use
  15052. 9:02:47group eye to do simple analyszis but as
  15053. 9:02:49things get complicated in the analytics
  15054. 9:02:52we use the window functions in order to
  15055. 9:02:54show the aggregations and as well add
  15056. 9:02:56additional informations.
  15057. 9:03:01All right everyone. So now we're going
  15058. 9:03:02to go and deep dive into the syntax of
  15059. 9:03:04the SQL window functions. We're going to
  15060. 9:03:06cover everything each part of the syntax
  15061. 9:03:08for you to understand how to use them.
  15062. 9:03:11So let's go. All right. So let's start
  15063. 9:03:12first by understanding the basic
  15064. 9:03:14components or the basic parts of each
  15065. 9:03:16window syntax. Mainly we have two parts.
  15066. 9:03:19The first part going to be the window
  15067. 9:03:21function. We have like sum, average and
  15068. 9:03:23so on. The second main part is going to
  15069. 9:03:25be the over close. And inside the overlo
  15070. 9:03:28we have three different parts. The first
  15071. 9:03:30one going to be the partition close. The
  15072. 9:03:32second order close and the last one we
  15073. 9:03:35have the frame close. And those are all
  15074. 9:03:37components that you can use inside the
  15075. 9:03:39window function. So two main parts
  15076. 9:03:41window function and the offer close. And
  15077. 9:03:43inside the over we have partition order
  15078. 9:03:45and frame. Let's go more in details. So
  15079. 9:03:47for example we have the following window
  15080. 9:03:49function. So as you can see we have a
  15081. 9:03:51lot of stuff going on here. We're going
  15082. 9:03:53to understand them step by step
  15083. 9:03:54component by component. Let's start from
  15084. 9:03:56the left from the first one. So what do
  15085. 9:03:58we have over here? We have a function
  15086. 9:04:00window function. So what is a window
  15087. 9:04:02function? Like here we have the average.
  15088. 9:04:04It's like any other function in SQL. You
  15089. 9:04:06can use it in order to do calculations
  15090. 9:04:08on top of the window. So the first thing
  15091. 9:04:10to do or to define in a window is to
  15092. 9:04:13define the function of the window. And
  15093. 9:04:15as we learned before, we have a long
  15094. 9:04:17list of many window functions available
  15095. 9:04:19in SQL. And we group them into three
  15096. 9:04:21groups. The first one we have the
  15097. 9:04:23aggregate functions. So we have the
  15098. 9:04:25count, sum, average, max. All those
  15099. 9:04:27functions we have them as well for the
  15100. 9:04:29group by. So those are used for the
  15101. 9:04:32aggregations. The second group of
  15102. 9:04:34functions we have the ranking functions.
  15103. 9:04:37So we have the row number, rank, entile
  15104. 9:04:39and so on. So we can use those groups in
  15105. 9:04:41order to give a rank for our data. The
  15106. 9:04:43last group we call it value or sometimes
  15107. 9:04:46analytics functions. So here we have
  15108. 9:04:48very important functions like the lead,
  15109. 9:04:49lag, first value and the last value in
  15110. 9:04:52order to access a specific value and of
  15111. 9:04:54course we're going to go and learn all
  15112. 9:04:56of them one by one understanding the
  15113. 9:04:58concepts some examples and as well for
  15114. 9:05:00you to understand when to use them for
  15115. 9:05:02that analyzers. All right so now let's
  15116. 9:05:04keep moving understanding the other
  15117. 9:05:05parts of the window syntax. Now inside
  15118. 9:05:08the function average we have here a
  15119. 9:05:10field name or column name called sales.
  15120. 9:05:12This called a function expression. It's
  15121. 9:05:15like a value, a parameter, argument that
  15122. 9:05:17we can pass it to the function. And here
  15123. 9:05:19we can use multiple different stuff. For
  15124. 9:05:22example, depend of the function of
  15125. 9:05:23course. So here it could be empty like
  15126. 9:05:25here in the ranking. It doesn't allow to
  15127. 9:05:27use an expression. So it should be
  15128. 9:05:29always empty. Or we can use a column
  15129. 9:05:31like in the example we use the sales. So
  15130. 9:05:34we use the column name as an argument or
  15131. 9:05:36an expression. For the average we are
  15132. 9:05:39finding the average of sales or we could
  15133. 9:05:41use a number. So here in the intile we
  15134. 9:05:43are allowed only to use numbers or we
  15135. 9:05:46could have multiple stuff. For example
  15136. 9:05:48in the lead we can have sales then
  15137. 9:05:50numbers and so on. So things get
  15138. 9:05:52complicated. Don't worry about it. I'm
  15139. 9:05:53going to explain that. So here we have
  15140. 9:05:55multiple stuff or we can have a whole
  15141. 9:05:58conditional logic. So for example here
  15142. 9:06:00we have the case win so on inside the
  15143. 9:06:03sum. So the whole thing over here holds
  15144. 9:06:06an expression for the sum. So as you can
  15145. 9:06:08see we can build here a complex logic
  15146. 9:06:10and the output of this logic can be
  15147. 9:06:12passed to the function sum. So that
  15148. 9:06:14means as an expression for the function
  15149. 9:06:16we can use different stuff of course
  15150. 9:06:18depends whether the function allows it
  15151. 9:06:20or not. All right. So now let's have a
  15152. 9:06:21quick overview in order to understand
  15153. 9:06:23which data types are allowed in the
  15154. 9:06:25expressions for those functions. Let's
  15155. 9:06:27see the aggregate functions. As you can
  15156. 9:06:29see the count function accept any data
  15157. 9:06:31type but the others like the sum,
  15158. 9:06:34average, min, max, they allow only
  15159. 9:06:36numerical data types. All right. So now
  15160. 9:06:38let's move to the rank function. The
  15161. 9:06:40expressions it's pretty easy. It should
  15162. 9:06:42be empty. It doesn't allow any argument
  15163. 9:06:44or anything inside those functions. So
  15164. 9:06:46as you can see all of them are empty but
  15165. 9:06:49only one that accept numerical values
  15166. 9:06:51which is the end tile. You have to
  15167. 9:06:53define a numeric value. And now moving
  15168. 9:06:55on to the last type we have the value
  15169. 9:06:57functions. they accept any data types
  15170. 9:06:59inside the expressions. So as you can
  15171. 9:07:01see each functions has its own
  15172. 9:07:03specifications and you have to be
  15173. 9:07:05careful which data type you are using in
  15174. 9:07:07the expressions. Okay. So now let's keep
  15175. 9:07:09moving to the next one. We have a very
  15176. 9:07:11important part in the window syntax. So
  15177. 9:07:13so far what do we have? We have a
  15178. 9:07:14function. We have an expression. It's
  15179. 9:07:16like usual stuff. We have done that
  15180. 9:07:18before using the group by. Now we have
  15181. 9:07:20to tell SQL that we are dealing with the
  15182. 9:07:23window function. It's not a normal one.
  15183. 9:07:25In order to do that we have to specify
  15184. 9:07:27the keyword over. So the second main
  15185. 9:07:30part in the syntax is the over clause
  15186. 9:07:32and we use it in order to define a
  15187. 9:07:34window and inside it we can define
  15188. 9:07:36multiple stuff like the partition pie
  15189. 9:07:38the order by the frame but all those
  15190. 9:07:41stuff are optional. We can skip it and
  15191. 9:07:43leave it empty. So the main task of the
  15192. 9:07:46over it tells first SQL we are dealing
  15193. 9:07:48with the window function here and as
  15194. 9:07:50well you can use it in order to define a
  15195. 9:07:53window of your data. So now we're going
  15196. 9:07:55to go and cover everything inside the
  15197. 9:07:56over clause and we're going to start
  15198. 9:07:58with the first one the partition
  15199. 9:08:03pi. All right. So now we're going to
  15200. 9:08:05learn how to define a window inside the
  15201. 9:08:07overlaus. The first part that we can
  15202. 9:08:10define is the partition pi. So for
  15203. 9:08:12example here we have partition pi
  15204. 9:08:14category. We have to define the
  15205. 9:08:15dimension. It's very similar to the
  15206. 9:08:17group by another wording. So the first
  15207. 9:08:19part is going to be the partition
  15208. 9:08:20clause. What it going to do? It's going
  15209. 9:08:23to divide the entire data sets into
  15210. 9:08:26groups or you can call it windows
  15211. 9:08:28partitions. So here we tell SQL how to
  15212. 9:08:31divide our data. And here we have two
  15213. 9:08:33options. Let me just show you. So if we
  15214. 9:08:36don't use anything so we have it empty.
  15215. 9:08:38You see over and partition by is not
  15216. 9:08:41used. What going to happen? SQL going to
  15217. 9:08:44use the entire data in order to do the
  15218. 9:08:46calculations. So the whole data the
  15219. 9:08:49entire data going to be counted as one
  15220. 9:08:51window. So we are telling SQL don't
  15221. 9:08:53divide anything leave it as it is. The
  15222. 9:08:56second option that we have is to divide
  15223. 9:08:57the data by partition pi. So we define
  15224. 9:09:00the window like this partition pi
  15225. 9:09:02products for example. So SQL going to go
  15226. 9:09:04and divide the entire data into
  15227. 9:09:06different windows. For example here two
  15228. 9:09:08windows. And here this time the
  15229. 9:09:10calculation the sum of sales will not
  15230. 9:09:12apply on the entire data set. This time
  15231. 9:09:15it going to be applied on the different
  15232. 9:09:17windows individually. So we're going to
  15233. 9:09:19find the sum of sales for window one
  15234. 9:09:22separately from the total sales of
  15235. 9:09:24window 2. All right. So now we have this
  15236. 9:09:25very simple example. We have here three
  15237. 9:09:27fields. The month, product, sales. They
  15238. 9:09:30are really easy informations. And now we
  15239. 9:09:32have the following SQL window function.
  15240. 9:09:34So we have sum of sales and inside the
  15241. 9:09:38overlo we are not using anything. So we
  15242. 9:09:41are not using partition by. So how SQL
  15243. 9:09:43going to define the window. Now SQL
  15244. 9:09:45going to say okay I don't have to divide
  15245. 9:09:47anything. The entire data set is one
  15246. 9:09:50window. So SQL going to go over here and
  15247. 9:09:53say the whole thing is one window. So
  15248. 9:09:56there is no partitions, there is
  15249. 9:09:57nothing. We have only one window. So the
  15250. 9:10:00entire data going to be aggregated. So
  15251. 9:10:02this is what happen if you don't use
  15252. 9:10:04partition pi and you leave the
  15253. 9:10:06overclos. The entire data is one window.
  15254. 9:10:09All right. So now let's move to the next
  15255. 9:10:10example. We don't want to have only one
  15256. 9:10:12window. We would like to have multiple
  15257. 9:10:13windows. So we have to divide the data
  15258. 9:10:16by something. So in the over clause
  15259. 9:10:18we're going to define the window like
  15260. 9:10:19the following partition by month. So
  15261. 9:10:22it's not empty. We are now dividing the
  15262. 9:10:25data by the field month. So the values
  15263. 9:10:28inside this column going to divide the
  15264. 9:10:30data sets. So here we have two months
  15265. 9:10:33January and February. So what's going to
  15266. 9:10:35do? SQL going to go and divide the data
  15267. 9:10:38into two sets. The first window going to
  15268. 9:10:40be this one of January. So we have the
  15269. 9:10:43first window going to make it smaller
  15270. 9:10:45and the second window going to be the
  15271. 9:10:47February. So it's going to be two
  15272. 9:10:49windows inside our data and the
  15273. 9:10:51calculation going to be happening on
  15274. 9:10:53each window separately. So here as you
  15275. 9:10:55can see we are using the month in order
  15276. 9:10:57to divide our data sets into two
  15277. 9:11:00windows. One window for January and
  15278. 9:11:03another window for the February. So now
  15279. 9:11:05let's have a quick overview about the
  15280. 9:11:06options that we have with the partition
  15281. 9:11:08p. The first option as we learned we can
  15282. 9:11:10just skip it. So without partition by
  15283. 9:11:12for example here total sales across all
  15284. 9:11:15rows and here we don't find anything
  15285. 9:11:16inside the SQL. The second option we can
  15286. 9:11:19use one field one column for example
  15287. 9:11:22partition by product. So we are using
  15288. 9:11:24one dimension but we can go and mix
  15289. 9:11:27stuff. We can use multiple columns or
  15290. 9:11:29multiple dimensions in the partition by
  15291. 9:11:31for example here partition by product
  15292. 9:11:33and order status. So here with the
  15293. 9:11:35partition by we can define a list of
  15294. 9:11:37dimensions that could be used in order
  15295. 9:11:39to divide our data. So in this example
  15296. 9:11:41we are saying find the total sales for
  15297. 9:11:44each combination of products and order
  15298. 9:11:46status. So those are the different
  15299. 9:11:48options on how to work with the
  15300. 9:11:49partition pi. So now let's have this
  15301. 9:11:51overview again for all functions. The
  15302. 9:11:54partition pi for all those functions is
  15303. 9:11:56optional. So if you don't use the
  15304. 9:11:58partition pi in all those functions you
  15305. 9:12:00will not get any errors. So now let's go
  15306. 9:12:02back to SQL in order to start practicing
  15307. 9:12:04with this clause. Okay. So now we have
  15308. 9:12:06the following task. Find the total sales
  15309. 9:12:08across all orders. And we have to
  15310. 9:12:10provide additional informations like the
  15311. 9:12:12order ID and the order date. So let's go
  15312. 9:12:15and solve it step by step. First I would
  15313. 9:12:17like to provide the details. So I'm
  15314. 9:12:19going to select the order ID and the
  15315. 9:12:21order dates from the table sales orders.
  15316. 9:12:26And next we're going to work with the
  15317. 9:12:27aggregations. So we need to find the
  15318. 9:12:28total sales across all orders. Again
  15319. 9:12:31since we have here details and
  15320. 9:12:32aggregations we cannot use group by. We
  15321. 9:12:35have to use the window function. So
  15322. 9:12:36we're going to go use the function sum
  15323. 9:12:39for sales. And now we have to tell SQL
  15324. 9:12:42we are working with window functions.
  15325. 9:12:44That's why we're going to use the over
  15326. 9:12:45close. And now the next step we have to
  15327. 9:12:47think about defining the window. So
  15328. 9:12:50let's check the task. It says total
  15329. 9:12:51sales across all orders. So that means
  15330. 9:12:54we don't have to partition or divide the
  15331. 9:12:57data sets into like chunks or
  15332. 9:12:59partitions. We have to leave it as it is
  15333. 9:13:01like the whole data going to be one
  15334. 9:13:03window. And that's why we don't use
  15335. 9:13:05partition pi inside the definition.
  15336. 9:13:07We're going to leave it empty. Let's go
  15337. 9:13:08now and give it a name. It's going to be
  15338. 9:13:10the total sales. Let's go and execute
  15339. 9:13:12this. And now at the results, as you can
  15340. 9:13:14see, we have all the orders, all the
  15341. 9:13:16details, and as well, we have the total
  15342. 9:13:18sales across all orders. So with that,
  15343. 9:13:21we have solved the tasks. We have the
  15344. 9:13:22total sales and as well some details
  15345. 9:13:24about the order. All right. So now let's
  15346. 9:13:26move to the next task. It's going to be
  15347. 9:13:28very similar. So it says find the total
  15348. 9:13:30sales for each product. And we have to
  15349. 9:13:32provide additional informations like the
  15350. 9:13:34order ID and the order dates. So it's
  15351. 9:13:36going to be very similar task but this
  15352. 9:13:38time we have to divide the entire data
  15353. 9:13:42into windows and that's going to be by
  15354. 9:13:44the product. Since we are saying total
  15355. 9:13:46sales for each product. So this time we
  15356. 9:13:48have to go and divide the data. So we're
  15357. 9:13:51going to define the window like this
  15358. 9:13:52partition by and we can use the
  15359. 9:13:55dimension product ID. Let's go and
  15360. 9:13:58execute this. So now you can see in the
  15361. 9:14:00total sales we don't have anymore the
  15362. 9:14:02total sales of the whole data but they
  15363. 9:14:04are divided but in order to understand
  15364. 9:14:06the results let's go and include the
  15365. 9:14:08product ID in the results. So product ID
  15366. 9:14:11and execute. So now by looking to the
  15367. 9:14:13results you can see that the data is
  15368. 9:14:15divided into four windows. Let's see
  15369. 9:14:18them. It's going to be by the product
  15370. 9:14:19ID. So this dimension going to be
  15371. 9:14:21controlling the partition. So the first
  15372. 9:14:23window going to be the product ID 101.
  15373. 9:14:26So we have the total sales for this
  15374. 9:14:27product 140 and the next window going to
  15375. 9:14:30be 102. The third one 104 and the last
  15376. 9:14:34window it's going to be only one row the
  15377. 9:14:36105 and the total sales of 60. So with
  15378. 9:14:39that we have solved the task. We have
  15379. 9:14:40the total sales for each product and as
  15380. 9:14:43well we have some details. Now I would
  15381. 9:14:44like to show you the dynamic of the
  15382. 9:14:46window function. We can add multiple
  15383. 9:14:49aggregations on multiple levels. Let me
  15384. 9:14:51show you what I mean. Let's say we stay
  15385. 9:14:53with the same example but we're going to
  15386. 9:14:55find the total sales across all orders
  15387. 9:14:57and as well the total sales for each
  15388. 9:15:00products. So what we can do we can do
  15389. 9:15:03the window functions on different levels
  15390. 9:15:05by for example here removing the whole
  15391. 9:15:07definition. So here we have the total
  15392. 9:15:08sales for the entire data for the first
  15393. 9:15:11task and the next one going to be the
  15394. 9:15:12total sales but divided by the product
  15395. 9:15:15ID. Let's here rename it by
  15396. 9:15:17products. Let's go and execute this. And
  15397. 9:15:21now you know what I'm going to go and
  15398. 9:15:22add the sales as well just to explain
  15399. 9:15:24the flexibility of the window function.
  15400. 9:15:26So let's go add the sales and execute it
  15401. 9:15:28again. And now by looking to the results
  15402. 9:15:30you can see we have the sales
  15403. 9:15:32informations three time but with
  15404. 9:15:34different granularities. The first sales
  15405. 9:15:37the sales it sales without any
  15406. 9:15:38aggregations. It is the highest level of
  15407. 9:15:41details of the sales and we're going to
  15408. 9:15:42have the sales for each order. The next
  15409. 9:15:45one the total sales with the window
  15410. 9:15:47function. Here we have the highest level
  15411. 9:15:48of aggregation. So we have the total
  15412. 9:15:50sales of all orders and the last one the
  15413. 9:15:53total sales by product it's something
  15414. 9:15:54like in the middle we are aggregating on
  15415. 9:15:57a window and the window going to be the
  15416. 9:15:59product ID. So as you can see we have
  15417. 9:16:01different granularities of the
  15418. 9:16:02aggregations and this is exactly the
  15419. 9:16:04flexibility that we have with the window
  15420. 9:16:06function. We can do all those stuff in
  15421. 9:16:08one query. Okay. So now let's keep
  15422. 9:16:10moving and adding stuff to our task.
  15423. 9:16:12It's going to say find the total sales
  15424. 9:16:14for each combination of the products and
  15425. 9:16:16the order status. So this time we have
  15426. 9:16:19to divide the data not only by the
  15427. 9:16:20product as as well with another
  15428. 9:16:23dimension the order status. So now let's
  15429. 9:16:25see how we can do that. I'm going to
  15430. 9:16:27just show the dimension order status and
  15431. 9:16:29the results and we're going to add the
  15432. 9:16:32following thing. So sum sales over since
  15433. 9:16:37it's a window function and let's go now
  15434. 9:16:39and define the window partition by. So
  15435. 9:16:41we have again the product ID but not
  15436. 9:16:43only this dimension as well the order
  15437. 9:16:46status and let's go and call it sales by
  15438. 9:16:50products and status. Let me just rename
  15439. 9:16:53those stuff. Okay. So let's go and
  15440. 9:16:56execute. All right. So now let's check
  15441. 9:16:57the results. It is the last aggregation
  15442. 9:16:59over here. And as you can see here the
  15443. 9:17:01aggregation has different granularities
  15444. 9:17:03as the previous one. And we have more
  15445. 9:17:06details. This time we are splitting the
  15446. 9:17:08data by two dimensions. So the first
  15447. 9:17:10window going to be the product ID with
  15448. 9:17:12the order status it's going to be only
  15449. 9:17:14those two rows. So we have the order ID
  15450. 9:17:16101 and the order status delivered. So
  15451. 9:17:19the total sales of this going to be 10 +
  15452. 9:17:2220 and we're going to have 30. The next
  15453. 9:17:24window going to be the same product but
  15454. 9:17:27with different status. So it's going to
  15455. 9:17:29be the 101 shipped and we're going to go
  15456. 9:17:31and summarize those two values and we're
  15457. 9:17:33going to have 110. The next product and
  15458. 9:17:36order status going to be the 102 and we
  15459. 9:17:38have it only once. So 102 delivered it's
  15460. 9:17:41only once. So it's going to be the same
  15461. 9:17:43value. The next partition or window it's
  15462. 9:17:45going to be two rows. 102 with the
  15463. 9:17:48shipped is going to be those two things
  15464. 9:17:5160 + 15 we're going to get 75. So as you
  15465. 9:17:54can see here the product ID and the
  15466. 9:17:56order status they are controlling how
  15467. 9:17:59many windows we're gonna get. So we get
  15468. 9:18:00here around like six windows. With the
  15469. 9:18:02product ID we got only four windows and
  15470. 9:18:05without using anything inside the
  15471. 9:18:07overlause we will get only one window.
  15472. 9:18:10So this is how the partition by
  15473. 9:18:15works. All right. So that was the first
  15474. 9:18:17part of the window definition within the
  15475. 9:18:19overclo. Let's move to the next part. We
  15476. 9:18:21have the order by. For example, we can
  15477. 9:18:23use order by order date. It's just a
  15478. 9:18:25field. So the order close is very
  15479. 9:18:28important in order to sort your data
  15480. 9:18:30within a window. So the order by is very
  15481. 9:18:32important as well for many functions. So
  15482. 9:18:34by just checking the overview over here
  15483. 9:18:36for the aggregate functions it is
  15484. 9:18:38optional. So you could just leave it or
  15485. 9:18:39add it. But for the rank function and as
  15486. 9:18:42well for the value functions they are a
  15487. 9:18:45must. So if you want to use those
  15488. 9:18:47functions you must use the order clause
  15489. 9:18:50because it makes no sense for example if
  15490. 9:18:52you are ranking the data without sorting
  15491. 9:18:54your data first. Okay guys. So now back
  15492. 9:18:56to our very simple example and we have
  15493. 9:18:57the following query. So the function
  15494. 9:18:59this time going to be rank. So we have
  15495. 9:19:01to rank the data and the definition of
  15496. 9:19:03the window going to be partition by
  15497. 9:19:05month. So that means we divide the data
  15498. 9:19:07by the months. So we have it over here.
  15499. 9:19:10And then the second part going to be
  15500. 9:19:12order by sales descending. So we have to
  15501. 9:19:14sort each window by descending order.
  15502. 9:19:17That means we start with the highest
  15503. 9:19:18value and we end up by the lowest value.
  15504. 9:19:21So let's see how SQL going to go and
  15505. 9:19:22execute this. So first partition by
  15506. 9:19:25month. So it's going to divide the data
  15507. 9:19:26into two partitions because we have two
  15508. 9:19:28values by the month. So let's see how
  15509. 9:19:31this going to look like. So one window
  15510. 9:19:33for January and another window for
  15511. 9:19:36February. All right. So now SQL going to
  15512. 9:19:38go to the second part and execute order
  15513. 9:19:40by sales descending. So what's going to
  15514. 9:19:42happen? SQL going to go for each window
  15515. 9:19:44separately and start sorting the data
  15516. 9:19:46from the highest to the lowest without
  15517. 9:19:48checking the other window. So in those
  15518. 9:19:50three values, the highest one is this
  15519. 9:19:52one. So it's going to be on top. Let me
  15520. 9:19:54just sort it. This is going to be the
  15521. 9:19:56lowest. You're going to be in the
  15522. 9:19:58middle. So SQL going to sort this window
  15523. 9:20:01separately from the next one. And then
  15524. 9:20:02once it's done, it's going to go to the
  15525. 9:20:04second one. So the highest value going
  15526. 9:20:06to be this one. You are the lowest. Let
  15527. 9:20:09me just do it like this. So SQL going to
  15528. 9:20:12sort it like this. The highest one is
  15529. 9:20:1470. The next one is 40. And the last one
  15530. 9:20:16is five. So with that SQL done with the
  15531. 9:20:18definition of the window. So it's
  15532. 9:20:20splitted by the month. And each window
  15533. 9:20:23is sorted by the cells. The next step is
  15534. 9:20:26going to go and rank those values. So
  15535. 9:20:28it's really simple. In the output, it's
  15536. 9:20:30going to rank the data like this. So the
  15537. 9:20:32first one going to be this value. The
  15538. 9:20:34next one going to be two and the third
  15539. 9:20:36one going to be three. So as you can
  15540. 9:20:38see, SQL is sorting only this window and
  15541. 9:20:40it's going to go and repeat the same
  15542. 9:20:42stuff for the second window. So each
  15543. 9:20:44rank is separately from the others. So
  15544. 9:20:46as you can see, it's very simple. This
  15545. 9:20:47is how SQL executes partition by
  15546. 9:20:50together with the order buy for the rank
  15547. 9:20:52function. All right. So now let's have a
  15548. 9:20:53quick task for the order by. It says
  15549. 9:20:55rank each order based on their sales
  15550. 9:20:57from the highest to the lowest. And we
  15551. 9:21:00have to provide additional informations
  15552. 9:21:01like order ID and order date. So let's
  15553. 9:21:03see how we can write the query. So we
  15554. 9:21:05have the basic stuff order ID, order
  15555. 9:21:07date and sales. And now we're going to
  15556. 9:21:09go and rank the data using window
  15557. 9:21:11function. So we're going to use the
  15558. 9:21:12function rank and then we're going to
  15559. 9:21:15tell SQL this is a window function and
  15560. 9:21:18inside it we have now to provide the
  15561. 9:21:20definition of the window. So now by
  15562. 9:21:21checking the task you can see that we
  15563. 9:21:23don't have to divide the data. So we
  15564. 9:21:25don't have to use partition by we have
  15565. 9:21:27just to use rank and with rank we have
  15566. 9:21:29to use the order by it is must. So we're
  15567. 9:21:31going to use order by the field going to
  15568. 9:21:34be the sales and from the highest to the
  15569. 9:21:36lowest. So let's just call it rank sales
  15570. 9:21:39and let's go and execute this. And as
  15571. 9:21:41you can see our results going to be
  15572. 9:21:43sorted from the highest to the lowest.
  15573. 9:21:45So you can see the sales 90 at the top
  15574. 9:21:47and the lowest going to be the 10. And
  15575. 9:21:49as well we have a rank. So for the top
  15576. 9:21:51rank it's going to be one and the lowest
  15577. 9:21:52rank going to be 10. So as you can see
  15578. 9:21:54we just quickly create a rank in SQL.
  15579. 9:21:57It's very simple. The whole thing is one
  15580. 9:21:59window since we are not using partition
  15581. 9:22:01pi. And of course if you want to have
  15582. 9:22:03ascending so from the lowest to the
  15583. 9:22:06highest you can just remove it because
  15584. 9:22:08optionally going to be ascending. So
  15585. 9:22:10let's go and execute the query. So now
  15586. 9:22:12we can see the orders are sorted the way
  15587. 9:22:14around. So we start with the lowest and
  15588. 9:22:16end up with the highest. And of course
  15589. 9:22:17you're going to get the same results if
  15590. 9:22:19you go over here and add ascending. So
  15591. 9:22:22if you execute you see we got exactly
  15592. 9:22:24the same results. So this is how you use
  15593. 9:22:26the order by inside the window
  15594. 9:22:28definition.
  15595. 9:22:32Okay guys, so with that we have covered
  15596. 9:22:34the second part of the window
  15597. 9:22:35definition. Now we're going to go to the
  15598. 9:22:37last part to the most advanced part of
  15599. 9:22:39window and we have the following stuff.
  15600. 9:22:41So we have rows unbounded proceeding. We
  15601. 9:22:45call this frame close or window frame.
  15602. 9:22:47So what we are doing over here that we
  15603. 9:22:49are defining a subset of rows within
  15604. 9:22:52each window that is relevant for the
  15605. 9:22:54calculation. Totally understand if this
  15606. 9:22:56is confusing at the start or complex. It
  15607. 9:22:58was for me as well. So what we're going
  15608. 9:23:00to do we're going to deep dive into the
  15609. 9:23:01concept in order to understand how this
  15610. 9:23:03works and we're going to do it step by
  15611. 9:23:05step. So don't worry about it. All
  15612. 9:23:06right. So now let's understand what is
  15613. 9:23:08going on with the frame close from the
  15614. 9:23:10basics. So now if you do aggregations
  15615. 9:23:12and you don't use window function you're
  15616. 9:23:14going to consider the entire data or
  15617. 9:23:16rows inside the table. But what we can
  15618. 9:23:18do we can go and divide the data using
  15619. 9:23:20partition pi to a window. So for example
  15620. 9:23:23here we have window one and window two.
  15621. 9:23:25Now if you go and do aggregations all
  15622. 9:23:27the rows in the window one going to be
  15623. 9:23:29aggregated and then scale going to go to
  15624. 9:23:31the window two and aggregate all the
  15625. 9:23:33rows. What we can do in scale is that we
  15626. 9:23:35can say you know what I don't want all
  15627. 9:23:37rows inside the window. I want a subset
  15628. 9:23:40of rows inside the window. So what we
  15629. 9:23:42are doing over here is that we have
  15630. 9:23:44those two windows but we specify a scope
  15631. 9:23:47or we specify subset of data from each
  15632. 9:23:50window to be involved in the
  15633. 9:23:51aggregations. And of course not only
  15634. 9:23:53aggregations we can do ranking other
  15635. 9:23:55stuff. So I mean calculations. So here
  15636. 9:23:57like we have a window inside a window.
  15637. 9:23:59So we are defining a scope of rows. Not
  15638. 9:24:02all rows should be involved in the
  15639. 9:24:04calculation but only specific subset of
  15640. 9:24:07data. And we can do that using the frame
  15641. 9:24:09clause. So again the partition by you
  15642. 9:24:12can use it in order to divide the entire
  15643. 9:24:14data set into multiple windows. And now
  15644. 9:24:17for the frame close. If you don't want
  15645. 9:24:18to consider all the rows within each
  15646. 9:24:20window in the calculation, you want to
  15647. 9:24:23focus and specify only a subset of data
  15648. 9:24:25within each window. Then you going to go
  15649. 9:24:27and use the frame close. All right. So
  15650. 9:24:29now let's go and understand the syntax
  15651. 9:24:31of the frame close. Let's have the
  15652. 9:24:33following example. We are saying the
  15653. 9:24:34window function is the average of sales
  15654. 9:24:37and then we define the window. So we
  15655. 9:24:38have the first partition by categories,
  15656. 9:24:41order by order dates and then we have
  15657. 9:24:43the frame close. It's going to be the
  15658. 9:24:45following rows between current row and
  15659. 9:24:48unbounded preceding. This is the frame
  15660. 9:24:50types and we have two types. We have the
  15661. 9:24:52rows and groups. Then we have like
  15662. 9:24:54between and range. So the first range
  15663. 9:24:57going to be the frame boundary, the
  15664. 9:24:59lower value. And here it accepts three
  15665. 9:25:02types of keywords like the current row
  15666. 9:25:05or number of preceding or the unbounded
  15667. 9:25:07preceding. And then we have another
  15668. 9:25:09frame boundary. It's going to be the
  15669. 9:25:11higher values and it accepts the
  15670. 9:25:12following stuff. We can use the current
  15671. 9:25:14row in following or unbounded following.
  15672. 9:25:17So as you can see we are defining like
  15673. 9:25:19boundary or a range from low value to
  15674. 9:25:21higher value. So now we have some rules.
  15675. 9:25:24We cannot use the frame clause without
  15676. 9:25:26order by. So order by must be exist in
  15677. 9:25:29the definition in order to use frame
  15678. 9:25:32clause. And the second rule it says
  15679. 9:25:34lower boundary must be before the higher
  15680. 9:25:36boundary. So always we start with the
  15681. 9:25:38lower boundary and we end up having the
  15682. 9:25:40higher boundary. You cannot switch that.
  15683. 9:25:43Okay. So now we have a very simple
  15684. 9:25:44example. We have the month and the sales
  15685. 9:25:46and the following query. Sum of sales.
  15686. 9:25:48This is the window function. And the
  15687. 9:25:50definition of the window going to be
  15688. 9:25:51order by month. We are not using
  15689. 9:25:53partition by just in order to make our
  15690. 9:25:54life easier. And the frame close going
  15691. 9:25:57to be defined like this. Rows between
  15692. 9:25:59current row and the two following. So
  15693. 9:26:01now let's see how SQL going to execute
  15694. 9:26:03this. The first definition order by
  15695. 9:26:05month. As you can see the months are
  15696. 9:26:06sorted already. So now SQL going to work
  15697. 9:26:09with the frame definition current row
  15698. 9:26:11and the two following. So SQL going to
  15699. 9:26:13process this row by row. So it's going
  15700. 9:26:15to start with the first row and it's
  15701. 9:26:17going to be our current row as here in
  15702. 9:26:19the SQL. So this is our current row and
  15703. 9:26:22we say the range until two rows, two
  15704. 9:26:24following rows. So it's going to be
  15705. 9:26:25February and March. So that means the
  15706. 9:26:28pointer going to be over here for the
  15707. 9:26:30two following. So with this we have the
  15708. 9:26:32frame boundaries and SQL have the
  15709. 9:26:34following scope for the first row. So we
  15710. 9:26:36have three rows and the summarization of
  15711. 9:26:39those three rows going to be around 70.
  15712. 9:26:42So we will get for the first row 70
  15713. 9:26:44because the scope is not all rows but
  15714. 9:26:46only this subset of data. Okay. So with
  15715. 9:26:49that scale is done with the first row
  15716. 9:26:50it's going to jump to the second row. So
  15717. 9:26:52the pointer going to be the current row
  15718. 9:26:54at the February and the second two
  15719. 9:26:56following going to be at April. So with
  15720. 9:26:58that as you can see we are sliding down
  15721. 9:27:01in the subset of data or in the window
  15722. 9:27:03and with that we have a new scope a new
  15723. 9:27:05subset and the summarization of all
  15724. 9:27:06those values going to be 45. So that's
  15725. 9:27:09it. I think you get it already. It's
  15726. 9:27:11going to go to the next one. The pointer
  15727. 9:27:13going to be on March and the two
  15728. 9:27:14following going to be on June and it's
  15729. 9:27:16going to slide like this. We have those
  15730. 9:27:18three rows in the scope and the
  15731. 9:27:19summarization of that going to be 105.
  15732. 9:27:22So now things gets interesting for the
  15733. 9:27:24next row. So the pointer for the current
  15734. 9:27:26row going to be April but the two
  15735. 9:27:28following going to be like after the end
  15736. 9:27:30of the table or something like that. So
  15737. 9:27:32as we slide down as you can see the
  15738. 9:27:34scope now or the subset of the frame
  15739. 9:27:35going to be only two rows and the output
  15740. 9:27:38going to be 75. And finally if you go to
  15741. 9:27:40the last row it's going to be the
  15742. 9:27:42current row and we're going to have only
  15743. 9:27:44one row for this subset because the two
  15744. 9:27:46following is just outside of the table
  15745. 9:27:48and we're going to get the same value as
  15746. 9:27:50the summarization. So as you can see
  15747. 9:27:51that's it. It's very simple right? So
  15748. 9:27:53the frame we use it in order to scope
  15749. 9:27:56which rows are involved in the
  15750. 9:27:58calculations. So all you have to do is
  15751. 9:28:00to define the boundaries of the frame,
  15752. 9:28:01the lower and the upper boundary. Let's
  15753. 9:28:04see what other options do we have with
  15754. 9:28:05the frames. Okay. So here we have the
  15755. 9:28:07same example but we redefine the
  15756. 9:28:09boundaries of the frame like this. Rows
  15757. 9:28:11between current row this is the first
  15758. 9:28:13boundary and unbounded following. This
  15759. 9:28:16means that we are targeting always the
  15760. 9:28:18last record in the window or in the
  15761. 9:28:20table. So unbounded following going to
  15762. 9:28:22be always static and it's going to be in
  15763. 9:28:24this example pointing to June. And now
  15764. 9:28:26it's still going to go row by row and
  15765. 9:28:28the current row going to be like the
  15766. 9:28:30start January and then February. I'm
  15767. 9:28:32just going to take this example the
  15768. 9:28:34pointer is on February and the subsets
  15769. 9:28:36or the frame going to be those four
  15770. 9:28:38rows. So it's going to be February,
  15771. 9:28:40March, April, June. So it's going to be
  15772. 9:28:41four rows and the total aggregation of
  15773. 9:28:44that going to be 115. So you can do it
  15774. 9:28:47like this. And previously it was like
  15775. 9:28:50flexible more flexible it was two
  15776. 9:28:52following but this time we have
  15777. 9:28:54unbounded following that means always
  15778. 9:28:56the boundary going to be the last one.
  15779. 9:28:58So as we are moving with the records
  15780. 9:29:00over here the boundary is going to be
  15781. 9:29:03smaller smaller and like this and the
  15782. 9:29:06last one they going to be both in the
  15783. 9:29:08same record. So the current record going
  15784. 9:29:11to be as well the unbounded following.
  15785. 9:29:13Okay let's see the next one. The
  15786. 9:29:14definition of the window going to be the
  15787. 9:29:16following rows between one proceeding
  15788. 9:29:18and the current row. So here is the way
  15789. 9:29:21around one proceeding is lower than the
  15790. 9:29:23current row. So let's see how SQL going
  15791. 9:29:25to execute this. Let's say that we are
  15792. 9:29:28currently at March. So this is the
  15793. 9:29:30current row and we are saying between
  15794. 9:29:32one proceeding. So that means one row
  15795. 9:29:34before the current row. So the frame
  15796. 9:29:37going to be like this and we have only
  15797. 9:29:39two rows. So the value going to be the
  15798. 9:29:41summarization of those two rows and it's
  15799. 9:29:43going to be 40. So that means we are
  15800. 9:29:45always targeting the rows before the
  15801. 9:29:48current row. Okay. So now let's keep
  15802. 9:29:49going with the other options in order to
  15803. 9:29:51understand everything about the frame.
  15804. 9:29:52So we redefine like this rows between
  15805. 9:29:55unbounded preceding and the current row.
  15806. 9:29:57So unbounded preceding going to be the
  15807. 9:29:59first row in the table or in the window.
  15808. 9:30:01So it's going to be static like this.
  15809. 9:30:03It's going to be the first one January.
  15810. 9:30:04And let's say that we are at this
  15811. 9:30:07current row in March. So the window or
  15812. 9:30:10the subset going to look like this.
  15813. 9:30:12Those three rows and the total of that
  15814. 9:30:14going to be 60. So now as SQL is
  15815. 9:30:16proceeding to the next one, it's going
  15816. 9:30:18to fix the first boundary. So it's going
  15817. 9:30:20to be always pointing to January and the
  15818. 9:30:22subset going to be a little bit bigger
  15819. 9:30:24until we reach the last one. And with
  15820. 9:30:27that we're going to have the subsets the
  15821. 9:30:30whole rows. So with that we get really
  15822. 9:30:32great flexibility on how to define the
  15823. 9:30:34subset and how the subset is shifting
  15824. 9:30:37through the window. Okay, so now we are
  15825. 9:30:38just having fun. So we are just playing
  15826. 9:30:40around with the boundaries. We don't
  15827. 9:30:41have always to use the current row. So
  15828. 9:30:43we can use for example here in this
  15829. 9:30:45definition row is between one proceeding
  15830. 9:30:48and one following. So we don't include
  15831. 9:30:50at all the current row in the
  15832. 9:30:51boundaries. So let's say again our
  15833. 9:30:54current row going to be in March. So one
  15834. 9:30:56preceding going to be February and one
  15835. 9:30:59following going to be April. So with
  15836. 9:31:01that our frame going to be the three
  15837. 9:31:03rows. And let me get it like this. And
  15838. 9:31:06the aggregation of this going to be
  15839. 9:31:08around 45. So with that as you can see
  15840. 9:31:10the boundary is going to be one
  15841. 9:31:11proceeding and one following. So it
  15842. 9:31:13should not be always the current row.
  15843. 9:31:15All right. So now I think you already
  15844. 9:31:16get it. What going to be the last
  15845. 9:31:17option? We're going to have everything.
  15846. 9:31:19So the definition of the frame going to
  15847. 9:31:21be rows between unbounded preceding and
  15848. 9:31:23unbounded following. What we're going to
  15849. 9:31:25have over here. The unbounded preceding
  15850. 9:31:27going to be January and the unbounded
  15851. 9:31:29following going to be June. And now the
  15852. 9:31:32frame going to be everything all the
  15853. 9:31:34rows. And it doesn't matter where are we
  15854. 9:31:37with the current row, it's going to be
  15855. 9:31:38always a fixed subsets. So it's going to
  15856. 9:31:41be always everything. So if we are over
  15857. 9:31:43here or February or March, we're going
  15858. 9:31:45to be considering all rows and the total
  15859. 9:31:48sales of that going to be 135. So we
  15860. 9:31:52will get the exact same results for
  15861. 9:31:54everything for all rows. So with that I
  15862. 9:31:57think it's not that complicated, right?
  15863. 9:31:59We just have to provide the boundaries
  15864. 9:32:01and then the calculation going to be
  15865. 9:32:02depending on the frame on the subset of
  15866. 9:32:05data. Okay guys, so now let's go back to
  15867. 9:32:07SQL and start practicing in order to
  15868. 9:32:09understand how the frame work. So let's
  15869. 9:32:11go and define a window like this. So sum
  15870. 9:32:14of sales and the window definition like
  15871. 9:32:17this. We going to divide the data by
  15872. 9:32:19order status and let's say we're going
  15873. 9:32:22to sort it by order date. And let's
  15874. 9:32:26define a frame like this. rows between
  15875. 9:32:29current row and two following. Let's
  15876. 9:32:33give it a name total sales. So let's go
  15877. 9:32:36and execute it. So now let's look to the
  15878. 9:32:38data. You see that SQL going to divide
  15879. 9:32:40our results into two sections, two
  15880. 9:32:42windows delivered and shipped. And you
  15881. 9:32:45can see that the data is sorted by the
  15882. 9:32:47order date. So as you can see over here
  15883. 9:32:49for example in this status delivered we
  15884. 9:32:52can see that 1 of January 10 and so on.
  15885. 9:32:56And then the third part we have defined
  15886. 9:32:57a frame in each window. So for example,
  15887. 9:33:00let's take the first one. So this is the
  15888. 9:33:02current row. So we say the frame is
  15889. 9:33:04between the current row and the two
  15890. 9:33:06following orders. So that means the
  15891. 9:33:08scope going to be like this. So 10 + 20
  15892. 9:33:1225 it's going to be 55. And now what is
  15893. 9:33:14interesting as well to check here is the
  15894. 9:33:16last record of each window. So now let's
  15895. 9:33:19take this window over here and the last
  15896. 9:33:21record going to be number seven. So this
  15897. 9:33:23order and let's say this is the current
  15898. 9:33:25record. So we set the frame between
  15899. 9:33:28current record and the two following.
  15900. 9:33:30But since it is the last record of this
  15901. 9:33:33window, it will not go and consider the
  15902. 9:33:35next two orders because those two orders
  15903. 9:33:38are outside of the window and that's why
  15904. 9:33:40we have here 30 and SQL doesn't go and
  15905. 9:33:43summarize all those value. So we have it
  15906. 9:33:4530 and there is nothing after that.
  15907. 9:33:48That's why we will get 30. So as you can
  15908. 9:33:51see the frame going to be calculated
  15909. 9:33:52within one window. So it will not
  15910. 9:33:55consider anything outside of the window.
  15911. 9:33:57So this is how the frame works within
  15912. 9:34:00partitions. So now I would like to show
  15913. 9:34:01you as well a few stuff about the
  15914. 9:34:03frames. We can use shortcuts but we can
  15915. 9:34:05use them only with the proceeding. So
  15916. 9:34:08for example let's say I'm going to
  15917. 9:34:09change the definition like this to
  15918. 9:34:12proceedings and current row. So let's go
  15919. 9:34:15and execute it and we will get those
  15920. 9:34:17results. So now if you want to check the
  15921. 9:34:18results quickly, let's take for example
  15922. 9:34:20this order over here and we are always
  15923. 9:34:23summarizing the values of the two
  15924. 9:34:25previous orders. So that means those
  15925. 9:34:28three orders going to be involved in the
  15926. 9:34:29frame and the output going to be 55. So
  15927. 9:34:32now there is a shortcut for SQL but only
  15928. 9:34:34for the proceeding where we can remove
  15929. 9:34:37the range. So we can go and remove
  15930. 9:34:39everything and we can leave it like this
  15931. 9:34:42rows to proceeding and if you go and
  15932. 9:34:44execute it we will get exact results. So
  15933. 9:34:46this is a quick way or a shortcut on how
  15934. 9:34:48to define a window but it only works
  15935. 9:34:50with the proceeding. So for example, if
  15936. 9:34:52I go over here and say for example
  15937. 9:34:55unbounded it's going to work. So we will
  15938. 9:34:57get the results between the unbounded
  15939. 9:35:00proceeding and the current row. But if
  15940. 9:35:02you go over here and you say you know
  15941. 9:35:03what let's have the unbounded following
  15942. 9:35:05SQL going to say there's an error. And
  15943. 9:35:07the same thing if you remove the
  15944. 9:35:08unbounded let's say for example one
  15945. 9:35:10following SQL will not like it. So you
  15946. 9:35:12can use the shortcut only with the
  15947. 9:35:15proceeding. And one last thing about the
  15948. 9:35:17frames it does there is a default frame.
  15949. 9:35:20So if you don't use any frame and you
  15950. 9:35:22use order by what can happen SQL going
  15951. 9:35:24to use a default frame. So if you check
  15952. 9:35:27the result you will notice that for this
  15953. 9:35:29window over here those values are not
  15954. 9:35:31like the whole values of the sales.
  15955. 9:35:33There is like frame there is hidden
  15956. 9:35:35frame and the default frame in SQL going
  15957. 9:35:37to be like this rows between unbounded
  15958. 9:35:41preceding and current row. So this is
  15959. 9:35:44the default frame if you use order by.
  15960. 9:35:47So now if you go and just execute it you
  15961. 9:35:49will see that we will get the exact
  15962. 9:35:51results. So be careful once you use
  15963. 9:35:53order by with the aggregate functions
  15964. 9:35:55there will be a hidden frame or a
  15965. 9:35:57default frame like this between the
  15966. 9:35:59unbounded proceeding and the current
  15967. 9:36:01row. So that means there are three ways
  15968. 9:36:02in order to do this scenario framework
  15969. 9:36:04between unbounded proceding and current
  15970. 9:36:06row. Either write it like this or you
  15971. 9:36:08can go and have a shortcut like this.
  15972. 9:36:11Let me just execute it. So we'll get the
  15973. 9:36:13same result or just remove it
  15974. 9:36:15completely. We will get as well the same
  15975. 9:36:17results. Now again the hidden frame or
  15976. 9:36:19the default frame is only working with
  15977. 9:36:21the order by. So if you go for example
  15978. 9:36:23here and remove the order by let's see
  15979. 9:36:26the results. The whole window will be
  15980. 9:36:28aggregated. So again let me just select
  15981. 9:36:30it. So you can see that SQL going to
  15982. 9:36:32consider all the rows in the
  15983. 9:36:34aggregations and we will get the total
  15984. 9:36:36sales for the whole window. So there
  15985. 9:36:38will be no frame defined only it's going
  15986. 9:36:40to be present once you use order by. All
  15987. 9:36:42right friends so with the frame closed
  15988. 9:36:44we have now covered all the components
  15989. 9:36:46on how to define a window inside an
  15990. 9:36:49overclo and with that we have covered
  15991. 9:36:51everything about the syntax of the
  15992. 9:36:54window functions.
  15993. 9:36:59Okay guys, so now we're going to go and
  15994. 9:37:00understand the rules or let's say the
  15995. 9:37:02limitations of window functions. So
  15996. 9:37:04let's learn what you are not allowed to
  15997. 9:37:06do while using window functions. Okay,
  15998. 9:37:08so the first rule that you are allowed
  15999. 9:37:10to use the window function only in the
  16000. 9:37:13select close and as well in the order by
  16001. 9:37:16clause. So here we have again the same
  16002. 9:37:17example where we finding the total sales
  16003. 9:37:19by the order status. So as you can see
  16004. 9:37:21we used the window function in the
  16005. 9:37:23select clause and we didn't get any
  16006. 9:37:25error right. So now we can go and use it
  16007. 9:37:28as well in the order by. So let's say
  16008. 9:37:30order by and let's go and copy
  16009. 9:37:32everything but not the name in the order
  16010. 9:37:35by. So if I go and execute this there
  16011. 9:37:37will be no errors and SQL going to allow
  16012. 9:37:39it. And as you can see the result didn't
  16013. 9:37:41change. So let's go and sort it for
  16014. 9:37:42example descending. So I'm going to
  16015. 9:37:44write here descending and let's execute.
  16016. 9:37:47Now we have the total sales with the
  16017. 9:37:49highest values then the lowest values.
  16018. 9:37:51So having this rule that we can use it
  16019. 9:37:52only in select and order by that means
  16020. 9:37:54we cannot use window functions in order
  16021. 9:37:57to filter data. So let me show you for
  16022. 9:38:00example instead of order by let's have
  16023. 9:38:03clause where the total sales let's say
  16024. 9:38:06bigger than 100. So let's go and execute
  16025. 9:38:08this. And as you can see XQL going to
  16026. 9:38:10say no you are not allowed to do that.
  16027. 9:38:12You can do that only for select and
  16028. 9:38:13order by. We are not allowed to use it
  16029. 9:38:16for filtering data using the wear clause
  16030. 9:38:18and as well you are not allowed to use
  16031. 9:38:20it in the group by. So if I go and do a
  16032. 9:38:22group by and as well remove the
  16033. 9:38:24condition over here. So if you execute
  16034. 9:38:26it you're going to get the same error.
  16035. 9:38:28You are not allowed to use the window
  16036. 9:38:29function in the group by. So only with
  16037. 9:38:32the order by or as well in the select
  16038. 9:38:35clause. Okay. So now to the second rule.
  16039. 9:38:37You cannot use window functions inside
  16040. 9:38:39another window function. So that means
  16041. 9:38:41you cannot go and nest window functions
  16042. 9:38:44together. Let me show you what I mean
  16043. 9:38:45with that. So let's remove the group
  16044. 9:38:47pie. Now everything should be working.
  16045. 9:38:50Let's take and copy the whole window
  16046. 9:38:51function over here and let's just nest
  16047. 9:38:53it. So instead of sales, we're going to
  16048. 9:38:56have now window function inside another
  16049. 9:38:58window function. So as you can see this
  16050. 9:39:00is the inner window function and the
  16051. 9:39:03rest the outside is the outside window
  16052. 9:39:06function. So if I go and execute this
  16053. 9:39:08you will see that scale going to tell us
  16054. 9:39:10you cannot use the window function in
  16055. 9:39:12the context of another window function.
  16056. 9:39:14So we cannot do nesting using window
  16057. 9:39:17functions. So as you can see this is
  16058. 9:39:18another limitation for those functions.
  16059. 9:39:20All right moving to the third rule or
  16060. 9:39:22let's say an info the window function
  16061. 9:39:24will be executed after filtering the
  16062. 9:39:27data with the work clause. Let's have an
  16063. 9:39:29example. So okay so now let's say that I
  16064. 9:39:31would like to have the same
  16065. 9:39:31informations. the total sales for each
  16066. 9:39:33status but only for two products 101 and
  16067. 9:39:36102. So let's go and do that. We're
  16068. 9:39:39going to use the wear clause and then
  16069. 9:39:41we're going to say product ID in we're
  16070. 9:39:43going to specify 101 and 102. So let's
  16071. 9:39:47go and execute this. Now you can see we
  16072. 9:39:49still have two partitions. So one for
  16073. 9:39:51the delivered and one for the shipped
  16074. 9:39:53but the total sales is reduced because
  16075. 9:39:55we are only focusing on two products and
  16076. 9:39:58we filtered the whole data sets. So how
  16077. 9:40:00SQL works? First the workflow is going
  16078. 9:40:02to be executed and then the window
  16079. 9:40:05functions going to be calculated. So
  16080. 9:40:07that means first filtering and then
  16081. 9:40:08aggregations. Okay guys, now we're going
  16082. 9:40:10to move to the last rule to the most
  16083. 9:40:11interesting one and it says the
  16084. 9:40:13following. You are allowed to use the
  16085. 9:40:15window function together with the group
  16086. 9:40:17by clause only if you use the same
  16087. 9:40:19columns. So let me explain what do I
  16088. 9:40:21mean but first some coffee.
  16089. 9:40:26Let's have the following task and it
  16090. 9:40:28says rank the customers based on their
  16091. 9:40:30total sales. So now it sounds really
  16092. 9:40:33easy but if you check it you have here
  16093. 9:40:35two calculations. The first one you have
  16094. 9:40:37to rank the customers and the second
  16095. 9:40:39calculation is an aggregation. You have
  16096. 9:40:42to find the total sales for each
  16097. 9:40:43customers. Okay. So now I'm going to
  16098. 9:40:45show you step by step how I usually
  16099. 9:40:46solve those tasks. So for now let's
  16100. 9:40:49check the total sales. It is an
  16101. 9:40:51aggregation right? So we can use the sum
  16102. 9:40:53function and this function is available
  16103. 9:40:55in both group pi and as well in the
  16104. 9:40:57window function. So for now I'm going to
  16105. 9:40:59go with the group by and that's because
  16106. 9:41:01the task is very simple. We don't have
  16107. 9:41:03to show any other details. Right? So
  16108. 9:41:05it's all about aggregations. So why not
  16109. 9:41:07using the group by and now to the first
  16110. 9:41:09part where we have to rank the
  16111. 9:41:11customers. We cannot use the rank
  16112. 9:41:13function with the group by right. Groupy
  16113. 9:41:15uses only aggregations. So here we are
  16114. 9:41:17forced to use the window function. So
  16115. 9:41:19that means for the rank I'm going to use
  16116. 9:41:21window function. For the total sales I'm
  16117. 9:41:23going to use a group by. So now let's do
  16118. 9:41:25it step by step. So first we have to
  16119. 9:41:27find the total sales for each customer
  16120. 9:41:30using group by. It's very simple. So I'm
  16121. 9:41:32just going to remove all those stuff in
  16122. 9:41:34our select statements. We need the
  16123. 9:41:36customer ID and then we don't need a
  16124. 9:41:39window function over here. And then
  16125. 9:41:41after the from we're going to have a
  16126. 9:41:43group by customer ID. So now I'm just
  16127. 9:41:45grouping the customers and finding the
  16128. 9:41:47sum of all sales. Let's go and execute
  16129. 9:41:50this. So now as you can see in the
  16130. 9:41:51results we have four customers and
  16131. 9:41:53that's why we have four rows and as well
  16132. 9:41:55we have the total sales. So let's say
  16133. 9:41:57the half of the tasks is already solved.
  16134. 9:42:00Right now what is missing that we need a
  16135. 9:42:03rank. So let's go and build that. The
  16136. 9:42:05second step we're going to use the rank
  16137. 9:42:08function and we can define a window for
  16138. 9:42:09that. So over and inside it will not
  16139. 9:42:12partition the data at all because it's
  16140. 9:42:13already like grouped up. So what we're
  16141. 9:42:16going to do over order by the rank
  16142. 9:42:18function always needs an order by don't
  16143. 9:42:20worry about it we can talk about it
  16144. 9:42:21later. So now we are ranking the data
  16145. 9:42:23based on the total sales that means the
  16146. 9:42:25sum of sales. So what we're going to do
  16147. 9:42:27let's just go and copy this and put it
  16148. 9:42:30after the order buy. And now we have to
  16149. 9:42:31decide whether ascending or descending.
  16150. 9:42:33It's going to be descending. So the
  16151. 9:42:34highest sales first and then the lowest
  16152. 9:42:36sales. So now as you can see we have now
  16153. 9:42:38a rank customers and we have a window
  16154. 9:42:41function now together with the group by.
  16155. 9:42:44So now let's go and execute this and see
  16156. 9:42:46whether SQL going to allow it. So let's
  16157. 9:42:48run it and as you can see SQL runs it
  16158. 9:42:50and we will get the rank for each
  16159. 9:42:52customers. So the customer three has the
  16160. 9:42:55highest total sale. Then the customer
  16161. 9:42:57number one and the last one going to be
  16162. 9:42:59customer number two with the lowest
  16163. 9:43:00total sales. All right. So we solve the
  16164. 9:43:03tasks. We have now ranked the customers
  16165. 9:43:05based on their total sales. So as you
  16166. 9:43:07can see SQL allows you to use window
  16167. 9:43:09function together with the group by but
  16168. 9:43:11only with one rule. Anything that you
  16169. 9:43:13are using inside the window function
  16170. 9:43:15should be part of the group I. So for
  16171. 9:43:18example, we fulfilled the rule because
  16172. 9:43:19we are using the sum of sales and the
  16173. 9:43:21sum of sales is a part of the group I
  16174. 9:43:24right. So now if I go I just break the
  16175. 9:43:26rule by not using the sum just using the
  16176. 9:43:28sales. So if I just remove the sum and
  16177. 9:43:31use only the sales, SQL will not allow
  16178. 9:43:33it because the sales is not part of the
  16179. 9:43:36group I. So as you can see SQL is very
  16180. 9:43:38strict with this. If you want to use
  16181. 9:43:39everything in one query without using
  16182. 9:43:42like subqueries and so on, you have to
  16183. 9:43:44use the exact same columns. So for
  16184. 9:43:46example, if I go over here instead of
  16185. 9:43:48sales, I use the customer ID. So since
  16186. 9:43:50the customer ID is a part of the group
  16187. 9:43:53by, SQL can allows it. So be careful
  16188. 9:43:55using window function together with the
  16189. 9:43:57group by. As long as you are using the
  16190. 9:43:59same columns, nothing going to go wrong
  16191. 9:44:01and SQL going to allows it. Okay, so now
  16192. 9:44:03I'm just going to go and fix this and
  16193. 9:44:06let's run it. So now as you can see it's
  16194. 9:44:08really easy if you follow those steps.
  16195. 9:44:10First build the query using group by. So
  16196. 9:44:12don't you think about the window
  16197. 9:44:13function just build the group by and
  16198. 9:44:15then the next step the last one you go
  16199. 9:44:18and define and build the window
  16200. 9:44:19function. So with that you can solve
  16201. 9:44:21really nice analytical use cases with a
  16202. 9:44:23simple one query without having you to
  16203. 9:44:25build like some queries and so on. You
  16204. 9:44:27can go and use group by together with
  16205. 9:44:29the window functions. All right guys so
  16206. 9:44:31those are the four rules for the SQL
  16207. 9:44:33window functions.
  16208. 9:44:37All right friends, so now let's have a
  16209. 9:44:39quick recap about the SQL window
  16210. 9:44:41functions. Let's start with the
  16211. 9:44:42definition. It will go and perform
  16212. 9:44:44calculations like aggregations on top of
  16213. 9:44:47subset of data without losing the level
  16214. 9:44:49of details. So that means we can do
  16215. 9:44:51aggregations and at the same time we are
  16216. 9:44:54not losing the details. Now, of course,
  16217. 9:44:56there is a lot of similarity between the
  16218. 9:44:57window function and the group by. But
  16219. 9:44:59the main difference is that window
  16220. 9:45:01functions are very powerful and dynamic
  16221. 9:45:04compared to the group by. We have way
  16222. 9:45:06more functions than the group by. Right?
  16223. 9:45:08But now if you are doing data analyzes
  16224. 9:45:10and you have an advanced use case, then
  16225. 9:45:12you have to go and use window function.
  16226. 9:45:14It's more suitable for complex and
  16227. 9:45:16advanced data analyzes. But in the other
  16228. 9:45:19hand if you have a simple question
  16229. 9:45:21simple data analyzes then you can go and
  16230. 9:45:23use the aggregate functions using the
  16231. 9:45:25group by and of course you can go and
  16232. 9:45:27use them in the same query in the same
  16233. 9:45:29select you can go and mix the group by
  16234. 9:45:32together with the window function with
  16235. 9:45:34only one rule you have to use the same
  16236. 9:45:36columns and of course the first step is
  16237. 9:45:38to do the group by and then later you do
  16238. 9:45:40the window function in the same query.
  16239. 9:45:42And now to the next point about the
  16240. 9:45:44window components we have two main
  16241. 9:45:46components. The first one is the window
  16242. 9:45:49function and the second part is the
  16243. 9:45:51window definition using the over close.
  16244. 9:45:53And inside the overlo we can define
  16245. 9:45:55three things. If you want to divide the
  16246. 9:45:57data to create windows you can use the
  16247. 9:46:00partition by the second section we have
  16248. 9:46:02the order by in order to sort your data.
  16249. 9:46:05And the last part you can go and specify
  16250. 9:46:07a subset of data like a frame within
  16251. 9:46:10each window. Now let's move to the last
  16252. 9:46:12part. We have rules for the SQL window
  16253. 9:46:14functions. So the first thing is that if
  16254. 9:46:16you have two window functions or
  16255. 9:46:18multiple window functions, you cannot go
  16256. 9:46:20and nest them together. You have to go
  16257. 9:46:22and use multiple subqueries. The next
  16258. 9:46:25point is that you can use the window
  16259. 9:46:27function only in the select and the
  16260. 9:46:29order by clause. So for example, you
  16261. 9:46:32cannot use the window together with the
  16262. 9:46:33wear clause in order to filter the data.
  16263. 9:46:36Talking about filtering data, how SQL
  16264. 9:46:38going to go and execute the window
  16265. 9:46:40function? It's always after SQL filter
  16266. 9:46:43the data. All right. So those are the
  16267. 9:46:44basic stuff about the SQL window
  16268. 9:46:46function. So with that we have learned
  16269. 9:46:47the basics about the window functions in
  16270. 9:46:49SQL. And next we're going to start
  16271. 9:46:51talking about the functions. So the
  16272. 9:46:53first group is the window aggregate
  16273. 9:46:54functions. And here we're going to learn
  16274. 9:46:56how to summarize our data for a specific
  16275. 9:46:58group of rows. So let's
  16276. 9:47:02go. Okay guys, let's say that in our
  16277. 9:47:05data we have the following informations.
  16278. 9:47:07We have the months and the sales. Now if
  16279. 9:47:10you apply any aggregate functions in SQL
  16280. 9:47:12what going to happen SQL going to go
  16281. 9:47:14through all rows of the window or the
  16282. 9:47:16entire data and start aggregating the
  16283. 9:47:18data. So that means in the result in the
  16284. 9:47:20output SQL going to give you one single
  16285. 9:47:23aggregated value. SQL going to go and
  16286. 9:47:26summarize all those values and in the
  16287. 9:47:28output you're going to find for example
  16288. 9:47:29here the total sales it's going to be
  16289. 9:47:32175 or you can use the average or count
  16290. 9:47:34the data and so on. So the aggregate
  16291. 9:47:36functions going to deliver at the end
  16292. 9:47:39one aggregated value for a window or for
  16293. 9:47:42the entire data. Okay. So now let's have
  16294. 9:47:43a quick overview of the syntax of all
  16295. 9:47:45aggregate functions. Most of them follow
  16296. 9:47:48the same rule. So first as usual we have
  16297. 9:47:50to define the function name. And in this
  16298. 9:47:52example we have the average. Then to the
  16299. 9:47:53next part we have to define inside it as
  16300. 9:47:56well the expression. We cannot leave it
  16301. 9:47:58empty. So here we are using the sales
  16302. 9:48:00and the second rule for all functions
  16303. 9:48:02beside the count. The data type of this
  16304. 9:48:05field should be a number. And this of
  16305. 9:48:07course makes sense, right? So we cannot
  16306. 9:48:09find the average of the first name of
  16307. 9:48:11customers or something like that. So we
  16308. 9:48:13have to define a number. Then next we
  16309. 9:48:14have to define the frame. So we have the
  16310. 9:48:16partition pi and it is optional. So you
  16311. 9:48:19could use it or leave it depends. And
  16312. 9:48:21then the next one we have the order by.
  16313. 9:48:22It is as well optional. It is not a must
  16314. 9:48:25or required. So you could use it or
  16315. 9:48:27leave it. That mean the whole definition
  16316. 9:48:29of the window could be empty for the
  16317. 9:48:31aggregate functions. Let's have a look
  16318. 9:48:32to all functions. So we have the count,
  16319. 9:48:35sum, average, min, max. And as you can
  16320. 9:48:37see, only the count accepts all data
  16321. 9:48:39types as an expression or arguments. All
  16322. 9:48:42others require you to have a number as a
  16323. 9:48:44data type. And for all functions, the
  16324. 9:48:46partition by is optional. The same for
  16325. 9:48:48order by and frame. So everything is
  16326. 9:48:50optional over here. So now what we're
  16327. 9:48:52going to do with that, we're going to go
  16328. 9:48:53and deep dive into each of those
  16329. 9:48:54functions in order to understand how
  16330. 9:48:56they work, what are the use cases, and
  16331. 9:48:59of course, we're going to practice in
  16332. 9:49:00SQL. So we're going to start with the
  16333. 9:49:02first one with the function
  16334. 9:49:07count. Okay. So what is the count
  16335. 9:49:09function? It's really simple. It's going
  16336. 9:49:10to return the number of rows within each
  16337. 9:49:13window. So it's going to help you to
  16338. 9:49:14understand how many rows do you have
  16339. 9:49:16within each subset of data. So now let's
  16340. 9:49:18go and understand how SQL works with
  16341. 9:49:21this function. All right guys, so now we
  16342. 9:49:22have again this very simple example for
  16343. 9:49:24the orders and we have the following
  16344. 9:49:26informations. We have the products and
  16345. 9:49:27sales and now we want to solve very
  16346. 9:49:29simple task. How many orders do we have
  16347. 9:49:32within each products? So in order to
  16348. 9:49:34solve it, we can use the function count
  16349. 9:49:36like the following. So we can say count
  16350. 9:49:38and then we pass for it an argument or
  16351. 9:49:41expression the star. So with that we are
  16352. 9:49:43telling SQL go and count how many rows
  16353. 9:49:45do we have in our table. But we have a
  16354. 9:49:48window definition like this over
  16355. 9:49:50partition by products. So now what SQL
  16356. 9:49:52going to do? We're going to go and
  16357. 9:49:53divide the data sets into two
  16358. 9:49:55partitions. We're going to have one
  16359. 9:49:56partition for the caps and another one
  16360. 9:49:59for the gloves. So with that we have
  16361. 9:50:01prepared our data into windows and we
  16362. 9:50:03are ready to do aggregations. So how
  16363. 9:50:04many rows do we have within each window?
  16364. 9:50:06It's going to be three. So for this
  16365. 9:50:07window it's going to be three rows and
  16366. 9:50:10as well for the next window we have as
  16367. 9:50:11well three rows. So we're going to have
  16368. 9:50:13three three and three. It's very simple
  16369. 9:50:16right guys? We are just finding the
  16370. 9:50:18number of rows within each window. But
  16371. 9:50:20now with the aggregate functions we have
  16372. 9:50:21to be very careful with the null values
  16373. 9:50:24for the count star. As you can see over
  16374. 9:50:26here we are not specifying anything
  16375. 9:50:28about the sales. So we are just saying
  16376. 9:50:30find me the number of rows. So that
  16377. 9:50:32means SQL will just count the nulls as
  16378. 9:50:34one row. So that means if we are using
  16379. 9:50:36the star as an argument for the function
  16380. 9:50:38count the null will not affect anything.
  16381. 9:50:41So whether we have nulls or nots we are
  16382. 9:50:43just counting how many rows do we have
  16383. 9:50:45inside our data. But in some scenarios,
  16384. 9:50:47we should be ignoring the nulls in our
  16385. 9:50:49account. For example, let's say that I
  16386. 9:50:51would like to count how many sales do we
  16387. 9:50:53have within each product. That means if
  16388. 9:50:56we have nulls, it should not be counted.
  16389. 9:50:58So now in order to achieve this task,
  16390. 9:51:00what we're going to do, we're going to
  16391. 9:51:02use instead of a star over here, we're
  16392. 9:51:04going to have the filled sales. So now
  16393. 9:51:06with this, we are telling SQL, don't
  16394. 9:51:08just count blindly how many rows do we
  16395. 9:51:10have within each window. You should be
  16396. 9:51:12very careful with the values. Find how
  16397. 9:51:15many cells do we have within each
  16398. 9:51:17window. So now let's see what's going to
  16399. 9:51:19happen. For the first window we have
  16400. 9:51:21three cells. So we have three values. So
  16401. 9:51:23the number of rows is correct. But for
  16402. 9:51:25the next one, how many cells do we have?
  16403. 9:51:27We have two. So we have this sale and
  16404. 9:51:30then the 70. But the last one is null.
  16405. 9:51:32So it will not be counted. It will be
  16406. 9:51:34ignored. That's why we're going to get
  16407. 9:51:36in the output the value two. We have two
  16408. 9:51:39sales. So as you can see the result did
  16409. 9:51:41change and we are now more sensitive to
  16410. 9:51:43the null values. So be careful what you
  16411. 9:51:45are specifying for the count. If you are
  16412. 9:51:47using a column name like this it will
  16413. 9:51:49ignore the nulls. But if you have a star
  16414. 9:51:52it just going to go and find how many
  16415. 9:51:54rows do we have within each partition.
  16416. 9:51:56Okay. So now if you go and compare the
  16417. 9:51:57results side by side you can see that if
  16418. 9:51:59you specify a column within the count
  16419. 9:52:01function it's going to be sensitive with
  16420. 9:52:03the nulls. So it's going to ignore it
  16421. 9:52:05and will not use it within the
  16422. 9:52:07aggregations. That's why we have here
  16423. 9:52:08only two rows. But if you go and use the
  16424. 9:52:11star within the count function, what
  16425. 9:52:13going to happen? SQL just going to go
  16426. 9:52:15and count it. So we're going to find the
  16427. 9:52:17number of rows that we have inside our
  16428. 9:52:18table. And there is one more way in
  16429. 9:52:20order to do the same thing here on the
  16430. 9:52:22left side. You can use instead of star
  16431. 9:52:24you can use one. So you might find it
  16432. 9:52:26somewhere that people are using count
  16433. 9:52:29one and then the same window function
  16434. 9:52:31and we will get exactly the same result.
  16435. 9:52:33So the nulls will be counted and will
  16436. 9:52:35not be ignored. So now you might ask me
  16437. 9:52:37which one should I use the one or the
  16438. 9:52:38star? Well, I would say it doesn't
  16439. 9:52:41matter right we are getting the same
  16440. 9:52:42results and if you are thinking about
  16441. 9:52:43the performance I hardly find any
  16442. 9:52:46differences between them so you can go
  16443. 9:52:47and try both of them and stick with the
  16444. 9:52:49one that is giving you like more better
  16445. 9:52:52performance. Now we have special case
  16446. 9:52:53for the count function compared to all
  16447. 9:52:55other aggregate functions it allows any
  16448. 9:52:57data type. So that means we can use
  16449. 9:53:00numbers we can use characters dates and
  16450. 9:53:02so on. So that means we can go and
  16451. 9:53:03specify something like the product for
  16452. 9:53:05the count instead of sales. So we can go
  16453. 9:53:07over here and say product and it's going
  16454. 9:53:09to go and count how many rows do we have
  16455. 9:53:10for the product. So it's going to be
  16456. 9:53:12three over here. And since here we don't
  16457. 9:53:14have any nulls, it's going to go and
  16458. 9:53:16count it like this. So we have three
  16459. 9:53:17rows and be careful here. We are not
  16460. 9:53:19counting the unique rows. We are just
  16461. 9:53:21counting the rows that we have inside
  16462. 9:53:23our data. So this will not be counted as
  16463. 9:53:25one and this as well would not be one.
  16464. 9:53:28So we have three times the caps. That's
  16465. 9:53:30why we have here three. Okay. Okay. So
  16466. 9:53:31now we have this very simple example.
  16467. 9:53:33Find the total number of orders. This is
  16468. 9:53:35very simple task in order to find how
  16469. 9:53:37many rows, how many records do we have
  16470. 9:53:40inside the table orders. So let's go and
  16471. 9:53:43solve it. So let's start by selecting
  16472. 9:53:45just star from the table orders without
  16473. 9:53:48anything like this. So as you can see we
  16474. 9:53:50have 10 orders. It's very simple. It's
  16475. 9:53:52very easy as well. But now let's say
  16476. 9:53:54that you have thousands or millions of
  16477. 9:53:56rows. You cannot do it like this by just
  16478. 9:53:57checking the rows. What you're going to
  16479. 9:53:59do? We're going to go and use the
  16480. 9:54:00function count. So we can go over here
  16481. 9:54:02and say counts star and then let's give
  16482. 9:54:05it a name total orders. So let's go and
  16483. 9:54:09execute it. So now as you can see we got
  16484. 9:54:10only one record, one value. We don't see
  16485. 9:54:13any other details. We got the 10 orders.
  16486. 9:54:16So this is the total number of orders.
  16487. 9:54:18This is very helpful in order to
  16488. 9:54:19understand the content of your data. So
  16489. 9:54:21this we call it overall analyzes or
  16490. 9:54:24let's say having the big numbers about
  16491. 9:54:26your business. For example, how many
  16492. 9:54:28orders do we have? how many customers,
  16493. 9:54:30products, employees and so on. So having
  16494. 9:54:32those big numbers going to help us to
  16495. 9:54:34track our business to understand how
  16496. 9:54:36well we are doing with the orders and
  16497. 9:54:39with the customers and so on. So this is
  16498. 9:54:41the basics of reporting. Now let's go
  16499. 9:54:43and extend our task by saying provide
  16500. 9:54:46details such as the order ID and the
  16501. 9:54:48order dates. So let's go and do that. So
  16502. 9:54:51select order ID, order dates. And now of
  16503. 9:54:54course we cannot do it like this. So let
  16504. 9:54:56me just execute it. we will get an error
  16505. 9:54:58because here we have different level of
  16506. 9:55:00details in our select. So in order to
  16507. 9:55:02solve this what we going to do we're
  16508. 9:55:04going to use the over clause and with
  16509. 9:55:07that we are telling SQL this is a window
  16510. 9:55:09function. So now let's go and execute
  16511. 9:55:11it. So with that you can see with that
  16512. 9:55:12we have solved the task we have details
  16513. 9:55:14we have the order ID order dates. So
  16514. 9:55:16this is the highest level of details
  16515. 9:55:19since we have the order ID and as well
  16516. 9:55:21we have the highest level of
  16517. 9:55:22aggregations. we have the total number
  16518. 9:55:24of orders in the entire table orders. So
  16519. 9:55:27now let's keep going and add more stuff
  16520. 9:55:29to our task. Let's say that we want to
  16521. 9:55:31find the total number of orders but for
  16522. 9:55:34each customers. So that means this time
  16523. 9:55:36we have to go and divide our data by the
  16524. 9:55:39customers. So let's go and do that.
  16525. 9:55:41We're going to use as well a window
  16526. 9:55:42function. So count star over we have to
  16527. 9:55:45divide the data using partition by and
  16528. 9:55:48we're going to use the field customer
  16529. 9:55:50ID. So let's call it orders by customers
  16530. 9:55:54and I would like to see as well the
  16531. 9:55:55customer informations in the query.
  16532. 9:55:57That's why I'm going to go and add it.
  16533. 9:55:59All right. So that's all. Let's go and
  16534. 9:56:00execute it. Now as we learned before
  16535. 9:56:02that SQL first going to go and divide
  16536. 9:56:04the data. So that means we have four
  16537. 9:56:06customers. We're going to get four
  16538. 9:56:07windows. The first window going to be
  16539. 9:56:09for the customer ID number one. And as
  16540. 9:56:11you can see we have three rows. That's
  16541. 9:56:13why we have here three orders. And the
  16542. 9:56:15same thing for the customer two. We have
  16543. 9:56:17three orders. customer three three
  16544. 9:56:19orders but only the last customer the
  16545. 9:56:22customer ID number four we have only one
  16546. 9:56:24row and one order. So now if you go and
  16547. 9:56:25look to the total orders and the orders
  16548. 9:56:27by customers you can see now we are not
  16549. 9:56:29doing the overall analyzes we are doing
  16550. 9:56:32like comparison between different
  16551. 9:56:34categories and of course in this example
  16552. 9:56:35the category is the customers and with
  16553. 9:56:38that we can understand as well the
  16554. 9:56:39behavior of our customers. So you can
  16555. 9:56:42see that we have three customers that
  16556. 9:56:44has exactly the same amount of orders.
  16557. 9:56:47So they are very similar but we have one
  16558. 9:56:49extreme which is the customer ID number
  16559. 9:56:51four. This customer has only one order.
  16560. 9:56:54So this is the only customer that has
  16561. 9:56:56different behavior than all other
  16562. 9:56:58customers. So you see with very simple
  16563. 9:57:00query we are able now to analyze our
  16564. 9:57:02business and understand the behavior of
  16565. 9:57:04our customers. So if you divide the data
  16566. 9:57:07by partition by and using count you can
  16567. 9:57:10go and now compare stuff together. All
  16568. 9:57:12right. So now let's keep moving. Next
  16569. 9:57:13we're going to understand the special
  16570. 9:57:15cases that we have with the function
  16571. 9:57:17count. So now we have this very simple
  16572. 9:57:19task. It says find the total number of
  16573. 9:57:21customers and additionally we have to
  16574. 9:57:23provide all customers details. So I
  16575. 9:57:25think it's very easy to solve. What
  16576. 9:57:27we're going to do we're going to go and
  16577. 9:57:28select star since we need all details
  16578. 9:57:30from customers from sales customers. So
  16579. 9:57:34let's just have a look. So we have five
  16580. 9:57:36customers and the function is count star
  16581. 9:57:39over and we don't have to divide the
  16582. 9:57:41data since we have to find the total
  16583. 9:57:43number of customers for the entire table
  16584. 9:57:45and it's going to be total customers. So
  16585. 9:57:47nothing new that's it we have five
  16586. 9:57:50customers and now as we learned before
  16587. 9:57:52if you are passing the star to the count
  16588. 9:57:54function what you are telling to escale
  16589. 9:57:56is that just go and count how many rows
  16590. 9:57:58do we have inside the table customers.
  16591. 9:58:00So SQL just going to go and start
  16592. 9:58:02counting and going to say we have five
  16593. 9:58:04customers, five rows. So it doesn't
  16594. 9:58:06matter whether we have nulls inside our
  16595. 9:58:08data like in the last name or the score.
  16596. 9:58:10It's just going to count the number of
  16597. 9:58:12rows. So now let's say that we have the
  16598. 9:58:13following task. It's going to say find
  16599. 9:58:16the total number of scores for
  16600. 9:58:18customers. So what do we need with this
  16601. 9:58:19task is to find out how many scores
  16602. 9:58:21inside our data. So as you can see we
  16603. 9:58:23have around four scores but the last
  16604. 9:58:26customer doesn't have any score. So we
  16605. 9:58:28have it as a null. So the result should
  16606. 9:58:30be four. We cannot go now and use the
  16607. 9:58:32star for it because we're going to get
  16608. 9:58:34five. We have to go and count the
  16609. 9:58:35scores. So let's see how we're going to
  16610. 9:58:37do that. We're going to count as well.
  16611. 9:58:39But this time the score and the
  16612. 9:58:42definition of the window going to be
  16613. 9:58:43empty. So total scores and let's go and
  16614. 9:58:46execute this. So now we can see in the
  16615. 9:58:48results we got four scores which is very
  16616. 9:58:50correct because SQL did ignore the null
  16617. 9:58:53and SQL now focusing only on one column.
  16618. 9:58:56So focusing on those values the nulls
  16619. 9:58:58will not be counted. This is really
  16620. 9:59:00great in order to check the quality of
  16621. 9:59:01your data. So let's say that you are not
  16622. 9:59:03expecting any nulls inside your data. So
  16623. 9:59:06instead of going manually through the
  16624. 9:59:07whole records what you can do you can go
  16625. 9:59:09and find the total number of customers
  16626. 9:59:11like this and then you can go and count
  16627. 9:59:14the total number of scores and you can
  16628. 9:59:16see there is a difference. So by just
  16629. 9:59:18checking the data I can say you know
  16630. 9:59:20what we have one null without checking
  16631. 9:59:23every record in our data. So with that
  16632. 9:59:25we can check the quality of our data and
  16633. 9:59:27understand very quickly how many nulls
  16634. 9:59:30do we have in the field score and you
  16635. 9:59:32can do the same stuff for example for
  16636. 9:59:33the first name show it to you. So I'm
  16637. 9:59:36just going to go and copy this and let's
  16638. 9:59:37say first name or let's say country
  16639. 9:59:40actually. So I will go with the country.
  16640. 9:59:42So let's go with the country total
  16641. 9:59:45countries. So let's go and execute this.
  16642. 9:59:48So now if you check the result you can
  16643. 9:59:49see we have five rows with the
  16644. 9:59:51countries. So SQL going to go and focus
  16645. 9:59:53on the countries and it will not find
  16646. 9:59:54any nulls. So we have here complete
  16647. 9:59:57data. We don't have any nulls because
  16648. 9:59:59the total number of customers is equal
  16649. 10:00:01to the total number of values within the
  16650. 10:00:03country. And I can immediately find okay
  16651. 10:00:05the data quality of the country is very
  16652. 10:00:08good. All right. So now one more thing
  16653. 10:00:09about the count function that we have
  16654. 10:00:10learned before. We can use either star
  16655. 10:00:13or one in order to count how many rows
  16656. 10:00:15do we have. So let's just try it. I'm
  16657. 10:00:17just going to go and duplicate it. And
  16658. 10:00:19instead of having a star, let's have a
  16659. 10:00:21one. Just going to give it a name here.
  16660. 10:00:23It's going to be one and you are star.
  16661. 10:00:25So let's go and execute it. So now if
  16662. 10:00:27you check the output, we got exactly
  16663. 10:00:30identical results. So there is no
  16664. 10:00:32difference between those two queries.
  16665. 10:00:34It's up to you. You can try it and check
  16666. 10:00:36the performance. I usually go with the
  16667. 10:00:38star instead of one. Okay. So now we're
  16668. 10:00:39going to talk about a very important use
  16669. 10:00:41case for the SQL window function count
  16670. 10:00:43that I frequently use in my real
  16671. 10:00:45projects. The data that we use for data
  16672. 10:00:47analyzes has usually bad data quality.
  16673. 10:00:51And if we don't find those data quality
  16674. 10:00:53issues and we don't clean it before
  16675. 10:00:54doing the analyzes, what going to
  16676. 10:00:56happen? We're going to deliver bad
  16677. 10:00:58results, bad analyzes which going to
  16678. 10:01:01lead to bad decisions. And one very
  16679. 10:01:03common data quality issue that you might
  16680. 10:01:05encounter in your project or on your
  16681. 10:01:06data is that having duplicates.
  16682. 10:01:08Duplicates are really bad for doing data
  16683. 10:01:10analyszis. So now in order to discover
  16684. 10:01:13or let's say identify the duplicates in
  16685. 10:01:15our data, we can go and use the SQL
  16686. 10:01:18window function count. So now let's go
  16687. 10:01:20and have some examples. Okay. So now the
  16688. 10:01:22task says check whether the table orders
  16689. 10:01:24contains any duplicate rows. So how we
  16690. 10:01:27going to do that? By checking now the
  16691. 10:01:28table orders over here. We can see that
  16692. 10:01:31there are many orders. But how to find
  16693. 10:01:33out the duplicates? Well, the first step
  16694. 10:01:35is to understand what is the primary key
  16695. 10:01:38of the table orders. So what we usually
  16696. 10:01:40do we go and check the data model if
  16697. 10:01:42there is one. So for example for this
  16698. 10:01:44course we have the following data model
  16699. 10:01:46and we can see that it is defined that
  16700. 10:01:48the order ID is the primary key for the
  16701. 10:01:50orders. The product ID is primary key
  16702. 10:01:52for the products. So that means for our
  16703. 10:01:55table the orders we have the order ID as
  16704. 10:01:57the primary key and it should be unique.
  16705. 10:01:59It should not contain any duplicates. So
  16706. 10:02:01now let's go to our data and check the
  16707. 10:02:04order ID. By just looking at the data
  16708. 10:02:06you can see that we don't have any
  16709. 10:02:08duplicates. Rightes all of them are
  16710. 10:02:09unique. So we have 1 2 3 4 and so on.
  16711. 10:02:12But of course in real projects you
  16712. 10:02:13cannot do it like this. You have to go
  16713. 10:02:15and build a query in order to find out
  16714. 10:02:17whether the primary key is unique. But
  16715. 10:02:20now you might say the primary keys are
  16716. 10:02:22usually unique because we can define it
  16717. 10:02:23in the DDL in the rules of building the
  16718. 10:02:26table. Well that's true. If you have it
  16719. 10:02:29like this then you don't have to find
  16720. 10:02:31any duplicates. But usually in data
  16721. 10:02:33analyzes we export a lot of files and a
  16722. 10:02:35lot of data inside an extra database and
  16723. 10:02:37we don't build such a rules. So now in
  16724. 10:02:39order to check the quality of the
  16725. 10:02:41primary keys that you get from the
  16726. 10:02:42source we can use the count function. So
  16727. 10:02:45let's go and build it. I'm just going to
  16728. 10:02:46select the order ID first as a detail.
  16729. 10:02:49And now we're going to do the following.
  16730. 10:02:50So count and then star. And let's go and
  16731. 10:02:53define the window. So it's going to be
  16732. 10:02:56partition by and here the field going to
  16733. 10:02:58be the primary key. So the order ID I'm
  16734. 10:03:01checking now the quality of this field.
  16735. 10:03:04This should not contain any duplicates.
  16736. 10:03:06And now we're going to go and give it a
  16737. 10:03:07name check primary key. So now my
  16738. 10:03:10expectation is that the result of this
  16739. 10:03:13should be at maximum one. That means we
  16740. 10:03:15have one row for each primary key. And
  16741. 10:03:17that means as well it is unique. So if
  16742. 10:03:19we get anything more than one then it
  16743. 10:03:21means we have duplicates. Let's go and
  16744. 10:03:23run the query. And as you can see in the
  16745. 10:03:25results we get for each primary key one.
  16746. 10:03:28So that's great. That means we don't
  16747. 10:03:29have any duplicates inside our data and
  16748. 10:03:32the primary key is unique. So that means
  16749. 10:03:34the table orders is clean and we don't
  16750. 10:03:36have any duplicates inside it. Now let's
  16751. 10:03:39check our database. We have here another
  16752. 10:03:41table called orders archive. Let's go
  16753. 10:03:44and check the table. So first I'm just
  16754. 10:03:46going to go and select the data. So
  16755. 10:03:48select from orders archive. So sales do
  16756. 10:03:51orders archive. Let's check the results.
  16757. 10:03:55And here we can see that we have exactly
  16758. 10:03:57the same structure as the table orders.
  16759. 10:04:00So now let's go and check whether the
  16760. 10:04:01data quality is well clean. So now what
  16761. 10:04:03we're going to do, we're going to use
  16762. 10:04:04exactly the same query as before, but
  16763. 10:04:07instead of using the table orders, we're
  16764. 10:04:09going to take the orders archive. So
  16765. 10:04:11that's it. Let's go and execute it. So
  16766. 10:04:14now by checking the data, you can see
  16767. 10:04:15that we don't have everywhere one.
  16768. 10:04:17Sometimes we have two rows for the same
  16769. 10:04:20primary key, which is really bad. So we
  16770. 10:04:22have here for the order ID four we have
  16771. 10:04:24two orders with the same order ID and as
  16772. 10:04:27well for this order id six we have three
  16773. 10:04:30orders that means those stuff are
  16774. 10:04:32duplicates and they are against our data
  16775. 10:04:35model. So now what else we can do is
  16776. 10:04:36that to generate a list specifically for
  16777. 10:04:38the data quality issue where we have
  16778. 10:04:40duplicates. So anything that has one we
  16779. 10:04:43are not interested in it. In order to do
  16780. 10:04:45that we're going to use the subquery. So
  16781. 10:04:48let's say select star from and then
  16782. 10:04:51we're going to use the first query as a
  16783. 10:04:53subquery and we're going to say in our
  16784. 10:04:55filter where the check primary key is
  16785. 10:04:58higher than one. So that means I need
  16786. 10:05:00only the order ids where we have
  16787. 10:05:02duplicates. So let's go and execute
  16788. 10:05:04this. Now I have a list with the primary
  16789. 10:05:06keys where we have duplicates. So we
  16790. 10:05:08have the order ID 4 and as well the
  16791. 10:05:10order ID six. So guys, as you can see,
  16792. 10:05:12the window count function is wonderful
  16793. 10:05:14in order to find data quality issues
  16794. 10:05:16like the duplicates. All right guys, so
  16795. 10:05:18those are the four most important use
  16796. 10:05:20cases in the SQL window function count.
  16797. 10:05:22So the first one we can use it in order
  16798. 10:05:24to do overall analyzes or we can use it
  16799. 10:05:27in order to do category analyzes like we
  16800. 10:05:29have done the analyzes on the customer
  16801. 10:05:31behavior or another use case we can use
  16802. 10:05:33it in order to check the nulls inside
  16803. 10:05:35our data. And the last use case we can
  16804. 10:05:38use it in order to identify or discover
  16805. 10:05:40the data quality issue duplicates in our
  16806. 10:05:43data. So now let's go and check the next
  16807. 10:05:45function. We have the
  16808. 10:05:46[Music]
  16809. 10:05:49sum. All right. So now let's understand
  16810. 10:05:52what is the sum function. It's very
  16811. 10:05:54simple. It's going to return the sum of
  16812. 10:05:56all values within each window. So now
  16813. 10:05:58let's go and understand how SQL works
  16814. 10:06:00with this function. All right. So this
  16815. 10:06:02is very easy and we are using the same
  16816. 10:06:04simple example and now we would like to
  16817. 10:06:06find the total sales for each products.
  16818. 10:06:08So we can define like this sum of sales
  16819. 10:06:11since we are finding the total sales and
  16820. 10:06:13then we define the window like this over
  16821. 10:06:16partition by products. So as we learned
  16822. 10:06:18SQL going to go first and divide our
  16823. 10:06:20data into two windows. So one window for
  16824. 10:06:22the caps and another window for the
  16825. 10:06:25gloves right. So now after SQL define
  16826. 10:06:27the windows it's going to go and starts
  16827. 10:06:28aggregating the data. So the sum of
  16828. 10:06:31sales that means for the first window we
  16829. 10:06:33have the three sales and it's going to
  16830. 10:06:34go and just simply summarize all those
  16831. 10:06:37values. So we are adding 20 + 10 + 5 and
  16832. 10:06:40we will get the result 35. So in the
  16833. 10:06:43outputs we will get everywhere 35. So
  16834. 10:06:47that's it for the first window and as
  16835. 10:06:48you can see SQL going to go aggregate
  16836. 10:06:50the data within each window separately.
  16837. 10:06:53So that means as we are aggregating the
  16838. 10:06:54data for the caps will not check
  16839. 10:06:57anything with the gloves. So they are
  16840. 10:06:59completely separated. So now it's going
  16841. 10:07:01to go for the next window. And here we
  16842. 10:07:03have two values and a null. So again
  16843. 10:07:05here the null will just be ignored. So
  16844. 10:07:07what we going to have? We're going to
  16845. 10:07:08have 30 + 70 and the total sales for
  16846. 10:07:12that going to be 100. So as you can see
  16847. 10:07:14it is very simple, right? So 100 100 and
  16848. 10:07:18so guys that's it. It's really simple.
  16849. 10:07:19We don't have here like a lot of special
  16850. 10:07:21cases like the count function. It's only
  16851. 10:07:24that it ignores the null in the
  16852. 10:07:25calculation and as well the requirement
  16853. 10:07:28here it allows only integers or let's
  16854. 10:07:30say numbers. So we cannot go and say sum
  16855. 10:07:33the products since the products are not
  16856. 10:07:35numbers they are characters. So you can
  16857. 10:07:37only use numbers for the sum function.
  16858. 10:07:40Let's go now and have some tasks and
  16859. 10:07:42some use cases in order to practice in
  16860. 10:07:43SQL. find the total sales across all
  16861. 10:07:46orders and as well find the total sales
  16862. 10:07:48for each product and additionally we
  16863. 10:07:50have to provide some details like the
  16864. 10:07:51order ID and the order dates. So let's
  16865. 10:07:54go and do that. Select order ID, order
  16866. 10:07:56date and let's get as well the sales.
  16867. 10:07:58And now we have to find the total sales
  16868. 10:08:00across all orders. That means we're
  16869. 10:08:02going to use the window function sum
  16870. 10:08:04sales and the definition of the window
  16871. 10:08:06going to be empty since we don't have to
  16872. 10:08:08divide the data. So that's it. total
  16873. 10:08:11sales and we have to select the table
  16874. 10:08:13sales orders. So that's it. Let's go and
  16875. 10:08:16execute it. So with that as you can see
  16876. 10:08:18we got all the details that we need and
  16877. 10:08:20as well the total sales the
  16878. 10:08:22summarization of all those sales in one
  16879. 10:08:25field. So with that we have our overall
  16880. 10:08:28analyzes one big number for our
  16881. 10:08:29reporting. We know how much sales we did
  16882. 10:08:32made in the entire business. So now
  16883. 10:08:34let's go for the next task. It says
  16884. 10:08:36total sales for each product. I think
  16885. 10:08:38you know already what we're going to do.
  16886. 10:08:39So sum of sales and we're going to do it
  16887. 10:08:42like this. Partition
  16888. 10:08:44by product ID. So that's it. We're going
  16889. 10:08:48to call it sales by products. And with
  16890. 10:08:51that we are dividing the data by the
  16891. 10:08:53product. So let's go and execute it. So
  16892. 10:08:55as you can see we don't have the product
  16893. 10:08:56information. So let's go and add the
  16894. 10:08:58product ID in the query just in order to
  16895. 10:09:01analyze the results. So we can see from
  16896. 10:09:03the data that the winner is the product
  16897. 10:09:05ID 101. So as you can see we have here
  16898. 10:09:08the highest sales if you compare it with
  16899. 10:09:10the other products and the lowest one
  16900. 10:09:12going to be the products ID 105. So as
  16901. 10:09:15you can see we can use the window
  16902. 10:09:16function sum together with the partition
  16903. 10:09:18by in order to compare stuff to do
  16904. 10:09:21comparison between the products in order
  16905. 10:09:22to understand the performance for
  16906. 10:09:24example of the products. So it's really
  16907. 10:09:26great analyzes for the performance. All
  16908. 10:09:28right. Now we're going to move to very
  16909. 10:09:30interesting use case for the aggregate
  16910. 10:09:31functions not only for the sum but as
  16911. 10:09:33well for the others. It is the
  16912. 10:09:35comparison analyzes. Okay. Okay, so
  16913. 10:09:37let's understand quickly what is the
  16914. 10:09:38comparison use cases. So it's going to
  16915. 10:09:40go and compare the current value. For
  16916. 10:09:42example, let's say we are currently at
  16917. 10:09:44the month of March and the sales is 30.
  16918. 10:09:47So we're going to compare this value,
  16919. 10:09:49the current sales with an aggregated
  16920. 10:09:51value. For example, let's say the total
  16921. 10:09:53sales using the sum function. So what
  16922. 10:09:55happen if you compare the current value
  16923. 10:09:57with the total sales? You are comparing
  16924. 10:09:59here or doing analyszis called part to
  16925. 10:10:01whole analyszis where it's going to help
  16926. 10:10:03us to understand how important was the
  16927. 10:10:05sales in this month compared to the
  16928. 10:10:08total sales or we can go and compare it
  16929. 10:10:10to the best months to the highest value.
  16930. 10:10:12For example, the highest value is June
  16931. 10:10:14and we can go and compare this month
  16932. 10:10:16with the best months of the year or to
  16933. 10:10:18the lowest month in the year or we can
  16934. 10:10:20go and compare the sales of the current
  16935. 10:10:22month with the average in order to
  16936. 10:10:24understand are we above the typical
  16937. 10:10:26sales or below the average. And this is
  16938. 10:10:28very important analysis in order to
  16939. 10:10:30study and understand the performance of
  16940. 10:10:33the current data. All right, let's have
  16941. 10:10:34an example in order to understand the
  16942. 10:10:36use case. Find the percentage
  16943. 10:10:38contribution of each product sales to
  16944. 10:10:40the total sales. So let's go and solve
  16945. 10:10:42it step by step. What we're going to do,
  16946. 10:10:44we're going to go and let's select the
  16947. 10:10:46order ID and as well let's take the
  16948. 10:10:49product ID and the sales just like this
  16949. 10:10:53from sales orders. So let's go and
  16950. 10:10:56execute it. Okay. Okay. So now as you
  16951. 10:10:57can see in the results we got the first
  16952. 10:10:59part of the equation. We have the sales.
  16953. 10:11:01So nothing like a crazy over here. Now
  16954. 10:11:04we need the total sales over all data.
  16955. 10:11:07So what we're going to do we're going to
  16956. 10:11:09have the sum of sales and the definition
  16957. 10:11:12going to be empty. So this is the total
  16958. 10:11:15sales. Let's go and execute it. So now
  16959. 10:11:18we have everything for the equation. We
  16960. 10:11:19have the sales and as well the total
  16961. 10:11:21sales and that is enough in order to
  16962. 10:11:23find the percentage of the contribution.
  16963. 10:11:25So the calculation for that is going to
  16964. 10:11:27be very simple. We're going to divide
  16965. 10:11:28the sales by the total sales. So it's
  16966. 10:11:32really simple. Let's go and do that.
  16967. 10:11:33It's going to be the sales divided by
  16968. 10:11:36the total sales. So we're going to go
  16969. 10:11:37and copy the whole window function over
  16970. 10:11:40here. And then we're going to multiply
  16971. 10:11:41it with 100. So that's it. Let's go and
  16972. 10:11:44execute it. So now you notice that in
  16973. 10:11:46the output we got zeros. This is because
  16974. 10:11:48of the data type. So now if we go to our
  16975. 10:11:50table over here on the left side you can
  16976. 10:11:52see that the orders has the data type of
  16977. 10:11:56integer. So if you divide integers you
  16978. 10:11:58will not get a float or decimal number.
  16979. 10:12:00You have to go and change the data type.
  16980. 10:12:02So now what we're going to do we're
  16981. 10:12:03going to go and change the data type for
  16982. 10:12:05one of them. So it's enough for the
  16983. 10:12:06sales over here. So we're going to use
  16984. 10:12:08the following statement. So cast sales
  16985. 10:12:11as floats. So that's it. I'm just
  16986. 10:12:13converting the integer to floats. So
  16987. 10:12:15that's it. Let me just give it a name.
  16988. 10:12:17So it's going to be percentage of total.
  16989. 10:12:20So that's it. Let's go and execute it.
  16990. 10:12:23So now in the output, you can see we got
  16991. 10:12:24now the percentage of the total or let's
  16992. 10:12:27say percentage of contribution. So now
  16993. 10:12:29what we're going to do with that, we're
  16994. 10:12:30going to go and round those numbers
  16995. 10:12:31because we have a lot of decimals. In
  16996. 10:12:33order to do that, we're going to use the
  16997. 10:12:35round function like this. Then we're
  16998. 10:12:37going to have two decimals. And let's go
  16999. 10:12:40and execute it. So now, as you can see,
  17000. 10:12:42it is really easier to read because we
  17001. 10:12:44have only two decimals. And we can find
  17002. 10:12:46immediately that the order rate is the
  17003. 10:12:48highest contributor to the total. So
  17004. 10:12:51this is what we call part to whole
  17005. 10:12:52analyszis where we find the percentage
  17006. 10:12:55of total. It is very common analyzes in
  17007. 10:12:57order to understand the performance of
  17008. 10:13:00each order compared to the total. So
  17009. 10:13:02this is an example how the window
  17010. 10:13:04function is helping us here to compare
  17011. 10:13:06the current value with an aggregated
  17012. 10:13:08value. All right everyone. So that's all
  17013. 10:13:10for the window function sum. Next we're
  17014. 10:13:12going to talk about the average
  17015. 10:13:13function.
  17016. 10:13:17All right. So now let's understand what
  17017. 10:13:19is an average function. As the name
  17018. 10:13:21says, it's going to find the average of
  17019. 10:13:23values within each window. So now let's
  17020. 10:13:25go and understand how SQL works with the
  17021. 10:13:28average. All right. So now back to our
  17022. 10:13:29very simple example and the task says
  17023. 10:13:31find the average sales for each product.
  17024. 10:13:33So it's really easy. We're going to use
  17025. 10:13:35the average then pass to it the column
  17026. 10:13:37sales and we define the window like this
  17027. 10:13:39partition by products. So the first
  17028. 10:13:41thing that SQL going to go is to define
  17029. 10:13:43the window. So it's going to divide our
  17030. 10:13:45data into two partitions. One for the
  17031. 10:13:47caps and one for the gloves. And now I
  17032. 10:13:49hope that everyone knows how to
  17033. 10:13:50calculate the average. So as you know
  17034. 10:13:52that it's going to go and summarize all
  17035. 10:13:54the values and divide it by the number
  17036. 10:13:56of rows. So it's going to go and
  17037. 10:13:57summarize 20 + 10 + 5 and divide it on
  17038. 10:14:01three rows and the output going to be
  17039. 10:14:0311. So we're going to get it for each
  17040. 10:14:05row. So as you can see SQL just ignored
  17041. 10:14:08everything in the next window. We are
  17042. 10:14:10focusing only on the caps. Now it's
  17043. 10:14:12going to go to the second window and
  17044. 10:14:14start doing the same aggregations. But
  17045. 10:14:15here we have the special case of null.
  17046. 10:14:17So the null is going to be ignored in
  17047. 10:14:19the calculations and we're going to have
  17048. 10:14:20it like this. It's going to say you know
  17049. 10:14:22what 30 + 70 and we are just including
  17050. 10:14:25two rows. So it's going to be divided by
  17051. 10:14:27two and the average going to be 50. So
  17052. 10:14:29we will get the result 50 for each row
  17053. 10:14:32and we are completely ignoring the
  17054. 10:14:34nulls. But now we might be in scenario
  17055. 10:14:36where your users understand the business
  17056. 10:14:37like this. If we find a null in the
  17057. 10:14:40sales it means a zero. So there is no
  17058. 10:14:42sales and it is actually a zero. But we
  17059. 10:14:44store it in the database as a null. So
  17060. 10:14:46that means the average that we have
  17061. 10:14:47provided is not really correct. We have
  17062. 10:14:49to divide by three. So that means first
  17063. 10:14:52we have to handle the nulls before doing
  17064. 10:14:54the aggregations before finding the
  17065. 10:14:56average. Now we're going to have a whole
  17066. 10:14:58chapter on how to handle nulls in SQL.
  17067. 10:15:00What are the different functions? But
  17068. 10:15:02for now we're going to go with the
  17069. 10:15:03functions qualisk. Okay. So now what
  17070. 10:15:05we're going to do, we will not use the
  17071. 10:15:06sales as it is. First we're going to
  17072. 10:15:08handle the nulls. So that means we're
  17073. 10:15:10going to use the qualisk sales and
  17074. 10:15:13replace it with zeros. So as you can see
  17075. 10:15:15we are not using immediately the sales
  17076. 10:15:17we are handling it first and then we're
  17077. 10:15:19going to find the average. So SQL going
  17078. 10:15:21to go over here and if it finds any null
  17079. 10:15:24going to go and replace it with zero and
  17080. 10:15:26that's going to have then an effect on
  17081. 10:15:28our average over here. So it going to be
  17082. 10:15:3030 + 7 + 70 but now plus 0. And now we
  17083. 10:15:33have three rows. So instead of dividing
  17084. 10:15:36by two, it's going to go and divide it
  17085. 10:15:37by three and the total result going to
  17086. 10:15:39be like this 33. So that means we're
  17087. 10:15:41going to have in the output 33 for each
  17088. 10:15:44row and with that we are now fulfilling
  17089. 10:15:47the expectation from the business. If
  17090. 10:15:49you have a null it's going to be handled
  17091. 10:15:50as zero and the result going to be more
  17092. 10:15:52accurate. You see right it is very
  17093. 10:15:54tricky. If you are doing data analyszis
  17094. 10:15:56and aggregations be very careful with
  17095. 10:15:58the nulls. understand them, understand
  17096. 10:16:01what they mean for the business, handle
  17097. 10:16:03them correctly in order to get correct
  17098. 10:16:05results in your analysis. So now let's
  17099. 10:16:08go back in order to practice SQL using
  17100. 10:16:10some tasks and use cases. Okay, so let's
  17101. 10:16:13start with the basics. We have the
  17102. 10:16:14following task. Find the average sales
  17103. 10:16:16across all orders and as well find the
  17104. 10:16:18average sales for each product. And
  17105. 10:16:20don't forget the details. So now let's
  17106. 10:16:22go and solve it step by step. So select
  17107. 10:16:24order ID, order date, and let's get the
  17108. 10:16:28sales as well. And let's go and find the
  17109. 10:16:30average sales. So it's going to be a
  17110. 10:16:31window function. And we have the sales
  17111. 10:16:33inside it. The usual stuff. The window
  17112. 10:16:35going to be empty. So average sales,
  17113. 10:16:38we're going to call it the table going
  17114. 10:16:40to be sales orders. So that's it. Let's
  17115. 10:16:44go and execute it. Oh, we have to select
  17116. 10:16:46everything of course. So what SQL did in
  17117. 10:16:48the output, it going to go and summarize
  17118. 10:16:50all those values and then divide it by
  17119. 10:16:5210. So with that we have the average
  17120. 10:16:54sales of 38. Very easy. So this is again
  17121. 10:16:57what we call an overall analyzis. Let's
  17122. 10:16:59move to the next one. Find the average
  17123. 10:17:01sales for each products. So again we're
  17124. 10:17:03going to go and build the window
  17125. 10:17:05function like this. Average sales over
  17126. 10:17:09and we're going to divide it by product
  17127. 10:17:11ID. And we're going to call it average
  17128. 10:17:13sales by products. And we're going to go
  17129. 10:17:16and add the product ID in the query. So
  17130. 10:17:19that's it. Let's go and execute. And we
  17131. 10:17:22missed something here. So it is the
  17132. 10:17:24partition by going to execute again. So
  17133. 10:17:27with that we have the following data. So
  17134. 10:17:28now SQL going to go and divide the data.
  17135. 10:17:30So for example for this products we have
  17136. 10:17:32those four orders. So what going to
  17137. 10:17:34happen is still going to go and
  17138. 10:17:35summarize the four values and then
  17139. 10:17:38divide it by four. That's why we have
  17140. 10:17:39here 35. The same thing for the next
  17141. 10:17:42order. It's going to divide it by three.
  17142. 10:17:44And the last one is just going to divide
  17143. 10:17:46it by one. That's why we have 60. So as
  17144. 10:17:48you can see the aggregation can done
  17145. 10:17:50separately for each window and this is
  17146. 10:17:52as well very nice way in order to
  17147. 10:17:54compare the averages between the
  17148. 10:17:56different products. Okay. So now let's
  17149. 10:17:58have an example in order to learn how to
  17150. 10:18:00deal with the nulls. Let's say that we
  17151. 10:18:01have the following task. Find the
  17152. 10:18:03average scores of customers and show as
  17153. 10:18:06well additional informations like the
  17154. 10:18:08customer ID and the last name. So let's
  17155. 10:18:10go and solve this. We are now targeting
  17156. 10:18:13the table customers. So let's just
  17157. 10:18:16select it first.
  17158. 10:18:18like this. And now let's go and include
  17159. 10:18:20the customer ID and the last name. And
  17160. 10:18:24let's have as well the score. But this
  17161. 10:18:26time we're going to go and find the
  17162. 10:18:27average score. So it's going to be the
  17163. 10:18:29average score. And since we don't
  17164. 10:18:31partition the data, we're going to leave
  17165. 10:18:33the definition like this and it's going
  17166. 10:18:35to be the average score. So that's it.
  17167. 10:18:39Let's go and execute it. So now as you
  17168. 10:18:40can see, we have the average score of
  17169. 10:18:42625. SQL is going to go and summarize
  17170. 10:18:45the four values and divide it by four.
  17171. 10:18:48But here we have a null. So now we have
  17172. 10:18:50to understand the business or ask about
  17173. 10:18:51it what the null means in the scores of
  17174. 10:18:54the customers. Is it zero or is it
  17175. 10:18:56something empty? If it's zero then the
  17176. 10:18:59average that we have is wrong because it
  17177. 10:19:00should be divided by five and not four.
  17178. 10:19:03So let's say it's zero that means we
  17179. 10:19:06have to go and handle the nulls. So what
  17180. 10:19:07we're going to do now we're going to go
  17181. 10:19:08and use the function kalis. So qualis
  17182. 10:19:12and for the score and replace the null
  17183. 10:19:15with zero. So you are the customer
  17184. 10:19:17score. Let's go and execute this. So now
  17185. 10:19:19as you can see if there is a value it's
  17186. 10:19:21going to be exactly the same value but
  17187. 10:19:23only if we have null it's going to be
  17188. 10:19:24replaced with zero. So now let's go and
  17189. 10:19:26correct the average. I'm just going to
  17190. 10:19:28do it like this. So let's go and copy
  17191. 10:19:31the whole thing. But now instead of
  17192. 10:19:33using the score we're going to use the
  17193. 10:19:35score that is handled with nulls. So I'm
  17194. 10:19:37just going to go and replace it like
  17195. 10:19:39this. So here without nulls. So let's go
  17196. 10:19:43and execute it. So now as you can see we
  17197. 10:19:45are getting more valid result at the
  17198. 10:19:47output compared to the previous one. And
  17199. 10:19:49this is only for the case if the null
  17200. 10:19:51means zero. So guys as you see be very
  17201. 10:19:54careful with the nulls especially if you
  17202. 10:19:55are doing aggregations and handle it
  17203. 10:19:57correctly before doing any aggregations
  17204. 10:19:59like the average. All right. Moving on
  17205. 10:20:01to the last use case. We have the
  17206. 10:20:03comparison analyzes and the task says
  17207. 10:20:05find all orders where the sales are
  17208. 10:20:08higher than the average sales across all
  17209. 10:20:10orders. So that means we have to go and
  17210. 10:20:13compare the current sales with the
  17211. 10:20:15aggregated value and this time the
  17212. 10:20:17average of sales. So now let's go and do
  17213. 10:20:18it step by step. So what we're going to
  17214. 10:20:20do we're going to go and select of
  17215. 10:20:22course the order ID. What do we need the
  17216. 10:20:24let's take the product ID and we need
  17217. 10:20:26the current sales. So it's going to be
  17218. 10:20:28the sales as it is and that's it for
  17219. 10:20:31now. So from sales orders. So that's it.
  17220. 10:20:35Let's go and execute it. So now by
  17221. 10:20:37checking the result, you can see that we
  17222. 10:20:39got the first part of the equation,
  17223. 10:20:40right? We have the sales for each order.
  17224. 10:20:43Now we need the second part, the average
  17225. 10:20:45sales across all orders. In order to do
  17226. 10:20:47that, we're going to go and use the
  17227. 10:20:48window function average sales and we're
  17228. 10:20:51going to use over since across all
  17229. 10:20:53orders that means it's going to be
  17230. 10:20:54empty. So let's give it a name average
  17231. 10:20:56sales. So let's go and execute it. So
  17232. 10:20:59now in the output we got the average
  17233. 10:21:01sales. So it's going to be 38. So now we
  17234. 10:21:03need all the orders that are higher than
  17235. 10:21:06the average. So as you can see for
  17236. 10:21:07example the order one is not higher but
  17237. 10:21:10the order for is higher than the
  17238. 10:21:12average. So in order to filter the data
  17239. 10:21:14we cannot use the window function in the
  17240. 10:21:17wear close. Right? So what we're going
  17241. 10:21:19to do sadly we're going to go and use
  17242. 10:21:21the subquery. So it's going to be like
  17243. 10:21:23this. select star from and then we're
  17244. 10:21:27going to define the condition outside
  17245. 10:21:30the subquery. So it's going to be where
  17246. 10:21:32the sales is higher than the average
  17247. 10:21:35sales. So that's it. Let's go and
  17248. 10:21:38execute it. And now as you can see it's
  17249. 10:21:40very simple. We got all the orders that
  17250. 10:21:42are higher than the average. Right? So
  17251. 10:21:44you can see all those sales are higher
  17252. 10:21:46than the average. It would be nice if we
  17253. 10:21:48can do all those stuff in the first
  17254. 10:21:50query. But since we cannot do that, we
  17255. 10:21:53need to use the subqueries in order to
  17256. 10:21:55filter the data afterward. So that we
  17257. 10:21:58can understand the importance of the
  17258. 10:21:59comparison analyszis. For example, here
  17259. 10:22:01we are finding or evaluating the data
  17260. 10:22:04whether they are above the average or
  17261. 10:22:06below the average. And this is very
  17262. 10:22:08important in the business analyzes. All
  17263. 10:22:10right, everyone. So that's all for the
  17264. 10:22:11window function average. Next, we're
  17265. 10:22:13going to talk about two very interesting
  17266. 10:22:15functions, the min and max.
  17267. 10:22:20All right guys, so what is min and max
  17268. 10:22:22functions? They are very simple but yet
  17269. 10:22:25very powerful functions for analytics.
  17270. 10:22:27So the min simply is the function that
  17271. 10:22:29can return the minimum or let's say the
  17272. 10:22:31lowest value within a window where the
  17273. 10:22:34max it's exactly the opposite. It's
  17274. 10:22:36going to find the maximum value or the
  17275. 10:22:38highest value within a window. So now
  17276. 10:22:41let's go and understand how SQL works
  17277. 10:22:43with these functions. All right. So now
  17278. 10:22:44we have the same data and we have two
  17279. 10:22:46tasks. First we have to find the lowest
  17280. 10:22:49sales for each product. And the second
  17281. 10:22:51one side by side we would like to find
  17282. 10:22:53the highest sales for each product. So
  17283. 10:22:55we're going to go and use the min max.
  17284. 10:22:57And as you can see the syntax is very
  17285. 10:22:58simple. Min the sales and then the
  17286. 10:23:00partition going to be by the products.
  17287. 10:23:02And here as well the same stuff but
  17288. 10:23:04having the max. Okay. So now let's see
  17289. 10:23:06how going to execute the first query. As
  17290. 10:23:08usual first it's going to prepare the
  17291. 10:23:09data. So it's going to split the data
  17292. 10:23:11into two windows. One for the caps and
  17293. 10:23:13another one for the gloves. And after
  17294. 10:23:15that it's going to search for the lowest
  17295. 10:23:17sales within each window separately. So
  17296. 10:23:20for the first window we have the
  17297. 10:23:21following values 20 10 and five. And of
  17298. 10:23:24course the lowest value going to be the
  17299. 10:23:26five. So that's why SQL going to find it
  17300. 10:23:28over here. And everywhere for this
  17301. 10:23:30window it's going to be the value five.
  17302. 10:23:32So we have it as the lowest sales for
  17303. 10:23:34the product caps. So now it's going to
  17304. 10:23:36jump to the next window for the gloves
  17305. 10:23:37and start searching the values. So as
  17306. 10:23:39you can see we have 30 70 and null. Null
  17307. 10:23:42will be ignored. So null will not be
  17308. 10:23:44considered as the lowest value. So SQL
  17309. 10:23:46going to find the lowest sales with the
  17310. 10:23:4830. So it's going to be actually the
  17311. 10:23:50first row within this window and the
  17312. 10:23:52value the output going to be 30 for each
  17313. 10:23:55row. So that's it. It's very simple,
  17314. 10:23:56right? Now let's move to the next one.
  17315. 10:23:58We have the same stuff but using max. So
  17316. 10:24:00the data is partitions and for the first
  17317. 10:24:02partition what is the highest value?
  17318. 10:24:04It's going to be the first row, right?
  17319. 10:24:06The 20. So SQL going to find it and in
  17320. 10:24:08the output we will get the highest sales
  17321. 10:24:1120 for this window and then it's going
  17322. 10:24:12to go to the second window and search
  17323. 10:24:14for the highest value. So here we have
  17324. 10:24:16two values 30 and 70 and it's going to
  17325. 10:24:18be the 70 right. So it's going to point
  17326. 10:24:20it over here and in the output we will
  17327. 10:24:22get everywhere 70. So guys it's really
  17328. 10:24:24simple right now let's back to our
  17329. 10:24:26scenario in the average where in our
  17330. 10:24:28business we understand nulls as zero in
  17331. 10:24:30the sales. So that means first we have
  17332. 10:24:32to handle the nulls and replace it with
  17333. 10:24:34zero and then we're going to go and
  17334. 10:24:36search for the value. So what's going to
  17335. 10:24:38happen? We're going to go and replace
  17336. 10:24:40nulls with zero. For the max nothing
  17337. 10:24:42going to change the highest value going
  17338. 10:24:44to be 70 and we're going to get the same
  17339. 10:24:45output. But for the min now we have new
  17340. 10:24:49lowest value. So it's not anymore the
  17341. 10:24:5130. It's actually the zero. So SQL going
  17342. 10:24:54to go over here and replace the 30 with
  17343. 10:24:56nulls. So nulls is the lowest sales for
  17344. 10:25:00the product gloves. So again guys, the
  17345. 10:25:02nulls are very tricky and those
  17346. 10:25:04functions are really sensitive with the
  17347. 10:25:05nulls. Understand what the nulls means
  17348. 10:25:08and handle it correctly so that you get
  17349. 10:25:10correct results in the output. So that's
  17350. 10:25:12it. Let's go back to SQL to have some
  17351. 10:25:14tasks and use cases in order to practice
  17352. 10:25:16SQL. All right everyone, let's start
  17353. 10:25:18with the basic stuff. find the highest
  17354. 10:25:20and lowest sales of all orders and as
  17355. 10:25:22well find the highest and lowest sales
  17356. 10:25:24for each product and we have to provide
  17357. 10:25:26additional informations. So let's go and
  17358. 10:25:29solve it. Select order ID order and
  17359. 10:25:33let's take as well the product ID. Now
  17360. 10:25:34let's find the highest sales of all
  17361. 10:25:36orders. It going to be the max function
  17362. 10:25:39for the sales and the window function
  17363. 10:25:42going to be empty since of all orders.
  17364. 10:25:44So you are the highest sales. Let's go
  17365. 10:25:47for the lowest sales of all orders. It's
  17366. 10:25:48going to be exactly the opposite. The
  17367. 10:25:50main function for sales over then we
  17368. 10:25:53have the lowest sales. So I'm just going
  17369. 10:25:56to make it bigger capital. So let's
  17370. 10:25:58select the table sales orders. So I
  17371. 10:26:02think that's it. Let's have as well the
  17372. 10:26:04sales actually. All right. So now let's
  17373. 10:26:06go and execute it. So now this is very
  17374. 10:26:08simple, right? This is the wholesales.
  17375. 10:26:10What is the highest sales? We have the
  17376. 10:26:1390 of the order eight. So, as you can
  17377. 10:26:15see, we have now the highest sales, the
  17378. 10:26:1790, and the lowest sales is the 10. The
  17379. 10:26:20first order is the lowest. So, it's very
  17380. 10:26:22easy. Now, we're going to go and repeat
  17381. 10:26:24the same stuff for the product. So, we
  17382. 10:26:26have go and partition the data by the
  17383. 10:26:28product ID. So, what I'm going to do,
  17384. 10:26:29I'm just going to go and copy paste
  17385. 10:26:31stuff around. So, the first one going to
  17386. 10:26:33be partition by the product ID. So,
  17387. 10:26:36highest sales by product. And the next
  17388. 10:26:39one going to be the same stuff. Copy
  17389. 10:26:41paste by the product. So that's it.
  17390. 10:26:45Let's go and execute it. So now again
  17391. 10:26:48the data going to be partitioned and
  17392. 10:26:49divided by the product. So for the first
  17393. 10:26:52window what is the highest sales? It's
  17394. 10:26:54going to be the 90 and the lowest sales
  17395. 10:26:55is going to be the 10. So it's exactly
  17396. 10:26:57like the overall rights now let's go to
  17397. 10:26:59the second window over here. We can see
  17398. 10:27:01that the lowest or the highest sales is
  17399. 10:27:03the 60 the first one and the lowest this
  17400. 10:27:05time is 15. And this is great in order
  17401. 10:27:08to see that the SQL going to execute
  17402. 10:27:10each of those functions for each window
  17403. 10:27:12separately. So let's go to the last
  17404. 10:27:14window. It's funny one. So the sales is
  17405. 10:27:1660 and we have only one row. So it's
  17406. 10:27:18going to be the highest and as well the
  17407. 10:27:19lowest sales. So with that as you can
  17408. 10:27:21see we can define a range for each
  17409. 10:27:22product and the range are different from
  17410. 10:27:24each product to another one. For
  17411. 10:27:26example, for this product 101 the range
  17412. 10:27:28from 10 until 90. But for the second
  17413. 10:27:31product we have it between 15 and 60.
  17414. 10:27:33Okay guys, let's move to the next one
  17415. 10:27:35which is one of my favorites in the
  17416. 10:27:36window function where we filter the data
  17417. 10:27:39using the minmax functions. Let's have
  17418. 10:27:41the following task. It says show the
  17419. 10:27:43employees who have the highest salaries.
  17420. 10:27:46So this sounds very simple but we can
  17421. 10:27:48use the help of window functions in
  17422. 10:27:50order to solve it. So now we are working
  17423. 10:27:52with the table employees. Let's just
  17424. 10:27:54select the data. So select from sales
  17425. 10:27:58employees. So that's it. Let's go and
  17426. 10:28:01execute it. So now we have five
  17427. 10:28:03employees and we have those different
  17428. 10:28:04salaries. Let's go and find the highest
  17429. 10:28:08salary. So max salary and let's use the
  17430. 10:28:11window function over but we don't
  17431. 10:28:13partition the data at all. So it's going
  17432. 10:28:15to be like this highest salary. So let's
  17433. 10:28:18go and execute it. And now by checking
  17434. 10:28:21the results we got a new column called
  17435. 10:28:22highest salary and inside it we have the
  17436. 10:28:2590k. So if you check those five salaries
  17437. 10:28:27you can see that the highest is from the
  17438. 10:28:30employee Michael. But still the task is
  17439. 10:28:32not solved. We have to show only the
  17440. 10:28:34employees who have the highest salaries.
  17441. 10:28:36So we have somehow to filter the data
  17442. 10:28:38and only show this employee. So in order
  17443. 10:28:41to do that we have to use the subqueries
  17444. 10:28:44since we cannot use the window function
  17445. 10:28:46in the wear clause. So what we're going
  17446. 10:28:48to do select star from and then our
  17447. 10:28:52first query going to be the inner query.
  17448. 10:28:55So we have the following condition. It's
  17449. 10:28:57going to be the
  17450. 10:28:59salary should be equal to the highest
  17451. 10:29:02salary. So it's very simple. So with
  17452. 10:29:04that we are comparing the salaries with
  17453. 10:29:06the highest salaries. If there is a
  17454. 10:29:08match the data going to be presented. So
  17455. 10:29:10let's go and execute that. And that's
  17456. 10:29:12it. As you can see we got the employee
  17457. 10:29:14with the highest salary. But if there
  17458. 10:29:16are like multiple employees with the
  17459. 10:29:18same salary of 90k of course we're going
  17460. 10:29:20to get it in the results. I think
  17461. 10:29:22Michael going to need a new job. Right.
  17462. 10:29:24This is the worst.
  17463. 10:29:30So this is another use case for the
  17464. 10:29:32window functions minmax. All right. So
  17465. 10:29:34now we come to the use case of the
  17466. 10:29:36comparison analyzers where we want to
  17467. 10:29:38compare the current sales with the
  17468. 10:29:40highest and the lowest value. So we have
  17469. 10:29:42the following task. It says find the
  17470. 10:29:44deviation of each sales from the minimum
  17471. 10:29:47and the maximum sales amount. So now as
  17472. 10:29:49you can see this is our sales. This is
  17473. 10:29:50the highest and this is the lowest. So
  17474. 10:29:52now we just have to go and subtract the
  17475. 10:29:54data from each others in order to get
  17476. 10:29:56the deviation. So it's very simple.
  17477. 10:29:58Let's get the first deviation where
  17478. 10:30:00we're going to go and subtract the sales
  17479. 10:30:02with the lowest value. So it's going to
  17480. 10:30:05be like this. So now what we are doing
  17481. 10:30:06over here, we are subtracting the sales
  17482. 10:30:08from the lowest sales of all records. So
  17483. 10:30:12we're going to go and call you
  17484. 10:30:14deviation from min. So let's go and
  17485. 10:30:17execute it. So now we can see from those
  17486. 10:30:19values how far is the current value from
  17487. 10:30:23the extreme. The extreme here is the
  17488. 10:30:25lowest value. So this is a really great
  17489. 10:30:27way on to analyze the extremes in your
  17490. 10:30:29data. So now as we are near to the
  17491. 10:30:31extreme the value going to be low. So as
  17492. 10:30:34you can see here we have a zero. This is
  17493. 10:30:35the lowest because we have it exactly as
  17494. 10:30:38the extreme. So actually this is our
  17495. 10:30:41value. So the 10. Now the next one is
  17496. 10:30:43little bit far away from the extreme
  17497. 10:30:45which is 15. So we have it here as a
  17498. 10:30:47five. So this is not far away from our
  17499. 10:30:49extreme value. And then if you check
  17500. 10:30:51this value over here we have it 80. So
  17501. 10:30:53the distance is very far away from our
  17502. 10:30:56extreme value the lowest sales. So this
  17503. 10:30:58is really nice analyszis in order to
  17504. 10:31:00analyze and evaluate the sales of your
  17505. 10:31:03data. Now of course we can go and
  17506. 10:31:05evaluate our data with an another
  17507. 10:31:07extreme which is the highest sales. So
  17508. 10:31:10in order to do that we're going to first
  17509. 10:31:12say let's get the highest sorry this one
  17510. 10:31:15the highest sales and subtract it from
  17511. 10:31:18the sales. So you are the deviation from
  17512. 10:31:21the max. So let's go and execute it. So
  17513. 10:31:24now we can see in the output we're going
  17514. 10:31:26to get exactly the opposite distances.
  17515. 10:31:28So the order number one is the farthest
  17516. 10:31:31from the extreme. So as you can see we
  17517. 10:31:33have the value of 80 and the order eight
  17518. 10:31:36is the identical one. So that's why we
  17519. 10:31:38have the distance of zero. So now we can
  17520. 10:31:40see as well very quickly which data
  17521. 10:31:42points are the nearest to the extreme to
  17522. 10:31:44the highest sales. So as you can see
  17523. 10:31:46guys using the window function min and
  17524. 10:31:48max it is very powerful in order to
  17525. 10:31:50understand and evaluate your data points
  17526. 10:31:53to the
  17527. 10:31:54[Music]
  17528. 10:31:57extremes. All right everyone so now
  17529. 10:31:59we're going to focus on very important
  17530. 10:32:00use case. One of the must know use cases
  17531. 10:32:03for data aggregations is doing running
  17532. 10:32:05total and rolling total. These two
  17533. 10:32:08concepts are very important for data
  17534. 10:32:10analyszis and doing reporting that you
  17535. 10:32:12must know. The key use case for those
  17536. 10:32:14two concept is to do tracking. For
  17537. 10:32:17example, we can go and track the current
  17538. 10:32:19total sales with the target sales in our
  17539. 10:32:22business. And as well, it's great in
  17540. 10:32:24order to do historical analyszis for the
  17541. 10:32:26trends. Okay. So now the question is
  17542. 10:32:28what is running a rolling total. They
  17543. 10:32:31are basically very similar. They're
  17544. 10:32:32going to go and aggregate a sequence of
  17545. 10:32:34members and the aggregation going to get
  17546. 10:32:36updated each time we add a new member to
  17547. 10:32:38the sequence. A sequence could be like a
  17548. 10:32:41time sequence. That's why we call this
  17549. 10:32:43type an analyzes over time. So now we
  17550. 10:32:46still have the question, what is the
  17551. 10:32:47difference between the running and the
  17552. 10:32:49rolling totals. The running total going
  17553. 10:32:51to go and aggregate everything from the
  17554. 10:32:53beginning until the current data point
  17555. 10:32:56without dropping off any old data. Where
  17556. 10:32:58on the other hand in the rolling total
  17557. 10:33:00it going to go and focus on a specific
  17558. 10:33:02time window like the last 30 days or the
  17559. 10:33:05last two monthses and each time we add a
  17560. 10:33:07new member or a new data point to the
  17561. 10:33:09window we will be dropping off the
  17562. 10:33:12oldest data point in the window and with
  17563. 10:33:14this we're going to get the effect of
  17564. 10:33:16rolling or let's say shifting window
  17565. 10:33:18okay I totally understand if this might
  17566. 10:33:20be complicated now let's go and have
  17567. 10:33:22very simple example in order to
  17568. 10:33:23understand this concept and as well how
  17569. 10:33:25we can solve it using SQL all right guys
  17570. 10:33:27so now We have very simple example. We
  17571. 10:33:29have the months and sales and we have it
  17572. 10:33:31twice because I want to show you side by
  17573. 10:33:33side how SQL works with the running
  17574. 10:33:35total and the rolling total. So now what
  17575. 10:33:37is the task on the left side? We want to
  17576. 10:33:39find the running total of sales for each
  17577. 10:33:42month and on the right side we would
  17578. 10:33:44like to find three month rolling total
  17579. 10:33:47of the sales for each month. So they
  17580. 10:33:49sound very similar but on the right side
  17581. 10:33:51we have only fixed window. So now how we
  17582. 10:33:54can solve this using SQL. On the left
  17583. 10:33:56side we can use sum of sales. So we want
  17584. 10:33:58to go and aggregate all the sales using
  17585. 10:34:00the sum function. And the definition for
  17586. 10:34:02the window going to be like this order
  17587. 10:34:04by month and of course you can go and do
  17588. 10:34:06anything like you can have here an
  17589. 10:34:07average. And if you use an average with
  17590. 10:34:09order by you will get the running
  17591. 10:34:11average or the running max or the
  17592. 10:34:13running count and so on. So that means
  17593. 10:34:16always if you go and mix an aggregate
  17594. 10:34:18function together with an order by you
  17595. 10:34:20will generate an effect of running
  17596. 10:34:22total. Now on the right side we can have
  17597. 10:34:24the same stuff. So we can have an
  17598. 10:34:26aggregate function together with order
  17599. 10:34:27by. So sum of sales, order by month. So
  17600. 10:34:31far we have everything like the left
  17601. 10:34:32side, right? But now you might ask why
  17602. 10:34:34is going to go and generate this effect
  17603. 10:34:36the running total. We didn't here
  17604. 10:34:38specify like crazy stuff, right? It's
  17605. 10:34:40all about the definition of the frame
  17606. 10:34:42close. So now do you remember if you use
  17607. 10:34:44an order by and you don't specify a
  17608. 10:34:46frame close you will get like hidden or
  17609. 10:34:49let's say default frame close and it's
  17610. 10:34:51going to look like this rows between
  17611. 10:34:53unbounded preceding and current row. And
  17612. 10:34:55what was the definition of the running
  17613. 10:34:57total? It's going to go and aggregate
  17614. 10:34:59all the data from the very first
  17615. 10:35:01beginning well the unbounded proceeding
  17616. 10:35:03until the current position the current
  17617. 10:35:06row without dropping off any old
  17618. 10:35:08members. So that means the definition of
  17619. 10:35:09the running total going to be the exact
  17620. 10:35:12definition of the default frame clause.
  17621. 10:35:14That's why it's going to go and generate
  17622. 10:35:16the effect of the running total. Now
  17623. 10:35:18let's go to the right side the rolling
  17624. 10:35:20total. Here again we have the same stuff
  17625. 10:35:22right. We're going to go and aggregate
  17626. 10:35:24the data using the sum function and
  17627. 10:35:26we're going to go and sort the data
  17628. 10:35:27order by month. So with that we are as
  17629. 10:35:29well generating the effect of running
  17630. 10:35:32total. So each time you use order by
  17631. 10:35:34with aggregate function. So now in the
  17632. 10:35:35running total we want always to specify
  17633. 10:35:37a frame. So here in this example three
  17634. 10:35:39months. So that means if we are getting
  17635. 10:35:41a new month we don't want to include the
  17636. 10:35:43latest months. We want always to be
  17637. 10:35:45fixed window. Now in order to have this
  17638. 10:35:48fixed window effect we have to go and
  17639. 10:35:50redefine the frame close because if you
  17640. 10:35:52leave it as a default like the running
  17641. 10:35:54total the frame going to keep extending.
  17642. 10:35:56You will see this effect in the example.
  17643. 10:35:58So now we define it like this rows
  17644. 10:36:00between two preceding and current row.
  17645. 10:36:03So the total number of rows going to be
  17646. 10:36:05included in each window going to be
  17647. 10:36:07maximum of three months. So now I know
  17648. 10:36:10you might saying bar what you are
  17649. 10:36:12talking about you didn't get anything.
  17650. 10:36:14It's total normal you will understand it
  17651. 10:36:16only with an example. So in order to do
  17652. 10:36:19this let's start with the left side. So
  17653. 10:36:20first going to go and sort the data. So
  17654. 10:36:22everything is sorted from the smallest
  17655. 10:36:24month until the highest one. So from
  17656. 10:36:26January until July everything is good.
  17657. 10:36:28And now it's going to go and start
  17658. 10:36:30working with the frame. So the frame
  17659. 10:36:32says unbounded proceeding. So this going
  17660. 10:36:34to be static. It's going to be always
  17661. 10:36:36pointing to January. This is the
  17662. 10:36:39unbounded proceeding. The first row in
  17663. 10:36:41the data set. And now of course we are
  17664. 10:36:43starting from top to bottom. The current
  17665. 10:36:45row going to be pointing as well to
  17666. 10:36:47January. So the frame going to look like
  17667. 10:36:49this. It's going to be only one row and
  17668. 10:36:52the total sale of this row going to be
  17669. 10:36:5420. So that's why we're going to have in
  17670. 10:36:55the output 20. So now let's move to the
  17671. 10:36:57right side. The current row going to be
  17672. 10:36:59as well January. And what is the two
  17673. 10:37:01proceeding? We don't have it yet. So
  17674. 10:37:03it's going to be pointing maybe
  17675. 10:37:04somewhere here before the table. So
  17676. 10:37:06again, what is the frame? It's going to
  17677. 10:37:08be as well one row. So in the output, we
  17678. 10:37:10will get exactly the same result 20. So
  17679. 10:37:13so far there is no differences between
  17680. 10:37:15the running total and the rolling total.
  17681. 10:37:17But let's keep going. Now we're going to
  17682. 10:37:19go to the next row over here. So what
  17683. 10:37:21can happen to our frame? It going to go
  17684. 10:37:23and extend, right? So we're going to
  17685. 10:37:24have now two months in this frame. And
  17686. 10:37:27what is the total sales over here? It's
  17687. 10:37:28going to be 30. So we added a new
  17688. 10:37:30member. You can calculate it like this.
  17689. 10:37:32Either go and calculate all the sales
  17690. 10:37:34within the frame or you can go and say
  17691. 10:37:37this is the previous aggregated value
  17692. 10:37:39plus the new member. So the previous one
  17693. 10:37:41was 20. The new member is 10. We will
  17694. 10:37:44get 30. Both of them is correct. So now
  17695. 10:37:46let's move to the right side. What's
  17696. 10:37:48going to happen? We're going to be as
  17697. 10:37:49well at February. The two preceding is
  17698. 10:37:51still like pointing somewhere outside.
  17699. 10:37:53And here the window going to go and
  17700. 10:37:55extend like this. We have two months and
  17701. 10:37:58the same aggregation going to happen. So
  17702. 10:37:59we have 30. So so far nothing crazy
  17703. 10:38:02right. Let's go to the next month March.
  17704. 10:38:04The frame going to be extended. So we
  17705. 10:38:06have now three months. And the
  17706. 10:38:08aggregation going to be either here 60
  17707. 10:38:10or 30 + 30. We will get the running
  17708. 10:38:13total of 60. And now on the right side
  17709. 10:38:15what going to happen? We're going to
  17710. 10:38:16point as well to March. And this time
  17711. 10:38:18the two proceeding going to be pointing
  17712. 10:38:19to January. And this is the first time
  17713. 10:38:22we are getting the whole fixed frame.
  17714. 10:38:24Right? So we have here three muscles in
  17715. 10:38:26this frame. So what is the total of
  17716. 10:38:28that? It's going to be 60. Okay. So now
  17717. 10:38:30you say, okay, we're still getting the
  17718. 10:38:31same results. There's no difference. I'm
  17719. 10:38:33going to say wait for it. It's going to
  17720. 10:38:34be the next one. So as we go to April,
  17721. 10:38:36the effect here is that the frame going
  17722. 10:38:38to get extended to four months because
  17723. 10:38:41always we start from the first month
  17724. 10:38:43until the current month without dropping
  17725. 10:38:45any member outside. So what is the total
  17726. 10:38:47of this? It's going to be 65. Sorry,
  17727. 10:38:50like this. So now on the right side,
  17728. 10:38:52what going to happen? We're going to go
  17729. 10:38:53and add a new member. the April but we
  17730. 10:38:55are at the maximum sides of the window
  17731. 10:38:57we have only three and that's because
  17732. 10:38:59the two preceding going to shift as well
  17733. 10:39:01down over here so the boundary going to
  17734. 10:39:04be from February until April and with
  17735. 10:39:06that we are dropping off January and now
  17736. 10:39:08you're going to see the effect it is
  17737. 10:39:10sliding it is rolling or shifting from
  17738. 10:39:13top to bottom and that's because the
  17739. 10:39:15boundaries as well shifting so you can
  17740. 10:39:17see now the effect of the rolling total
  17741. 10:39:20the newest member going to be added the
  17742. 10:39:22oldest member going to be But we are
  17743. 10:39:24allowed only to have three muscles. So
  17744. 10:39:26what is the total of this? It's going to
  17745. 10:39:28be 45. So this times we are not
  17746. 10:39:30aggregating this value the 60 together
  17747. 10:39:32with the five. We are aggregating the
  17748. 10:39:35values within the window. So now let's
  17749. 10:39:37keep going. Now we are at June. What can
  17750. 10:39:40happen on the left side? The frame going
  17751. 10:39:41to get bigger. And with that we will get
  17752. 10:39:43the result of 135. So the frame is
  17753. 10:39:47getting really bigger. But on the right
  17754. 10:39:48side it's going to has a fixed frame. So
  17755. 10:39:51we are just sliding, shifting and
  17756. 10:39:53rolling. So with that we are adding new
  17757. 10:39:56member. Another member is leaving the
  17758. 10:39:57oldest one. And the total over here
  17759. 10:39:59going to be 105. And now we're going to
  17760. 10:40:01go to the last row. We will have
  17761. 10:40:03everything for the ring total. So the
  17762. 10:40:05whole data set is going to be
  17763. 10:40:07aggregated. So this is the maximum what
  17764. 10:40:09we're going to get. It's going to be
  17765. 10:40:11around 175. But on the right side it
  17766. 10:40:15just going to keep shifting until we
  17767. 10:40:16reach the last record. the window the
  17768. 10:40:19frame going to be as well shifting like
  17769. 10:40:20this. So the total of this going to be
  17770. 10:40:22105. Okay guys so you see it's very
  17771. 10:40:25simple the running total it's always
  17772. 10:40:27consider everything from the starting
  17773. 10:40:30position until the current row without
  17774. 10:40:32dropping any member. The rolling total
  17775. 10:40:35it's always drop the oldest member in
  17776. 10:40:37order to add something new and the
  17777. 10:40:39window is keep shifting. So the running
  17778. 10:40:42total is very great in order to do
  17779. 10:40:43tracking like for example budget
  17780. 10:40:45tracking or we track for example the
  17781. 10:40:48current total sales with a target or
  17782. 10:40:50something like that. So always we are
  17783. 10:40:52considering the whole data sets but with
  17784. 10:40:54the rolling total we always do here
  17785. 10:40:56focused analyzes. We are always
  17786. 10:40:58interested with the window of 3 months.
  17787. 10:41:01So they might sound very similar but
  17788. 10:41:03they have completely different scope for
  17789. 10:41:04analyzes but both of them are doing
  17790. 10:41:07aggregations over time. So they're going
  17791. 10:41:09to help us to do analyzes over time like
  17792. 10:41:11checking whether our business is growing
  17793. 10:41:13over time or declining. So guys as you
  17794. 10:41:15can see using very simple SQLs using the
  17795. 10:41:17window functions we can do really great
  17796. 10:41:20analysis on our data. So those stuff are
  17797. 10:41:22really fundamental of data analyzes or
  17798. 10:41:25doing reporting for our business. So
  17799. 10:41:27window functions are really powerful for
  17800. 10:41:29data
  17801. 10:41:33analytics. Okay. Okay. So now we have
  17802. 10:41:35the following task and it says calculate
  17803. 10:41:37the moving average of sales for each
  17804. 10:41:39products over the time. So now we have
  17805. 10:41:42here something called moving average. It
  17806. 10:41:44is very similar to the running total. In
  17807. 10:41:47the running total we used count and sum
  17808. 10:41:49and so on. But here we're going to go
  17809. 10:41:51and use the function average and instead
  17810. 10:41:53of calling it running average we call it
  17811. 10:41:56moving average. So let's go and solve
  17812. 10:41:58the task. Let's start always by
  17813. 10:42:00selecting the usual stuff. So let's get
  17814. 10:42:02the order ID. Let's get the product ID
  17815. 10:42:05and I would say since it's over the time
  17816. 10:42:07I will get the order date as well and
  17817. 10:42:09the last one the sales from our table
  17818. 10:42:12sales orders. So that's it. Let's go and
  17819. 10:42:17execute it. So now we got our 10 orders
  17820. 10:42:19with the products order date and sales.
  17821. 10:42:21Let's start building our window function
  17822. 10:42:23step by step. So which function do we
  17823. 10:42:26need? We need the average. This is the
  17824. 10:42:27easiest one. It says moving average. So
  17825. 10:42:30that's it. We need the sales. So it's
  17826. 10:42:32going to be the average of sales. Let's
  17827. 10:42:34go and define the window. So now do we
  17828. 10:42:36have to divide the data, partition the
  17829. 10:42:38data? Well, yes. It says for each
  17830. 10:42:41product that means we're going to go and
  17831. 10:42:43use the partition by clause by the
  17832. 10:42:45product ID. So now I would say that's it
  17833. 10:42:48for the first step. So average by
  17834. 10:42:51product. So let's go and execute it. So
  17835. 10:42:54now if you check the result, you can see
  17836. 10:42:55that we got our windows. So the first
  17837. 10:42:57one for the product 101 and the total
  17838. 10:43:00average of the sales going to be 35. So
  17839. 10:43:03we have like aggregated one value for
  17840. 10:43:06each window. The same thing for the next
  17841. 10:43:08product and for the next and so on. So
  17842. 10:43:10we don't have any progress over time or
  17843. 10:43:12something like moving average all the
  17844. 10:43:14time. Right? We don't have this effect.
  17845. 10:43:16We have just one average for each
  17846. 10:43:18window. So now in order to have the
  17847. 10:43:19effect of the moving average, it's going
  17848. 10:43:21to be like the running total. We have to
  17849. 10:43:23use the aggregate function together with
  17850. 10:43:25the order by. So I'm just going to make
  17851. 10:43:28it in the new column. I'm just going to
  17852. 10:43:30copy everything like here. And now what
  17853. 10:43:33we going to do? Order by. And since it's
  17854. 10:43:36over the time, we're going to go and use
  17855. 10:43:38the order dates. Order dates. And we're
  17856. 10:43:42going to have it ascending because it's
  17857. 10:43:44overtime. Over time always like start
  17858. 10:43:46with the earliest dates, end up with the
  17859. 10:43:48latest dates. So from the lowest to the
  17860. 10:43:50highest, we're going to leave it like
  17861. 10:43:52this. So let's call it moving average.
  17862. 10:43:55So now let's go and execute it. And we
  17863. 10:43:58got here an extra comma because of the
  17864. 10:44:00copy paste. So let's execute it again.
  17865. 10:44:02All right. So now let's check the
  17866. 10:44:03results. Let's take the first window
  17867. 10:44:05over here. And you can see we have on
  17868. 10:44:07the moving average like a progress. So
  17869. 10:44:10it start with 10 15 14 35. So there is
  17870. 10:44:14like moving average. We don't have one
  17871. 10:44:16solid number for the average. We have
  17872. 10:44:19different values. So now how SQL going
  17873. 10:44:21to solve this? It's really simple. It's
  17874. 10:44:22going to start row by row. So the first
  17875. 10:44:24row what is the average of 10? It's
  17876. 10:44:26going to be 10. Then moving on to the
  17877. 10:44:28next one it's going to be 10 + 20
  17878. 10:44:30divided by 2 you will get 15. So now
  17879. 10:44:33moving to the third one all those three
  17880. 10:44:35values going to be summarized divided by
  17881. 10:44:37three you will get 40. And now to the
  17882. 10:44:40last row in the window it's going to be
  17883. 10:44:42summarizing all those four values
  17884. 10:44:44divided by four and you will get 35. And
  17885. 10:44:47this is exactly the same value in the
  17886. 10:44:49previous column. You have here the
  17887. 10:44:51average byproducts. We don't have order
  17888. 10:44:52by you got as well 35 exactly like this
  17889. 10:44:56last row and that's because we have the
  17890. 10:44:58same calculation. It is summarizing all
  17891. 10:45:00those four values dividing it by four.
  17892. 10:45:02But now it's interesting the next value.
  17893. 10:45:05So as you can see the next value it
  17894. 10:45:06comes from another window. So you see
  17895. 10:45:09here we have 15 for the product 102 but
  17896. 10:45:12the average going to be as well 15. So
  17897. 10:45:15scale is not considering the old values
  17898. 10:45:17from the other window. So SQL going to
  17899. 10:45:20calculate each window separately. So
  17900. 10:45:22it's again here this is the first value
  17901. 10:45:24of this window 15 the average 15 then
  17902. 10:45:27the same stuff right. So summarizing
  17903. 10:45:29those values divided by two and so on.
  17904. 10:45:31And this we call in data analyzes this
  17905. 10:45:34last field over here we call it a moving
  17906. 10:45:36average and you can implement it very
  17907. 10:45:38simply using an average function
  17908. 10:45:40together with the order by. All right,
  17909. 10:45:42let's move to the next task and it says
  17910. 10:45:44calculate the moving average of sales
  17911. 10:45:46for each product over time including
  17912. 10:45:49only the next order. So as you can see
  17913. 10:45:52the first part we have already done it
  17914. 10:45:53right. We have the moving average and
  17915. 10:45:55divided by partition by for the products
  17916. 10:45:58but here we have more specifications. It
  17917. 10:46:00says including only the next order. That
  17918. 10:46:03means we are talking about the current
  17919. 10:46:05order and as well the next order. So
  17920. 10:46:08here we have like a fixed frame or fixed
  17921. 10:46:10window. So we don't need the whole
  17922. 10:46:12average of the window. We need only
  17923. 10:46:14maximum two orders in each calculation.
  17924. 10:46:17So how we going to do that? We can have
  17925. 10:46:19our custom frame close inside our window
  17926. 10:46:22function. So that means we cannot leave
  17927. 10:46:24it as a default. We have to specify it.
  17928. 10:46:27So let's go and do that. I will just
  17929. 10:46:29copy the old definition of the window
  17930. 10:46:31because we have the exact stuff. So we
  17931. 10:46:33have the average sales over partition by
  17932. 10:46:36product ID order by date. So this is the
  17933. 10:46:39first part. So now we would like to have
  17934. 10:46:41this fixed window. So we're going to go
  17935. 10:46:43now and define our frame close. I'm just
  17936. 10:46:46going to zoom out a little bit. It's
  17937. 10:46:48going to be rows between. So we have now
  17938. 10:46:50the boundaries of the frame. It says
  17939. 10:46:52including the next order. So we're going
  17940. 10:46:54to go and use the following. So the
  17941. 10:46:56first boundary going to be the current
  17942. 10:46:58row. And since it's next order, so it's
  17943. 10:47:00going to be one following. So that is
  17944. 10:47:03our frame including only the next order.
  17945. 10:47:06And we have it like this one following.
  17946. 10:47:09Let's call it yeah rolling average. So
  17947. 10:47:12that's it. Let's go and execute. So now
  17948. 10:47:14let's go and check the result. You can
  17949. 10:47:16see the moving average has completely
  17950. 10:47:18different values as the rolling average.
  17951. 10:47:20So let's go and understand why. We're
  17952. 10:47:22going to do it row by row. Let's take
  17953. 10:47:24the first row over here. So the sales
  17954. 10:47:26here is 10 and the rolling average is
  17955. 10:47:2815. So why is that? Because in the
  17956. 10:47:31calculation we are considering the next
  17957. 10:47:33value. So 10 + 20 divided by 2 you will
  17958. 10:47:37get 15. So that means the SQL defined
  17959. 10:47:40the frame like this those two rows for
  17960. 10:47:42this calculation for the first row. So
  17961. 10:47:44now moving on to the second row. SQL
  17962. 10:47:47going to include as well the third one
  17963. 10:47:49right the next one. But since the window
  17964. 10:47:52is only two orders it's going to go and
  17965. 10:47:55drop the first row. So the next frame
  17966. 10:47:57going to be like this. And as you can
  17967. 10:48:00see it's going to be 20 + 19 divided by
  17968. 10:48:022. You will get 55. So now you can see
  17969. 10:48:05the effect of the rolling average.
  17970. 10:48:07Right? So now for the next one going to
  17971. 10:48:09be exact same. So we are at the third
  17972. 10:48:11row. It's going to go and include the
  17973. 10:48:12next one and we're going to get the same
  17974. 10:48:14value because 19 + 20 divid by two you
  17975. 10:48:17will get 55. Now interesting to the last
  17976. 10:48:20row in the window over here. It will not
  17977. 10:48:22go and consider the next value because
  17978. 10:48:25it is outside of the window. So it's
  17979. 10:48:27going to be 20 and it's going to stay as
  17980. 10:48:30well 20. So that's it. All right guys.
  17981. 10:48:32So with that we have learned about the
  17982. 10:48:34moving average, the rolling average and
  17983. 10:48:36those amazing concepts using the window
  17984. 10:48:39function. All right. Now we're going to
  17985. 10:48:40have a quick overview of the different
  17986. 10:48:41use cases in the aggregate functions and
  17987. 10:48:44how the definition of the window going
  17988. 10:48:46to change the whole use case. So now the
  17989. 10:48:48first use case is finding the overall
  17990. 10:48:50total. And here if you don't define
  17991. 10:48:53anything in the window if you leave it
  17992. 10:48:54empty what going to happen you are doing
  17993. 10:48:56here overall analyzes. So you're going
  17994. 10:48:59to go and aggregate the whole data sets
  17995. 10:49:02and then provide this aggregation for
  17996. 10:49:04each row. So this is what happen if you
  17997. 10:49:06leave it empty. You don't define
  17998. 10:49:07anything. You are aggregating the whole
  17999. 10:49:10data sets. Now moving to the next step,
  18000. 10:49:12we can do analysis called total pair
  18001. 10:49:14groups. So what we're going to do, we
  18002. 10:49:17will add partition by to the definition
  18003. 10:49:19of the window. So by adding for example
  18004. 10:49:21here partition by products, what can
  18005. 10:49:23happen? The data going to be splitted
  18006. 10:49:25into two categories or two groups and
  18007. 10:49:27the aggregation going to be done for
  18008. 10:49:29each window separately. This is of
  18009. 10:49:31course a great analysis in order to go
  18010. 10:49:32and compare different products like here
  18011. 10:49:35the caps and gloves. So this is helpful
  18012. 10:49:37in order to compare categories. So you
  18013. 10:49:39can do this analysis total pair groups
  18014. 10:49:41if you use the partition by. Now if you
  18015. 10:49:44go and use the order by you're going to
  18016. 10:49:46land in the third use case. As we
  18017. 10:49:48learned we will be doing running total.
  18018. 10:49:50So as you can see here in the output we
  18019. 10:49:52are building a cumulative value for the
  18020. 10:49:54sales and this going to help us in order
  18021. 10:49:56to do progress over time analyzes in
  18022. 10:49:59order to understand the performance of
  18023. 10:50:00our business. And now moving on to the
  18024. 10:50:02last use case the final phase of the
  18025. 10:50:04window function with the aggregation.
  18026. 10:50:06Here you have the aggregate function
  18027. 10:50:08together with the order by with
  18028. 10:50:10customized fixed window. And of course
  18029. 10:50:12we can use it in order to help us
  18030. 10:50:14building progress over time in specific
  18031. 10:50:16fixed window. And of course you can use
  18032. 10:50:18those use cases you will get the same
  18033. 10:50:20effect if you use the other functions
  18034. 10:50:22not only the sum you can use average
  18035. 10:50:24count max so all aggregate functions. So
  18036. 10:50:26guys as you can see the window function
  18037. 10:50:28in scale is very important in order to
  18038. 10:50:30do data analytics by just like changing
  18039. 10:50:33the part of the window you are
  18040. 10:50:34generating a whole new use case for data
  18041. 10:50:40analytics. All right friends so now
  18042. 10:50:42let's do a quick recap about the window
  18043. 10:50:44aggregate functions. So what they do
  18044. 10:50:46they're going to go and aggregate a set
  18045. 10:50:48of values and return a single aggregated
  18046. 10:50:51value for each row. So it's very similar
  18047. 10:50:53to the groupy but here we don't lose
  18048. 10:50:55details. Now to the next point what are
  18049. 10:50:57the rules for the syntax about the
  18050. 10:51:00expressions they all expect a number in
  18051. 10:51:02the expression. So you have to pass a
  18052. 10:51:04number like sales or any integer but
  18053. 10:51:06only for the count you can go and use
  18054. 10:51:08any data type. And the things for the
  18055. 10:51:10aggregate functions are very simple.
  18056. 10:51:12Everything is optional inside the
  18057. 10:51:13definition of the overclouds or the
  18058. 10:51:15definition of the window. So you can go
  18059. 10:51:17and use partition by order by frames or
  18060. 10:51:19not or just leave everything empty. So
  18061. 10:51:21everything is optional. So now as we
  18062. 10:51:23learned we have a lot of use cases for
  18063. 10:51:25the aggregate functions and they are
  18064. 10:51:26really amazing for analytics. So the
  18065. 10:51:28first one the simplest one you can do
  18066. 10:51:30overall analyzes if you just leave the
  18067. 10:51:32window function empty. So you will get
  18068. 10:51:34one big number about your business. And
  18069. 10:51:36the next use case we can do total bear
  18070. 10:51:38groups analyzes. As you've learned, we
  18071. 10:51:40can use partition by in order to compare
  18072. 10:51:42categories with each others like
  18073. 10:51:44comparing the products or customers and
  18074. 10:51:45so on. Moving on to the next one, we can
  18075. 10:51:47do partto-hole analyszis. We can go and
  18076. 10:51:49compare the performance of each data
  18077. 10:51:51point with the overall. So you can for
  18078. 10:51:53example compare the sales to the total
  18079. 10:51:55sales in the window or to the all data
  18080. 10:51:58sets. And we have many comparison
  18081. 10:52:00analyzes. We can go and compare the
  18082. 10:52:01current value with the average or we can
  18083. 10:52:04compare them to the extreme to the
  18084. 10:52:05highest sales to the lowest sales and so
  18085. 10:52:07on. And another use case, we can go and
  18086. 10:52:09identify data quality issues in our
  18087. 10:52:11data. So we can go for example and
  18088. 10:52:13identify duplicates using the count
  18089. 10:52:15function. Moving on to the next use
  18090. 10:52:17case, we have the outlier detection. We
  18091. 10:52:18can go and find out which data points
  18092. 10:52:21are above the average and below the
  18093. 10:52:23average and so on. Then the next one we
  18094. 10:52:25have the running total. As we learned,
  18095. 10:52:27it is great tool in order to track the
  18096. 10:52:29progress or to monitor the performance
  18097. 10:52:31of our business over the time. Or if you
  18098. 10:52:34want to be more specific, you can go and
  18099. 10:52:36use the rolling total in order to have
  18100. 10:52:39like a specific window and only track
  18101. 10:52:41this window like three months or
  18102. 10:52:43something like that. And the last use
  18103. 10:52:44case, we can go and calculate the moving
  18104. 10:52:46average of our data. So it's really
  18105. 10:52:48amazing how order by and aggregate
  18106. 10:52:50functions can open for you a door for
  18107. 10:52:52amazing or advanced analyzers. So guys,
  18108. 10:52:55as you can see, we have a lot of use
  18109. 10:52:56cases for the window aggregate functions
  18110. 10:52:58in the world of data analytics. All
  18111. 10:53:00right. Right. So with that we have
  18112. 10:53:01covered the aggregate window functions
  18113. 10:53:03and in the next step it's going to be
  18114. 10:53:04very important. We will learn how to
  18115. 10:53:06rank our data using window functions. So
  18116. 10:53:09let's
  18117. 10:53:12go. All right. So now let's say that we
  18118. 10:53:14have the following data. We have
  18119. 10:53:16products and their sales. If you want
  18120. 10:53:18now to go and rank your products first
  18121. 10:53:21you have to sort the data based on
  18122. 10:53:22something like for example ranking the
  18123. 10:53:25products based on their sales. So that
  18124. 10:53:27means SQL first is going to go and start
  18125. 10:53:29sorting your data from the highest to
  18126. 10:53:31the lowest. So sorting the data is
  18127. 10:53:33always the first thing SQL has to do
  18128. 10:53:36before ranking anything. Now in order to
  18129. 10:53:39rank our data we have two methods. The
  18130. 10:53:41first method we call it the integer
  18131. 10:53:43based ranking. So that means SQL going
  18132. 10:53:45to go and assign for each row an integer
  18133. 10:53:48a whole number based on the position of
  18134. 10:53:51the row. So now by looking to the
  18135. 10:53:52example the first row we have the
  18136. 10:53:54product E with the sales 70 it's going
  18137. 10:53:57to be rank number one then the next row
  18138. 10:54:00the product B with 30 sales we will get
  18139. 10:54:02the rank number two then the next one
  18140. 10:54:04going to be three four and the last one
  18141. 10:54:06going to be five. So that means SQL here
  18142. 10:54:08is assigning an integer for each row
  18143. 10:54:11based on their position in the sorted
  18144. 10:54:13list. So this method we call it integer
  18145. 10:54:16based ranking. Now let's go to the
  18146. 10:54:18second method we have the
  18147. 10:54:19percentagebased ranking. So in this
  18148. 10:54:21methods going to go first and calculate
  18149. 10:54:24the relative position of the row
  18150. 10:54:26compared to all others and then assign a
  18151. 10:54:29percentage for each row. So here in the
  18152. 10:54:31output is going to start assigning
  18153. 10:54:33percentages instead of integer and we're
  18154. 10:54:36going to have a scale from 0 to one. So
  18155. 10:54:38now if you go and compare both of the
  18156. 10:54:40methods you can see that on the left
  18157. 10:54:41side on the integer base ranking we have
  18158. 10:54:44discrete distinct values. So it starts
  18159. 10:54:47from 1 then 2 3 and end up in this
  18160. 10:54:50example by five. So it really depends on
  18161. 10:54:52how many rows do we have in the results.
  18162. 10:54:55So it could be five, it could be 500, 5
  18163. 10:54:57million and so on. But in the right side
  18164. 10:55:00we have always the same scale from one
  18165. 10:55:02to zero. So between 0 and one we have
  18166. 10:55:05infinite number of data points and this
  18167. 10:55:07scale we call it a normalized scale or
  18168. 10:55:10we call it continuous scale continuous
  18169. 10:55:13values. So now the question is when to
  18170. 10:55:15use which method. So for example for the
  18171. 10:55:17percentage based ranking it is great to
  18172. 10:55:19answer such questions find the top 20%
  18173. 10:55:22products based on their sales. So this
  18174. 10:55:24method is a great way in order to
  18175. 10:55:26understand the contributions of data
  18176. 10:55:28values to the overall total and we call
  18177. 10:55:31this kind of analyszis a distribution
  18178. 10:55:34analyszis where in the other hand in the
  18179. 10:55:36integer based ranking we can answer
  18180. 10:55:38questions like find the top three
  18181. 10:55:40products. So with this question we are
  18182. 10:55:42not interesting about the contributions
  18183. 10:55:44of each product to the overall total. We
  18184. 10:55:46are just interested in the position of
  18185. 10:55:49the value within a list. So this is as
  18186. 10:55:51well very commonly used analyzes and
  18187. 10:55:53reporting. We call it top button in
  18188. 10:55:56analyzers. So now let's group up our
  18189. 10:55:57ranking functions based on those two
  18190. 10:55:59methods. For the first group in the
  18191. 10:56:01integer based ranking we have four
  18192. 10:56:03functions. Row number rank d rank and
  18193. 10:56:06inile. But in the other hand we have
  18194. 10:56:08only two functions that generate
  18195. 10:56:10percentage based ranking. We have the
  18196. 10:56:12cumid list and as well the percentile.
  18197. 10:56:15So now that was an introduction an
  18198. 10:56:17overview of those methods and how we
  18199. 10:56:19group up those ranking functions. Next
  18200. 10:56:21we're going to go and learn about the
  18201. 10:56:23syntax of the ranking functions. Most of
  18202. 10:56:25them follow the same rules. So for
  18203. 10:56:27example we start always with the
  18204. 10:56:28function name. So we have here the rank.
  18205. 10:56:31But as you can see we don't use any
  18206. 10:56:33expressions. So they don't allow you to
  18207. 10:56:35use any argument inside it. It must be
  18208. 10:56:38empty. So this is the first rule using
  18209. 10:56:40rank functions. Then about the
  18210. 10:56:42definition of the window as usual the
  18211. 10:56:44partition by it is an optional thing.
  18212. 10:56:46You can use it or leave it. And now to
  18213. 10:56:48the second part we have the order by it
  18214. 10:56:50is as well required. So you must order
  18215. 10:56:53the data or sort your data in order to
  18216. 10:56:55do ranking. So you cannot leave it
  18217. 10:56:57empty. So that means for the definition
  18218. 10:56:59of the window at least we should have an
  18219. 10:57:02order by for example here sales. So we
  18220. 10:57:05cannot leave it empty. All right. So the
  18221. 10:57:07two requirements you cannot use any
  18222. 10:57:09expressions for those functions and as
  18223. 10:57:11well you have to sort your data using
  18224. 10:57:13order by. Okay. So now let's have an
  18225. 10:57:15overview of all functions. So as you can
  18226. 10:57:16see all those functions are ranking
  18227. 10:57:18functions and almost all of them don't
  18228. 10:57:21allow to use any expressions inside
  18229. 10:57:23them. Beside this function here we have
  18230. 10:57:26the end tile. it accepts a number inside
  18231. 10:57:28it. So that means you cannot use it
  18232. 10:57:30empty. You should use a number inside
  18233. 10:57:32it. All others must be empty. So now for
  18234. 10:57:35the partition by all of them are
  18235. 10:57:36optional and for the order by all of
  18236. 10:57:39them are required. So you must use order
  18237. 10:57:42by and the frame clause they are not
  18238. 10:57:45allowed to use in the ranking functions.
  18239. 10:57:47So you cannot change the definition of
  18240. 10:57:49the frame inside the window function. So
  18241. 10:57:51now what we're going to do as usual,
  18242. 10:57:53we're going to go and deep dive into all
  18243. 10:57:54of those functions in order to
  18244. 10:57:56understand when to use them and what are
  18245. 10:57:58the use cases and as well practice in
  18246. 10:58:01SQL. So we're going to start with the
  18247. 10:58:02first one, the row
  18248. 10:58:07number. All right. So what is a row
  18249. 10:58:09number in SQL? The row number function
  18250. 10:58:11going to go and assign for each row a
  18251. 10:58:13unique number as a rank and it doesn't
  18252. 10:58:16care at all about the ties. That means
  18253. 10:58:18if you have two rows sharing the same
  18254. 10:58:21value, they will not share the same
  18255. 10:58:23rank. Okay. So now we have very simple
  18256. 10:58:25example. We have a list of all sales and
  18257. 10:58:28we have the following query. So it's
  18258. 10:58:30going to start with the ranking function
  18259. 10:58:32row number. It doesn't accept any
  18260. 10:58:33argument inside it. And the definition
  18261. 10:58:35of the window going to be like this
  18262. 10:58:37order by sales disk. So that means we're
  18263. 10:58:40going to go and sort the data descending
  18264. 10:58:43from the highest to the lowest. So SQL
  18265. 10:58:45going to go and do the following. The
  18266. 10:58:47highest going to be the 100. The lowest
  18267. 10:58:50going to be the 20. And here we have
  18268. 10:58:52twice the 80. So now once SQL done
  18269. 10:58:55sorting the data, what's going to
  18270. 10:58:56happen? It's going to start assigning a
  18271. 10:58:58rank. So the row number going to go and
  18272. 10:59:00assign a unique number for each row. So
  18273. 10:59:03that means it's going to start with the
  18274. 10:59:04first one. The 100 going to be the rank
  18275. 10:59:07number one. The next one going to be
  18276. 10:59:09rank number two. The 80 going to be rank
  18277. 10:59:11number three. And the 54. And then the
  18278. 10:59:14last one going to be five. And now if
  18279. 10:59:15you check the output you can see that
  18280. 10:59:17all those numbers are unique. We don't
  18281. 10:59:19have any repetitions. So 1 2 3 4 5
  18282. 10:59:22there's no repetitions. They are unique
  18283. 10:59:24distinct value. And as well there are no
  18284. 10:59:27skipping of ranking. So that means we
  18285. 10:59:29have here 1 2 3 there is no jumping to 6
  18286. 10:59:317 or something. They are clear sequence
  18287. 10:59:34of distinct value and there are no gaps.
  18288. 10:59:37But still there is something special in
  18289. 10:59:38our data. We can see that in the sales
  18290. 10:59:41we have the same value twice. So we have
  18291. 10:59:43two rows with the same sales. As you can
  18292. 10:59:46see in the row number they will get
  18293. 10:59:48distinct values. So they will not share
  18294. 10:59:51the same ranking. So that means row
  18295. 10:59:53number does not handle the ties. If you
  18296. 10:59:56have multiple rows sharing the same
  18297. 10:59:58values they will not share the same
  18298. 11:00:00rank. They going to have a distinct rank
  18299. 11:00:03different ranks. So this is how the row
  18300. 11:00:05number works in SQL. It generates unique
  18301. 11:00:07ranks for each row. It does not handle
  18302. 11:00:09the ties and as well it doesn't leave
  18303. 11:00:12any gaps. So there is no skipping of
  18304. 11:00:14ranking. So now let's go to SQL in order
  18305. 11:00:16to have few examples and use cases. All
  18306. 11:00:18right. So now we have the following
  18307. 11:00:19task. It's very simple. Rank the orders
  18308. 11:00:21based on their sales from the highest to
  18309. 11:00:24the lowest. So now this is very easy.
  18310. 11:00:25We're going to go and select first the
  18311. 11:00:27data. So order ID, product ID. Let's
  18312. 11:00:30take the sales as well and select the
  18313. 11:00:33table. So it's going to be sales orders.
  18314. 11:00:35Let's go and execute it. So with that we
  18315. 11:00:38got all our orders. What we're going to
  18316. 11:00:39do now is to assign for each row a rank.
  18317. 11:00:42So that means we need a column here that
  18318. 11:00:45contains the rank for each row. So in
  18319. 11:00:47order to do that we're going to go and
  18320. 11:00:48use the window function row number. It
  18321. 11:00:51doesn't accept any argument inside it.
  18322. 11:00:53So should be empty. And then we have to
  18323. 11:00:54define the window. So as we learned in
  18324. 11:00:57the ranking functions we cannot leave it
  18325. 11:00:59empty. We have to sort the data using
  18326. 11:01:00order by. So order by is a must. We
  18327. 11:01:03don't have to use any partition by. So
  18328. 11:01:05we're going to rank all the data that we
  18329. 11:01:07have inside the table. So how to sort
  18330. 11:01:08the data? It says it should be based on
  18331. 11:01:10their sales from highest to lowest. That
  18332. 11:01:12means we order by sales since from
  18333. 11:01:15highest to lowest we have to use the
  18334. 11:01:17descending. And now we're going to go
  18335. 11:01:18and give it a name sales rank and let's
  18336. 11:01:21say row since we are using the row
  18337. 11:01:23number. So that's it. It's very simple.
  18338. 11:01:26Let's go and execute it. So now let's
  18339. 11:01:28have a look to the results. Before SQL
  18340. 11:01:30did sort the data by the order ID since
  18341. 11:01:32we didn't define anything. But since now
  18342. 11:01:34we are order by sale descending SQL went
  18343. 11:01:37and sorted the data by the sales from
  18344. 11:01:39the highest to the lowest and start
  18345. 11:01:41assigning a rank or let's say an integer
  18346. 11:01:44unique integer for each row. So now the
  18347. 11:01:46highest order going to be the order
  18348. 11:01:48number eight. We have the sales of 90.
  18349. 11:01:50This is the highest one. So as you can
  18350. 11:01:51see we have 1 2 3 4 5 until 10. So now
  18351. 11:01:54by checking the results you can see that
  18352. 11:01:56the ranking here is unique. So there is
  18353. 11:01:59no duplicates over here and as well
  18354. 11:02:01there is no skipping or gaps. So we have
  18355. 11:02:03everything between 1 and 10 even though
  18356. 11:02:05that we have in our data a couple of
  18357. 11:02:07sales that sharing the same value. So
  18358. 11:02:09for example we have those two orders you
  18359. 11:02:11can see both of them has the 60 at the
  18360. 11:02:13sales but they don't share the same
  18361. 11:02:15ranking. Right? So we have here as well
  18362. 11:02:18the 9 and three they share the same
  18363. 11:02:20value 20 but they don't share the same
  18364. 11:02:22ranking. So with that we have solved the
  18365. 11:02:24task. It's very simple. We have now a
  18366. 11:02:26rank based on the sales from highest to
  18367. 11:02:28the lowest.
  18368. 11:02:33All right. So what is a rank function in
  18369. 11:02:35SQL? The rank function going to go and
  18370. 11:02:36assign for each row a number a rank and
  18371. 11:02:39this time it going to go and handle the
  18372. 11:02:41ties. So that means if in your data you
  18373. 11:02:44have two rows having the same values
  18374. 11:02:46they going to share the same ranking.
  18375. 11:02:49One thing about the ranking function is
  18376. 11:02:50that it's going to go and leave gaps in
  18377. 11:02:52the ranking. So there is possibility of
  18378. 11:02:55skipping ranks. In order to understand
  18379. 11:02:57how the rank function works in SQL,
  18380. 11:02:59we're going to have a very simple
  18381. 11:03:00example. All right. So again with the
  18382. 11:03:02same data but with different function.
  18383. 11:03:04So our window looks like this. It start
  18384. 11:03:06with the function rank doesn't accept
  18385. 11:03:08any argument inside it. Then we have the
  18386. 11:03:10window like this. Order by sales
  18387. 11:03:12descending from the highest to the
  18388. 11:03:14lowest. And our data is already sorted
  18389. 11:03:16like that. So now how is scale going to
  18390. 11:03:18go and assign the ranks. The first row
  18391. 11:03:19going to be the highest rank. So the
  18392. 11:03:21value 100 is going to be one. Then the
  18393. 11:03:23second one going to be two. But now for
  18394. 11:03:25the third one, as you can see, we have
  18395. 11:03:27here two values that are the same. So we
  18396. 11:03:29have a tie and this time SQL going to go
  18397. 11:03:32and as well let them to share the same
  18398. 11:03:35rank. So both of them going to be the
  18399. 11:03:37rank two. So it's not like the row
  18400. 11:03:39number where we have over here three.
  18401. 11:03:41This time we have two because we have a
  18402. 11:03:43tie. So having same values means they
  18403. 11:03:46going to share the same rank. And now
  18404. 11:03:48moving to the next value going to be
  18405. 11:03:49tricky one because if you check over
  18406. 11:03:51here you can see that the next rank
  18407. 11:03:54should be like the three right? So we
  18408. 11:03:55have one two and then the next value
  18409. 11:03:57that generated in the rank should be
  18410. 11:03:59three but going to say you know what
  18411. 11:04:02this value position going to be number
  18412. 11:04:04four. So as you can see 1 2 3 four. So
  18413. 11:04:07actually the position number here is
  18414. 11:04:08four and going to go and give it the
  18415. 11:04:11rank of four. So with that SQL going to
  18416. 11:04:14be leaving a gap in the ranking. You can
  18417. 11:04:16see we are skipping the rank number
  18418. 11:04:18three and this always happen once you
  18419. 11:04:20have a tie where you are sharing the
  18420. 11:04:22same ranking. So for the next one it's
  18421. 11:04:24going to be easy. It's going to be the
  18422. 11:04:25row number five. So now by looking to
  18423. 11:04:27the output of the rank function you can
  18424. 11:04:29see that we don't have a unique ranking.
  18425. 11:04:31Here we have shared ranking in case of
  18426. 11:04:34the ties. So it handles the ties but
  18427. 11:04:36here we have gaps in the ranks. So we
  18428. 11:04:39are skipping ranks. When I think about
  18429. 11:04:41the rank function I think about the
  18430. 11:04:43Olympics. If two athletes tie for the
  18431. 11:04:46gold medal, the first place, there will
  18432. 11:04:49be no silver medal for the second place,
  18433. 11:04:51the next medal going to be given to the
  18434. 11:04:53bronze to the third place. All right. So
  18435. 11:04:55now let's go in SQL in order to practice
  18436. 11:04:57the rank function. All right. Now we're
  18437. 11:04:59going to go and solve the same task but
  18438. 11:05:00using the rank function. So what we're
  18439. 11:05:03going to do, we're going to stay with
  18440. 11:05:04the same example over here and we're
  18441. 11:05:05going to rank the order based on their
  18442. 11:05:07sales from highest to lowest but this
  18443. 11:05:08time using the rank function. So we use
  18444. 11:05:12the rank and everything inside is going
  18445. 11:05:14to be empty and then our window going to
  18446. 11:05:16be exactly the same as before. So over
  18447. 11:05:19order by sales and disk. So let's give
  18448. 11:05:23it a name sales rank. Yeah, let's give
  18449. 11:05:26it a rank. So that's it. As you can see
  18450. 11:05:28the syntax is very simple and very
  18451. 11:05:29similar to the row number. We just
  18452. 11:05:31changed the function. So now let's go
  18453. 11:05:33and execute this in order to check the
  18454. 11:05:35results. So now let's go and check the
  18455. 11:05:37results by looking to the new rank. If
  18456. 11:05:39you go and compare it with the old rank,
  18457. 11:05:41we can see that we are sharing some
  18458. 11:05:43ranking, right? We have here the two
  18459. 11:05:44twice. So the rank number two, we have
  18460. 11:05:46it twice because we have over here the
  18461. 11:05:49same value. So 60 60 we have it here two
  18462. 11:05:51and two. But if you compare it to the
  18463. 11:05:54row number, you can see that it is not
  18464. 11:05:56sharing the same ranking. So this is one
  18465. 11:05:58difference. And as well here the same
  18466. 11:06:00thing. They have the same value. The
  18467. 11:06:01sales is 20. So we have it twice the
  18468. 11:06:04rank number seven. And here we have it
  18469. 11:06:06as different values. And the next value
  18470. 11:06:08as you can see we are skipping the rank.
  18471. 11:06:11So there is gap there is no rank of
  18472. 11:06:13eight. So you can see that this is the
  18473. 11:06:15row number nine and that's why it get
  18474. 11:06:17the nine. The same thing I believe over
  18475. 11:06:20here. So now if you check those two
  18476. 11:06:21ranks the next one should be three. But
  18477. 11:06:23since it is in the row number four it's
  18478. 11:06:26going to get the rank four. So by
  18479. 11:06:27checking the results we can see that
  18480. 11:06:29sharing the same ranks and as well we
  18481. 11:06:31have gaps. So this is how the rank
  18482. 11:06:33works.
  18483. 11:06:37All right. So what is a dense rank? It
  18484. 11:06:40is very similar to the ranking function.
  18485. 11:06:41It's going to go and assign for each row
  18486. 11:06:43a number rank and it as well handles the
  18487. 11:06:46ties. So same values they going to share
  18488. 11:06:48the same ranking but this time it
  18489. 11:06:51doesn't leave any gaps like the rank
  18490. 11:06:53function. So the d rank it will not
  18491. 11:06:56leave any gaps. It will not skip any
  18492. 11:06:58ranking. So in order to understand this
  18493. 11:07:00we're going to have a very simple
  18494. 11:07:01example. So let's go. All right. So
  18495. 11:07:03again the same data but with different
  18496. 11:07:04function. We have this time the rank
  18497. 11:07:06function dense rank and the window going
  18498. 11:07:09to be the same order by sales descending
  18499. 11:07:11from the highest to the lowest. So now
  18500. 11:07:13the data is as well sorted already.
  18501. 11:07:15Let's see how SQL going to go and assign
  18502. 11:07:17the ranks as usual. The first row going
  18503. 11:07:19to be the rank number one the second as
  18504. 11:07:22well but again here we have the same
  18505. 11:07:24values. So we have same values and it's
  18506. 11:07:26like the rank it's going to go and share
  18507. 11:07:28the same rank. So both of them going to
  18508. 11:07:30has the rank number two. And now you
  18509. 11:07:33might say, well this is very similar to
  18510. 11:07:35the rank function. So why do we have
  18511. 11:07:36dense rank? I'm going to say wait for
  18512. 11:07:38it. We're going to have the difference
  18513. 11:07:40in the next value. So it's going to come
  18514. 11:07:42over here. This value is exactly after
  18515. 11:07:44the tie. In rank SQL went and took the
  18516. 11:07:47position number. So the row number it
  18517. 11:07:49was four, right? So 1 2 3 4. But this
  18518. 11:07:52time with the dense rank SQL will not
  18519. 11:07:54leave gaps in ranking. So there will be
  18520. 11:07:56no skipping the next rank in the
  18521. 11:07:59sequence going to be three. So that's
  18522. 11:08:01why we're going to have the rank three
  18523. 11:08:03for this value. So as you can see there
  18524. 11:08:05is no gap. We have one, we have two and
  18525. 11:08:07three. So we are not skipping, we are
  18526. 11:08:09not leaving any gaps. And the last one
  18527. 11:08:11going to be four. So this is exactly the
  18528. 11:08:14difference between the dense rank and
  18529. 11:08:15the rank. So now by checking the output
  18530. 11:08:17of the dense rank, you can see that we
  18531. 11:08:20don't have unique ranks. We have here
  18532. 11:08:23shared ranks. As you can see, we have
  18533. 11:08:24here repetition. So, it handles the ties
  18534. 11:08:27and as well it doesn't leave any gaps.
  18535. 11:08:30It doesn't skip anything in the ranking.
  18536. 11:08:32Okay, so that's it. Now, let's go back
  18537. 11:08:34to SQL to practice the dense rank. All
  18538. 11:08:36right, so now we have the same task.
  18539. 11:08:37Rank the orders based on their sales
  18540. 11:08:39from highest to lowest. So, we're going
  18541. 11:08:41to do the same stuff, but this time
  18542. 11:08:42using the function dense rank. So, dense
  18543. 11:08:46rank is going to be empty. And then
  18544. 11:08:47we're going to define it like all others
  18545. 11:08:49over order by sales disk. And then we're
  18546. 11:08:53going to give it the name of sales rank
  18547. 11:08:55dense. And that's it. So as you can see
  18548. 11:08:57all of those functions having the exact
  18549. 11:09:00syntax, right? So let's go and execute
  18550. 11:09:02it. Okay. So now let's go and check the
  18551. 11:09:04results. We got our newest rank using
  18552. 11:09:06the dens. And by just checking the
  18553. 11:09:08results, you can see that it handles the
  18554. 11:09:10tie. We have two twice, right? So let's
  18555. 11:09:13check the example over here. We have the
  18556. 11:09:15sales 60 twice. That's why they are
  18557. 11:09:17sharing the same ranking in the dense
  18558. 11:09:19and as well in the normal rank. But now
  18559. 11:09:21what is interesting is the value after
  18560. 11:09:24the tie. So as you can see over here
  18561. 11:09:26with the dense rank we have three. So we
  18562. 11:09:28didn't skip any ranking. We don't have
  18563. 11:09:30any gap 1 2 and then three. But with the
  18564. 11:09:33rank it's just focus on the position
  18565. 11:09:36number. So it is the row number four.
  18566. 11:09:38That's why it's four. With that we have
  18567. 11:09:40a gap. So as you can see now we don't
  18568. 11:09:42have any gaps in the dense rank. So we
  18569. 11:09:44have three four five. And now we have
  18570. 11:09:46over here the same two values. So we
  18571. 11:09:49have sales of 2020 and they share the
  18572. 11:09:51six twice. So as you can see there is
  18573. 11:09:53difference now between the dense and the
  18574. 11:09:55rank. So here we have seven seven but
  18575. 11:09:57here we are at the rank 66. So that's
  18576. 11:09:59why we have differences between them
  18577. 11:10:01because we skipped before in the rank
  18578. 11:10:03number three. Now the other stuff you
  18579. 11:10:04can see we have seven and eight. So now
  18580. 11:10:06if you compare those three ranking you
  18581. 11:10:08can see that they all start with the
  18582. 11:10:10rank number one but they didn't all end
  18583. 11:10:13with the same ranking. So the row number
  18584. 11:10:15and the rank they really focus on the
  18585. 11:10:18position number or the row number of the
  18586. 11:10:20orders. So you can see over here it is
  18587. 11:10:23the row number 10. That's why we have
  18588. 11:10:24here 10 and 10. So the scale is from 1
  18589. 11:10:27to 10. And that is exactly the same for
  18590. 11:10:30the row number from 1 to 10. But with
  18591. 11:10:32the d over here we have it from 1 to 8
  18592. 11:10:35and that's because we shared the same
  18593. 11:10:37ranking and with that we wasted let's
  18594. 11:10:40say few ranks. So the scale is different
  18595. 11:10:42from the two others. And that's because
  18596. 11:10:44we have ties twice. This is one tie and
  18597. 11:10:47as well we have over here one tie.
  18598. 11:10:49That's why we are missing over here two
  18599. 11:10:51ranks. So this is how the dense ranks
  18600. 11:10:53works. And you can go and compare now
  18601. 11:10:55all three togethers in order to
  18602. 11:10:57understand how those ranks are
  18603. 11:11:02working. All right. So now let's quickly
  18604. 11:11:04compare the three functions side by
  18605. 11:11:05side. Let's start with the first point
  18606. 11:11:07about the uniqueness of the rank. And if
  18607. 11:11:09you compare those three you can see that
  18608. 11:11:11only the row number generates unique
  18609. 11:11:13distinct rank. So this going to be
  18610. 11:11:16unique rank and the two others we have
  18611. 11:11:18duplicates or let's say shared ranks.
  18612. 11:11:20Okay. So now the second point whether
  18613. 11:11:22the function handles the ties and the
  18614. 11:11:25only one that doesn't handle the ties is
  18615. 11:11:26the row number. So this one doesn't
  18616. 11:11:29handle the ties and the two others
  18617. 11:11:31handles the ties since they offer the
  18618. 11:11:33shared rank. And now we have the last
  18619. 11:11:35point about leaving gaps or skipping
  18620. 11:11:37ranking. So now if you check the row
  18621. 11:11:39number and the dense rank you can see
  18622. 11:11:41there will be no skipping. So there is
  18623. 11:11:44no gaps for the row number and as well
  18624. 11:11:47for the dense rank only for the rank
  18625. 11:11:50function the middle one we are skipping
  18626. 11:11:52ranks and we are leaving gaps. So that's
  18627. 11:11:54it guys. This is the differences between
  18628. 11:11:56those three functions. I tend usually to
  18629. 11:11:58work with the row number more often than
  18630. 11:12:00that to others.
  18631. 11:12:05All right guys, so now I had a look to
  18632. 11:12:07those three functions and I checked my
  18633. 11:12:09projects real projects and I found out
  18634. 11:12:11that there are many use cases for the
  18635. 11:12:14function row number compared to the
  18636. 11:12:16other functions dense rank and rank. So
  18637. 11:12:19now what we're going to do I'm going to
  18638. 11:12:20show you a few use cases for the rank
  18639. 11:12:22number that I usually use in my real
  18640. 11:12:24projects in order for you to understand
  18641. 11:12:26how important is the row number
  18642. 11:12:28function. So let's go to SQL. All right.
  18643. 11:12:30So now let's start with the first use
  18644. 11:12:31case and we have the task of find the
  18645. 11:12:33top highest sales for each product. So
  18646. 11:12:36this is very classic in reporting or
  18647. 11:12:39data analyzes. We call this top end
  18648. 11:12:41analyzes. So here the managers or
  18649. 11:12:44decision makers they would like to have
  18650. 11:12:46the best performers or the best success
  18651. 11:12:48in our data. So for example the top
  18652. 11:12:50highest five customers or the top five
  18653. 11:12:54products or categories and so on. So
  18654. 11:12:56this is very important analyzis in order
  18655. 11:12:58to focus on the best products or on to
  18656. 11:13:01the most important customers and so on
  18657. 11:13:03and this is as I said very classic and
  18658. 11:13:05very important in order to make
  18659. 11:13:06decisions in the business. So now let's
  18660. 11:13:09see how we can solve this. So we're
  18661. 11:13:10going to start with the usual stuff.
  18662. 11:13:11Let's first select the data. So select
  18663. 11:13:14order ID. Let's take as well the product
  18664. 11:13:16ID and the sales from sales orders. So
  18665. 11:13:21let's go and execute this. And now as we
  18666. 11:13:23know that for each product we have
  18667. 11:13:24multiple orders and we have multiple
  18668. 11:13:26sales but we are interested only in the
  18669. 11:13:28highest sales for each product. So we
  18670. 11:13:30have to go and create a rank. In order
  18671. 11:13:32to do that we're going to use the row
  18672. 11:13:34function row number and we have to
  18673. 11:13:37define the window now. So do we need
  18674. 11:13:38partition by check the query. So it says
  18675. 11:13:42for each product that means we have to
  18676. 11:13:44divide the data by the product ID. So
  18677. 11:13:46let's go and use the partition by
  18678. 11:13:49products ID. And now we must use the
  18679. 11:13:52order by. So order by. And now how to
  18680. 11:13:55sort the data by the sales, right? And
  18681. 11:13:57it is from the highest to the lowest. So
  18682. 11:13:59let's go sales. And we have here
  18683. 11:14:02descending. So from highest to lowest.
  18684. 11:14:04Let's go and give it a name. So you're
  18685. 11:14:06going to be rank by products. So let's
  18686. 11:14:09go and execute this. And now by looking
  18687. 11:14:12to the result, you can see that SQL did
  18688. 11:14:14divide the data by the product ID. So we
  18689. 11:14:16have here like around four windows. The
  18690. 11:14:19first one over here you can see that the
  18691. 11:14:20rank starts from one end with four. So
  18692. 11:14:23the highest rank can be the order number
  18693. 11:14:25eight with the sales of 90 and then it
  18694. 11:14:28goes to the four. Now as you can see
  18695. 11:14:31that the second window we have a new
  18696. 11:14:33ranking. So it resets the first going to
  18697. 11:14:35be uh the order number 10 and the last
  18698. 11:14:38one going to be order number two. So as
  18699. 11:14:40you can see each window has its own
  18700. 11:14:42ranking and as well the last one we have
  18701. 11:14:44it only as one row. So now of course in
  18702. 11:14:47the task we have to return the highest.
  18703. 11:14:49So we are not interested in the others.
  18704. 11:14:51We have to return this row this row as
  18705. 11:14:53well and this one and this one. So as
  18706. 11:14:55you can see we have to return everything
  18707. 11:14:57that has the rank one. We are not
  18708. 11:14:59interested in the rank 2 3 4 and so on.
  18709. 11:15:02So we would like to have the highest. So
  18710. 11:15:04now in order to filter the data what
  18711. 11:15:05we're going to do we're going to go and
  18712. 11:15:07use subqueries. So select star from and
  18713. 11:15:12then we're going to have the following
  18714. 11:15:13condition. So where and we're going to
  18715. 11:15:15say rank by product equals to one. So we
  18716. 11:15:20are interested only on the rank number
  18717. 11:15:22one. So let's go and execute it. And
  18718. 11:15:24with that since we have four products in
  18719. 11:15:26our data, we're going to have only four
  18720. 11:15:27rows and we have the highest sales. So
  18721. 11:15:30as you can see we have only number one
  18722. 11:15:31over here. And those sales are the
  18723. 11:15:33highest for each product. And with that
  18724. 11:15:36we have solved the tasks by finding the
  18725. 11:15:38top end analyzers.
  18726. 11:15:44Okay, moving on to the next use case. We
  18727. 11:15:46have the following task and it says find
  18728. 11:15:48the lowest two customers based on their
  18729. 11:15:50total sales. So now we have the exact
  18730. 11:15:53opposite use case. We call it button in
  18731. 11:15:56analyzes. So now in this example in the
  18732. 11:15:58business the decision makers want to
  18733. 11:16:00optimize the costs want to cut costs and
  18734. 11:16:03with that they have to analyze the
  18735. 11:16:05lowest performers in the products or the
  18736. 11:16:08lowest performance in the employees in
  18737. 11:16:10order to cut costs. So now with this
  18738. 11:16:12analysis the decision makers are not
  18739. 11:16:14focusing on the best successful stuff.
  18740. 11:16:16We are focusing on the lowest stuff the
  18741. 11:16:19lowest performers. So now let's solve
  18742. 11:16:21this tasks. So now if you check the
  18743. 11:16:22question we have multiple stuff right we
  18744. 11:16:24have the total sales and as well we have
  18745. 11:16:27to find the lowest two customers. So we
  18746. 11:16:29have ranking and as well aggregations
  18747. 11:16:31remember we can do stuff together with
  18748. 11:16:33the group I. So now let's do it step by
  18749. 11:16:35step. First let's select the data right.
  18750. 11:16:37So what do we need? Order ID customer ID
  18751. 11:16:40and we need the sales from sales orders.
  18752. 11:16:45So let's go and execute this. So now if
  18753. 11:16:47you check the customers over here we
  18754. 11:16:49have around four customers and they have
  18755. 11:16:51multiple sales. Now we would like to
  18756. 11:16:53have the total sales for each customers
  18757. 11:16:56in order to find the lowest two. So
  18758. 11:16:58let's start first with the aggregations.
  18759. 11:17:00So what we going to do? We're going to
  18760. 11:17:01go and aggregate the sales. So the sum
  18761. 11:17:03of sales and let's call it total sales.
  18762. 11:17:06And now in order to do the group by we
  18763. 11:17:08have to have only the customer. So group
  18764. 11:17:11by and we have the customer ID. So it is
  18765. 11:17:14very simple group by statements. Let's
  18766. 11:17:17go and execute this. So now by checking
  18767. 11:17:18the result we can see that SQL did
  18768. 11:17:20aggregate the data. We have four rows
  18769. 11:17:22and that's because we have four
  18770. 11:17:23customers and we have their total sales.
  18771. 11:17:26So we have solved the first part of the
  18772. 11:17:28task. We have the total sales for each
  18773. 11:17:30customers. Now let's move to the second
  18774. 11:17:32part. It says lowest two customers. That
  18775. 11:17:35means we have to use the ranking
  18776. 11:17:37functions in order to rank those
  18777. 11:17:39customers. So we are not interested in
  18778. 11:17:41all customers. We are interested only in
  18779. 11:17:43the lowest two. So in order to do that
  18780. 11:17:45now we're going to go and use the window
  18781. 11:17:47function row number. So and then over.
  18782. 11:17:51Now do we have to partition the data?
  18783. 11:17:53Well no we don't have to do that. We
  18784. 11:17:55have now to sort the data. So order by.
  18785. 11:17:58So this time we're going to go and use
  18786. 11:18:00the aggregations in the order by. So the
  18787. 11:18:02sum of sales and we want to have it
  18788. 11:18:04sorted from the lowest to the highest.
  18789. 11:18:07So I'm just going to go and use the
  18790. 11:18:09defaults. So it is ascending. Now let's
  18791. 11:18:11call it rank customers. So that's it.
  18792. 11:18:15Again here the rule is that if you are
  18793. 11:18:17using a window function together with
  18794. 11:18:19the group by function, you have to use
  18795. 11:18:21only columns that is used in the group
  18796. 11:18:23by. So this should be working. Let's go
  18797. 11:18:25and execute it. So now as you can see in
  18798. 11:18:27the results, we got an extra column for
  18799. 11:18:29the rank. So now the lowest customer
  18800. 11:18:31going to be the customer number two. The
  18801. 11:18:33second one going to be four with the 90
  18802. 11:18:35total sales. And the highest customer
  18803. 11:18:38with the sales is going to be the last
  18804. 11:18:39one, the 125 customer number three. So
  18805. 11:18:42now we have almost everything but the
  18806. 11:18:44list should contain only the last two.
  18807. 11:18:47So in order to do that to filter the
  18808. 11:18:48data, we're going to go and use
  18809. 11:18:50subquery. So select star
  18810. 11:18:53from and then we have to define the
  18811. 11:18:55condition where rank customers it should
  18812. 11:18:59be smaller or equal to two. Right? So
  18813. 11:19:01with that we will get the first two. So
  18814. 11:19:03let's go and execute this. And with that
  18815. 11:19:06we got the lowest two customers based on
  18816. 11:19:08their total sales. So customer number ID
  18817. 11:19:10you two and the four. So that's it. We
  18818. 11:19:13have solved the task and now we have
  18819. 11:19:14done button in
  18820. 11:19:19analyzes. Okay let's keep moving to the
  18821. 11:19:21next use case and we have the following
  18822. 11:19:23task. It says assign unique ids to the
  18823. 11:19:26rows of the table orders archive. So now
  18824. 11:19:30guys we might be in situation where you
  18825. 11:19:31have a table without any primary key and
  18826. 11:19:34you would like to create an ID for each
  18827. 11:19:36row. So in order to do that we can use
  18828. 11:19:38the function row number in order to
  18829. 11:19:40generate unique identifier ids for each
  18830. 11:19:44row inside our table if we don't have
  18831. 11:19:45one. And generating such ID for each
  18832. 11:19:47row. It's very important to do stuff
  18833. 11:19:49like importing data, exporting data,
  18834. 11:19:52maybe joining tables as well using this
  18835. 11:19:53ID or let's say optimizing the
  18836. 11:19:56performance of query using the ID. So
  18837. 11:19:58now let's see how we can generate that
  18838. 11:20:00using row number. Okay. So now let's
  18839. 11:20:02first select the table order archives in
  18840. 11:20:04order to understand the content. So
  18841. 11:20:06select star from sales orders archive.
  18842. 11:20:11So let's go and execute. So now by
  18843. 11:20:13checking the result you can see that we
  18844. 11:20:14have 10 orders and we have repetitions
  18845. 11:20:17in the order ID over here. So it is not
  18846. 11:20:19really primary key. As you can see over
  18847. 11:20:21here we have twice the ID four and here
  18848. 11:20:24we have three times the ID6. So now what
  18849. 11:20:26we're going to do we're going to go and
  18850. 11:20:27generate unique identifier for each row.
  18851. 11:20:30So in order to do that what we're going
  18852. 11:20:32to do going to go over here and say row
  18853. 11:20:34number and then we're going to define
  18854. 11:20:37the window function. We don't partition
  18855. 11:20:39the data at all but we have to sort the
  18856. 11:20:41data by the order ID. So order by order
  18857. 11:20:46ID or you can use something else as well
  18858. 11:20:48using the order date or something
  18859. 11:20:50doesn't matter. So let's add to it order
  18860. 11:20:53data as well and let's call it unique
  18861. 11:20:57ID. Let's go and execute this. Now by
  18862. 11:21:00checking the data you can see that we
  18863. 11:21:02have a new ID over here that comes from
  18864. 11:21:05the row number and we have like a unique
  18865. 11:21:08identifier. As you can see we have 10
  18866. 11:21:10rows and with that we have as well 10
  18867. 11:21:12different distinct unique ids. So with
  18868. 11:21:14this as you can see we have solved the
  18869. 11:21:16task and we have now a unique identifier
  18870. 11:21:18an ID for the table orders archive. So
  18871. 11:21:21now having this ID we can do many stuff
  18872. 11:21:23like joining tables or doing something
  18873. 11:21:25special and important called pagenating.
  18874. 11:21:28Imagine we have like a huge table and we
  18875. 11:21:30would like to retrieve the data. So now
  18876. 11:21:32in order to not have all the data in one
  18877. 11:21:35go we can go and divide the data by the
  18878. 11:21:37primary ID or by unique identifier. For
  18879. 11:21:39example, we can make a page from 1 until
  18880. 11:21:42100,000 and then the second page starts
  18881. 11:21:45from 100K to 200ks. So now by dividing
  18882. 11:21:48the data, we can maybe improve exporting
  18883. 11:21:50or importing data or we can have faster
  18884. 11:21:53retrieval for the users. We don't want
  18885. 11:21:54to have the whole data in one go in one
  18886. 11:21:57page. So it has a lot of benefits using
  18887. 11:21:59pagionating and we can do that only if
  18888. 11:22:01we have a nice ID like
  18889. 11:22:06this. All right. Right. Today I'm going
  18890. 11:22:08to show you the last use case for the
  18891. 11:22:09function row number that I usually use
  18892. 11:22:11in my real projects. So sometimes if you
  18893. 11:22:14are doing data analyszis you're going to
  18894. 11:22:15find out that there are data quality
  18895. 11:22:17issues especially with the duplicates.
  18896. 11:22:19So what I usually use I use the raw
  18897. 11:22:22number in order to identify the
  18898. 11:22:23duplicates. Not only that I can use it
  18899. 11:22:26in order to delete the duplicates. So we
  18900. 11:22:28can use it in order to do data
  18901. 11:22:30cleansing. And this is essential task
  18902. 11:22:32for each data engineer not only data
  18903. 11:22:35analysts in order to prepare and clean
  18904. 11:22:37up the data before doing data analyzes.
  18905. 11:22:40So let's have the following task.
  18906. 11:22:41Identify duplicate rows in the table
  18907. 11:22:43orders archive and return a clean result
  18908. 11:22:46without any duplicates. So not only we
  18909. 11:22:48have to identify the duplicates, we have
  18910. 11:22:50to return no duplicates in our results.
  18911. 11:22:53So let's see how we can do this. Let's
  18912. 11:22:54first select the data. So select star
  18913. 11:22:56from sales orders archive. So let's go
  18914. 11:23:01and execute. So now by looking to the
  18915. 11:23:02data you can see that we have
  18916. 11:23:03duplicates. We have an issue. So the
  18917. 11:23:05order ID number four is twice in our
  18918. 11:23:07database. It doesn't make sense, right?
  18919. 11:23:09It should be only one. So which one is
  18920. 11:23:11the correct one? If you check the data
  18921. 11:23:13over here, you can see that this order
  18922. 11:23:15is shipped and then delivered. So it
  18923. 11:23:17looks like the last one is the correct
  18924. 11:23:19one. So how we can do that? If you just
  18925. 11:23:22scroll to the right, you can see that we
  18926. 11:23:24have a creation time. And we usually use
  18927. 11:23:26such a time stamp in order to identify
  18928. 11:23:29what was the last valid like order. And
  18929. 11:23:32here we can see immediately that this
  18930. 11:23:34order time is higher than the previous
  18931. 11:23:36one. Which means this is the more up to
  18932. 11:23:38date, right? The more current. So what
  18933. 11:23:41we're going to do, we're going to go and
  18934. 11:23:43rank our data for each order ID and sort
  18935. 11:23:46the data by the creation time in order
  18936. 11:23:48to find the last inserted or created row
  18937. 11:23:51for this order. So let's see how we can
  18938. 11:23:53do that. What we going to do? We're
  18939. 11:23:55going to go over here and say let's have
  18940. 11:23:57a row number and then over and what
  18941. 11:24:01we're going to do, we're going to
  18942. 11:24:02partition by the primary key. So
  18943. 11:24:04partition by order ID and as we said we
  18944. 11:24:07have to order the data by this time stab
  18945. 11:24:09at the end. So partition by or order by
  18946. 11:24:13creation time and descending. So we want
  18947. 11:24:16the highest then the lowest. So that's
  18948. 11:24:19it. Let's call it Rn and execute the
  18949. 11:24:22query. So now by checking the data if
  18950. 11:24:24everything is clean and we don't have
  18951. 11:24:25duplicates everything should be one
  18952. 11:24:28because maximum for each primary key we
  18953. 11:24:30should has one row. So but you can see
  18954. 11:24:32over here we have here two and we have
  18955. 11:24:34here three two. So that means this is
  18956. 11:24:36indicator that we have duplicates inside
  18957. 11:24:38our data. So now by checking one by one
  18958. 11:24:40as you can see the order ID is only one.
  18959. 11:24:43So we have the rank one the second one
  18960. 11:24:45as well we have the rank one but here we
  18961. 11:24:47have the issue. So as you can see we
  18962. 11:24:49have now two ranks for the order ID
  18963. 11:24:51four. So now which one is the correct in
  18964. 11:24:54our logic? We say it is the last row
  18965. 11:24:56that is inserted inside our data and
  18966. 11:24:58this is rank number one. So if you
  18967. 11:25:00scroll to the right side you can see
  18968. 11:25:01that the creation time here is higher
  18969. 11:25:04than the second one. So with that we
  18970. 11:25:06have identified what we want. We want
  18971. 11:25:08the last inserted row for each ID. And
  18972. 11:25:12now let's check this over here. So here
  18973. 11:25:14we have it three times. So it says the
  18974. 11:25:17first one is the highest creation date.
  18975. 11:25:19So if you go to the right side and now
  18976. 11:25:21by comparing those time stamps you can
  18977. 11:25:22see that this record the first one is
  18978. 11:25:26the la latest one that is inserted
  18979. 11:25:28inside our data. So as you can see this
  18980. 11:25:31one is the one that we need the other
  18981. 11:25:33two we don't need it because it is old
  18982. 11:25:35informations. So now everything that
  18983. 11:25:37doesn't has the rank number one is not
  18984. 11:25:39valid. It's something old and it's
  18985. 11:25:41actually bad data quality. So we want to
  18986. 11:25:44remove it or not to select it. So now in
  18987. 11:25:46order to have a clean data what we going
  18988. 11:25:48to do we're going to go and select the
  18989. 11:25:50following as sub select. So select star
  18990. 11:25:52from the table and now we are interested
  18991. 11:25:56only with the rank number one. We don't
  18992. 11:25:59need anything else. So let's go and
  18993. 11:26:00execute. And now if you check the
  18994. 11:26:02results you can check the order ID over
  18995. 11:26:03here. It is unique. We don't have any
  18996. 11:26:05duplicates. Right? 1 2 3 4 5 6 7. There
  18997. 11:26:08is no duplicates at all. And we have now
  18998. 11:26:11only the latest inserted data inside the
  18999. 11:26:13orders. and we don't have any duplicates
  19000. 11:26:16or data quality issue. So now of course
  19001. 11:26:18now we can go with this results in order
  19002. 11:26:19to do for the analyzes and this is
  19003. 11:26:21exactly what data engineers usually do
  19004. 11:26:23clean up the data and prepare the data
  19005. 11:26:25before doing any data analyzes. And of
  19006. 11:26:28course if you want to communicate those
  19007. 11:26:30data quality issues to the source of the
  19008. 11:26:32data let's say you are not the owner of
  19009. 11:26:33those informations. You can generate a
  19010. 11:26:35list of all bad data quality issues and
  19011. 11:26:38you can send it to the source system and
  19012. 11:26:39tell them to clean it up from the
  19013. 11:26:41sources. So now in order to select the
  19014. 11:26:43bad data what we're going to do is we
  19015. 11:26:45can just change here the condition and
  19016. 11:26:47say if it is higher than one then you
  19017. 11:26:50are like bad data. So let's go and
  19018. 11:26:52execute this. And now with this we have
  19019. 11:26:54in the results all records that
  19020. 11:26:56shouldn't exist in the data in the first
  19021. 11:26:58place. So we can go and export it and
  19022. 11:27:00communicate it to the source and tell
  19023. 11:27:01them check here you have something wrong
  19024. 11:27:03in your system and those information
  19025. 11:27:05should not be inserted in the data. So
  19026. 11:27:07everyone it is very strong right? It is
  19027. 11:27:09very powerful. I use it a lot in my
  19028. 11:27:11projects. There are many use cases for
  19029. 11:27:13the row number function in SQL. We can
  19030. 11:27:15do it in order to find the top end
  19031. 11:27:18analyzes, the bottom end analyzes, the
  19032. 11:27:20best performance, worst performance and
  19033. 11:27:22as well we can assign unique ids to do
  19034. 11:27:24benating or we can use it in order to
  19035. 11:27:26discover data quality issues to clean up
  19036. 11:27:29our data. So it is amazing function in
  19037. 11:27:31SQL and you're going to use it a lot. So
  19038. 11:27:33that's it for the three functions ro
  19039. 11:27:34number, rank and dense rank. Now we're
  19040. 11:27:36going to talk about the
  19041. 11:27:40inile. Okay. So what is inile? Intile in
  19042. 11:27:44SQL is very simple. It's going to go and
  19043. 11:27:45divide your rows, your data into
  19044. 11:27:48specific number of almost equal groups
  19045. 11:27:51or sometimes we call them packets. So
  19046. 11:27:53now in order to understand this and how
  19047. 11:27:55it scale works with this function, we're
  19048. 11:27:57going to have a very simple example. So
  19049. 11:27:58let's go. Okay, we have the following
  19050. 11:28:00setup. We have four rows for sales and
  19051. 11:28:02we would like to divide it into two
  19052. 11:28:04groups or into two buckets. So in order
  19053. 11:28:07to do that we can use the entile
  19054. 11:28:09function. It has different syntax than
  19055. 11:28:11the other ranking functions. So it
  19056. 11:28:13starts with entile then we must define a
  19057. 11:28:16number. So we cannot leave it empty like
  19058. 11:28:18the other ranking. So here we have two
  19059. 11:28:20buckets then over and here again we have
  19060. 11:28:23to sort the data. So it is must order by
  19061. 11:28:26sales descending from the highest to the
  19062. 11:28:28lowest. So now as usual SQL going to go
  19063. 11:28:30and sort the data. We have it already
  19064. 11:28:32sorted in this example. Then it going to
  19065. 11:28:34start assigning each of those rows into
  19066. 11:28:36buckets. But SQL first has to calculate
  19067. 11:28:40the bucket size. So how many rows we can
  19068. 11:28:43like insert inside each bucket. So the
  19069. 11:28:45calculation is very simple. It says the
  19070. 11:28:47bucket size equals to the number of rows
  19071. 11:28:51divided by the number of buckets. So
  19072. 11:28:53what is the number of rows here? We have
  19073. 11:28:55four rows, right? So we have four over
  19074. 11:28:58here. Then the number of buckets we
  19075. 11:29:00define it in the syntax of the query. So
  19076. 11:29:02here we defined two buckets. We need two
  19077. 11:29:04groups. So that means we are dividing
  19078. 11:29:07four by two. And the size of the bucket
  19079. 11:29:09going to be two. So now with this SQL is
  19080. 11:29:11ready and going to start assigning each
  19081. 11:29:13row to a bucket. So it's going to start
  19082. 11:29:15on the top. The first one going to be in
  19083. 11:29:16the bucket number one. Then go to the
  19084. 11:29:19next one. It's going to say okay we
  19085. 11:29:20still have enough space in the bucket.
  19086. 11:29:22Right? So it's going to sign as well to
  19087. 11:29:24one. But with this we reach the maximum
  19088. 11:29:27number of rows within each bucket. So
  19089. 11:29:29the next row going to be assigned to
  19090. 11:29:31another bucket. So it's going to be two
  19091. 11:29:33and the last one going to be as well
  19092. 11:29:35too. So as you can see it's very simple.
  19093. 11:29:37We have just assigned our sales based on
  19094. 11:29:39the sorting of course into two buckets.
  19095. 11:29:41These two sales belongs to the bucket
  19096. 11:29:43number one and the other two belongs to
  19097. 11:29:45the bucket number two. Very easy. So
  19098. 11:29:47that was very straightforward because we
  19099. 11:29:49are dividing even numbers and we got
  19100. 11:29:51perfectly sized buckets. But now what
  19101. 11:29:53going to happen if we have an odd
  19102. 11:29:55number? So we have here five instead of
  19103. 11:29:57four. So the bucket size going to be
  19104. 11:30:00dividing five by two. We're going to get
  19105. 11:30:022.5. And now of course SQL will not go
  19106. 11:30:04and divide like two half for each
  19107. 11:30:06bucket. Then we are splitting this into
  19108. 11:30:08two packets. Of course this will not be
  19109. 11:30:10working. We should has now a bucket with
  19110. 11:30:12three and another bucket with two. So
  19111. 11:30:14now the rule in SQL make it very clear.
  19112. 11:30:17It says larger groups comes first then
  19113. 11:30:20smaller. So that means if we have here
  19114. 11:30:22an even number like this, the larger
  19115. 11:30:24group going to be the first group. So
  19116. 11:30:26that's going to look like this. It's
  19117. 11:30:28going to like reset everything. So let's
  19118. 11:30:32see what's going to happen. The first
  19119. 11:30:33one going to be one. The second one has
  19120. 11:30:35bill one. The third one going to be as
  19121. 11:30:37well one. So it going to has a larger
  19122. 11:30:40package than the second one. Then the
  19123. 11:30:43rest going to be two. So as you can see
  19124. 11:30:45the larger group comes first then the
  19125. 11:30:48smaller. And this is how a scale going
  19126. 11:30:50to work. if you have odd numbers. So you
  19127. 11:30:52don't have here perfectly sized buckets.
  19128. 11:30:54You have approximately or roughly
  19129. 11:30:56equally sized buckets. So this is how
  19130. 11:30:58the intel works. Now let's go back to
  19131. 11:31:00scale in order to practice this
  19132. 11:31:01function. Okay. So now let's have some
  19133. 11:31:03fun working with this function. So we
  19134. 11:31:05just going to select something like
  19135. 11:31:07order ID sales from sales orders. So
  19136. 11:31:13let's go and execute it. And with that
  19137. 11:31:15we got our 10 rows. Now let's say that I
  19138. 11:31:17would like to create only one bucket
  19139. 11:31:19from the data. So entile and only one
  19140. 11:31:23bucket over partition let's say not
  19141. 11:31:26partition by let's take order by sales
  19142. 11:31:29descending. So that's it. I'm going to
  19143. 11:31:32call it one bucket. So let's go and
  19144. 11:31:35execute it. As usual it's still going to
  19145. 11:31:37go and sort the data and then calculate
  19146. 11:31:38the bucket. It's going to be 10 rows
  19147. 11:31:41divided by one. So the size of the
  19148. 11:31:43bucket going to be 10. So that's why
  19149. 11:31:45you're going to see everywhere here as
  19150. 11:31:47one because all those rows going to fit
  19151. 11:31:49into one bucket. So this is very simple.
  19152. 11:31:52We have only one bucket. Let's go and
  19153. 11:31:54now have two buckets. So I'm just going
  19154. 11:31:56to copy and paste. And instead of one,
  19155. 11:31:59we're going to have two and let's call
  19156. 11:32:00it two buckets. So let's go and execute
  19157. 11:32:04this. So now here again, what is the
  19158. 11:32:06size of the buckets? It is 10 divided by
  19159. 11:32:08two. So we will get perfectly grouped
  19160. 11:32:11buckets. So the first bucket going to be
  19161. 11:32:13five rows and the second one going to be
  19162. 11:32:15the next five rows. So it is very
  19163. 11:32:17perfect. Let's go to the next one. Let's
  19164. 11:32:20have three buckets. So three. So let's
  19165. 11:32:24go and execute. So now what going to
  19166. 11:32:26happen is going to go and divide 10 by
  19167. 11:32:28three in order to get the size of the
  19168. 11:32:30bucket. And it's going to be 3.3. So it
  19169. 11:32:33is decimal and we will not get perfectly
  19170. 11:32:35sized buckets. So again the larger group
  19171. 11:32:38comes first then the smaller. So as you
  19172. 11:32:41can see we have to fit then in the first
  19173. 11:32:43group four in order to get the others
  19174. 11:32:45with three. So that's why the first
  19175. 11:32:47bucket is going to be the biggest one.
  19176. 11:32:49So four rows into the first bucket. Then
  19177. 11:32:51the second three rows going to be in the
  19178. 11:32:53bucket two. And as well the last one
  19179. 11:32:55going to be bucket three. So as you can
  19180. 11:32:57see the largest group is going to be the
  19181. 11:32:59first bucket. So now let's keep playing
  19182. 11:33:01with the data. Let's go and take now
  19183. 11:33:04four. We would like to have four
  19184. 11:33:05buckets. Now things going to get
  19185. 11:33:08interesting. So now by checking the
  19186. 11:33:09result it's going to be interesting. SQL
  19187. 11:33:11going to divide 10 by four and we will
  19188. 11:33:13get something like 2.5. So again we will
  19189. 11:33:16not get perfectly sized groups. So SQL
  19190. 11:33:18has to fit now 10 rows into four groups.
  19191. 11:33:22So the first three rows going to be fit
  19192. 11:33:24in the bucket number one and as well the
  19193. 11:33:27second three rows like this going to be
  19194. 11:33:29in the bucket number two. And then you
  19195. 11:33:32can see over here we have two buckets
  19196. 11:33:34with a size of two. And with that we can
  19197. 11:33:36fit 10 into four groups. And again you
  19198. 11:33:38can see the larger groups comes first
  19199. 11:33:41like this one and then the second and
  19200. 11:33:43the smallers comes later. Okay. So this
  19201. 11:33:46is how the inter works in SQL. And now
  19202. 11:33:47you might say you know what why do I
  19203. 11:33:49need buckets in the first place. So what
  19204. 11:33:51is the use
  19205. 11:33:55case? There is two use cases for the
  19206. 11:33:58intel function in my projects. In one
  19207. 11:34:00hands if I am data analyst I'm going to
  19208. 11:34:02use the intel function in order to
  19209. 11:34:04segment my data. In the other hand, if
  19210. 11:34:06I'm data engineer, I'm going to use the
  19211. 11:34:08intel function in order to do ETL
  19212. 11:34:10processing and as well to do load
  19213. 11:34:13balancing. So now let's start with the
  19214. 11:34:14first use case as a data analyst where
  19215. 11:34:17you want to do segmentations with the
  19216. 11:34:18entire function. Segmentations is very
  19217. 11:34:21nice way in order to understand your
  19218. 11:34:22data. So you can go and segment your
  19219. 11:34:25data into different buckets or groups
  19220. 11:34:27like for example doing segmentations for
  19221. 11:34:29the customers. So you can go and group
  19222. 11:34:32up your customers depend on their
  19223. 11:34:33behavior like the total sales or the
  19224. 11:34:36total number of orders. So with that you
  19225. 11:34:38can make like for example VIB section
  19226. 11:34:41and then the medium and then the low. So
  19227. 11:34:43now in order to understand the
  19228. 11:34:44segmentation use case let's have the
  19229. 11:34:46following task. Okay. The task says
  19230. 11:34:48segment all orders into three categories
  19231. 11:34:51high medium and low sales. So in order
  19232. 11:34:54to solve this let's do the basic stuff
  19233. 11:34:57right. So select order ID. Let's take
  19234. 11:34:59the sales from our table sales orders
  19235. 11:35:03and let's go and execute it. So as usual
  19236. 11:35:06we got our 10 sales. So now if you check
  19237. 11:35:08the task it says we need three
  19238. 11:35:10categories. So that means we need three
  19239. 11:35:12buckets right and it says high, medium
  19240. 11:35:15and low sales. So that means we are
  19241. 11:35:18dividing by the sales. So let's go and
  19242. 11:35:20do it step by step. So we're going to
  19243. 11:35:22use inile since we need to segment the
  19244. 11:35:24data. Three categories means three
  19245. 11:35:26buckets. And then let's define the
  19246. 11:35:29window over we don't have to divide the
  19247. 11:35:31data by partition by we just need to
  19248. 11:35:33sort it first by the sales. So it's
  19249. 11:35:36going to be by sales and let's take
  19250. 11:35:38discrete since we want to sort it from
  19251. 11:35:40the highest to the lowest. So that's it.
  19252. 11:35:42Let's say you are our buckets. So let's
  19253. 11:35:46go and execute this. So now if you check
  19254. 11:35:48the data you can see that they are
  19255. 11:35:49segmented into three buckets. So the
  19256. 11:35:52first bucket going to contain all orders
  19257. 11:35:54with the high sales. Then the second one
  19258. 11:35:57going to be all sales with the medium.
  19259. 11:35:59And then the last one going to be all
  19260. 11:36:01sales with the low sales. So as you can
  19261. 11:36:03see we have already categorized our data
  19262. 11:36:06into three groups. But now as you can
  19263. 11:36:08see we have numbers and maybe the user
  19264. 11:36:10is expecting to have those text high,
  19265. 11:36:12medium, low. So that means what we're
  19266. 11:36:14going to do now we're going to go and
  19267. 11:36:15translate those numbers into text into
  19268. 11:36:17words. And of course we cannot do that
  19269. 11:36:19inside the window function. We're going
  19270. 11:36:21to use data transformation using the
  19271. 11:36:23case when statements. Don't worry about
  19272. 11:36:25it. We're going to have complete
  19273. 11:36:26dedicated section explaining the case
  19274. 11:36:28when. So for now just follow me in order
  19275. 11:36:31to see how this works. We're going to go
  19276. 11:36:33and use subquery. So it's going to be
  19277. 11:36:35select and let's take the star for
  19278. 11:36:38everything and then let's have the
  19279. 11:36:39following logic. Case when buckets equal
  19280. 11:36:43to one then it is high the sales is
  19281. 11:36:46high. So we are just mapping the numbers
  19282. 11:36:49into text. So otherwise case when the
  19283. 11:36:52brackets equal to two then we are
  19284. 11:36:54targeting the medium medium and then the
  19285. 11:36:58last group packets equal to three then
  19286. 11:37:02those sales are low. So let's call it
  19287. 11:37:05end it and let's call it sales
  19288. 11:37:08segmentations. So that's it. Let me just
  19289. 11:37:10make it a little bit smaller in order
  19290. 11:37:12for you to see it. And all right so from
  19291. 11:37:17and then we have our subquery like this.
  19292. 11:37:20So as you can see we just mapped the
  19293. 11:37:22numbers into text. We are just doing
  19294. 11:37:25translations. So let's go and execute
  19295. 11:37:27it. And now by checking the results we
  19296. 11:37:29got our three categories for the users.
  19297. 11:37:32So the first category going to be the
  19298. 11:37:33high sales. The second one going to be
  19299. 11:37:35the medium sales and the third one going
  19300. 11:37:37to be the low sales. So guys you see
  19301. 11:37:39Intel is very powerful in order to
  19302. 11:37:41segment our data. So now you can go and
  19303. 11:37:43segment stuff like the customers by
  19304. 11:37:46their total sales or the products by
  19305. 11:37:48prices, employees by their salaries and
  19306. 11:37:51so
  19307. 11:37:54on. All right. So this is the first use
  19308. 11:37:56case for the Intel function as a data
  19309. 11:37:58analyst where you go and segment your
  19310. 11:38:00data in order to understand the
  19311. 11:38:01behavior. Now in the other hand, if you
  19312. 11:38:04are data engineer, you can use Intel
  19313. 11:38:06function in order to do load balancing
  19314. 11:38:08in your ETL. So now I'm just going to
  19315. 11:38:10explain it in very simple sketch. All
  19316. 11:38:12right. So now we have the following
  19317. 11:38:13scenario where we have two databases and
  19318. 11:38:15we would like to move one big table from
  19319. 11:38:18the database A to database B. So in this
  19320. 11:38:21case I'm doing something called full
  19321. 11:38:22load. That means I'm loading all the
  19322. 11:38:24rows from one database to another. So if
  19323. 11:38:27you do it in one go what could happen is
  19324. 11:38:30that it could take long time. So it
  19325. 11:38:32could take hours or even sometimes days
  19326. 11:38:34and maybe at the end you will get maybe
  19327. 11:38:36some network errors because you have
  19328. 11:38:38stressed the networks between those two
  19329. 11:38:40databases and everything going to break
  19330. 11:38:41and you're going to lose the data and
  19331. 11:38:43you have to start again. So now instead
  19332. 11:38:44of loading this table in one go what we
  19333. 11:38:47can do we can go and split it into
  19334. 11:38:49fractions or let's say packets. So we
  19335. 11:38:51can split this table for example into
  19336. 11:38:53four small tables using the function
  19337. 11:38:56entile. So now after we split this big
  19338. 11:38:58table into small tables, we're going to
  19339. 11:39:00go and start moving those small tables
  19340. 11:39:02one after another and with that we are
  19341. 11:39:05not stressing the networks and it's
  19342. 11:39:06going to succeed. So now after loading
  19343. 11:39:08everything at the end in the target
  19344. 11:39:10database we're going to have those small
  19345. 11:39:12tables and of course we can go and use
  19346. 11:39:14the union in order to merge them in
  19347. 11:39:16order to have again the big table that
  19348. 11:39:18we have it in the original database. So
  19349. 11:39:20this is very common use case for the
  19350. 11:39:22entile in order to split the load and to
  19351. 11:39:24balance the processing of extracting
  19352. 11:39:27data. All right. So now we have the
  19353. 11:39:28following SQL task. It says in order to
  19354. 11:39:30export the data divide the orders into
  19355. 11:39:33two groups. So let's go and do that.
  19356. 11:39:35First we're going to select everything
  19357. 11:39:37from the table just in order to see the
  19358. 11:39:39data sales orders. So let's go and
  19359. 11:39:43execute it. So now we got our 10 orders
  19360. 11:39:45and what we have to do is that to go and
  19361. 11:39:47split it into two groups. In order to do
  19362. 11:39:49that we can use the entile function. Two
  19363. 11:39:53groups means two buckets. So let's
  19364. 11:39:55define the window. So here we don't have
  19365. 11:39:57to partition the data using partition by
  19366. 11:39:59but we have to specify the order by. So
  19367. 11:40:02now which column we're going to use in
  19368. 11:40:04order to sort the data. Of course here
  19369. 11:40:06there is no rule like you can go and
  19370. 11:40:07split the data by sales or by the order
  19371. 11:40:10status by date by anything you want. But
  19372. 11:40:12we usually go and use the primary key.
  19373. 11:40:15It's just systematic, better, and more
  19374. 11:40:17clean, especially if you have a sequence
  19375. 11:40:19of numbers in the order ID. So you can
  19376. 11:40:21export the first range of the orders,
  19377. 11:40:23then you can go to the next group and so
  19378. 11:40:25on. So let's go with the order ID and
  19379. 11:40:28let's give it a name buckets. So that's
  19380. 11:40:31it. Let's go and hit execute. Now, as
  19381. 11:40:33you can see, it's very simple. We got
  19382. 11:40:35our two groups. So this is the first
  19383. 11:40:37batch of of the data and this is the
  19384. 11:40:40second batch of data. So now we can go
  19385. 11:40:42and select the first batch and export
  19386. 11:40:44it, import it in the next system. And
  19387. 11:40:46then after that we go with the second
  19388. 11:40:48batch. And of course if you still suffer
  19389. 11:40:49from the size of those packets, you can
  19390. 11:40:51go and split it to more smaller size. So
  19391. 11:40:54you can go over here and make it four.
  19392. 11:40:56So with that we're going to get smaller
  19393. 11:40:58buckets and it might be easier to export
  19394. 11:41:01the data. So this is really great use
  19395. 11:41:02case for the entile function. All right
  19396. 11:41:04everyone. So with this you have learned
  19397. 11:41:06the two use cases for the entile
  19398. 11:41:07function that I usually follow in my
  19399. 11:41:09projects. So as a data analyst you can
  19400. 11:41:11use it in order to do segmentations and
  19401. 11:41:13as a data engineer you can use it in
  19402. 11:41:15order to do load balancing of the
  19403. 11:41:20ETL. Okay everyone so with that we have
  19404. 11:41:23covered everything about the integer
  19405. 11:41:24based ranking functions. Now we're going
  19406. 11:41:26to talk about the second methods. We
  19407. 11:41:28have the percentagebased ranking
  19408. 11:41:30functions and here we have two functions
  19409. 11:41:32the cubist and as well the percentile.
  19410. 11:41:35So now let's have a quick recap. So with
  19411. 11:41:37the percentage based ranking SQL going
  19412. 11:41:39to go and calculate a relative position
  19413. 11:41:42as a percentage and assign it for each
  19414. 11:41:44row. So the output going to be a
  19415. 11:41:46continuous normalized scale from 0 to
  19416. 11:41:50one. And this is really amazing in order
  19417. 11:41:52to do distribution analyszis. So those
  19418. 11:41:54functions going to consider in their
  19419. 11:41:56calculation the overall total the whole
  19420. 11:41:59size of the data set which can help us
  19421. 11:42:01in order to find out the contribution of
  19422. 11:42:03each value to the overall total. And now
  19423. 11:42:06in SQL in order to generate the
  19424. 11:42:08percentage we have two different
  19425. 11:42:10formulas. So in one hand we have the
  19426. 11:42:12function cumist and in the other hand we
  19427. 11:42:15have the percent rank. So that means we
  19428. 11:42:17have two different functions with
  19429. 11:42:18different formulas in order to generate
  19430. 11:42:20and calculate the percentage. So now
  19431. 11:42:23let's start with the first function the
  19432. 11:42:28cumist. All right everyone. So now let's
  19433. 11:42:30start with the first function. We have
  19434. 11:42:32the dis and it stands for
  19435. 11:42:34commumulative distribution. It's going
  19436. 11:42:36to go and focus or calculate the
  19437. 11:42:38distribution of your data points within
  19438. 11:42:40a window. So what this means in order to
  19439. 11:42:42understand it, we're going to go and
  19440. 11:42:44have very simple example to understand
  19441. 11:42:46how SQL works with this function. So
  19442. 11:42:48let's go. All right. Again we have our
  19443. 11:42:49very simple example of the sales and we
  19444. 11:42:52have the following query. So dist
  19445. 11:42:55then we don't give any argument inside
  19446. 11:42:56it. So it's going to be empty and the
  19447. 11:42:58window going to be like usual order by
  19448. 11:43:00sales descending from the highest to the
  19449. 11:43:02lowest and the order by is must. So the
  19450. 11:43:05first step is SQL going to go and sort
  19451. 11:43:06the data. We have it already sorted from
  19452. 11:43:08the highest to the lowest. So now the
  19453. 11:43:10next step is that SQL going to go and
  19454. 11:43:11start calculating the percentage for
  19455. 11:43:13each row. And we have a very simple
  19456. 11:43:16formula. It says the cumist equals to
  19457. 11:43:18the position number of the value divided
  19458. 11:43:21by the number of rows. So now the next
  19459. 11:43:24step is still going to go and start
  19460. 11:43:25calculate the percentage for each row.
  19461. 11:43:27And we have this very simple formula. It
  19462. 11:43:30says the cubist equals to the position
  19463. 11:43:32number of the value divided by the
  19464. 11:43:35number of rows. It's very simple. Let's
  19465. 11:43:37do it step by step. So SQL going to
  19466. 11:43:39start with the first value in our list.
  19467. 11:43:41So it going to be calculated like this.
  19468. 11:43:43So what is the position number of the
  19469. 11:43:45first value? It's going to be one,
  19470. 11:43:47right? So this is the first value in our
  19471. 11:43:50list. And what is the total number of
  19472. 11:43:52rows? We have five rows, right? So 1 2 3
  19473. 11:43:544 5. So we're going to divide one by
  19474. 11:43:57five. And the result going to be 0.2. So
  19475. 11:44:01this going to be the first value for the
  19476. 11:44:02first row. Okay. So now SQL going to go
  19477. 11:44:04to the next row. And this time we're
  19478. 11:44:06going to get a special case. As you can
  19479. 11:44:08see, we have the 80 twice. So we have
  19480. 11:44:10here a tie. So now first we need the
  19481. 11:44:12position number. As you can see, we are
  19482. 11:44:14at the position number two, right? But
  19483. 11:44:17since we have the 80 multiple times, SQL
  19484. 11:44:20going to go and take the last position
  19485. 11:44:22that we see the value 80 and the last
  19486. 11:44:24position going to be the record number
  19487. 11:44:27three. So that's why SQL going to say
  19488. 11:44:29for this record it's going to be the
  19489. 11:44:31position number three and not two and
  19490. 11:44:34then it's going to go and divide it by
  19491. 11:44:35five and we will get the value of 0.6.
  19492. 11:44:39So this is the most confusing thing with
  19493. 11:44:40this function. So if SQL finds a tie, it
  19494. 11:44:43will completely ignore the current
  19495. 11:44:45position number. So we don't have two.
  19496. 11:44:47It going to go and take the last
  19497. 11:44:49position number for the same value. And
  19498. 11:44:52the last in our list going to be the
  19499. 11:44:54record number three. So that's why we
  19500. 11:44:56have three over here. Okay. So now let's
  19501. 11:44:58keep moving. Let's go to the third row.
  19502. 11:45:00And as you can see, we are again in the
  19503. 11:45:02tie. But this time, this is the last
  19504. 11:45:04time we see 80. So next we don't have
  19505. 11:45:0680. So what's going to happen? We're
  19506. 11:45:08going to have exact same result. So it's
  19507. 11:45:10going to be 3 divided by 5. So as you
  19508. 11:45:13can see if we have a tie they going to
  19509. 11:45:15share the same percentage. So that means
  19510. 11:45:17with the cube list if you have same
  19511. 11:45:19values they going to share the same
  19512. 11:45:21rank. So let's keep moving to the fourth
  19513. 11:45:24one. So now what is the position number
  19514. 11:45:26of the 50 we are at the record four. So
  19515. 11:45:29position number four divided by five we
  19516. 11:45:32will get 0 comma 8. Okay. So now let's
  19517. 11:45:35move to the last one and it is the
  19518. 11:45:37easiest one. So which position do we
  19519. 11:45:39have over here? It is the position
  19520. 11:45:41number five. It's the last one. And the
  19521. 11:45:43number of rows is five. That's why we
  19522. 11:45:45will get one. So guys, that's it. This
  19523. 11:45:47is how the cumulative distribution
  19524. 11:45:48works. Once you understand the formula,
  19525. 11:45:51it's going to be very easy in order to
  19526. 11:45:52understand the output. So as you can
  19527. 11:45:54see, calculating the percentage always
  19528. 11:45:56depends on the total size of our data
  19529. 11:45:58sets. You can see here the number of
  19530. 11:46:00rows. So with this we're going to get an
  19531. 11:46:02output that help us in order to
  19532. 11:46:03understand the distribution of our data
  19533. 11:46:05points within the data
  19534. 11:46:10sets. All right everyone. So now we're
  19535. 11:46:12going to go and focus on the second
  19536. 11:46:13function that generate percentage as a
  19537. 11:46:16rank. We have the percent rank. So the
  19538. 11:46:18percent rank going to go and focus on
  19539. 11:46:20generating the relative position of each
  19540. 11:46:23row within a window. So in order to
  19541. 11:46:26understand what this means, we can have
  19542. 11:46:27a very simple example in order to
  19543. 11:46:29understand how scale works with this
  19544. 11:46:31function. So let's go. Okay, again we
  19545. 11:46:33have those sales very simple example and
  19546. 11:46:35the syntax going to be like this percent
  19547. 11:46:37rank and inside it we don't use any
  19548. 11:46:39arguments and the window going to be
  19549. 11:46:41like this order by it is a must sales
  19550. 11:46:44descending from the highest to the
  19551. 11:46:46lowest the first step that is going to
  19552. 11:46:48do is that it's going to go and sort the
  19553. 11:46:49data from the highest to the lowest and
  19554. 11:46:51we have it already like this and next
  19555. 11:46:53SQL going to go and start calculate the
  19556. 11:46:54percentage which is very similar to the
  19557. 11:46:57cumulative distribution but this time
  19558. 11:46:59it's going to be like this position
  19559. 11:47:01number then we subtract it from one and
  19560. 11:47:04as well divided by the number of rows
  19561. 11:47:07subtracted from one. So it's like exact
  19562. 11:47:10formula but we are only subtracting here
  19563. 11:47:12once for both numbers. Okay. So now
  19564. 11:47:14let's go through all rows step by step
  19565. 11:47:16and see the output. So it's still going
  19566. 11:47:18to start with the first row right. So
  19567. 11:47:20what is the position number of the first
  19568. 11:47:22row? It's going to be one. Then we have
  19569. 11:47:24to subtract it by one. That's why we
  19570. 11:47:26will get zero. Now what is the total
  19571. 11:47:28number of rows? So we have here five
  19572. 11:47:30rows and it is subtracted by one that's
  19573. 11:47:32why we're going to get four. So now 0
  19574. 11:47:35divided by any value the output going to
  19575. 11:47:37be a zero. So that's why for the first
  19576. 11:47:39value we will get a zero. All right. So
  19577. 11:47:41now let's move to the second row over
  19578. 11:47:43here. And here we have our special case
  19579. 11:47:45where we have a tie. So we have two
  19580. 11:47:47sales sharing the same value 80. So now
  19581. 11:47:50for the percent rank SQL gonna have
  19582. 11:47:51different behavior than the cumist.
  19583. 11:47:54Remember in the list SQL did search
  19584. 11:47:56for the last position of the shared
  19585. 11:47:58value. So it was the position number
  19586. 11:48:00three since this is the last time we see
  19587. 11:48:0380. But now with the person rank is
  19588. 11:48:05still going to stick with the first
  19589. 11:48:06occurrence of the shared value. So now
  19590. 11:48:08by checking those two 80s what is the
  19591. 11:48:10first occurrence? It is the record
  19592. 11:48:12number two. So that's why we have
  19593. 11:48:14position number two subtracted by one we
  19594. 11:48:16will get one. And here the same going to
  19595. 11:48:18be number of totals we have five
  19596. 11:48:21subtract by one we have four. So now if
  19597. 11:48:22you divide one by four we will get the
  19598. 11:48:24result of 0 comma 25. So this is the
  19599. 11:48:28percentage of this value. So now let's
  19600. 11:48:30go to the second row. Here we have again
  19601. 11:48:31the tie. So scale going to stick with
  19602. 11:48:34the position number two the first
  19603. 11:48:35occurrence. So it's going to be the same
  19604. 11:48:38two subtracted by one we will get one.
  19605. 11:48:40And as well the total number of rows
  19606. 11:48:42five subtract by one we will have four.
  19607. 11:48:44That's why we will get the same exact
  19608. 11:48:46results. So here as you can see with the
  19609. 11:48:48percent rank it's like the list the
  19610. 11:48:50shared value going to share as well the
  19611. 11:48:52same percentage rank. Now let's move to
  19612. 11:48:54the fourth one. So we have the value 50.
  19613. 11:48:57So what is the position of this? It's
  19614. 11:48:58going to be the record number four.
  19615. 11:49:00Subtract it by one we will get three.
  19616. 11:49:03And if you divide three by four you will
  19617. 11:49:05get
  19618. 11:49:060.75. And now moving to the last value
  19619. 11:49:09over here it's going to be easy. So what
  19620. 11:49:11is the position number of the 30? It is
  19621. 11:49:13five. Five subtracted by one it's going
  19622. 11:49:15to be four. And as well we're going to
  19623. 11:49:17have four as well here for the total
  19624. 11:49:19numbers subtracted by one. So if you
  19625. 11:49:21divide four by four you will get one. So
  19626. 11:49:23that's it guys. This is how the percent
  19627. 11:49:25rank works. It always has the scale from
  19628. 11:49:280 to one. So it's always like this.
  19629. 11:49:30Doesn't matter which values do we have
  19630. 11:49:32inside and it's going to has like
  19631. 11:49:34continuous scale. And again here if you
  19632. 11:49:36have a tie they're going to go and share
  19633. 11:49:37the same percentage rank. Okay guys. So
  19634. 11:49:39now if you go and compare those two
  19635. 11:49:41functions you're going to see that they
  19636. 11:49:42are really similar to each others. The
  19637. 11:49:43output of both functions we are
  19638. 11:49:45generating percentage based ranking and
  19639. 11:49:48both of them as well handling the ties
  19640. 11:49:50perfectly. So they share the same
  19641. 11:49:52percentage rank. If you check the syntax
  19642. 11:49:54they are very similar. And now by
  19643. 11:49:55checking the formulas of both of them we
  19644. 11:49:57are always considering the overall size
  19645. 11:50:00of the data sets. So here the size is
  19646. 11:50:03considered in the calculation to help us
  19647. 11:50:05finding the relative position of each
  19648. 11:50:08value to the overall and this is very
  19649. 11:50:10important in the analyszis in order to
  19650. 11:50:12measure the contribution of each value
  19651. 11:50:14to the overall. So now about the use
  19652. 11:50:16cases if you want to focus on the
  19653. 11:50:18distribution of your data points go with
  19654. 11:50:20the cumulative distribution but if you
  19655. 11:50:22want to focus on the relative position
  19656. 11:50:24of each rows then go with the percent
  19657. 11:50:26rank. All right. So now there is one
  19658. 11:50:28more difference between the and the
  19659. 11:50:30percent rank and that's if you check the
  19660. 11:50:32formulas. You can see that the is
  19661. 11:50:35more inclusive. We always consider the
  19662. 11:50:38position number of the current row. But
  19663. 11:50:40with the person rank we don't consider
  19664. 11:50:42the current row. We like skip it or make
  19665. 11:50:45it exclusive. So we say for the person
  19666. 11:50:47rank it is more exclusive and the
  19667. 11:50:50cumulative distribution it is more
  19668. 11:50:52inclusive. So now if you ask me the hard
  19669. 11:50:53question which one to use, I'm going to
  19670. 11:50:55say if you want to be more inclusive, go
  19671. 11:50:58with the commutive distribution. If you
  19672. 11:51:00want to be more exclusive with the
  19673. 11:51:01current row, go with the person rank. So
  19674. 11:51:04they are very similar to each others. So
  19675. 11:51:06if you want to calculate the
  19676. 11:51:07distribution of your data, go with the
  19677. 11:51:08cumulative distribution. If you want to
  19678. 11:51:10find the relative position of each row,
  19679. 11:51:13then go with the percent rank. All
  19680. 11:51:15right. So now we have the following task
  19681. 11:51:16that says find the products that fall
  19682. 11:51:19within the highest 40% of the prices.
  19683. 11:51:22Let's go and solve this. Now we are
  19684. 11:51:23targeting the table products and I will
  19685. 11:51:26just select like two columns products
  19686. 11:51:28price from sales products. So that's it.
  19687. 11:51:33Let's go and execute this. So now as you
  19688. 11:51:36can see we got five products and their
  19689. 11:51:37prices. And the task says find the
  19690. 11:51:40highest 40%. So we have to find and
  19691. 11:51:42generate a percentage rank. In order to
  19692. 11:51:45do that we have the two functions cumist
  19693. 11:51:47and the percent rank. I will go this
  19694. 11:51:49time with the list. So let's go and
  19695. 11:51:52do that. So list and then let's go
  19696. 11:51:55and define the window like this. It's
  19697. 11:51:58going to be order by we are targeting
  19698. 11:52:00now the prices right? So order by the
  19699. 11:52:03price from the highest to the lowest and
  19700. 11:52:05let's go give it a name this rank. So
  19701. 11:52:08let's go and execute this. So now with
  19702. 11:52:10that SQL going to go and generate for us
  19703. 11:52:12a percentage ranking using the formula
  19704. 11:52:14that we just learned before. So now in
  19705. 11:52:16the output we are getting all the
  19706. 11:52:17products but the task says we have to
  19707. 11:52:19get only the products that are in the
  19708. 11:52:21highest 40%. So that means the first row
  19709. 11:52:24the second row and that's it. So those
  19710. 11:52:27rows are in the highest 40% the rest are
  19711. 11:52:31below that. So in order to do that to
  19712. 11:52:32filter the data we're going to use the
  19713. 11:52:34subquery. So select star from and then
  19714. 11:52:38we have our sub query like this and then
  19715. 11:52:41our filter going to be this rank smaller
  19716. 11:52:45or equal to 0.4. So this is our
  19717. 11:52:49threshold in order to get the data. So
  19718. 11:52:51let's go and execute this. And now as
  19719. 11:52:53you can see we got the top products the
  19720. 11:52:55top 40%. Now of course you can go and
  19721. 11:52:58format the percentage. We can do that
  19722. 11:53:00like this. So let's take the test
  19723. 11:53:05rank multiply it with 100. So let's go
  19724. 11:53:08and execute this. So as you can see we
  19725. 11:53:09got 20 and 40%. We can go and add to it
  19726. 11:53:13as well the percentage character right.
  19727. 11:53:15So we can go and say concat and we're
  19728. 11:53:18going to add the character after that
  19729. 11:53:21like this and let's call it test rank
  19730. 11:53:25percentage. So that's it. Let's go and
  19731. 11:53:27execute it. So that we have solved the
  19732. 11:53:29task. We have the products that fall
  19733. 11:53:31within the highest 40%. Now, of course,
  19734. 11:53:33you can go and try the percent rank. So,
  19735. 11:53:36it's very simple. We just have to go and
  19736. 11:53:38switch the cumulative distribution with
  19737. 11:53:40the function percent bank. So, let's go
  19738. 11:53:44and execute it. Now, as you can see, we
  19739. 11:53:46will get the exact same results. So,
  19740. 11:53:48we're still getting the gloves and caps
  19741. 11:53:50as the highest products within the 40%
  19742. 11:53:53of the price. So, guys, that's it. It's
  19743. 11:53:54very simple, right?
  19744. 11:53:59All right friends, so now let's have a
  19745. 11:54:01quick recap for the window ranking
  19746. 11:54:02functions. So what they're going to do,
  19747. 11:54:04they're going to go and assign a rank
  19748. 11:54:05for each row within a window. And we
  19749. 11:54:08have two types of ranking, right? The
  19750. 11:54:10first one is the integer based ranking.
  19751. 11:54:12It's going to go and assign a number an
  19752. 11:54:14integer for each row. And here we have
  19753. 11:54:16four functions. Row number, rank, dense
  19754. 11:54:19rank, and in tile. And the second type
  19755. 11:54:21of ranking, we have the percentage based
  19756. 11:54:23ranking. So scale fair is going to go
  19757. 11:54:25and calculate a rank and then assign it
  19758. 11:54:27for each row. And here we have two types
  19759. 11:54:29of formula or functions. So we have the
  19760. 11:54:31cube dist the cumulative distribution
  19761. 11:54:34and the second one we have the percent
  19762. 11:54:35rank. And now to the next point if we
  19763. 11:54:37are talking about the rules of the
  19764. 11:54:38syntax. So the expression should be
  19765. 11:54:41empty. We should not pass any argument
  19766. 11:54:42to the functions. We must use order by
  19767. 11:54:45in order to sort our data. So it is
  19768. 11:54:47required and the frame clause are not
  19769. 11:54:50allowed to use. So you cannot go and
  19770. 11:54:51customize a frame within the window
  19771. 11:54:54function. And as we learned there are
  19772. 11:54:56many use cases for the ranking
  19773. 11:54:57functions. For example, we have the top
  19774. 11:54:59end analyzes the button end analyzes in
  19775. 11:55:02order to identify our top performers or
  19776. 11:55:04the worst performers in our business.
  19777. 11:55:07Another use case using the row number we
  19778. 11:55:09can identify and remove duplicates in
  19779. 11:55:11our data. So we can use it in order to
  19780. 11:55:14find data quality issues and as well to
  19781. 11:55:16improve the quality. And another use
  19782. 11:55:18case if our table don't have a clean
  19783. 11:55:20primary key we can go and generate
  19784. 11:55:22unique ids using the row number in order
  19785. 11:55:24to do as well by generating one more use
  19786. 11:55:26case it was the data segmentations you
  19787. 11:55:29can use the intel in order to segment
  19788. 11:55:31your customers your products employees
  19789. 11:55:33and so on and another use case we can do
  19790. 11:55:35data distribution analysis as we learned
  19791. 11:55:37we can use the cubeist in order to
  19792. 11:55:39understand the data distributions of our
  19793. 11:55:42data points compared to the overall and
  19794. 11:55:44the last use case it's more for data
  19795. 11:55:46engineering we can use the intel
  19796. 11:55:47function in order to equalize the
  19797. 11:55:49loading process of our ETLs. So as you
  19798. 11:55:51can see there are many use cases for the
  19799. 11:55:53ranking functions. Okay, so that's all
  19800. 11:55:55about how to rank your data using the
  19801. 11:55:57window functions and now we're going to
  19802. 11:55:59cover the last group. We will learn
  19803. 11:56:00about the value window functions. How to
  19804. 11:56:03access another records. So let's
  19805. 11:56:08go. All right everyone. So now we have
  19806. 11:56:10this very simple example. We have the
  19807. 11:56:12months and the sales. Now we can use the
  19808. 11:56:15value functions in order to access a
  19809. 11:56:17value from another row. So in order to
  19810. 11:56:20understand it let's say that SQL now
  19811. 11:56:22processing the months and we are
  19812. 11:56:24currently at the month of March. So now
  19813. 11:56:26for example I would like to access the
  19814. 11:56:28value from the previous month from
  19815. 11:56:30February. So in order to do that we can
  19816. 11:56:32use the lag function in order to get the
  19817. 11:56:35value of 10. So with that we have in the
  19818. 11:56:37same row the current sales of the month
  19819. 11:56:40March and as well the sales from the
  19820. 11:56:42previous month the February. And maybe
  19821. 11:56:45in other cases I would like to get the
  19822. 11:56:47sales of the next month from April. In
  19823. 11:56:50order to do that we can use the function
  19824. 11:56:52lead and we will get at the same row the
  19825. 11:56:55value five. So now I can very quickly
  19826. 11:56:57compare the current month with the
  19827. 11:56:59previous month and as well with the next
  19828. 11:57:02month. And now in the other cases you
  19829. 11:57:03might be interested in the first month
  19830. 11:57:06of your list. So it's going to be here
  19831. 11:57:07January. So in order to get the sales of
  19832. 11:57:10the first month you can use the function
  19833. 11:57:13first value. So we're going to get at
  19834. 11:57:15the same row 20. And now for the last
  19835. 11:57:17option I think you already get it. We
  19836. 11:57:19can go and get the value of sales of the
  19837. 11:57:22last month. So here we can get the July.
  19838. 11:57:24So for that we're going to use the
  19839. 11:57:25function last value and we will get the
  19840. 11:57:28value of 40. So this is exactly the
  19841. 11:57:30purpose of the value functions or
  19842. 11:57:32analytical functions. We can access a
  19843. 11:57:35value from another rows. And here is
  19844. 11:57:37really important to understand as well
  19845. 11:57:38the value functions is like the ranking
  19846. 11:57:40functions. We have to use the order by
  19847. 11:57:43in order to sort the data in order to
  19848. 11:57:45understand what is the first row and the
  19849. 11:57:47last row. In this example, the data is
  19850. 11:57:49sorted by the month. So guys, the access
  19851. 11:57:51functions are really important for
  19852. 11:57:52analytics. You can use it in order to
  19853. 11:57:54access a value from other rows in order
  19854. 11:57:57to do comparison. All right. Right. So
  19855. 11:57:58now let's have a quick overview of the
  19856. 11:58:00syntax and the rules for the value
  19857. 11:58:02functions. So here we have four
  19858. 11:58:04functions lead, lag, first value and
  19859. 11:58:06last value. So as you can see we can
  19860. 11:58:08group them into two groups. So we have
  19861. 11:58:10the lead and lag. They are very similar
  19862. 11:58:12to each others. Especially with the
  19863. 11:58:13syntax we can use three things or three
  19864. 11:58:16arguments inside it. Expression offset
  19865. 11:58:18default for both of them. For the first
  19866. 11:58:21value we can use only an expression. So
  19867. 11:58:23that means we have to pass a value for
  19868. 11:58:26those functions. You cannot leave it
  19869. 11:58:27empty. So now about the expression data
  19870. 11:58:29type, you can use any field with any
  19871. 11:58:31data type. There is no restrictions
  19872. 11:58:32about only for example using numbers.
  19873. 11:58:35Any data type is allowed. Now about the
  19874. 11:58:37definition of the window. The partition
  19875. 11:58:39by as usual is optional like any other
  19876. 11:58:41group. The order by here is a must. You
  19877. 11:58:44must define an order by. It's like the
  19878. 11:58:46ranking. So here you cannot leave it
  19879. 11:58:48empty. And now we come to the last one.
  19880. 11:58:50We have the frame clause. There are
  19881. 11:58:52really different stuff over here. So for
  19882. 11:58:54the first two functions lead and lag you
  19883. 11:58:56are not allowed to define any frame. So
  19884. 11:58:58you are not allowed to define any subset
  19885. 11:59:00of data. It's very similar to the
  19886. 11:59:02ranking. So you must use order by but
  19887. 11:59:05you cannot define the frame of the
  19888. 11:59:07window. But for the other two functions
  19889. 11:59:09the first value and the last value they
  19890. 11:59:11are optional. You can go and use them.
  19891. 11:59:13And for the last value it is recommended
  19892. 11:59:16to define frame close. Don't worry about
  19893. 11:59:18it. We're going to have enough examples
  19894. 11:59:19in order to understand. So as you can
  19895. 11:59:21see those functions has different
  19896. 11:59:22requirements. So there is no generic
  19897. 11:59:24rule for all of them. But one thing that
  19898. 11:59:26they all agree on that you must use
  19899. 11:59:29order by. So now as usual what we're
  19900. 11:59:31going to do we're going to go and deep
  19901. 11:59:32dive into those functions. We're going
  19902. 11:59:34to address first the two functions lead
  19903. 11:59:36and lag because they are very similar to
  19904. 11:59:38each others. We're going to understand
  19905. 11:59:40the use cases when to use them and of
  19906. 11:59:42course we're going to practice in SQL.
  19907. 11:59:44So let's go.
  19908. 11:59:48lead and lag functions. The lead
  19909. 11:59:50function can allow you to access a value
  19910. 11:59:52from the next row within a window where
  19911. 11:59:56the lack function is exactly the
  19912. 11:59:57opposite. It's going to allow you to
  19913. 11:59:59access a value from a previous row
  19914. 12:00:02within a window. It sounds very easy,
  19915. 12:00:04right? So let's understand how is SQL
  19916. 12:00:05going to execute those functions. Okay.
  19917. 12:00:07So now let's have a quick overview of
  19918. 12:00:08the syntax for both of the functions
  19919. 12:00:10lead and lag. We have here very simple
  19920. 12:00:12example for the lead function. So as
  19921. 12:00:15usual we start with the function name.
  19922. 12:00:16It's going to be the lead. And now after
  19923. 12:00:18that we're going to go and pass the
  19924. 12:00:20arguments. And as you can see we have
  19925. 12:00:21here multiple stuff. So let's do it step
  19926. 12:00:24by step. So the first thing is that
  19927. 12:00:25we're going to go and specify an
  19928. 12:00:26expression. And the data type could be
  19929. 12:00:28any data type. It could be a number like
  19930. 12:00:31here the sales. It could be a character
  19931. 12:00:32like names or dates or anything. So this
  19932. 12:00:36is required. We have to specify an
  19933. 12:00:39expression. We cannot leave it empty.
  19934. 12:00:41And we can use any data type. Now moving
  19935. 12:00:43on to the next one. We have here a
  19936. 12:00:44number. So what is this? This is the
  19937. 12:00:47offset and this offset is optional. So
  19938. 12:00:49you can go and skip it. So what offsets
  19939. 12:00:51means? What we are doing over here? We
  19940. 12:00:53are specifying for SQL the number of
  19941. 12:00:56rows forward or backward from the
  19942. 12:00:59current row. So here in this example we
  19943. 12:01:00are specifying the offset as two using
  19944. 12:01:02the lead. And with that we are telling
  19945. 12:01:04SQL go jump to the next two rows and get
  19946. 12:01:06me the value. And if you are using lag
  19947. 12:01:08it means you are telling SQL go back two
  19948. 12:01:11rows up and get me the value. So here
  19949. 12:01:13you are telling SQL how many rows it
  19950. 12:01:15needs to jump and if you don't specify
  19951. 12:01:17anything like leave it empty SQL going
  19952. 12:01:19to go and use a one. So the default of
  19953. 12:01:22this with the offsets going to be one if
  19954. 12:01:23you don't specify anything. All right
  19955. 12:01:25moving on to the last one and to the
  19956. 12:01:26third one. This is as well optional. You
  19957. 12:01:28can go and leave it empty. So here it is
  19958. 12:01:31the default value. Now what happens with
  19959. 12:01:33those functions is that sometimes SQL
  19960. 12:01:35jump to the next two rows or something
  19961. 12:01:37like that and SQL doesn't find anything.
  19962. 12:01:39So there is no more rows available to
  19963. 12:01:41access and with that SQL going to go and
  19964. 12:01:44return a null. So that means if SQL goes
  19965. 12:01:46to the next rows or go to the previous
  19966. 12:01:48rows and doesn't find anything SQL as a
  19967. 12:01:51default going to go and return a null.
  19968. 12:01:53So if you don't specify anything over
  19969. 12:01:55here in those scenarios you will have a
  19970. 12:01:57null values as a return from the whole
  19971. 12:02:00function. But in some scenarios you
  19972. 12:02:01don't want to have a null you would like
  19973. 12:02:03to have a value. So here you are
  19974. 12:02:05defining the default value. So it should
  19975. 12:02:08not be a null, it should be a 10. So
  19976. 12:02:10scale if you don't find anything return
  19977. 12:02:12a 10. Don't return a null. So again
  19978. 12:02:15guys, the default values, the offsets,
  19979. 12:02:17all those informations are optional for
  19980. 12:02:18you in order to configure it. But you
  19981. 12:02:20should know the default if you don't use
  19982. 12:02:22anything for the offset is going to be
  19983. 12:02:24one for the default value going to be
  19984. 12:02:26null. But you must specify an
  19985. 12:02:28expression. So here you cannot leave it
  19986. 12:02:30empty. All right. So that's all about
  19987. 12:02:32the arguments that you can pass to the
  19988. 12:02:34lead or lag functions. Then the next
  19989. 12:02:36stuff are the standard stuff. So we have
  19990. 12:02:38the overclos then we have the partition
  19991. 12:02:40by as usual partition by is optional.
  19992. 12:02:43And then to the order by those functions
  19993. 12:02:45it's like the rank functions. It
  19994. 12:02:47requires you to sort the data. So it is
  19995. 12:02:50a must to sort the data otherwise will
  19996. 12:02:52not know what is the next row what are
  19997. 12:02:54the previous rows. So we have to sort
  19998. 12:02:56the data. It is required. You cannot
  19999. 12:02:58skip this. So it is not optional. All
  20000. 12:03:00right. So the syntax is not crazy right?
  20001. 12:03:02We have the usual stuff but only we can
  20002. 12:03:04go and configure the default value and
  20003. 12:03:06the offsets. Okay guys, now we have very
  20004. 12:03:07simple example. We have months and sales
  20005. 12:03:10and we're going to go and understand how
  20006. 12:03:11the SQL works for both of the functions
  20007. 12:03:14lead and lag side by side. So now in the
  20008. 12:03:16first example we are interested in the
  20009. 12:03:18sales of the next month. So in order to
  20010. 12:03:21do that we're going to use the lead
  20011. 12:03:22function. So lead and then we're going
  20012. 12:03:25to specify the argument. It is the
  20013. 12:03:26sales. We want the value of sales and
  20014. 12:03:28then we define the window like this
  20015. 12:03:31order by month. So it's going to be
  20016. 12:03:33ascending. And now in the right side
  20017. 12:03:34we're going to be interested in the
  20018. 12:03:36sales of the previous months. So in
  20019. 12:03:38order to do that we're going to use the
  20020. 12:03:40lag function. So it's going to be very
  20021. 12:03:42similar to the lead. We have lag and
  20022. 12:03:44then the sales since we are interested
  20023. 12:03:45in the sales and we're going to sort the
  20024. 12:03:47data by the month. So now let's see how
  20025. 12:03:49going to do it step by step and side by
  20026. 12:03:51side. So going to start with the first.
  20027. 12:03:53So now let's see how skill going to
  20028. 12:03:55process those informations side by side
  20029. 12:03:57and row by row. So it's going to start
  20030. 12:03:59with the first row over here. What is
  20031. 12:04:02the next month of January? It is
  20032. 12:04:04February and we are interested in the
  20033. 12:04:07sales of this row. So SQL going to take
  20034. 12:04:10the value from the next row and we're
  20035. 12:04:12going to have the value of 10. So now by
  20036. 12:04:14looking through the January we can see
  20037. 12:04:16the sales of the next month of February
  20038. 12:04:18in the same row. So now let's check the
  20039. 12:04:20right side over here. Now we are
  20040. 12:04:22interested in the previous month. So
  20041. 12:04:24what is the previous month of the first
  20042. 12:04:26row? It will be nothing. Right? So we
  20043. 12:04:28cannot point it with anything. That's
  20044. 12:04:31why going to say this is null. There is
  20045. 12:04:33no previous month for the current row.
  20046. 12:04:36And we're going to have it as a null.
  20047. 12:04:37Okay. So now it's going to go to the
  20048. 12:04:39next row. We are at February. What is
  20049. 12:04:41the next month? It's going to be March.
  20050. 12:04:43And it's going to point to it. So we
  20051. 12:04:45will get the 30 as the sales of the next
  20052. 12:04:48month of March. And on the right side,
  20053. 12:04:51what is the previous month of February?
  20054. 12:04:54It's going to be January, right? So,
  20055. 12:04:56it's going to get the value the sales of
  20056. 12:04:58the previous month. And here we will get
  20057. 12:05:0120. So, as you can see, it's very
  20058. 12:05:02simple. On the lead, we are always
  20059. 12:05:04checking the next values. On the lag, we
  20060. 12:05:06are always checking the previous value.
  20061. 12:05:08So, let's keep going. We are currently
  20062. 12:05:10at March. What is the next month? It's
  20063. 12:05:12going to be April. So, it's going to go
  20064. 12:05:14and point to it like this. and we will
  20065. 12:05:18get the sales of the next month April.
  20066. 12:05:21For the March on the right side, what is
  20067. 12:05:22the previous month? It is February.
  20068. 12:05:25Right? So, it's going to go and point to
  20069. 12:05:27February. So, we will get the sales of
  20070. 12:05:3010. And now, interesting to the last row
  20071. 12:05:32over here. You can see that we are at
  20072. 12:05:34April. What is the next month of April?
  20073. 12:05:37There is nothing because we are at the
  20074. 12:05:39end of our table, right? So, since there
  20075. 12:05:41is no month after that, we will get a
  20076. 12:05:44null in the output. But for the lag, we
  20077. 12:05:47still have a previous month for April.
  20078. 12:05:48So what is the previous month? It is
  20079. 12:05:50March. And we will get the sales of the
  20080. 12:05:54March. So it's going to be 30. So that's
  20081. 12:05:56it guys. It's really simple, right? It's
  20082. 12:05:58just like they are doing the opposite
  20083. 12:05:59things. So now if you check those values
  20084. 12:06:01side by side, you can see that with the
  20085. 12:06:03lead, we will always get a value for the
  20086. 12:06:06first row, but for the last row, it can
  20087. 12:06:08be always empty because there is no next
  20088. 12:06:11value. We are at the end of the table.
  20089. 12:06:13But if you check the lag for the first
  20090. 12:06:15value, we will always get a null because
  20091. 12:06:18there is no previous value or previous
  20092. 12:06:20record from the first row. And for the
  20093. 12:06:22last record, as you can see, we're
  20094. 12:06:24always going to get a value because we
  20095. 12:06:26will have a previous value. Okay, let's
  20096. 12:06:28move on in order to understand how scale
  20097. 12:06:29this time works with the offsets and the
  20098. 12:06:31default value. So now we have the same
  20099. 12:06:33data, but we have different task. So now
  20100. 12:06:35on the left side, we would like to get
  20101. 12:06:36the sales of two months ahead. So it's
  20102. 12:06:39not the next month, it's going to be two
  20103. 12:06:41months. And we would like to tell SQL if
  20104. 12:06:43you don't find any value don't return
  20105. 12:06:45null return for us is zero. So this is
  20106. 12:06:47going to be our default. Now if you
  20107. 12:06:49check the syntax it's going to be exact
  20108. 12:06:51like before but we are adding now an
  20109. 12:06:53offset of two because we are interested
  20110. 12:06:55in two months ahead and we are
  20111. 12:06:58specifying here a default value zero. So
  20112. 12:07:00if you don't find anything put zero
  20113. 12:07:02don't put null. Now on the right side we
  20114. 12:07:04have the exact opposite. We are
  20115. 12:07:06interested in the sales of two months
  20116. 12:07:08ago. So we are not interested in the
  20117. 12:07:10direct previous month we need the sales
  20118. 12:07:12of two months ago. And here the same
  20119. 12:07:14thing if you don't find anything don't
  20120. 12:07:16return null give us a zero. So as you
  20121. 12:07:18can see we have the same syntax but
  20122. 12:07:19using the function lag. So now let's
  20123. 12:07:21understand how going to execute this
  20124. 12:07:23step by step and side by side. So going
  20125. 12:07:25to start with the first month January.
  20126. 12:07:27So now SQL going to ask what is the
  20127. 12:07:28sales of two months ahead. So we are at
  20128. 12:07:32January. It will not be February it's
  20129. 12:07:34going to be the month of March. So it's
  20130. 12:07:36going to go and point it like this and
  20131. 12:07:38we will get the value of 30. So 30 is
  20132. 12:07:41the sales of two months ahead. And now
  20133. 12:07:44on the right side we are as well at
  20134. 12:07:45January. It's going to ask the question
  20135. 12:07:47what is the sales of two months ago. So
  20136. 12:07:50we don't have any previous data. Right?
  20137. 12:07:52So we will not get anything. It's going
  20138. 12:07:54to return null but it's going to check
  20139. 12:07:56do we have a default value? Well yes. So
  20140. 12:07:59this time HQL will not return null. It's
  20141. 12:08:01going to return the default value. And
  20142. 12:08:03this time it's going to be zero. All
  20143. 12:08:04right. All right. So now let's go to the
  20144. 12:08:06next value. We are currently at
  20145. 12:08:07February. What is the sales of two
  20146. 12:08:10months ahead? So it will not be March,
  20147. 12:08:12it's going to be April. So it's going to
  20148. 12:08:14go and point it like this and we will
  20149. 12:08:16get the value of five. So now on the
  20150. 12:08:18right side we are currently at February.
  20151. 12:08:20Now the question is what is the sales of
  20152. 12:08:22two months ago? We have history. We have
  20153. 12:08:24the previous month but we don't have two
  20154. 12:08:26months in the history. That's why we
  20155. 12:08:29will still get zero as the output with
  20156. 12:08:31the default value. Okay. Okay. So now
  20157. 12:08:33let's keep going to the next value. We
  20158. 12:08:34are currently at March. SQL going to ask
  20159. 12:08:37what is the sales of the two months
  20160. 12:08:38ahead. We have only one month after that
  20161. 12:08:41but we don't have two months. That's why
  20162. 12:08:43SQL will not find anything and it's
  20163. 12:08:45going to return null but it's going to
  20164. 12:08:47go and use the default. So here we're
  20165. 12:08:48going to go and get the value of zero.
  20166. 12:08:50There is no more data available in the
  20167. 12:08:52table. But now on the right side we are
  20168. 12:08:54currently at March and we are asking
  20169. 12:08:56what is the sales of two months ago. So
  20170. 12:08:59now we have enough history in the past
  20171. 12:09:01and it's going to get the value of 20.
  20172. 12:09:04All right. So now let's go to the last
  20173. 12:09:05month over here in our table. April.
  20174. 12:09:07What is the sales of two months ahead?
  20175. 12:09:10We don't have any data. So it's going to
  20176. 12:09:12be zero as well. But now on the right
  20177. 12:09:13side, we are currently at April. What is
  20178. 12:09:16sales of two months ago? We have enough
  20179. 12:09:18history. That's why SQL going to get and
  20180. 12:09:20point it like this. So we will get the
  20181. 12:09:23February going to be 10. So that's it.
  20182. 12:09:25This is how SQL works with the lead and
  20183. 12:09:27lag using offsets and as well default
  20184. 12:09:30value. Let's go back in SQL in order to
  20185. 12:09:32practice those two
  20186. 12:09:36functions. Okay, so now we have the
  20187. 12:09:38following task and it says analyze the
  20188. 12:09:40month over month performance by finding
  20189. 12:09:42the percentage change in sales between
  20190. 12:09:45the current and the previous month. So
  20191. 12:09:46that means we have to go and compare the
  20192. 12:09:48current month with the previous month.
  20193. 12:09:50So the main use case for the lead unlock
  20194. 12:09:52is to do comparison analyszis and we
  20195. 12:09:55have a very common use case it's called
  20196. 12:09:57time series analyzes. So it is the
  20197. 12:10:00method of analyzing our business our
  20198. 12:10:02data in order to understand the patterns
  20199. 12:10:05and trends over the time. And one of the
  20200. 12:10:08most important and classical question
  20201. 12:10:10that you're going to get from the
  20202. 12:10:11decision makers or business is to do
  20203. 12:10:14year-over-year analyszis or month over
  20204. 12:10:16month analyszis. So the year-over-year
  20205. 12:10:18analysis is going to help us in order to
  20206. 12:10:20understand the overall growth or decline
  20207. 12:10:23in the performance of our business over
  20208. 12:10:26the years over the time. But in the
  20209. 12:10:27other hand, we have month- over-month
  20210. 12:10:29analyszis in order to do shortterm
  20211. 12:10:32trends analyzes and as well discover the
  20212. 12:10:34patterns in the seasonality. So the main
  20213. 12:10:36focus is to understand the performance
  20214. 12:10:38of our business over the time. So now
  20215. 12:10:40let's go back to it in order to solve
  20216. 12:10:42the task. Okay guys, so now let's go and
  20217. 12:10:44do it step by step. Now what is the
  20218. 12:10:46first step? Before we go and compare
  20219. 12:10:48things together, we have to collect the
  20220. 12:10:49data. We have to do the calculations
  20221. 12:10:51first. So we have to find out first the
  20222. 12:10:53total sales for the current month and
  20223. 12:10:55then the total sales for the previous
  20224. 12:10:57month. And after that we can go and
  20225. 12:10:59compare them. So now let's start with
  20226. 12:11:00the easy stuff. We have to find out the
  20227. 12:11:03current sales for the current month. So
  20228. 12:11:05in order to do that, let's just do very
  20229. 12:11:07simple select. So what do we need? We
  20230. 12:11:09need let's take the order ID. Let's take
  20231. 12:11:11the order date because inside it we have
  20232. 12:11:14the month. Uh let's go and collect the
  20233. 12:11:16sales. So that's it for now from sales
  20234. 12:11:21orders. So let's go and execute this. So
  20235. 12:11:24now in the result we got the usual
  20236. 12:11:25stuff. We have 10 orders, sales and
  20237. 12:11:28order dates. But the order date is on
  20238. 12:11:30the level of the days and we are not
  20239. 12:11:32interested on the whole date. We would
  20240. 12:11:34like to get only the month in order to
  20241. 12:11:36calculate the total sales for the month.
  20242. 12:11:38Now we're going to go and use a function
  20243. 12:11:39in order to extract the month from a
  20244. 12:11:41date. Don't worry about it. We're going
  20245. 12:11:42to have a dedicated chapter in order to
  20246. 12:11:45show you how to deal with the dates
  20247. 12:11:46format in SQL. So now what we're going
  20248. 12:11:48to do, we will use a very simple
  20249. 12:11:51function called month and order dates.
  20250. 12:11:54And let's call it order month. So that's
  20251. 12:11:57it. Let's go and execute it. Now, as you
  20252. 12:11:59can see, we got a new field where we
  20253. 12:12:01have only the month of informations. So
  20254. 12:12:03here we have January, February, and
  20255. 12:12:04March. So now the next step is that we
  20256. 12:12:06want to find the total sales for each
  20257. 12:12:08month. So what we're going to do, we're
  20258. 12:12:10going to go and use group by. So, let's
  20259. 12:12:12do that. We're going to go and say we
  20260. 12:12:15want the sum of sales. I'm just going to
  20261. 12:12:18call it current month sales. And let's
  20262. 12:12:22go and get rid of all those
  20263. 12:12:23informations. We're going to go and
  20264. 12:12:25group by the month, right? So, group by
  20265. 12:12:28and let's have the month. So, that's it.
  20266. 12:12:31Let's go and execute it. So, it's very
  20267. 12:12:33simple, right? We got now the three
  20268. 12:12:35months and the total sales of the
  20269. 12:12:37current month. So now with that we got
  20270. 12:12:39the first information that we need in
  20271. 12:12:40order to do the comparison. We have for
  20272. 12:12:42each row the total sales for the current
  20273. 12:12:45month. So now the next thing that we're
  20274. 12:12:46going to do is to find out the total
  20275. 12:12:49sales for the previous month like side
  20276. 12:12:51by side in the same row. And in order to
  20277. 12:12:53do that we have learned we can go and
  20278. 12:12:55use the lag function. So we're going to
  20279. 12:12:57go and integrate the lag window function
  20280. 12:12:59in the same group by. So we're going to
  20281. 12:13:01do it like this. So lag we are now
  20282. 12:13:04interested in the previous month. So
  20283. 12:13:06that's why we're going to go and get the
  20284. 12:13:08sum of sales as an expression inside it.
  20285. 12:13:11And after that we're going to define the
  20286. 12:13:12window. It's going to be like this over
  20287. 12:13:14and order by is a must. So we're going
  20288. 12:13:16to go and sort the data by the month.
  20289. 12:13:19Right? So let's go and do it. And with
  20290. 12:13:21that we have defined the previous month
  20291. 12:13:24sales. So you are the previous month
  20292. 12:13:27sales. So now let's go and execute it in
  20293. 12:13:29order to see the results. All right. So
  20294. 12:13:31now let's check the results. The first
  20295. 12:13:33row what is the previous month? There is
  20296. 12:13:35no previous month. We are at the first
  20297. 12:13:37record and the first month that's why we
  20298. 12:13:39have null. Now let's go to February.
  20299. 12:13:41What is the sales of the previous month
  20300. 12:13:44from January? It is 105. So this is
  20301. 12:13:47correct. And now to the last value to
  20302. 12:13:49the March. What is the sales of
  20303. 12:13:51February? The previous month it is 195.
  20304. 12:13:54So with that we got the two
  20305. 12:13:56informations. We have the current month
  20306. 12:13:58and as well the previous month. So guys
  20307. 12:14:00as you can see it's magic right? It's
  20308. 12:14:02very simple. we can go and use the lead
  20309. 12:14:04and lag functions in order to access
  20310. 12:14:07another values from another rows without
  20311. 12:14:09doing any complicated joins and so on.
  20312. 12:14:12Okay. So now what is the next step?
  20313. 12:14:13We're going to go and subtract the total
  20314. 12:14:15sales from the current month with the
  20315. 12:14:17previous month. So in order to do that
  20316. 12:14:19we're going to go and use a sub query
  20317. 12:14:21like this. So select star from and we're
  20318. 12:14:26going to have it like this as subquery.
  20319. 12:14:28And now the calculation is very simple.
  20320. 12:14:30Let me just move this a little bit down.
  20321. 12:14:33So it is the current month subtracted
  20322. 12:14:36from the previous month and let's go and
  20323. 12:14:39call it month over month change. So
  20324. 12:14:43that's it. Let's go and execute this. So
  20325. 12:14:45now let's go and check the results for
  20326. 12:14:47the first month. You can see that we
  20327. 12:14:49don't have any value and that is correct
  20328. 12:14:50because the previous month is empty. So
  20329. 12:14:53there is no change. And now moving on to
  20330. 12:14:55the February. You can see over here we
  20331. 12:14:57got plus 90. That means we have here
  20332. 12:15:00improvement in the performance of our
  20333. 12:15:02sales. Now moving on to the last one.
  20334. 12:15:04It's really bad. We have decline in our
  20335. 12:15:06performance. We can see that we have
  20336. 12:15:08minus 115. So that means the current
  20337. 12:15:11month is doing really bad compared to
  20338. 12:15:13the previous month. So the March is
  20339. 12:15:15really bad month. Okay. So now as you
  20340. 12:15:16can see in the output we got the
  20341. 12:15:18absolute numbers but the task says find
  20342. 12:15:20the percentage change. So we have to
  20343. 12:15:22convert this to a percentage and we can
  20344. 12:15:24do it like this. It's very simple. Let's
  20345. 12:15:26do it in a new column. Just going to
  20346. 12:15:28zoom out a little bit. So, it's going to
  20347. 12:15:31be the change the differences divided by
  20348. 12:15:34the previous month sales. And then let's
  20349. 12:15:36go and multiply it with 100 in order to
  20350. 12:15:39get the percentage. So, like this. And
  20351. 12:15:41now, as you can see, we got zeros. And
  20352. 12:15:43that's because those numbers are
  20353. 12:15:45integer. So, we have to go and cast one
  20354. 12:15:47of those values. Just going to do it for
  20355. 12:15:49the first. So, cast and float. So,
  20356. 12:15:53that's it. Let's go and execute it
  20357. 12:15:55again. Now the result looks better. We
  20358. 12:15:57have the percentages but we have a lot
  20359. 12:15:59of decimals. So let's go and round the
  20360. 12:16:02number to let's say one decimal. So only
  20361. 12:16:05one and let's give it a name. So you are
  20362. 12:16:07month over month percentage. So let's
  20363. 12:16:11execute. So now as you can see things
  20364. 12:16:12get better. And with that we have
  20365. 12:16:14calculated the percentage change in
  20366. 12:16:16sales between the current and the
  20367. 12:16:19previous months. And this is how we do
  20368. 12:16:21month overmonth analyszis.
  20369. 12:16:26All right. So now we have another use
  20370. 12:16:28case for the lead and lag function. We
  20371. 12:16:30can use them in order to do customer
  20372. 12:16:31retention analyzes. It's all about
  20373. 12:16:33measuring the customer behavior and
  20374. 12:16:35loyalty. So we are helping the business
  20375. 12:16:37and decision makers to build strong
  20376. 12:16:40relationship with the loyal customers
  20377. 12:16:42and for them as well to focus on their
  20378. 12:16:44needs. So now let's see how we can use
  20379. 12:16:46lead and lag function in order to do
  20380. 12:16:48customer retention analyszis. So let's
  20381. 12:16:50go. All right. Right. So now we have the
  20382. 12:16:51following task and it says in order to
  20383. 12:16:53analyze customer loyalty rank customers
  20384. 12:16:56based on the average days between their
  20385. 12:16:58orders. So there is a lot of things
  20386. 12:17:00going on over here. Let's do it step by
  20387. 12:17:02step. And I would like always to start
  20388. 12:17:03with a very simple select. So let's go
  20389. 12:17:06select informations like the order ID.
  20390. 12:17:09Let's get the customer ID and as well
  20391. 12:17:12since we want the days we would like to
  20392. 12:17:14have the date. So order dates from the
  20393. 12:17:17table sales orders and let's go and sort
  20394. 12:17:21the data. So order by customer ID and
  20395. 12:17:25order dates. So that's it. Let's go and
  20396. 12:17:28execute. So now as usual we got our 10
  20397. 12:17:30orders, the customers and when they did
  20398. 12:17:32order. So now let's check the task.
  20399. 12:17:35Let's solve this over here. Days between
  20400. 12:17:37their orders. So we have to find how
  20401. 12:17:39many days are between two orders. For
  20402. 12:17:42example, if we check the customer number
  20403. 12:17:44one over here, he did order around 10
  20404. 12:17:47January and the second order is like
  20405. 12:17:50after 10 days 20 January. So we have to
  20406. 12:17:53go and subtract those two dates. Now in
  20407. 12:17:56order to subtract those informations and
  20408. 12:17:58do calculations, we have to have
  20409. 12:17:59everything in the same row. So for
  20410. 12:18:01example, if we are at the first row over
  20411. 12:18:03here, I would like to have as well one
  20412. 12:18:05column about the next order. So the date
  20413. 12:18:08of the next order. So we have to access
  20414. 12:18:11a value from another row. Of course, we
  20415. 12:18:13can go and do joins, but we have lead
  20416. 12:18:16and lag functions. And for this
  20417. 12:18:17scenario, we're going to go and use the
  20418. 12:18:19lead window function. So let's go and do
  20419. 12:18:21that. I'm going to go and call the order
  20420. 12:18:23date over here as a current order. And
  20421. 12:18:26let's go and calculate the lead. So we I
  20422. 12:18:30would like to get the next order date.
  20423. 12:18:32So I would like to get this value over
  20424. 12:18:34here in the same row. That's why we this
  20425. 12:18:37time we're going to get the order dates.
  20426. 12:18:39And now let's go and define the window.
  20427. 12:18:42Now we have to go and partition the data
  20428. 12:18:44because we are analyzing each customers
  20429. 12:18:46separately, right? So that's why we have
  20430. 12:18:48to partition that by the customer ID.
  20431. 12:18:51And of course in order to do the lead,
  20432. 12:18:53we have to use the order by. So let's go
  20433. 12:18:55and define that as well. Order by and
  20434. 12:18:58it's going to be by the order date. So
  20435. 12:19:00now we have to give it a name. The order
  20436. 12:19:02date here is the current order. This
  20437. 12:19:04going to be the next order. So next
  20438. 12:19:07order. Let me zoom out a little bit and
  20439. 12:19:10make this smaller. So let's go and
  20440. 12:19:12execute it. So now as you can see in the
  20441. 12:19:14output we got a new column called next
  20442. 12:19:16order. And with that we got the current
  20443. 12:19:19order, the current row and as well the
  20444. 12:19:22value from the next row. So what is the
  20445. 12:19:24next row? It's going to be the 20
  20446. 12:19:25January. The same thing of course for
  20447. 12:19:27the next row. Over here we have the
  20448. 12:19:29current order date and the next order
  20449. 12:19:32date. So this value going to be exactly
  20450. 12:19:34as the next one over here 15 of February
  20451. 12:19:37and then since we are working with
  20452. 12:19:39window since this is the whole window
  20453. 12:19:40over here the last order for this
  20454. 12:19:43customer it's 15 of the February there
  20455. 12:19:46is no next order so this going to be
  20456. 12:19:48null the same thing if you check the
  20457. 12:19:50other customers you're going to see
  20458. 12:19:52always the last order don't have any
  20459. 12:19:54next order so looks like everything is
  20460. 12:19:57fine and for the last customer he has
  20461. 12:19:59only one order so now with this we got
  20462. 12:20:01all the informations for our
  20463. 12:20:03calculations. So we have the current
  20464. 12:20:05order and the next order in the same
  20465. 12:20:07row. Now we can go and subtract them in
  20466. 12:20:10order to get the days between those two
  20467. 12:20:12orders. And now in order to subtract
  20468. 12:20:14date we has to use the function date
  20469. 12:20:16div. Don't worry about those functions.
  20470. 12:20:18We're going to explain all those stuff
  20471. 12:20:19in the next chapters. So now just follow
  20472. 12:20:21me with those steps. What we're going to
  20473. 12:20:23do, we're going to go and subtract this
  20474. 12:20:25date the order date with the whole thing
  20475. 12:20:27over here. Right? So the whole thing
  20476. 12:20:29here is the next order. So let's do it
  20477. 12:20:31in a new line and it's going to be very
  20478. 12:20:34simple. So date diff we are finding the
  20479. 12:20:37differences between two dates. So the
  20480. 12:20:39syntax going to be like this. First we
  20481. 12:20:41have to define what we are talking
  20482. 12:20:42about. Are they days, months, years and
  20483. 12:20:44so on. So we have to tell SQL find me
  20484. 12:20:46the differences in days. Now we have to
  20485. 12:20:49specify two days. So the first one going
  20486. 12:20:51to be the order date. This is the
  20487. 12:20:53current date and the second date going
  20488. 12:20:55to be the whole thing from here. So
  20489. 12:20:58let's take it and put it side by side
  20490. 12:21:00and this calculation going to give us
  20491. 12:21:02number of days. So we're going to call
  20492. 12:21:04this days until next order. All right.
  20493. 12:21:08So now let's go and execute the whole
  20494. 12:21:10thing. So now let's check the result. As
  20495. 12:21:11you can see over here we got 10. So this
  20496. 12:21:13is 10 days between those two dates and
  20497. 12:21:16the next one we have around 26 days.
  20498. 12:21:19Here we have a null because we don't
  20499. 12:21:20have here a date and for the next one we
  20500. 12:21:23have 31 days. So we have a whole month
  20501. 12:21:25over here. So everything is working
  20502. 12:21:27perfectly and with that we have solved
  20503. 12:21:30only this part days between their
  20504. 12:21:32orders. So guys you see right this is
  20505. 12:21:34the magic of the lead and lag function.
  20506. 12:21:36We can very easily access any
  20507. 12:21:38information you need in the same row in
  20508. 12:21:40order to do such a important analyzis
  20509. 12:21:42and with very simple query. We are not
  20510. 12:21:44doing any crazy stuff like joining and
  20511. 12:21:46stuff. We are just specifying the lead
  20512. 12:21:48function. So now we got all the
  20513. 12:21:50informations that we need. Next we're
  20514. 12:21:52going to go and calculate the average of
  20515. 12:21:53those days. So in order to do that we
  20516. 12:21:56have to go and use a subquery. So let me
  20517. 12:21:58just zoom out. So let's go and select
  20518. 12:22:01star just prepare the subquery. So the
  20519. 12:22:05whole thing going to be a subquery. I'm
  20520. 12:22:06going just get rid of the order by it's
  20521. 12:22:08not now necessary. So let's me just put
  20522. 12:22:11it like this and shift it. So now what
  20523. 12:22:14do we need? We need the average of the
  20524. 12:22:16days. So we need the average of this
  20525. 12:22:17value. So what can we do? We're going to
  20526. 12:22:19go and use a group by. So customer ID
  20527. 12:22:22since we have to find the average for
  20528. 12:22:24each customers and we're going to get
  20529. 12:22:26this value and say average days until
  20530. 12:22:29the next order and we're going to call
  20531. 12:22:30it average days. So and we have here to
  20532. 12:22:34group by. So group by customer ID. So
  20533. 12:22:38like this just make this a little bit
  20534. 12:22:41smaller and zoom in here. So that's it.
  20535. 12:22:43Now we are just doing a very simple
  20536. 12:22:45average and group I statements. So let's
  20537. 12:22:47go and execute it. Now as you can see
  20538. 12:22:49it's going to go and aggregate the data.
  20539. 12:22:51So we have now only four customers and
  20540. 12:22:53for each customer we have the average
  20541. 12:22:56days between their orders. So now what
  20542. 12:22:58is missing in our task? If you check
  20543. 12:23:00over here it says rank the customers
  20544. 12:23:02based on this average. So we have to go
  20545. 12:23:05and use the rank function. So here again
  20546. 12:23:07another window function that we have to
  20547. 12:23:09go and use. We're going to do it
  20548. 12:23:10together with the group by. So let me
  20549. 12:23:12just make this a little bit smaller and
  20550. 12:23:15then let's do it over here. So I'm just
  20551. 12:23:17going to go with the rank function. Then
  20552. 12:23:19we're going to define the window like
  20553. 12:23:21this over order by and then we're going
  20554. 12:23:23to go and sort the data by the average
  20555. 12:23:25days. So that means we're going to go
  20556. 12:23:27and get this calculation over here and
  20557. 12:23:29put it as order by it's going to be
  20558. 12:23:31ascending. So we are focusing on the
  20559. 12:23:33lowest average days. So that's it. Let's
  20560. 12:23:36call it rank average. So now let's go
  20561. 12:23:39and execute this. So now by checking the
  20562. 12:23:41result, you can see now we have a
  20563. 12:23:43ranking for the average. And here skill
  20564. 12:23:46says that the number one customer or the
  20565. 12:23:49number one loyal customer is the
  20566. 12:23:51customer number four which is not really
  20567. 12:23:52correct because the number four we don't
  20568. 12:23:54have a lot of informations about this
  20569. 12:23:56customer he or she did order only once.
  20570. 12:23:59So either now you go and like filter the
  20571. 12:24:01data and remove this customer where you
  20572. 12:24:03say if the average is null then don't
  20573. 12:24:05put it in the rank or we can go and
  20574. 12:24:07replace this value with a very huge
  20575. 12:24:09value in order to make it at the end of
  20576. 12:24:11our list. For example, we can go over
  20577. 12:24:13here and replace the null with
  20578. 12:24:16qualisk like this. And we say if the
  20579. 12:24:19average is null, then let's say give me
  20580. 12:24:22a crazy number like this very huge one.
  20581. 12:24:25So that's it. Let's go and execute. And
  20582. 12:24:27now as you can see this customer going
  20583. 12:24:29to be at the end of our list. And now we
  20584. 12:24:31can see that the most loyal customer is
  20585. 12:24:33number one. And then the other two
  20586. 12:24:35customers are in the rank two. Here we
  20587. 12:24:38are sharing the same rank since we have
  20588. 12:24:39the same average. So guys with that we
  20589. 12:24:41have solved the task and we have ranked
  20590. 12:24:42the customers based on the average days
  20591. 12:24:45between their orders. So we have now a
  20592. 12:24:47really nice rank and we can understand
  20593. 12:24:49now the behavior of the customers and
  20594. 12:24:51maybe we have to go and focus on the
  20595. 12:24:53customer number one and understand her
  20596. 12:24:55or her needs. And of course the function
  20597. 12:24:56that helped us here in order to do such
  20598. 12:24:58a customer retention analyszis is the
  20599. 12:25:01lead function in order to find the next
  20600. 12:25:03order to calculate the days. So this is
  20601. 12:25:05how you use lead functions to do such a
  20602. 12:25:07use case.
  20603. 12:25:12the first value and the last value
  20604. 12:25:14functions. I think the name says
  20605. 12:25:16everything, right? So the first value
  20606. 12:25:17going to allow you to access a value
  20607. 12:25:19from the first row within a window where
  20608. 12:25:22the last value exactly the opposite. It
  20609. 12:25:24going to allow you to access a value
  20610. 12:25:26from the last row within a window. Easy,
  20611. 12:25:29right? So now let's understand how SQL
  20612. 12:25:31execute those functions. Okay. So now as
  20613. 12:25:33usual, we have this very simple example.
  20614. 12:25:34we have the months and sales and we have
  20615. 12:25:36it twice because we would like now to go
  20616. 12:25:38and compare side by side the two
  20617. 12:25:40functions first value and last value. So
  20618. 12:25:42now for the left sides we would like to
  20619. 12:25:44get the sales of the first month and on
  20620. 12:25:47the right sides we would like to get the
  20621. 12:25:49sales of the last month. So now for the
  20622. 12:25:51first task we can go and use the first
  20623. 12:25:53value. It's very simple. So the first
  20624. 12:25:55value function then the argument going
  20625. 12:25:56to be sales since we want the sales and
  20626. 12:25:59then the window going to be defined like
  20627. 12:26:00this order by month because we want to
  20628. 12:26:03get the first month. So as usual we must
  20629. 12:26:06use order by now on the right side in
  20630. 12:26:08order to get the sales of the last
  20631. 12:26:09months we can go and use the last value
  20632. 12:26:11right so the same things last value
  20633. 12:26:13sales over order by month. So as you can
  20634. 12:26:16see on the left and right we don't use
  20635. 12:26:18any frame definition but the default
  20636. 12:26:20going to be used from this. All right.
  20637. 12:26:21So now let's see how SQL going to
  20638. 12:26:22process both of those queries side by
  20639. 12:26:25side. So the first step is SQL going to
  20640. 12:26:26go and sort the data. They are already
  20641. 12:26:28sorted from the lowest to the highest.
  20642. 12:26:30And then the next step is going to start
  20643. 12:26:32row by row finding the first value on
  20644. 12:26:34the left side. So what is the unbounded
  20645. 12:26:36proceeding? It's going to be static and
  20646. 12:26:39always pointing to January. So this is
  20647. 12:26:42always going to be the unpounded
  20648. 12:26:43proceeding. We have it in both sides
  20649. 12:26:45like this. And what is the current row?
  20650. 12:26:48It's going to be at the start the first
  20651. 12:26:50row. And on the right side the same
  20652. 12:26:52things over here. So the window
  20653. 12:26:54definition going to be is only one row
  20654. 12:26:57right. So what is the first value in
  20655. 12:27:00this window? It is 20. Right? The same
  20656. 12:27:03things on the right side. What is the
  20657. 12:27:05last value in this window? It is as well
  20658. 12:27:0820. So we will get exactly same results.
  20659. 12:27:10Now let's move to the second row. So
  20660. 12:27:12it's going to be pointing to February.
  20661. 12:27:14And the frame definition going to be
  20662. 12:27:16here extended like this. So what is the
  20663. 12:27:19first value in this frame? It's going to
  20664. 12:27:21be as well 20. Right? So in the output
  20665. 12:27:24we're going to get 20. And now in the
  20666. 12:27:25right side the current row going to be
  20667. 12:27:27as well pointing to February and the
  20668. 12:27:30window going to go get extended. So now
  20669. 12:27:32what is the last value of this frame?
  20670. 12:27:35It's going to be 10. Now let's keep
  20671. 12:27:37going. We're going to go to the March
  20672. 12:27:39and the window going to get extended.
  20673. 12:27:41What is the first value? It's always
  20674. 12:27:44going to be the same. So 20 on the right
  20675. 12:27:46side window going to get extended. What
  20676. 12:27:49is the last value? It's going to be 30.
  20677. 12:27:52So as you can see the default definition
  20678. 12:27:53is always having the static start always
  20679. 12:27:56the same start of the subset and as we
  20680. 12:27:58are moving with the current row the
  20681. 12:28:00frame going to get extended. So now
  20682. 12:28:02moving to the last one and with that we
  20683. 12:28:04will get the whole data set inside the
  20684. 12:28:07frame and the first cell is going to be
  20685. 12:28:0920 on the right side. the same things
  20686. 12:28:12going to get extended like this and this
  20687. 12:28:14time the last one going to be April and
  20688. 12:28:16five. So now if you go and compare them
  20689. 12:28:18side by side you see that on the left
  20690. 12:28:20side the task is solved and everything
  20691. 12:28:22is working correctly right. So we have
  20692. 12:28:24for each row always the sales of the
  20693. 12:28:26first row and what is the first row it
  20694. 12:28:29is January. So we have everywhere a 20
  20695. 12:28:31which is correct. But now if you check
  20696. 12:28:33the right side you can see there is
  20697. 12:28:35something wrong right? We are getting
  20698. 12:28:37not the last value. We should always get
  20699. 12:28:39April right? We should have here
  20700. 12:28:40everywhere a five. So we have here
  20701. 12:28:43exactly the same result as the sales. So
  20702. 12:28:45it's really useless to use it like this,
  20703. 12:28:47right? And that's of course because SQL
  20704. 12:28:49is using the default definition of the
  20705. 12:28:51window frame. Last value is the only
  20706. 12:28:53function from all window functions that
  20707. 12:28:55you cannot use the default frame
  20708. 12:28:58definition. You have to go and customize
  20709. 12:29:00the frame definition in order to get the
  20710. 12:29:02effect of the last value. For the first
  20711. 12:29:04value, everything is working. If you're
  20712. 12:29:05using a default frame, if you are not
  20713. 12:29:07specifying anything, but for the last
  20714. 12:29:09value, you will not get the effect
  20715. 12:29:10correctly without customizing the frame
  20716. 12:29:13window. So my friends, you can go and
  20717. 12:29:15use the first value function like all
  20718. 12:29:17other window functions without defining
  20719. 12:29:19a frame. You can go with the default and
  20720. 12:29:21you will get the effect of the first
  20721. 12:29:22value, but the last value you have to go
  20722. 12:29:24and define a frame. So let's see how we
  20723. 12:29:26can solve that. All right. So now in
  20724. 12:29:28order to solve this, we going to define
  20725. 12:29:29the frame like this. It's going to be
  20726. 12:29:31the rows between the current row and the
  20727. 12:29:34unbounded following. So we just switch
  20728. 12:29:36things around. So now let's see how this
  20729. 12:29:38going to work. Now of course it's going
  20730. 12:29:40to go and sort the data and so on. Now
  20731. 12:29:42it's still going to have a pointer to
  20732. 12:29:44the unbounded following. So it's going
  20733. 12:29:46to point always to the last row in our
  20734. 12:29:48data set and then it's going to proceed
  20735. 12:29:50step by step. So the first row going to
  20736. 12:29:52be like this and the frame going to be
  20737. 12:29:54the whole thing, right? So from the
  20738. 12:29:56current row until the unbounded
  20739. 12:29:58following. So what is the last value the
  20740. 12:30:01last row? It's going to be the five,
  20741. 12:30:03right? The April. So we will get in the
  20742. 12:30:04output five. Now let's proceed to the
  20743. 12:30:07next value. The frame going to be
  20744. 12:30:09shorter and smaller. And what is the
  20745. 12:30:11last value? It's going to be as well the
  20746. 12:30:13five. Right? So now we jump to the next
  20747. 12:30:15one. And the frame going to be like
  20748. 12:30:17this. What is the last value? As well
  20749. 12:30:19five. And then we will get the last
  20750. 12:30:21value like this. Current row is equal to
  20751. 12:30:24the unbounded following. We have only
  20752. 12:30:25one row and it's going to be as well
  20753. 12:30:27five. So as you can see it's very simple
  20754. 12:30:29just fix the frame clause and you will
  20755. 12:30:31get the last value working as expected.
  20756. 12:30:34So this is how SQL going to go and do
  20757. 12:30:36it. Now let's go back to SQL and start
  20758. 12:30:38practicing. All right. So now we have
  20759. 12:30:39the following task. It says find the
  20760. 12:30:42lowest and highest sales for each
  20761. 12:30:44product. So now let's see how we can do
  20762. 12:30:46this. As usual we're going to start with
  20763. 12:30:47very simple select statement. So select
  20764. 12:30:50order ID. We need the product ID and as
  20765. 12:30:54well their sales. So let's select the
  20766. 12:30:56table sales orders. So that's it. Let's
  20767. 12:31:00go and select this. Now in the output we
  20768. 12:31:02got our orders, products and sales. So
  20769. 12:31:05now let's start with the first part of
  20770. 12:31:06the task. Find the lowest sales for each
  20771. 12:31:09product. So in order to do that, we can
  20772. 12:31:11use the first value function. So let's
  20773. 12:31:14go and do that. First value. Then what
  20774. 12:31:17we are talking about, we have to give an
  20775. 12:31:18expression. We need the lowest and
  20776. 12:31:21highest sales. So let's go and have the
  20777. 12:31:23sales inside it. And now we have to
  20778. 12:31:25define the window. So over since we are
  20779. 12:31:28saying for each product that means we
  20780. 12:31:29have to go and make windows. So we have
  20781. 12:31:32to divide the data using partition by
  20782. 12:31:34products ID. And then we must use an
  20783. 12:31:37order by right. So we have to go and
  20784. 12:31:39sort the data by the sales. Since the
  20785. 12:31:42first value should be the lowest value,
  20786. 12:31:45we have to do it as ascending from the
  20787. 12:31:47lowest sales to the highest sales. So
  20788. 12:31:49we're just going to leave it like this
  20789. 12:31:50as a default and we're going to call it
  20790. 12:31:53lowest sales. So let's go and execute
  20791. 12:31:57this. So now let's go and check our
  20792. 12:31:58results. First going to go and partition
  20793. 12:32:00the data by the product ID. So as you
  20794. 12:32:02can see we got now here four windows.
  20795. 12:32:05Then sort the data by the sales. So the
  20796. 12:32:07data are sorted from the lowest to the
  20797. 12:32:09highest from 10 to 90. So now what is
  20798. 12:32:12the first value of the sales? It is the
  20799. 12:32:14first row, right? So it's going to be
  20800. 12:32:1610. That's why we have everywhere a 10.
  20801. 12:32:19Let's check another one. Let's take this
  20802. 12:32:21one here. So this window has two rows
  20803. 12:32:23and it is sorted the lowest sales or
  20804. 12:32:26let's say the first value is 25. So with
  20805. 12:32:29that we have solved the first part of
  20806. 12:32:31the task finding the lowest sales for
  20807. 12:32:33each product. Let's go to the next one.
  20808. 12:32:35We have to find out the highest sales
  20809. 12:32:36for each product. So let's go and use
  20810. 12:32:39the last value for this. So let's have a
  20811. 12:32:41new line. We're going to have a last
  20812. 12:32:44value again the
  20813. 12:32:47sales. Then we're going to go and define
  20814. 12:32:49the window. So it's going to be the
  20815. 12:32:50exact same window. We have to partition
  20816. 12:32:52the data by the product ID and order the
  20817. 12:32:54data by sales. So let's go and just copy
  20818. 12:32:58the previous one and let's call it for
  20819. 12:33:00now highest sales. So let's go and
  20820. 12:33:04execute it. So now if you check the
  20821. 12:33:06results, you will see our issue over
  20822. 12:33:07here again. Right? We are not getting
  20823. 12:33:09the highest sales for this window. The
  20824. 12:33:11highest sales is 90. But as you can see,
  20825. 12:33:13we are getting the exact same sales. And
  20826. 12:33:15we have explained that in the previous
  20827. 12:33:16example. So in order to fix this, we're
  20828. 12:33:19going to go and add for it the frame. So
  20829. 12:33:22rows between current row and the
  20830. 12:33:26unbounded following.
  20831. 12:33:28So now let's go and execute this. So now
  20832. 12:33:32let's check the result. As you can see
  20833. 12:33:34over here, we got the highest sales
  20834. 12:33:36correctly. So for this window, the
  20835. 12:33:37highest ones is 90. and as well for this
  20836. 12:33:40window the 60 and so on. So with that
  20837. 12:33:42you have solved both of the tasks the
  20838. 12:33:44lowest and the highest sales. But now I
  20839. 12:33:46would like to show you my honest opinion
  20840. 12:33:48about this tasks. I will not go and use
  20841. 12:33:51the last value to find the highest
  20842. 12:33:53sales. So let me show you how I usually
  20843. 12:33:55do it. I'm going to go and use the first
  20844. 12:33:57value in order to find the last value.
  20845. 12:34:00So now let me show you what I mean.
  20846. 12:34:01Let's go and add a new row. I will just
  20847. 12:34:04take the whole thing from the lowest
  20848. 12:34:06sales. But what I'm going to do, I'm
  20849. 12:34:09just going to go and change the order.
  20850. 12:34:10So that means we will not go and sort
  20851. 12:34:12the data like this ascending from the
  20852. 12:34:15lowest sales to the highest sales. We're
  20853. 12:34:16going to go and switch it. So we're
  20854. 12:34:19going to go and sort the data from the
  20855. 12:34:20highest sales to the lowest sales. And
  20856. 12:34:23with that, the first value going to be
  20857. 12:34:25the highest sales. So let me just rename
  20858. 12:34:28it highest sales. Let's give it like
  20859. 12:34:31two. So let's go and execute this. And
  20860. 12:34:34now you can see over here we got the
  20861. 12:34:36exact same results because we sorted the
  20862. 12:34:38data differently and we get the first
  20863. 12:34:40value. So this is going to give you the
  20864. 12:34:42exact same effect like the last value.
  20865. 12:34:45And as you can see I don't have to
  20866. 12:34:46define now any window or something like
  20867. 12:34:48that. I can stick with the default frame
  20868. 12:34:51but just twisting the order by. So this
  20869. 12:34:54is how you can do it as well using only
  20870. 12:34:56the first value. So now just for the
  20871. 12:34:58sake of this task there's as well
  20872. 12:35:00another possibility in how to solve
  20873. 12:35:01this. You can go and use the minmax
  20874. 12:35:04functions. So let me just take the same
  20875. 12:35:07and have a new one the lowest sales. We
  20876. 12:35:10can go and say you know what let's get
  20877. 12:35:13the min. So we are saying find me the
  20878. 12:35:15minimum sales and we don't have to go
  20879. 12:35:18and sort anything. So we can go and just
  20880. 12:35:20divide it like this. So let's give it
  20881. 12:35:22another ID. Let's go and execute it. So
  20882. 12:35:25as you can see we got the exact same
  20883. 12:35:27results like the other two highest
  20884. 12:35:29sales. So as you can see we can solve
  20885. 12:35:31this task using three different
  20886. 12:35:32functions. Either go and use the last
  20887. 12:35:35value but you have to define the frame
  20888. 12:35:37or you can go and use the first value
  20889. 12:35:39where you switch or flip the order by or
  20890. 12:35:42simply just using the max function in
  20891. 12:35:44order to get the highest sales. So guys
  20892. 12:35:47as you can see we can use the first
  20893. 12:35:48value and the last value in order to
  20894. 12:35:50find out the extremes like here in this
  20895. 12:35:52example the lowest and the highest
  20896. 12:35:54sales. So there is like similarity
  20897. 12:35:56between those two functions and as well
  20898. 12:35:57the min and max. And of course what
  20899. 12:35:59we're going to do with this value over
  20900. 12:36:01here we can go and compare it with the
  20901. 12:36:03current sales. So for example we can go
  20902. 12:36:05and extend our task where we say find
  20903. 12:36:07the difference in sales between the
  20904. 12:36:09current and the lowest sales. So in
  20905. 12:36:12order to do that let me just clean up
  20906. 12:36:13all those stuff and let's stick with the
  20907. 12:36:16first value and the highest value like
  20908. 12:36:18this. So we have to compare now the
  20909. 12:36:20current sales which is this field over
  20910. 12:36:23here. the sales the original one with
  20911. 12:36:25the lowest sales with the whole thing
  20912. 12:36:27from here. So let's go and do that. So
  20913. 12:36:29we're going to have a new line and we're
  20914. 12:36:30going to say just simply subtract the
  20915. 12:36:33sales from the lowest sales like this.
  20916. 12:36:36And let's give it a name sales
  20917. 12:36:39difference. So that's it. Let's go and
  20918. 12:36:42execute it. Now as you can see the
  20919. 12:36:44result in one row I'm comparing the
  20920. 12:36:46current sales which is 90 with the
  20921. 12:36:48lowest sales from this product. It's
  20922. 12:36:50going to be the 10. So with that we're
  20923. 12:36:52going to get the distance let's say
  20924. 12:36:54between those two informations and it
  20925. 12:36:56going to be 80. So now for the next one
  20926. 12:36:58the distance between this value and the
  20927. 12:37:00lowest value is shorter. So we are near
  20928. 12:37:03the lowest value. So as you can see over
  20929. 12:37:05here we can now compare the sales
  20930. 12:37:08between the current sales and one
  20931. 12:37:10extreme in order to find the distances
  20932. 12:37:12between two values. So this is again
  20933. 12:37:15very important analysis in order to do
  20934. 12:37:17comparison analyszis.
  20935. 12:37:22All right friends, so now let's do a
  20936. 12:37:24quick recap about the value functions or
  20937. 12:37:25we call them sometimes analytical
  20938. 12:37:27functions. So what they do, they're
  20939. 12:37:29going to go and allow you to access a
  20940. 12:37:30specific value from another row. This
  20941. 12:37:33going to help you in order to do complex
  20942. 12:37:34calculations with very simple SQL
  20943. 12:37:37without having you joining tables
  20944. 12:37:39together or doing self joins. And for
  20945. 12:37:41the value functions we have four types
  20946. 12:37:43or let's say for functions the first one
  20947. 12:37:45allows you to access the previous value
  20948. 12:37:47like the previous month using the lag
  20949. 12:37:50function. The next one it allows you to
  20950. 12:37:52access the next values the next month
  20951. 12:37:55using the lead function. Then we have
  20952. 12:37:57another one it allows you to access the
  20953. 12:38:00first value in a subset using the first
  20954. 12:38:02value function. And another option we
  20955. 12:38:04can go and access the last value in a
  20956. 12:38:07subset using the last value function.
  20957. 12:38:09Moving on to the next one, we have the
  20958. 12:38:11rules of the syntax. So about the first
  20959. 12:38:13point, it is the expressions. We can go
  20960. 12:38:15and use any data type. It could be a
  20961. 12:38:17number, string, a date, anything. Now in
  20962. 12:38:19order to perform those functions, we
  20963. 12:38:21have to go and sort the data by the
  20964. 12:38:22order by. So order by is required. It is
  20965. 12:38:25a must. Then for the frame, you are
  20966. 12:38:28allowed to use it. So it is an optional
  20967. 12:38:30thing. I would say always leave it empty
  20968. 12:38:32for the frame. But only for the last
  20969. 12:38:33value, you have to go and customize
  20970. 12:38:35otherwise it will not work. Now to the
  20971. 12:38:37next point, we have the use cases. We
  20972. 12:38:39have simply very important use cases for
  20973. 12:38:41the value functions in data analytics.
  20974. 12:38:43So what we can do? We can do time series
  20975. 12:38:45analyszis. As we learned, we can do
  20976. 12:38:47month overmonth analyzes and
  20977. 12:38:49yearover-year analyzes. Those analyszis
  20978. 12:38:52are classical and it's always the first
  20979. 12:38:54question in that analyszis in order to
  20980. 12:38:56measure are we growing with the business
  20981. 12:38:58or are we declining? How the performance
  20982. 12:39:00between the current year and the
  20983. 12:39:02previous year. So as you can see we are
  20984. 12:39:03doing always comparison using those
  20985. 12:39:06window functions. The next use case is
  20986. 12:39:08as well about the time we can do time
  20987. 12:39:10gap analyzes as we analyzed the customer
  20988. 12:39:13behavior the customer retention where we
  20989. 12:39:15have calculated the average days between
  20990. 12:39:17two orders and the last use case it's as
  20991. 12:39:20well about comparison comparison
  20992. 12:39:21analyzes we can go and use the value
  20993. 12:39:24functions in order to compare the
  20994. 12:39:25current value with extreme like
  20995. 12:39:27comparing the current sales with the
  20996. 12:39:29highest sales or to the lowest sales. So
  20997. 12:39:32my friends those analyzers are essential
  20998. 12:39:34in data analyzers you will be countering
  20999. 12:39:37them in each company in each business
  21000. 12:39:39you have to answer those questions and
  21001. 12:39:41you can do that very easily using the
  21002. 12:39:43SQL window functions all right my
  21003. 12:39:45friends so that's all about the window
  21004. 12:39:47value functions and with that we have
  21005. 12:39:49covered everything about how to
  21006. 12:39:50aggregate your data using SQL and those
  21007. 12:39:53are very important tools on how to do
  21008. 12:39:55data analytics in SQL especially if you
  21009. 12:39:58are a data scientist and data analyst.
  21010. 12:40:00So with that we are done with this
  21011. 12:40:01chapter and I can tell you with that we
  21012. 12:40:03have covered the intermediate level. So
  21013. 12:40:05we have learned how to filter the data,
  21014. 12:40:07how to combine the data and as well the
  21015. 12:40:09most important functions in SQL. Now
  21016. 12:40:11we're going to go to the third and last
  21017. 12:40:13level we will cover now the advanced
  21018. 12:40:15level. So the first level going to be
  21019. 12:40:17about the advanced SQL techniques. So
  21020. 12:40:19now if you go inside it and in SQL there
  21021. 12:40:21are like different techniques in order
  21022. 12:40:23to organize our complex projects. So
  21023. 12:40:26first I'm going to explain for you what
  21024. 12:40:27is exactly I'm talking about what is
  21025. 12:40:29complex queries and why we have it and
  21026. 12:40:31then we're going to start with the first
  21027. 12:40:32topic the subqueries. So let's
  21028. 12:40:38go. Normally in projects we have a
  21029. 12:40:40database and we have a person that is
  21030. 12:40:42responsible for the database the
  21031. 12:40:44database administrator that take cares
  21032. 12:40:47of the database structure. And now in
  21033. 12:40:49very simple scenario we're going to have
  21034. 12:40:50a user that is writing queries in order
  21035. 12:40:53to retrieve data from the database. So
  21036. 12:40:55he or she going to write an SQL query
  21037. 12:40:57and then this query going to be sent to
  21038. 12:40:59the database where it's going to execute
  21039. 12:41:00it and then the database going to return
  21040. 12:41:03the results. So at the end our user
  21041. 12:41:05going to see the result of the query
  21042. 12:41:07that he wrote. So this is a very
  21043. 12:41:09simplified scenario on how we use a
  21044. 12:41:13database. But my friends in the real
  21045. 12:41:15world things are totally different.
  21046. 12:41:17Things in real projects get very
  21047. 12:41:19complicated like this. So for example,
  21048. 12:41:21you have a financial analyst that is
  21049. 12:41:24writing a huge block of SQL query that
  21050. 12:41:27is very complex and there will be like
  21051. 12:41:30another user that have different role
  21052. 12:41:32like a risk manager that is as well
  21053. 12:41:34writing a very complex query and from
  21054. 12:41:38different departments from different
  21055. 12:41:39projects for different tasks. You will
  21056. 12:41:42have a lot of analysts that are writing
  21057. 12:41:45many complex queries. So all those
  21058. 12:41:47analysts and managers have a direct
  21059. 12:41:50access to your database and they are
  21060. 12:41:52executing a complex analytical queries
  21061. 12:41:54in order to generate maybe a report or
  21062. 12:41:57something. Now not only those guys are
  21063. 12:41:59doing analyszis on your database you
  21064. 12:42:01will have as well our friend the data
  21065. 12:42:03engineer that is saying you know what
  21066. 12:42:05I'm building a data warehouse and I
  21067. 12:42:07would like to extract your data. So that
  21068. 12:42:09data engineer going to go and write an
  21069. 12:42:11extract query in order to extract the
  21070. 12:42:13data from the database. And then he has
  21071. 12:42:16a different script for the
  21072. 12:42:17transformations in order to manipulate,
  21073. 12:42:20filter, clean up, aggregate your data.
  21074. 12:42:22And then a third script in order to
  21075. 12:42:25collect the result of the
  21076. 12:42:26transformations and load it in another
  21077. 12:42:29database called data warehouse. A data
  21078. 12:42:32warehouse is like special database that
  21079. 12:42:34collect data from different sources and
  21080. 12:42:36integrate it in one place. in order to
  21081. 12:42:38do analytics and reporting. And now at
  21082. 12:42:40the end of this chain, you will have a
  21083. 12:42:42data analyst and she writes as well
  21084. 12:42:44queries in order to analyze the data in
  21085. 12:42:47the data warehouse. Or you might have a
  21086. 12:42:49different query in order to prepare the
  21087. 12:42:51data before inserting it to a tool like
  21088. 12:42:53PowerBI in order to generate
  21089. 12:42:56visualizations and reports. So we call
  21090. 12:42:58this a data warehouse system or a
  21091. 12:43:00business intelligence system that
  21092. 12:43:02extract and extract from your data and
  21093. 12:43:05manipulate it and transform it for
  21094. 12:43:07analyzes. Now not only we have a data
  21095. 12:43:09engineer and data analyst accessing your
  21096. 12:43:11database and doing queries, we have as
  21097. 12:43:13well our friend the data scientist. So
  21098. 12:43:15now our data scientist as well has a
  21099. 12:43:17direct access to your database. So he
  21100. 12:43:20might write like different queries in
  21101. 12:43:22order to extract the data and as well to
  21102. 12:43:24manipulate the data that are needed in
  21103. 12:43:26order to develop a model and doing
  21104. 12:43:28machine learning and AI. And now one
  21105. 12:43:30more scenario that I see in many
  21106. 12:43:32projects where the result of the data
  21107. 12:43:34analyst going to be used in another
  21108. 12:43:36query in order to prepare the results
  21109. 12:43:38for data visualizations PowerBI or in
  21110. 12:43:41order to export like a Excel list. So as
  21111. 12:43:43you can see we have a lot of people with
  21112. 12:43:45different roles that want to access your
  21113. 12:43:48database and do analyzes on top of it
  21114. 12:43:50and that's because everyone want to
  21115. 12:43:52answer questions based on the data and
  21116. 12:43:54now if I look to this I still think this
  21117. 12:43:56is a simplified version and how things
  21118. 12:43:59works in the data projects and I can
  21119. 12:44:01tell you in real projects things are way
  21120. 12:44:03more complicated than this so now if you
  21121. 12:44:05sit back and look to this we will find
  21122. 12:44:08many challenges and problems for example
  21123. 12:44:10all those people are not talking to each
  21124. 12:44:12others And each one of them are creating
  21125. 12:44:14like their own query. But if you go and
  21126. 12:44:17take all those queries and compare them
  21127. 12:44:19side by side, you will find in the
  21128. 12:44:21scripts and queries logic that is keep
  21129. 12:44:23repeating. So the queries from the
  21130. 12:44:25analyst or the data scientists and data
  21131. 12:44:28engineers, they might contain a
  21132. 12:44:30redundant logic. And of course the issue
  21133. 12:44:33of this we have the same effort
  21134. 12:44:35repeating over and over and maybe not
  21135. 12:44:38everyone is getting the logic
  21136. 12:44:39implemented correctly because not all of
  21137. 12:44:41them having the right skills in SQL. So
  21138. 12:44:44this is a big issue in this setup. And
  21139. 12:44:46now we have another challenge having
  21140. 12:44:48this scenario. If you don't optimize it
  21141. 12:44:51you will have a performance issue
  21142. 12:44:53everywhere. So the data warehouse or the
  21143. 12:44:55data engineer scripts might take like 5
  21144. 12:44:57hours and the query from the analyst
  21145. 12:45:00might take like 40 minutes and before
  21146. 12:45:02inserting the data to reports we might
  21147. 12:45:04have 30 minutes and 1 hour there 30
  21148. 12:45:06minutes there and everyone else is as
  21149. 12:45:08well suffering from bad performance on
  21150. 12:45:10their queries and the performance
  21151. 12:45:12everywhere is really bad. So if everyone
  21152. 12:45:14is writing big complex queries don't
  21153. 12:45:16expect that they will have a good
  21154. 12:45:18performance. Now to the third challenge
  21155. 12:45:20that I observed in many projects and
  21156. 12:45:22that is the complexity. Now behind the
  21157. 12:45:24original database you might have a data
  21158. 12:45:26model that is prepared and optimized
  21159. 12:45:29only for one application. So you will
  21160. 12:45:31have in the data model a lot of tables
  21161. 12:45:32and all those tables have different
  21162. 12:45:34relationship between them and of course
  21163. 12:45:36only the developers and the experts of
  21164. 12:45:39this database understand the physical
  21165. 12:45:41data model behind this database. And now
  21166. 12:45:43if you give access to all those analysts
  21167. 12:45:46they will have a lot of questions
  21168. 12:45:48because first they have to understand
  21169. 12:45:50the data model before writing any query.
  21170. 12:45:53So that means a lot of data workers are
  21171. 12:45:55keep asking our expert from this
  21172. 12:45:58database questions. So for example how
  21173. 12:46:00to connect the table A with the table B
  21174. 12:46:02and where do I find my columns? What
  21175. 12:46:04this table means? I'm getting bad result
  21176. 12:46:06in my query because your data is really
  21177. 12:46:08corrupt. So the developers of the
  21178. 12:46:10database will get a lot of questions
  21179. 12:46:12from the analyst and they have to
  21180. 12:46:14explain over and over their data model
  21181. 12:46:16so that the users are able to write
  21182. 12:46:19those complex queries. So that means all
  21183. 12:46:21those users are stressing the database
  21184. 12:46:23team by many questions and as well the
  21185. 12:46:26users are writing very complex queries.
  21186. 12:46:28So the complexity is a really big
  21187. 12:46:30challenge. Now as well by looking to
  21188. 12:46:32this picture you will find a lot of
  21189. 12:46:34errors from those queries to the
  21190. 12:46:35database and this might cause a lot of
  21191. 12:46:39database stress. So keep executing
  21192. 12:46:41repeatedly a big complex queries going
  21193. 12:46:44to makes really big stress for the
  21194. 12:46:46database and it going to bring the
  21195. 12:46:48database down. And the last challenge of
  21196. 12:46:50this picture is that the data security.
  21197. 12:46:52So if you leave it like this by giving
  21198. 12:46:54the users a direct access to your
  21199. 12:46:56database tables you might have a problem
  21200. 12:46:59because it might be okay for like some
  21201. 12:47:01data engineers and so on but you don't
  21202. 12:47:03want to give for each data analyst a
  21203. 12:47:05full access to the database tables. So
  21204. 12:47:08you have to protect your tables the
  21205. 12:47:10columns the rows everything. So you
  21206. 12:47:12cannot leave it like this where everyone
  21207. 12:47:14having a direct access to the physical
  21208. 12:47:16database tables. Now enough talking
  21209. 12:47:18about challenges problems and issues.
  21210. 12:47:20Let's be solutionoriented. So what are
  21211. 12:47:23the solutions of those issues? Of
  21212. 12:47:25course, there are many solutions, but
  21213. 12:47:26we're going to focus now on five
  21214. 12:47:28techniques. We can go and use sub
  21215. 12:47:30queries or CTE, common table
  21216. 12:47:32expressions. We can introduce views to
  21217. 12:47:34our database or temporary tables or we
  21218. 12:47:37can go and use the technique of the CTAs
  21219. 12:47:40carrier table as select. So this is
  21220. 12:47:43exactly why we have to understand those
  21221. 12:47:45five techniques in order to solve all
  21222. 12:47:47those issues that we might face in our
  21223. 12:47:49data
  21224. 12:47:53projects. All right friends, so now
  21225. 12:47:55after we understood the importance of
  21226. 12:47:57those five techniques, let's take a
  21227. 12:48:00quick and simplified look to the
  21228. 12:48:01database architecture because I want you
  21229. 12:48:03to understand what happens behind the
  21230. 12:48:06scenes and how the database execute the
  21231. 12:48:09queries from these five techniques. So
  21232. 12:48:12by understanding this architecture you
  21233. 12:48:14will understand how things works. So
  21234. 12:48:16let's go. For each story there are two
  21235. 12:48:18sides. We have the server side and the
  21236. 12:48:20client side. In the client side it's
  21237. 12:48:22like for example you you are writing an
  21238. 12:48:24SQL query for a specific purpose. Now in
  21239. 12:48:27the server side we have many things. So
  21240. 12:48:30the server is where the database lives
  21241. 12:48:32and it has many components like the
  21242. 12:48:34database engine. The database engine is
  21243. 12:48:37the brain of the database that handles
  21244. 12:48:40different operations like storing,
  21245. 12:48:42retrieving and managing data in the
  21246. 12:48:45database. So each time you execute a
  21247. 12:48:47query, the database engine going to take
  21248. 12:48:49care of it. And now in the database we
  21249. 12:48:51have very important component that is
  21250. 12:48:53the storage and the two main types of
  21251. 12:48:55storage in a database are disk storage
  21252. 12:48:58and cache. The disk storage is like a
  21253. 12:49:01long-term memory where the data is
  21254. 12:49:03stored permanently. So it's like the
  21255. 12:49:05disk at your PC. It stores the data
  21256. 12:49:08permanently even if you turn off the
  21257. 12:49:10system. And one important feature of the
  21258. 12:49:12disk is that it can stores a lot of
  21259. 12:49:14data. But the disadvantage of the disk
  21260. 12:49:16storage is that it is slow. So it is
  21261. 12:49:19slow to write and to read. Now in the
  21262. 12:49:21other hand we have the cache is a
  21263. 12:49:23short-term memory where the data is
  21264. 12:49:25stored temporary. It's like the RAMs at
  21265. 12:49:27your PC. It holds the most frequently
  21266. 12:49:30used data. So the database can access it
  21267. 12:49:33quickly in order to retrieve data. And
  21268. 12:49:35the big advantage of the cache is that
  21269. 12:49:37it is fast. So it is very fast for the
  21270. 12:49:39database to retrieve data from the cache
  21271. 12:49:41compared to the disk. But the
  21272. 12:49:43disadvantage of the cache, the data is
  21273. 12:49:45stored there only for short period. So
  21274. 12:49:47it's like tradeoff between the speed and
  21275. 12:49:49how much data you can store and how
  21276. 12:49:51long. Now let's talk about the disk
  21277. 12:49:53storage. This is very important in
  21278. 12:49:55databases. There are typically three
  21279. 12:49:57types of storage areas. There we have
  21280. 12:49:59the user data, the system catalog and
  21281. 12:50:02the temporary data and each storage type
  21282. 12:50:05has a different purpose. So what is user
  21283. 12:50:07data storage? It is the main content of
  21284. 12:50:10the database. So it stores the actual
  21285. 12:50:13data all the informations that are
  21286. 12:50:15relevant for the users. So it's stored
  21287. 12:50:18there all the important data that the
  21288. 12:50:20users cares about. So this is the
  21289. 12:50:22storage where the users are interacting
  21290. 12:50:24all the time. So where do we find the
  21291. 12:50:26user data? If you go to our database
  21292. 12:50:28sales DB and then you go to the tables
  21293. 12:50:30now we find all these tables that we are
  21294. 12:50:32already used the customers employees
  21295. 12:50:34orders and so on those tables are the
  21296. 12:50:37user data. So now if I go and say select
  21297. 12:50:41from sales orders and all those
  21298. 12:50:44informations that we are seeing now are
  21299. 12:50:46the users data. So this is what we users
  21300. 12:50:49actually care about. All other stuff
  21301. 12:50:51that we see inside databases as a user
  21302. 12:50:54we don't care about it. We care only
  21303. 12:50:55about our data. But in the database, we
  21304. 12:50:58don't have only the user data. We have
  21305. 12:51:00many other informations. So this is what
  21306. 12:51:02we mean with the user data
  21307. 12:51:07storage. Now what is system catalog?
  21308. 12:51:10This is the internal storage for the
  21309. 12:51:12database for its own information. So
  21310. 12:51:15it's like a blueprint that keeps
  21311. 12:51:17tracking everything about the database
  21312. 12:51:20itself. So that means the main purpose
  21313. 12:51:22of the system catalog is that it holds
  21314. 12:51:25the metadata informations about the
  21315. 12:51:28database. So what is a metadata?
  21316. 12:51:30Metadata is data about data. Now let's
  21317. 12:51:33understand what this means. What we have
  21318. 12:51:35done so far is that we have created a
  21319. 12:51:37table called customers and we have
  21320. 12:51:39defined inside it like multiple columns
  21321. 12:51:41like the customer ID, first name, last
  21322. 12:51:43name and then we have inserted our data
  21323. 12:51:45inside this table. So we have inserted
  21324. 12:51:48five customers. So those informations
  21325. 12:51:50are my data. I have created those
  21326. 12:51:52informations and stored it inside the
  21327. 12:51:54database. That's why we call it the user
  21328. 12:51:57data. So nothing so far is new. So now
  21329. 12:51:59what happens behind the scenes is that
  21330. 12:52:01the database server will not only store
  21331. 12:52:04the user data that you have provided but
  21332. 12:52:06also it's going to go and store a
  21333. 12:52:08different type of data inside the
  21334. 12:52:10database and this data is the metadata.
  21335. 12:52:13So the database server going to store
  21336. 12:52:15the metadata of the customer's table and
  21337. 12:52:18it going to look like this. There is
  21338. 12:52:20like a table name, there is a column
  21339. 12:52:22names and those are the column names
  21340. 12:52:24that you have defined inside your
  21341. 12:52:26database and those are the column names
  21342. 12:52:29that you have defined as you are
  21343. 12:52:31creating the table customers and it's
  21344. 12:52:33going to store as well additional
  21345. 12:52:35informations like which data type like
  21346. 12:52:37the customer ID is int and the last name
  21347. 12:52:39is v charts and many other informations
  21348. 12:52:41like the length of the column and
  21349. 12:52:44whether the column is nullable or not.
  21350. 12:52:46So as you can see in the metadata we are
  21351. 12:52:48having a description a data about the
  21352. 12:52:52structure of the customers and in the
  21353. 12:52:54metadata we can find a lot of
  21354. 12:52:56informations about not only the tables
  21355. 12:52:57and columns but as well about the
  21356. 12:52:59schemas and the database. So you can
  21357. 12:53:02find a full catalog about the structure
  21358. 12:53:04of your database. Basic table the
  21359. 12:53:06customers table it contains data about
  21360. 12:53:09the actual data. So it stores data about
  21361. 12:53:12the customers. But the metadata of the
  21362. 12:53:14customers table contains data about
  21363. 12:53:17data. So in the databases each table
  21364. 12:53:20that you are using in order to store
  21365. 12:53:21your data has a table twin that
  21366. 12:53:24describes the structure of your data. So
  21367. 12:53:27this is what we mean with a system
  21368. 12:53:29catalog or a metadata. And now you might
  21369. 12:53:31ask where I can find all those system
  21370. 12:53:33catalog and metadata inside our client
  21371. 12:53:36here. Well, you cannot navigate through
  21372. 12:53:38those informations in the object
  21373. 12:53:40explorer like we used to do for the user
  21374. 12:53:42data. But you can find those
  21375. 12:53:43informations in a special hidden schema
  21376. 12:53:47called the information schema. The
  21377. 12:53:49information schema in SQL server is a
  21378. 12:53:52systemdefined schema that contains a set
  21379. 12:53:55of built-in views that help us to find
  21380. 12:53:58information about our database like
  21381. 12:54:00tables, columns, and other objects. So
  21382. 12:54:03let's go and explore it. We're going to
  21383. 12:54:05go and say select star from
  21384. 12:54:09information schema. And then let's have
  21385. 12:54:11a dot. And now we get from SQL a list of
  21386. 12:54:14all views that are available in order to
  21387. 12:54:16browse the metadata of our database. So
  21388. 12:54:19for example, you can see here tables.
  21389. 12:54:21You can see informations about the views
  21390. 12:54:24and as well about the columns. So let's
  21391. 12:54:26go and select the columns and let's go
  21392. 12:54:29and execute it. And now in the output we
  21393. 12:54:31can find informations about the schema
  21394. 12:54:33about the table names like for example
  21395. 12:54:36here the customers. Let me just go and
  21396. 12:54:38select this table. And then we find all
  21397. 12:54:41the columns inside this table how they
  21398. 12:54:44are sorted. So we have here the order of
  21399. 12:54:46each column and as well the data type
  21400. 12:54:49and the size of each column and many
  21401. 12:54:52other stuff. So as you can see we got
  21402. 12:54:54here all the informations all the
  21403. 12:54:56metadata of each table and as well for
  21404. 12:55:00each column inside the table. So with
  21405. 12:55:02that you can check which tables does
  21406. 12:55:04exist in your database. For example I
  21407. 12:55:05find here like something called test
  21408. 12:55:07two. So maybe I was trying to test
  21409. 12:55:09something. I can go now and clean up
  21410. 12:55:11stuff right and this is exactly why the
  21411. 12:55:13database maintain such a catalog. It
  21412. 12:55:16helps the database to quickly find the
  21413. 12:55:18structure of each table and of each
  21414. 12:55:20column. and it helps me as well as a
  21415. 12:55:22user to browse the catalog of the
  21416. 12:55:24database. So for example I can go over
  21417. 12:55:26here and say okay let's get a distinct
  21418. 12:55:29table name. So with that I will get a
  21419. 12:55:32list of everything that I have inside
  21420. 12:55:35the database. So we have the customers
  21421. 12:55:37employees and some tests that I have
  21422. 12:55:39done. So metadata are
  21423. 12:55:43awesome. Now we come to the third
  21424. 12:55:45storage that temporary data storage. It
  21425. 12:55:48is a temporary space used by the
  21426. 12:55:50database for short-term task like
  21427. 12:55:53processing a query or sorting data. And
  21428. 12:55:55once these tasks are done, what going to
  21429. 12:55:58happen? The database going to go and
  21430. 12:55:59clean up the storage. And now of course
  21431. 12:56:01the question is where we can find these
  21432. 12:56:02temporary tables that is using the
  21433. 12:56:05temporary storage in the disk. Well
  21434. 12:56:07actually if you go to the object
  21435. 12:56:08explorer you will not find it inside our
  21436. 12:56:11database sales DB but you will find it
  21437. 12:56:14inside the system databases. Now since
  21438. 12:56:16we are working locally we have the full
  21439. 12:56:18access to everything inside the SQL
  21440. 12:56:20server. But in real projects if you are
  21441. 12:56:22just a user or let's say developer you
  21442. 12:56:25will not have access to the system
  21443. 12:56:26databases only for the database
  21444. 12:56:29administrators. But now we are working
  21445. 12:56:30on the local copy. So let's go to the
  21446. 12:56:33system database and here you have a
  21447. 12:56:35special database from the SQL server
  21448. 12:56:37called temp DB. And if you go inside it
  21449. 12:56:41we will find here tables and temporary
  21450. 12:56:43tables. So this is exactly where you can
  21451. 12:56:45find all the temporal tables that you
  21452. 12:56:47are generating. Now currently we didn't
  21453. 12:56:49create any temporary tables that's why
  21454. 12:56:52it's empty. But once you start creating
  21455. 12:56:54temporary tables you will find those
  21456. 12:56:56tables underneath this folder. We will
  21457. 12:56:58learn about the temporary tables in the
  21458. 12:57:00next
  21459. 12:57:04sections. So these are the main
  21460. 12:57:06component of the database architecture.
  21461. 12:57:09So now let's have an example. Now we
  21462. 12:57:10have a table called orders that is
  21463. 12:57:12stored inside the user storage and the
  21464. 12:57:15metadata of this table is stored in the
  21465. 12:57:16catalog. So now let's say that you are
  21466. 12:57:18at the client side and you write a
  21467. 12:57:20simple select query in order to select
  21468. 12:57:22the data of the orders. So now that
  21469. 12:57:24query is sent to the server in order to
  21470. 12:57:26be executed and the database engine
  21471. 12:57:28going to take the query in order to
  21472. 12:57:29process it. So first the database engine
  21473. 12:57:32going to check whether we have the data
  21474. 12:57:33in the cache because if the data is
  21475. 12:57:35stored in the cache then things going to
  21476. 12:57:37be really fast and the database engine
  21477. 12:57:38can solve the task quickly but in this
  21478. 12:57:40scenario we don't have the orders
  21479. 12:57:42informations in the cache that's why the
  21480. 12:57:44database engine going to say okay it's
  21481. 12:57:46not in the cache let's check the disk so
  21482. 12:57:48it will find the orders information in
  21483. 12:57:50the disk and the query going to be
  21484. 12:57:51executed then the result of this query
  21485. 12:57:54going to be sent back to the client side
  21486. 12:57:56where at the end in return you will see
  21487. 12:57:58in the output the result of the table
  21488. 12:58:01orders. So this is how the SQL database
  21489. 12:58:03execute very simple select
  21490. 12:58:09query query is a query inside another
  21491. 12:58:13query. So what this means let's have a
  21492. 12:58:16sketch to understand it. So so far what
  21493. 12:58:18we have learned we have different
  21494. 12:58:19database tables like the orders
  21495. 12:58:21customers and so on and we write a
  21496. 12:58:23simple SQL queries like select from
  21497. 12:58:26where. So the SQL going to retrieve data
  21498. 12:58:28from the database tables and in the
  21499. 12:58:30output we will get some kind of results.
  21500. 12:58:32So this is so far what you have done. We
  21501. 12:58:34have done very simple queries. Now in
  21502. 12:58:36our query we can have things little bit
  21503. 12:58:38different. So we could have another
  21504. 12:58:40query that is inside our query where we
  21505. 12:58:42do the same things like select from
  21506. 12:58:44where. So we have now a query inside our
  21507. 12:58:47query and we call this embedded query we
  21508. 12:58:50call it a sub query and the original
  21509. 12:58:52query the first one where we have select
  21510. 12:58:54from we call it main query. So now if
  21511. 12:58:56you execute the whole query what going
  21512. 12:58:58to happen SQL first going to go and
  21513. 12:58:59select the subquery and then it's going
  21514. 12:59:01to execute it. So it's going to go and
  21515. 12:59:03select and retrieve data from our
  21516. 12:59:05database tables and the result of the
  21517. 12:59:07subquery will not be sent to the users
  21518. 12:59:09to us. So we cannot see it. What can
  21519. 12:59:12happen? the result can stay inside the
  21520. 12:59:14query as an intermediate results and
  21521. 12:59:17then now our main query can go and start
  21522. 12:59:20interacting with this intermediate
  21523. 12:59:22result from the subquery. So the main
  21524. 12:59:24query going to do some kind of
  21525. 12:59:25operations on top of this intermediate
  21526. 12:59:27results and use it for filtering or
  21527. 12:59:29joining or any purpose and still the
  21528. 12:59:31main query can go and query the original
  21529. 12:59:34database tables. So now the main query
  21530. 12:59:36has two sources for data. The original
  21531. 12:59:38database tables and as well the result
  21532. 12:59:41from another query. So now by looking to
  21533. 12:59:44this you can see the subquery is a query
  21534. 12:59:46inside the main query and it play a role
  21535. 12:59:49of supporter. So it supports the main
  21536. 12:59:52query with data and the main job of the
  21537. 12:59:55main query is of course to get all those
  21538. 12:59:57data and to show us at the end the final
  21539. 13:00:00results. Now there is now two things
  21540. 13:00:02about this intermediate results that we
  21541. 13:00:04got as a result from the subquery. Once
  21542. 13:00:06the execution of the query is completely
  21543. 13:00:09done, what can happen is going to go and
  21544. 13:00:11destroy this intermediate result. So
  21545. 13:00:13it's going to totally drop it. So we
  21546. 13:00:15will not find it anywhere. It's
  21547. 13:00:17completely lost. Now the other thing
  21548. 13:00:19about the intermediate results is that
  21549. 13:00:21imagine you are making another query
  21550. 13:00:23that is completely outside of the first
  21551. 13:00:25query. We are selecting few tables from
  21552. 13:00:27our database. Now you might say you know
  21553. 13:00:29what is it possible to access the
  21554. 13:00:32intermediate results from the first
  21555. 13:00:34query. So now we are talking about
  21556. 13:00:36completely external query you cannot do
  21557. 13:00:38that. The intermediate result of the
  21558. 13:00:40subquery is only locally known from the
  21559. 13:00:44main query itself and it is not globally
  21560. 13:00:46available for any other query. So the
  21561. 13:00:48subquery can be used only from the main
  21562. 13:00:51query.
  21563. 13:00:55So with that we have understood what are
  21564. 13:00:57subqueries and now you might ask me why
  21565. 13:01:00do we need them in the first place? Why
  21566. 13:01:02sub queries are important? Let's have
  21567. 13:01:04the following sketch. Now in our complex
  21568. 13:01:06task we might have to do several stuffs
  21569. 13:01:08in our query. Like for example the first
  21570. 13:01:10step we have to go and join tables in
  21571. 13:01:12order to prepare the data and then the
  21572. 13:01:14outcome of the joins should be filtered.
  21573. 13:01:16So this going to be our step two. And
  21574. 13:01:18then on top of that in the step three we
  21575. 13:01:20have to go and do transformations like
  21576. 13:01:22maybe handling the nulls or creating new
  21577. 13:01:25columns and many other stuff. And the
  21578. 13:01:27last step we want to go and do data
  21579. 13:01:29aggregations like summarizing the data
  21580. 13:01:31or finding average. Now if you go
  21581. 13:01:32immediately and start writing the SQL
  21582. 13:01:34query without having a plan what can
  21583. 13:01:36happen you're going to end up having a
  21584. 13:01:39long complex SQL query and it's going to
  21585. 13:01:41be really hard to write and as well to
  21586. 13:01:44understand and read. And now what we can
  21587. 13:01:45do instead of that we're going to go and
  21588. 13:01:47divide our task based on those steps. So
  21589. 13:01:50we're going to write one query section
  21590. 13:01:52for each step. For example, for joining
  21591. 13:01:53tables we're going to have one query for
  21592. 13:01:55filtering another one transformation
  21593. 13:01:57another one and for the aggregation
  21594. 13:01:59we're going to have the last query. So
  21595. 13:02:00now since each step is like a
  21596. 13:02:03preparation for the next step we can go
  21597. 13:02:05and say each of those queries is a
  21598. 13:02:07subquery. So for step one, step two,
  21599. 13:02:10step three, we have sub queries and they
  21600. 13:02:13are all doing like calculations and
  21601. 13:02:15preparations for the last step to the
  21602. 13:02:17aggregations and we call the last step
  21603. 13:02:19the main query and of course the whole
  21604. 13:02:21thing can exist in one single query. So
  21605. 13:02:23if you want to visual this like you have
  21606. 13:02:25a subquery in circle and then this
  21607. 13:02:28circle belongs to a bigger circle called
  21608. 13:02:30the main query. By the way, sometimes we
  21609. 13:02:32call the main query as the outer query
  21610. 13:02:35and the subquery we can call it an inner
  21611. 13:02:37query. And of course, we can have many
  21612. 13:02:40subqueries and many small circles inside
  21613. 13:02:42each others to form something called
  21614. 13:02:44nested queries. So this is the main
  21615. 13:02:46purpose of using subqueries in our
  21616. 13:02:49scripts and queries. It's going to help
  21617. 13:02:51us to reduce the complexity and going to
  21618. 13:02:53make it easier to read and we can have
  21619. 13:02:56like a flow logical flow inside our
  21620. 13:02:58queries.
  21621. 13:03:03Now for the sub queries there are many
  21622. 13:03:05different types and categories. So now
  21623. 13:03:07what we're going to do I'm going to show
  21624. 13:03:08you an overview of all those types and
  21625. 13:03:10categories and then later we're going to
  21626. 13:03:12deep dive into each of those types. So
  21627. 13:03:14first of all if you are thinking about
  21628. 13:03:16the dependencies between the subquery
  21629. 13:03:18and the main query. There is mainly two
  21630. 13:03:20types of subqueries. We have the
  21631. 13:03:23non-correlated subquery. That means the
  21632. 13:03:26subquery is independent from the main
  21633. 13:03:28query. And the second type is the
  21634. 13:03:30correlated subquery. It's exactly the
  21635. 13:03:33opposite. The subquery gonna depend on
  21636. 13:03:35the main query. Of course, we can
  21637. 13:03:37explain all those stuff in details.
  21638. 13:03:39Don't worry about it. So, this is the
  21639. 13:03:40first group. Now, there is another group
  21640. 13:03:42on how to group up the subqueries
  21641. 13:03:45depending on the result type. So, I mean
  21642. 13:03:48with this that the subquery has
  21643. 13:03:50different output and results. For
  21644. 13:03:52example, we have scalar subquery. It
  21645. 13:03:54returns only one single value. or
  21646. 13:03:56another type it's called the row
  21647. 13:03:58subquery. It's going to return multiple
  21648. 13:04:01rows and the final type called the table
  21649. 13:04:03subquery. It is a subquery that returns
  21650. 13:04:06multiple rows and as well multiple
  21651. 13:04:08columns. Now we come to the third way
  21652. 13:04:10and the last way on how to categorize
  21653. 13:04:12the subqueries and this time based on
  21654. 13:04:14the location and the clauses. So we are
  21655. 13:04:17describing here where the subquery going
  21656. 13:04:19to be used within the main query. So we
  21657. 13:04:22can use it in different locations and
  21658. 13:04:24clauses like the select clause or we can
  21659. 13:04:27use it in the from clause and this is
  21660. 13:04:29the most common type for the subqueries
  21661. 13:04:31or we can use it before joining tables
  21662. 13:04:33and we can use it in order to filter the
  21663. 13:04:35data in the work clause and in the work
  21664. 13:04:38clause as we learned there are two
  21665. 13:04:39different sets of operators. We can use
  21666. 13:04:42the subgrade together with the
  21667. 13:04:43comparison operators the less, greater,
  21668. 13:04:46equal and so on. Or we can use it with
  21669. 13:04:48the logical operators like the in, any,
  21670. 13:04:52all and exists. So now those are the
  21671. 13:04:55different types and categories for the
  21672. 13:04:57subqueries and we're going to now deep
  21673. 13:04:59dive into all of them. So now let's go
  21674. 13:05:01and start with the easiest category, the
  21675. 13:05:03result types of the subqueries.
  21676. 13:05:10Now we have different types of
  21677. 13:05:11subqueries based on the results. So this
  21678. 13:05:14means the amount of data that the
  21679. 13:05:16subquery going to return. So the first
  21680. 13:05:18type is the scalar subquery. So it is a
  21681. 13:05:21subquery that it's going to return only
  21682. 13:05:24one single value like for example the
  21683. 13:05:26value three. Let's have an example for
  21684. 13:05:28the scalar subquery. So in this query
  21685. 13:05:30for example if you are saying select
  21686. 13:05:32star you will get all columns all the
  21687. 13:05:34rows from one table. But for the scalar
  21688. 13:05:36subquery we need only one value. So how
  21689. 13:05:39we usually get it is by doing some
  21690. 13:05:41aggregations. For example, if you go and
  21691. 13:05:43say let's get the average of sales. So
  21692. 13:05:46let's execute it. And with that in the
  21693. 13:05:49output we have only one value with a 38.
  21694. 13:05:51We call such a query as a scalar query.
  21695. 13:05:54So it has only one row and only one
  21696. 13:05:57column. So this is a scalar query. All
  21697. 13:05:59right. So now to the second type we have
  21698. 13:06:02the row subquery. So it is a subquery
  21699. 13:06:05that going to return multiple rows and a
  21700. 13:06:08single column. So we're going to have
  21701. 13:06:09like values 1 2 3. So it is only one
  21702. 13:06:12column with multiple rows. Let's have an
  21703. 13:06:14example for the row query. As you can
  21704. 13:06:16see now we are saying select star from
  21705. 13:06:18the table orders and now we are getting
  21706. 13:06:21multiple rows and multiple columns. But
  21707. 13:06:24for the row queries we need only one
  21708. 13:06:26column. So you can go over here for
  21709. 13:06:27example say customer ID. And if you go
  21710. 13:06:31and execute it. So now if you check the
  21711. 13:06:32output we have a single column and as
  21712. 13:06:35well multiple rows. So we have like a
  21713. 13:06:37list of values and this is what we call
  21714. 13:06:40row query. All right. So now to the last
  21715. 13:06:42type we have the table sub query. It's
  21716. 13:06:45going to go and return multiple rows and
  21717. 13:06:48as well multiple columns like any
  21718. 13:06:50regular tables. So this subquery going
  21719. 13:06:52to return a lot of values. Okay. So
  21720. 13:06:54let's see an example of that table
  21721. 13:06:56query. So if you check our example here,
  21722. 13:06:58select star from orders, we got here
  21723. 13:07:01multiple rows and as well multiple
  21724. 13:07:04columns and of course we can go and
  21725. 13:07:06select multiple columns like for example
  21726. 13:07:08the order ID and the order dates. So if
  21727. 13:07:12we execute it here in the output we have
  21728. 13:07:15multiple columns we have two columns and
  21729. 13:07:17as well multiple rows that's why this
  21730. 13:07:19kind of query is as well a table query.
  21731. 13:07:22All right. So with that we have learned
  21732. 13:07:23the different types of subqueries based
  21733. 13:07:25on the result type. Now we're going to
  21734. 13:07:27go and learn how to use the subqueries
  21735. 13:07:30in different locations in our query. So
  21736. 13:07:32we're going to start with how to use
  21737. 13:07:34subquery in the from
  21738. 13:07:36[Music]
  21739. 13:07:39clause. Okay. So we typically use the
  21740. 13:07:42subqueries in the from clause in order
  21741. 13:07:45to create temporary result sets that act
  21742. 13:07:48as a table for the main query. So it's
  21743. 13:07:51like in some scenarios we cannot use the
  21744. 13:07:54tables directly from the database. We
  21745. 13:07:56have to prepare it somehow before we do
  21746. 13:07:59our actual query. Okay. So let's check
  21747. 13:08:01the syntax of the sub query inside the
  21748. 13:08:03from clause. So we start with the usual
  21749. 13:08:05stuff where we go and say select and few
  21750. 13:08:08columns that we want to retrieve and
  21751. 13:08:10then we say okay from usually after the
  21752. 13:08:12from comes the table name from our
  21753. 13:08:14database that we want to query. But this
  21754. 13:08:17time instead of writing the table name,
  21755. 13:08:19we're going to have another SQL query.
  21756. 13:08:22So that means we don't define the table
  21757. 13:08:24name, we define another select
  21758. 13:08:26statements where we have as well again
  21759. 13:08:28select a column from specific table and
  21760. 13:08:31then maybe we have a filter. And in
  21761. 13:08:33order now to tell SQL this is a
  21762. 13:08:35subquery, we have to use the
  21763. 13:08:37parenthesis. So we're going to have the
  21764. 13:08:38parenthesis at the start and at the end.
  21765. 13:08:41This is a subquery. This is not the main
  21766. 13:08:43query. And after the parenthesis, we can
  21767. 13:08:45go and define the alias for the results
  21768. 13:08:48that we're going to get from this
  21769. 13:08:49subquery. In many databases, this alias
  21770. 13:08:52is an optional, but for the SQL server,
  21771. 13:08:54we have to go and specify an alias. So,
  21772. 13:08:57it is a must in SQL server. So, again,
  21773. 13:08:59we call this a subquery and the outer
  21774. 13:09:03query we call it a main query. So, this
  21775. 13:09:05is the syntax of the subquery in the
  21776. 13:09:07from clause. Okay. Okay, so now we have
  21777. 13:09:09the following task and it says find the
  21778. 13:09:11products that have a price higher than
  21779. 13:09:14the average price of all products. So
  21780. 13:09:16we're going to do it step by step and
  21781. 13:09:18here we have two steps. The first one is
  21782. 13:09:20that we have to go and calculate the
  21783. 13:09:22average price of all products and the
  21784. 13:09:24second step we're going to use this
  21785. 13:09:25value in order to filter the table
  21786. 13:09:28products in order to find the prices
  21787. 13:09:30that is higher than this average price.
  21788. 13:09:33So let's start with the first step where
  21789. 13:09:34we're going to find the average price.
  21790. 13:09:36I'm going to select the following
  21791. 13:09:38informations. So product ID,
  21792. 13:09:42price from the table sales products. So
  21793. 13:09:47let's go and execute it. So now we have
  21794. 13:09:49the product and as well the prices and
  21795. 13:09:51we need this price here in order to
  21796. 13:09:53compare it with the average price. So
  21797. 13:09:56that means we need this price and as
  21798. 13:09:58well side by side we need the average
  21799. 13:10:00price. So that means we need
  21800. 13:10:02aggregations and details and that's why
  21801. 13:10:04we're going to go with the window
  21802. 13:10:05function average. So let's go and do
  21803. 13:10:07this. This is very simple. So it's going
  21804. 13:10:09to be the average
  21805. 13:10:11price and we don't want to partition the
  21806. 13:10:14data. So it's going to be an over empty
  21807. 13:10:16and this going to be the average price
  21808. 13:10:19like this. So let's go and execute it.
  21809. 13:10:21And with that we have calculated the
  21810. 13:10:23average price. So now we have all the
  21811. 13:10:24informations in the first step. We have
  21812. 13:10:26the average price, we have the price and
  21813. 13:10:28as well the products. So now the next
  21814. 13:10:30step is that we have to go and filter
  21815. 13:10:32the data to find out all the products
  21816. 13:10:35where the price is higher than the
  21817. 13:10:37average. That means we will do this step
  21818. 13:10:40based on those information that we have
  21819. 13:10:42now. So that means we have to go and use
  21820. 13:10:44the logic of subquery and main query.
  21821. 13:10:47Since this is the first step to prepare
  21822. 13:10:49the data, we're going to use this as a
  21823. 13:10:52subquery. So we're going to call this a
  21824. 13:10:54sub query like this. And we have to go
  21825. 13:10:58and use it in the main query. So how we
  21826. 13:11:01going to do that? We have to go and
  21827. 13:11:02write the main query. So it's going to
  21828. 13:11:04be I'm going to start over here. Select
  21829. 13:11:07and then I will take all the columns
  21830. 13:11:10from. So this is the main query. Let me
  21831. 13:11:14just make this a little bit smaller. And
  21832. 13:11:17what we're going to do now so now the
  21833. 13:11:18main query going to get the data from
  21834. 13:11:20the sub query. So the whole thing going
  21835. 13:11:23to be used inside the from close. So now
  21836. 13:11:26in order to put the subquery inside the
  21837. 13:11:28main query we have to go and use the
  21838. 13:11:30parenthesis. So we're going to have it
  21839. 13:11:32at the start and as well at the end and
  21840. 13:11:34what we usually do we go and add like a
  21841. 13:11:37tab in order to understand okay this is
  21842. 13:11:40the subquery and then this is the main
  21843. 13:11:42query. So now one more thing that we
  21844. 13:11:44have to add for the whole subquery in
  21845. 13:11:46the SQL server that we have to give it
  21846. 13:11:48an alias. So you can go and give it any
  21847. 13:11:50name that you would like. I usually go
  21848. 13:11:52with only one character with the T. It
  21849. 13:11:55stands for table. So you can use
  21850. 13:11:56anything that you want. But we have in
  21851. 13:11:57SQL Server to give an alias for the
  21852. 13:12:00subquery. So now what we are saying, we
  21853. 13:12:02are saying select everything from the
  21854. 13:12:04subquery. If you go over here and
  21855. 13:12:06execute it, you will get the exact same
  21856. 13:12:09results because the main query is doing
  21857. 13:12:11nothing. It's saying just select
  21858. 13:12:12everything from the subquery. But now in
  21859. 13:12:15order to solve the task, we are not
  21860. 13:12:16interested with all products. We are
  21861. 13:12:18interested only the products where the
  21862. 13:12:19price is higher than the average. That's
  21863. 13:12:22why we have to go and use the where
  21864. 13:12:24clause. So we're going to say where the
  21865. 13:12:27price is higher than the average price.
  21866. 13:12:32So this filtering is done in the main
  21867. 13:12:34query. It's not inside the subquery. So
  21868. 13:12:37now that means in the main query we are
  21869. 13:12:39doing something. Let's go and execute
  21870. 13:12:41it. And with that we saw the task. We
  21871. 13:12:43are getting now two products where the
  21872. 13:12:45price is higher than the average price.
  21873. 13:12:47So as you can see it's very simple. If
  21874. 13:12:49the task has multiple steps then we can
  21875. 13:12:51do that using multiple sub queries until
  21876. 13:12:54we have the main query and we can learn
  21877. 13:12:56from this that the subquery is here is
  21878. 13:12:58only to support the main query. So we
  21879. 13:13:01are preparing here that all the data
  21880. 13:13:03that we need in order to have the final
  21881. 13:13:05result for the main query. So for this
  21882. 13:13:07task we cannot go immediately
  21883. 13:13:09calculating the results we have first.
  21884. 13:13:12So for this kind of task we cannot
  21885. 13:13:13immediately like put everything in one
  21886. 13:13:15select query. We have first to prepare
  21887. 13:13:18the data in one subquery and then pass
  21888. 13:13:20the values for the main query. And this
  21889. 13:13:23is what we mean with the table subquery.
  21890. 13:13:26And here one quick tip for you. If you
  21891. 13:13:27would like to see the intermediate
  21892. 13:13:29results that we are getting from the
  21893. 13:13:31subquery, you can go and highlight the
  21894. 13:13:33subquery itself without the parenthesis.
  21895. 13:13:36So we are just highlighting the
  21896. 13:13:38subquery. You can go now and execute it.
  21897. 13:13:41And with that SQL will not go and
  21898. 13:13:43execute everything. SQL going to execute
  21899. 13:13:45only what you are highlighting. So this
  21900. 13:13:47is really nice way in order to see the
  21901. 13:13:49results of the subquery as you are like
  21902. 13:13:52debugging or searching for errors. You
  21903. 13:13:54can go and see the intermediate results
  21904. 13:13:56that is used from the main query. And of
  21905. 13:13:58course if you deselect and not highlight
  21906. 13:14:00anything and execute SQL going to go and
  21907. 13:14:03execute everything the whole query. So
  21908. 13:14:05this is how we use the table sub query
  21909. 13:14:08inside the from close. All right. Right.
  21910. 13:14:10So let's have another task and it says
  21911. 13:14:12rank the customers based on their total
  21912. 13:14:15amount of sales. So again if you check
  21913. 13:14:17here we have like two steps. First we
  21914. 13:14:20have to find the total amount of sales
  21915. 13:14:22and then after that we have to go and
  21916. 13:14:25rank the customers. So again we have
  21917. 13:14:27like two steps and we can use the
  21918. 13:14:29subqueries in order to solve it. So
  21919. 13:14:31let's start with the first step where
  21920. 13:14:32we're going to find the total amount of
  21921. 13:14:34sales. So let's go and select the
  21922. 13:14:36customer ID and as well the
  21923. 13:14:39sales from the table sales
  21924. 13:14:44orders. Let's go and execute it. So now
  21925. 13:14:47in the output we have like multiple
  21926. 13:14:48customers and their sales. We have to go
  21927. 13:14:50and now find the total amount of sales
  21928. 13:14:53for each customer. That means we have to
  21929. 13:14:55go and use the group by. So we're going
  21930. 13:14:57to go and summarize the
  21931. 13:15:00sales. So total sales and then group up
  21932. 13:15:05the data by the customer ID. So like
  21933. 13:15:08this. Let's go and execute it. Now as
  21934. 13:15:11you can see in the output we have four
  21935. 13:15:12customers and we have the total sales
  21936. 13:15:14for each customer. And with that we have
  21937. 13:15:16solved the first step. We have the total
  21938. 13:15:18amount of sales for each customer and we
  21939. 13:15:20have now prepared the data for the next
  21940. 13:15:23query in order to rank the customers. So
  21941. 13:15:26now I think you already getting how
  21942. 13:15:28important are the subqueries in order to
  21943. 13:15:30do stepby-step analyszis. So this is our
  21944. 13:15:33subquery. Now we need the main query. So
  21945. 13:15:37I will start preparing it. So main query
  21946. 13:15:39like this. And let's go first and select
  21947. 13:15:42everything. So select star from let me
  21948. 13:15:46just make this a little bit bigger like
  21949. 13:15:48this. And now we have to go and convert
  21950. 13:15:50this query to a subquery. So we need the
  21951. 13:15:52parenthesis. So the starting and the
  21952. 13:15:55ending and for the SQL server I'm going
  21953. 13:15:57to give it an alias and I would like to
  21954. 13:15:59push everything to the right side. So
  21955. 13:16:02let's go and execute it. Perfect. So it
  21956. 13:16:04is working with that the subquery is
  21957. 13:16:07passing the data in the from clause to
  21958. 13:16:09the main query. Now of course the main
  21959. 13:16:11query is now is useless. It's just like
  21960. 13:16:13selecting the data. We have to go and
  21961. 13:16:15calculate the rank and for that we have
  21962. 13:16:17a very nice window function. So we're
  21963. 13:16:20going to go and use the rank. So it
  21964. 13:16:22doesn't need any parameters over we have
  21965. 13:16:25to sort the data order by. So we have to
  21966. 13:16:28go and sort the data by the total sales
  21967. 13:16:30descending from the highest to the
  21968. 13:16:32lowest. So we're going to go with the
  21969. 13:16:34total sales and descending. So now as
  21970. 13:16:37you can see we are using the total sales
  21971. 13:16:39that we have already prepared in the
  21972. 13:16:41subquery. So without preparing first the
  21973. 13:16:43data we will not be able to rank the
  21974. 13:16:46customers in the main query. So that's
  21975. 13:16:48it. Let's go and execute it. And with
  21976. 13:16:50that SQL sorted our data and we have a
  21977. 13:16:52nice ranking based on the data that we
  21978. 13:16:55had from the subquery. So this is the
  21979. 13:16:58highest customer with the sales and then
  21980. 13:17:00the customer number one and so on. So
  21981. 13:17:02again in this task we have like multiple
  21982. 13:17:04steps and we use the power of the
  21983. 13:17:06subqueries in order to do it step by
  21984. 13:17:08step. So that's all on how to use the
  21985. 13:17:10subquery inside the from close. Okay. So
  21986. 13:17:13now let's see quickly how SQL executed
  21987. 13:17:15our query. So we have here our query and
  21988. 13:17:17we are quering the table orders. So the
  21989. 13:17:19first step is that SQL going to go and
  21990. 13:17:21identify the subquery and then it going
  21991. 13:17:24to go and execute it. So SQL going to go
  21992. 13:17:26and execute the subquery part where we
  21993. 13:17:28are aggregating the data based on the
  21994. 13:17:30customer ID. So once the subquery is
  21995. 13:17:32executed the next step is that the
  21996. 13:17:35result going to be introduced as an
  21997. 13:17:37intermediate results. So these results
  21998. 13:17:39we will not see it in the output. It's
  21999. 13:17:41going to be like temporarily saved in
  22000. 13:17:43the memory. So now the next step is that
  22001. 13:17:46SQL going to go to the main query and
  22002. 13:17:48it's going to execute it based on the
  22003. 13:17:50intermediate results. So that means the
  22004. 13:17:52main query will not go back to the
  22005. 13:17:54original table. It's going to go and
  22006. 13:17:56query the intermediate results. So here
  22007. 13:17:58what SQL going to do going to go and
  22008. 13:18:00rank the intermediate results by
  22009. 13:18:02introducing a new column where we see
  22010. 13:18:04the ranks 1 2 3 4 and the output of the
  22011. 13:18:06main query going to be the final
  22012. 13:18:08results. So as you can see it's very
  22013. 13:18:09simple. First SQL is executing the
  22014. 13:18:11subquery and the result of the subquery
  22015. 13:18:14going to be used in the main query and
  22016. 13:18:16once the main query is executed we will
  22017. 13:18:19get the final results. So the subquery
  22018. 13:18:21here is only supporting the main query.
  22019. 13:18:24So those are the steps that SQL uses in
  22020. 13:18:26order to execute the
  22021. 13:18:32subqueries. So now let's understand how
  22022. 13:18:34the database server execute the
  22023. 13:18:36subqueries behind the scenes. Let's go.
  22024. 13:18:39So now let's say that you are data
  22025. 13:18:40analyst and you are writing a query at
  22026. 13:18:42the client side where you have a
  22027. 13:18:44subquery inside the main query. So once
  22028. 13:18:46you go and execute it what's going to
  22029. 13:18:48happen the database engine going to go
  22030. 13:18:50and identify the subquery and in this
  22031. 13:18:53situation the database going to execute
  22032. 13:18:55first the subquery. So here subquery is
  22033. 13:18:57like selecting and retrieving data from
  22034. 13:18:59the table orders. So that means the
  22035. 13:19:01database has to retrieve the data from
  22036. 13:19:04the disk storage from the user data. So
  22037. 13:19:07now once the subquery is executed the
  22038. 13:19:09result the intermediate results going to
  22039. 13:19:11be stored in the cache. So this means
  22040. 13:19:14the result of the subquery is temporary
  22041. 13:19:16and as well very fast to retrieve. And
  22042. 13:19:19now once the database engine is done
  22043. 13:19:21with the subquery it going to go and
  22044. 13:19:23start executing the main query. So let's
  22045. 13:19:25see in this scenario it's completely
  22046. 13:19:27depending on the result of the subquery.
  22047. 13:19:29So that means the main query going to go
  22048. 13:19:31and interact with the cache storage. So
  22049. 13:19:34this means now the data going to be
  22050. 13:19:35retrieved very fast from the result of
  22051. 13:19:37the subquery. Once it's done, it's going
  22052. 13:19:39to forward the result to the database
  22053. 13:19:41engine and the database engine going to
  22054. 13:19:43forward the results to the client side.
  22055. 13:19:45And at your side, you will find the
  22056. 13:19:47final result. And of course, once
  22057. 13:19:49everything is executed, the database
  22058. 13:19:51engine going to go and clean up the
  22059. 13:19:53cache. So the subquery results going to
  22060. 13:19:55be destroyed and removed completely from
  22061. 13:19:57the cache in order to have a free space
  22062. 13:19:59for other queries. So this is how the
  22063. 13:20:01database server execute the subqueries
  22064. 13:20:04behind the
  22065. 13:20:08scenes. All right. So now we're going to
  22066. 13:20:10talk about how to use the subquery in
  22067. 13:20:12the select clause. So now we typically
  22068. 13:20:14use the subqueries in the select clause
  22069. 13:20:17to aggregate the data side by side with
  22070. 13:20:19the columns of the main query. Okay. So
  22071. 13:20:22let's check the syntax of the subquery
  22072. 13:20:24in the select clause. So we start with
  22073. 13:20:26the simple stuff where we say okay let's
  22074. 13:20:28go and select a column that we want to
  22075. 13:20:30retrieve from specific table. So nothing
  22076. 13:20:33new we are just quering a table. And now
  22077. 13:20:35what we can do in this query is that not
  22078. 13:20:37only we can go and select the columns
  22079. 13:20:39from specific table we can go and insert
  22080. 13:20:42here inside the select another query
  22081. 13:20:45like a full query like select from and
  22082. 13:20:48where. So again it's like query inside
  22083. 13:20:50another query and we call this of course
  22084. 13:20:52a subquery. In order to tell SQL this is
  22085. 13:20:55a subquery we go and add the
  22086. 13:20:57parenthesis. So with SQL going to
  22087. 13:20:59understand huh this is a subquery and
  22088. 13:21:01the result of this query going to be
  22089. 13:21:03used in the select. So we can handle it
  22090. 13:21:06like any other column. We can go and
  22091. 13:21:07give it like an alias. It is here
  22092. 13:21:09optional and not m to add an alias. So
  22093. 13:21:12this inner query we call it a subquery
  22094. 13:21:14and the outer query going to be the main
  22095. 13:21:16query. So this is how you put a subquery
  22096. 13:21:18in the select clause. But there is one
  22097. 13:21:21rule for this query that the result of
  22098. 13:21:24this subquery must be a scalar query.
  22099. 13:21:27That means the result must be a single
  22100. 13:21:29value because otherwise it will not
  22101. 13:21:31work. SQL here is expecting only one
  22102. 13:21:34value. So this is how we use the
  22103. 13:21:36subquery inside the select clause. All
  22104. 13:21:38right, let's have the following task and
  22105. 13:21:39it says show the product ids, product
  22106. 13:21:42names, prices and the total number of
  22107. 13:21:45orders. So now if we check the task
  22108. 13:21:47there is like two parts. The first part
  22109. 13:21:49is that we are showing the details about
  22110. 13:21:51the products and the second part that we
  22111. 13:21:53have to go and calculate the total
  22112. 13:21:55number of orders. So let's see what
  22113. 13:21:56we're going to do. First let's go and
  22114. 13:21:58solve this simple part here where we
  22115. 13:22:00have the product ID, product names and
  22116. 13:22:02prices. So we're going to go and select
  22117. 13:22:05the product ID and the product and then
  22118. 13:22:08the price from the table sales products.
  22119. 13:22:13Let's go and execute it. So with that we
  22120. 13:22:15have solved the first part of the task.
  22121. 13:22:17We have the details about the products.
  22122. 13:22:20Now we go and solve the second part. We
  22123. 13:22:22have to go and calculate the total
  22124. 13:22:23number of orders. Now this information
  22125. 13:22:25come from different table from the
  22126. 13:22:27products. We cannot calculate it from
  22127. 13:22:29products. We have to go and query the
  22128. 13:22:30orders. So now what am I going to do?
  22129. 13:22:32I'm going to go and calculate this part
  22130. 13:22:34in separate query. Instead of having it
  22131. 13:22:37here inside the products. So let's have
  22132. 13:22:39a semicolon in order to have a second
  22133. 13:22:42query. So we're going to go and select
  22134. 13:22:44the total number of orders. That means
  22135. 13:22:46we can go simply do account star from
  22136. 13:22:49the table sales orders. Let me just make
  22137. 13:22:53it a little bit bigger. So we're going
  22138. 13:22:55to call it total orders and a semicolon
  22139. 13:22:59as well. So now if you just execute the
  22140. 13:23:01whole thing, you will get here like two
  22141. 13:23:03parts in the results. First you have the
  22142. 13:23:05details of the products and the second
  22143. 13:23:07part we have now the total number of
  22144. 13:23:09orders. We have 10 orders. But now with
  22145. 13:23:12that we have like two different queries
  22146. 13:23:14like separated from each others and we
  22147. 13:23:16have two different results. But in the
  22148. 13:23:18task we have to show all those
  22149. 13:23:19informations in one result. So now what
  22150. 13:23:22we can do we can put one query inside
  22151. 13:23:24another query. So now if you check the
  22152. 13:23:26second query the total orders you can
  22153. 13:23:28see we have only single value. So we
  22154. 13:23:31have a scalar query scalar subquery.
  22155. 13:23:34That's why we can go with this as a
  22156. 13:23:36[Music]
  22157. 13:23:37subquery like this. And I'm going to go
  22158. 13:23:40and put everything in one line in order
  22159. 13:23:42to see it. So let's remove the
  22160. 13:23:44semicolons. We don't need it. And now
  22161. 13:23:46what we're going to do, we're going to
  22162. 13:23:47go and take the whole thing and put it
  22163. 13:23:50inside the main query. So this is the
  22164. 13:23:54main query. And now think about it as
  22165. 13:23:57new column. So I will put the query
  22166. 13:24:00here. So it is just one new column in
  22167. 13:24:02our select. But in order to have it as a
  22168. 13:24:05subquery, we have to use the parenthesis
  22169. 13:24:08at the start and at the end. And of
  22170. 13:24:10course, we have to go and give it a
  22171. 13:24:11name. So I'm going to go and use the
  22172. 13:24:13same name over here. So it's going to be
  22173. 13:24:16as total orders. So with that, the setup
  22174. 13:24:19for the subquery is ready and it is
  22175. 13:24:21inside the select clause in the main
  22176. 13:24:25query. Let's go and execute it. Now, as
  22177. 13:24:27you can see, we have everything
  22178. 13:24:28together. We have the three informations
  22179. 13:24:30the product details and as well side by
  22180. 13:24:33side with the total orders and since it
  22181. 13:24:35is always the same value it going to go
  22182. 13:24:37and be repeated for each row. So this is
  22183. 13:24:39what we call scalar sub query inside the
  22184. 13:24:42select clause and here again very
  22185. 13:24:44important to understand if you are using
  22186. 13:24:46a subquery inside the select clause only
  22187. 13:24:50the scalar subquery is allowed. So for
  22188. 13:24:53example instead of having one value from
  22189. 13:24:54the aggregation we can go and use the
  22190. 13:24:57order ID. So let's see what going to
  22191. 13:25:00happen. We will get an error. It going
  22192. 13:25:02to says subquery is returning more than
  22193. 13:25:04one value and this is not allowed
  22194. 13:25:06because we are using the subquery in the
  22195. 13:25:08select clause. So that's why we have to
  22196. 13:25:11have only one value and by using the
  22197. 13:25:13aggregation you will get one value. So
  22198. 13:25:15let's repair it. And it's working. And
  22199. 13:25:17now again if you would like only to see
  22200. 13:25:19the results from the subquery what you
  22201. 13:25:21can do you can go and highlight the
  22202. 13:25:23subquery like this without the
  22203. 13:25:25parenthesis of course and you go and
  22204. 13:25:27execute it and with that you can see in
  22205. 13:25:29the output the 10 this is the
  22206. 13:25:31intermediate results that's going to be
  22207. 13:25:33passed to the main query and if you want
  22208. 13:25:35the whole thing to be executed just like
  22209. 13:25:38unmark it and execute and with that
  22210. 13:25:40everything can be executed the subquery
  22211. 13:25:42and the main query. So this is the
  22212. 13:25:43scalar subquery in the select clause.
  22213. 13:25:46Okay, so now let's see quickly how SQL
  22214. 13:25:48executed this query step by step. So
  22215. 13:25:50this is our original query and we need
  22216. 13:25:52two tables from our database for it. So
  22217. 13:25:54the first step is that SQL going to go
  22218. 13:25:56and identify the subquery and it's going
  22219. 13:25:59to go and execute it. So this is the
  22220. 13:26:01first step. So the query is targeting
  22221. 13:26:03the orders table and we are just simply
  22222. 13:26:05doing a count. So in the output we will
  22223. 13:26:08get an intermediate results where we are
  22224. 13:26:10counting the number of rows of the
  22225. 13:26:12orders. Now the next step is that SQ is
  22226. 13:26:14going to go and pass this value to the
  22227. 13:26:17main query. So this is the second step
  22228. 13:26:19and if you go and pass this value to the
  22229. 13:26:21main query, it's going to look like
  22230. 13:26:23this. So you are saying product ID,
  22231. 13:26:25products and the tin. So after SQL
  22232. 13:26:27prepared the main query, SQL going to go
  22233. 13:26:30and execute it. So this time we are
  22234. 13:26:32targeting the products and in the output
  22235. 13:26:34we will get all the informations from
  22236. 13:26:36the products without any filter because
  22237. 13:26:37here we don't have any work clouds and
  22238. 13:26:39the final results we will get it like
  22239. 13:26:42this. So we will have the product ID,
  22240. 13:26:43the product and the total that we got it
  22241. 13:26:46from the subquery. So as you can see
  22242. 13:26:47here the subquery here is a scalar
  22243. 13:26:49subquery where we have only one single
  22244. 13:26:52value. So again it's very simple always
  22245. 13:26:54SQL starts with the subquery and then
  22246. 13:26:57it's going to go and pass the values to
  22247. 13:26:59the main query and at the end the main
  22248. 13:27:01query going to be executed and we will
  22249. 13:27:03get the final result from it. So this is
  22250. 13:27:05how SQL executed our query.
  22251. 13:27:12All right, next we're going to talk
  22252. 13:27:13about how to use the subquery in the
  22253. 13:27:16join clause. All right, so now as we are
  22254. 13:27:18joining tables in SQL, sometimes we have
  22255. 13:27:20to go and prepare the data before doing
  22256. 13:27:23the join to dynamically create a result
  22257. 13:27:25sets for joining with another table. So
  22258. 13:27:28again here we cannot join tables
  22259. 13:27:30directly. We have to do a preparation
  22260. 13:27:32step before doing the joins. Okay, let's
  22261. 13:27:34have the following task and it says show
  22262. 13:27:37all customer details and find the total
  22263. 13:27:40orders of each customer. Now, of course,
  22264. 13:27:42in SQL, you don't have only one
  22265. 13:27:43solution, you have multiple solutions.
  22266. 13:27:45But I would like to solve this task
  22267. 13:27:47using the subquery. So, now if you check
  22268. 13:27:49the task, we have like two parts. The
  22269. 13:27:51first part we have to show all the
  22270. 13:27:53customer details. And the second part,
  22271. 13:27:54we have like here an aggregation find
  22272. 13:27:57the total orders of each customer. So,
  22273. 13:27:59now let's solve those different parts
  22274. 13:28:01using two different queries. Let's start
  22275. 13:28:03with the easiest one. Show all customer
  22276. 13:28:05details. So I think this is very simple.
  22277. 13:28:07So select star from sales customers. So
  22278. 13:28:13let's go and execute it. So in the
  22279. 13:28:15output we have all the details about the
  22280. 13:28:16customers and we have solved the first
  22281. 13:28:18part. Very simple. Now let's go and
  22282. 13:28:20solve the second part. We have defined
  22283. 13:28:23the total number of orders of each
  22284. 13:28:25customer. That means let me just have a
  22285. 13:28:28semicolon over here. We have to go to
  22286. 13:28:30the table orders. So let's go and select
  22287. 13:28:33first the order ID, customer
  22288. 13:28:36ID from the table sales orders like
  22289. 13:28:40this. So I will just highlight the
  22290. 13:28:42second query and execute it. Now in the
  22291. 13:28:44output we have 10 orders and we have the
  22292. 13:28:46different customers. Now in order to
  22293. 13:28:48find the total orders for each customer
  22294. 13:28:49we have to go and use the group pie. In
  22295. 13:28:51order to do that it's very simple. We're
  22296. 13:28:54going to go over here and say so count
  22297. 13:28:57let's go with the star and then we're
  22298. 13:28:59going to go and group up the data by the
  22299. 13:29:01customer ID. I will go and call this
  22300. 13:29:04total orders. So let's go and execute
  22301. 13:29:08only these parts and with that we have
  22302. 13:29:10four customers and we have the total
  22303. 13:29:12number of orders. So with that we have
  22304. 13:29:14solved the second part of the task. So
  22305. 13:29:17now what I'm going to do, I'm going to
  22306. 13:29:18go and execute both of those queries
  22307. 13:29:20using the semicolon separately like
  22308. 13:29:23this. I will just make this a little bit
  22309. 13:29:25bigger. So let's go and execute it. Now
  22310. 13:29:27in the output we have the two results,
  22311. 13:29:29all details about the customers and the
  22312. 13:29:32total number of orders for each
  22313. 13:29:34customer. So now what we want to do is
  22314. 13:29:35to go and combine those two results in
  22315. 13:29:38one. And in order to do that we can use
  22316. 13:29:41the joins. So now we have to think about
  22317. 13:29:43what is the first query, what is the
  22318. 13:29:45second query. Since the first query
  22319. 13:29:47returns all the customers that we have
  22320. 13:29:49in the database, I would like to have
  22321. 13:29:51this as the left table and since in the
  22322. 13:29:54second query we have only four
  22323. 13:29:55customers, I would like to have it then
  22324. 13:29:57as the right table and I will go with
  22325. 13:30:00the left join so that I don't miss any
  22326. 13:30:03customer because if I do the inner join,
  22327. 13:30:05I will lose the customer number five. So
  22328. 13:30:07let's go and do that. So this is the
  22329. 13:30:09first query in the main query. So I'm
  22330. 13:30:11going to call this main query.
  22331. 13:30:15And now I'm going to give this as well
  22332. 13:30:17an alias like the C. And now we're going
  22333. 13:30:19to go and join this table from the
  22334. 13:30:22database together with the results the
  22335. 13:30:24output of this query. So that means
  22336. 13:30:27we're going to do it like this. Left
  22337. 13:30:29join and now we're going to join with a
  22338. 13:30:32sub query. So we will have our
  22339. 13:30:34parenthesis. I will just put here few
  22340. 13:30:36spaces so that it's clear it is a
  22341. 13:30:39subquery and we need for this an alias.
  22342. 13:30:41So let's go and say for example the O.
  22343. 13:30:44So with that we are joining a table with
  22344. 13:30:46the result of a sub query. And now of
  22345. 13:30:49course what is missing is joining the
  22346. 13:30:51tables using a key. Now if you check the
  22347. 13:30:53two results you can see in both queries
  22348. 13:30:55we have the customer ID. That's why
  22349. 13:30:58we're going to join with the customer
  22350. 13:31:00ID. So on then the customer
  22351. 13:31:04ID with the customer ID from the sub
  22352. 13:31:08query like this. So we have everything
  22353. 13:31:12and let's go and execute it. Now as you
  22354. 13:31:14can see in the output we have all the
  22355. 13:31:16details about the customer and as well
  22356. 13:31:18together with the total number of orders
  22357. 13:31:21for each customer together with the
  22358. 13:31:23total number of orders for each customer
  22359. 13:31:25and as you can see we didn't miss any
  22360. 13:31:27customer. So we have all the customers
  22361. 13:31:29from the database and we can see that
  22362. 13:31:31Anna doesn't have any orders. Now you
  22363. 13:31:34might say you know what we have here the
  22364. 13:31:35customer ID twice. So what I'm going to
  22365. 13:31:37do I will select all the columns from
  22366. 13:31:40the customers but from the subquery I'm
  22367. 13:31:43interested only on the total orders. So
  22368. 13:31:47like this let's go and execute it. Let's
  22369. 13:31:49make this a little bit smaller. So now
  22370. 13:31:51the results are really clean. We have
  22371. 13:31:53all details from the customers and as
  22372. 13:31:55well the total orders of each customer.
  22373. 13:31:58And of course as we learned if you would
  22374. 13:31:59like to check the results from only the
  22375. 13:32:01subquery you go and highlight it and
  22376. 13:32:03execute it. So as you can see you can
  22377. 13:32:05put the subqueries almost everywhere and
  22378. 13:32:07this is how we use subqueries inside
  22379. 13:32:13joins. Okay. So now we're going to focus
  22380. 13:32:15on how to use the subquery in the wear
  22381. 13:32:18clause. So now in this scale as we
  22382. 13:32:20learned we can go and filter the tables
  22383. 13:32:22using the wear clause by using like
  22384. 13:32:24static values. But now in real data
  22385. 13:32:27projects we're going to go and filter
  22386. 13:32:28the data based on like complex logic. So
  22387. 13:32:31now in order to prepare this complex
  22388. 13:32:33logic we go and use the sub queries in
  22389. 13:32:36order to make like dynamic filtering for
  22390. 13:32:39our main tables. And now in order to
  22391. 13:32:41filter data using the wear clause we
  22392. 13:32:43have to go and use operators and we can
  22393. 13:32:45split it into like two groups. We have
  22394. 13:32:47the comparison operators and another
  22395. 13:32:49sets we can call it logical operators or
  22396. 13:32:52sometime we call it subqueries
  22397. 13:32:53operators. So now first we're going to
  22398. 13:32:55talk about the comparison operators. So
  22399. 13:32:57there are operators that we can use in
  22400. 13:32:59order to compare two values in order to
  22401. 13:33:01help us filtering the data based on
  22402. 13:33:04specific condition. And now in SQL
  22403. 13:33:06basics we have learned that we have
  22404. 13:33:07different comparison operators and they
  22405. 13:33:09are very simple. So in order to compare
  22406. 13:33:11two values we have operator like the
  22407. 13:33:13equal we have as well not equal the
  22408. 13:33:15opposite. So we have greater than less
  22409. 13:33:18than and as well we have greater than or
  22410. 13:33:21equal to and the last one we have less
  22411. 13:33:23than or equal to. So they are very
  22412. 13:33:25simple. Now instead of comparing two
  22413. 13:33:27values, we're going to go and compare a
  22414. 13:33:29value with the result of subquery using
  22415. 13:33:32the comparison operators. All right,
  22416. 13:33:34let's check the syntax of the subquery
  22417. 13:33:36inside the wear clause using the
  22418. 13:33:38comparison operators. So we start with
  22419. 13:33:40the standard stuff where we say select
  22420. 13:33:42few columns that we want to retrieve and
  22421. 13:33:44we want to get the data directly from
  22422. 13:33:46specific table in our database and now
  22423. 13:33:48we come to the where condition where we
  22424. 13:33:50want to filter the table. So we say
  22425. 13:33:52where and then we select specific column
  22426. 13:33:55from the table one. Now since we are
  22427. 13:33:57talking about the comparison operators
  22428. 13:33:59we can go with operator for example
  22429. 13:34:00equal and usually we go and specify here
  22430. 13:34:03like static value like a number or
  22431. 13:34:05string but instead of having a static
  22432. 13:34:07value what we can do we can get the
  22433. 13:34:10value from another select statements
  22434. 13:34:12another query like here for saying
  22435. 13:34:14select a column from table two and with
  22436. 13:34:17a filter. So now whatever comes from
  22437. 13:34:19this subquery going to be used in order
  22438. 13:34:22to filter the table number one. And of
  22439. 13:34:24course we are telling SQL this is a
  22440. 13:34:26subquery by defining the parenthesis at
  22441. 13:34:28the start and at the ends and the outer
  22442. 13:34:30query going to be the main query. So as
  22443. 13:34:32you can see we are using the subquery in
  22444. 13:34:35order to filter the main query. And here
  22445. 13:34:37in SQL if you're using subquery with the
  22446. 13:34:39comparison operators we have a rule the
  22447. 13:34:42subquery must be a scalar subquery. So
  22448. 13:34:45only one single value. So that's all
  22449. 13:34:47about how to use the subquery in the
  22450. 13:34:49wear clause using the comparison
  22451. 13:34:51operators. All right. So now we have
  22452. 13:34:53again the same task and it says find the
  22453. 13:34:56products that have a price higher than
  22454. 13:34:58the average price of all products. We
  22455. 13:35:01have solved this task already using the
  22456. 13:35:02subquery inside the from clause. But now
  22457. 13:35:05we're going to go and solve it again
  22458. 13:35:07using the subquery but this time inside
  22459. 13:35:09the wear clause. So let's do it step by
  22460. 13:35:11step. Let's go and get the informations
  22461. 13:35:14that we need. So we need the product ID,
  22462. 13:35:17we need the price from the table sales
  22463. 13:35:21products. So let's go and execute it. So
  22464. 13:35:23now we got the list of all products. But
  22465. 13:35:26we have to go and filter those
  22466. 13:35:28informations using the column price. So
  22467. 13:35:31with that in the result, we got all the
  22468. 13:35:32products, but we don't need all the
  22469. 13:35:34products. We need only the products
  22470. 13:35:36where the price is higher than the
  22471. 13:35:38average. That means we have to go and
  22472. 13:35:40filter the table based on the values of
  22473. 13:35:42the price. So now in order to do that
  22474. 13:35:44what we're going to do we're going to
  22475. 13:35:45use the wear clause and we have to go
  22476. 13:35:48and filter the data based on the price
  22477. 13:35:50and since we need higher than we're
  22478. 13:35:52going to go and use the compressor
  22479. 13:35:53operator higher than now next we need
  22480. 13:35:55the value average price. So how we going
  22481. 13:35:58to do it? We don't have the average
  22482. 13:36:00price like out of the box in the table
  22483. 13:36:02products. We have to go and calculate
  22484. 13:36:04it. That's why we're going to go and
  22485. 13:36:06write another query where we're going to
  22486. 13:36:08go and find the average
  22487. 13:36:11price from the table sales products like
  22488. 13:36:16this. So now let's go and highlight it
  22489. 13:36:18and then execute it. And with that we
  22490. 13:36:21got now the average price of our
  22491. 13:36:23products. And as you can see in the
  22492. 13:36:24output we have only one single value. So
  22493. 13:36:27this is a scalar query. So now what we
  22494. 13:36:30need? We need this value in order to be
  22495. 13:36:32used in order to filter the first query.
  22496. 13:36:35So that's why the first query is the
  22497. 13:36:38main query bigger. The second one is the
  22498. 13:36:41subquery that going to support the main
  22499. 13:36:44query in order to filter the data. So
  22500. 13:36:46now what we're going to do, we're going
  22501. 13:36:48to take the subquery and use it in the
  22502. 13:36:51wear clause. And now of course we have
  22503. 13:36:52to tell SQL this is a subquery. That's
  22504. 13:36:54why we have to put it inside two
  22505. 13:36:56parenthesis. So with that we have the
  22506. 13:36:58sub query inside the wear clause in
  22507. 13:37:01order to filter the main query. So let's
  22508. 13:37:03go and execute it. And now as you can
  22509. 13:37:05see in the output we have now only two
  22510. 13:37:07products where the price is higher than
  22511. 13:37:10the average price. So with that we have
  22512. 13:37:12solved the task but this time using the
  22513. 13:37:14subquery in the wear clouds in order to
  22514. 13:37:17filter the main query. And of course in
  22515. 13:37:18order to see this value in our select
  22516. 13:37:21since it is scalar sub query we can as
  22517. 13:37:23well go over here and put it in our
  22518. 13:37:26select just in order to see the value.
  22519. 13:37:28So average price. So let's go and
  22520. 13:37:31execute it. And with that we can see as
  22521. 13:37:32well in our results the average price.
  22522. 13:37:35So this is how we use the subquery in
  22523. 13:37:36the workcloud using the comparison
  22524. 13:37:38operator. Okay. So let's see quickly how
  22525. 13:37:40is going to execute our query step by
  22526. 13:37:42step. So as usual first is going to go
  22527. 13:37:44and identify the subquery. It's going to
  22528. 13:37:47be our select average price and so on.
  22529. 13:37:49And now the next step SQL going to go
  22530. 13:37:51and execute our sub query. So it is
  22531. 13:37:53based on the products and since we are
  22532. 13:37:55doing aggregations without group by at
  22533. 13:37:57the output we will get only one value.
  22534. 13:38:00So the average going to be 20. This
  22535. 13:38:02value is start intermediately in the
  22536. 13:38:04memory. So we will not see it in the
  22537. 13:38:05output. SQL going to go and pass this
  22538. 13:38:08value to the main query. So the main
  22539. 13:38:10query going to look like this. We are
  22540. 13:38:12selecting few columns from the table and
  22541. 13:38:15we are filtering the data based on the
  22542. 13:38:16price that is higher than the value 20
  22543. 13:38:20that we got it from the subquery. So now
  22544. 13:38:22once SQL have everything for the main
  22545. 13:38:24query SQL going to go and execute it. So
  22546. 13:38:26SQL going to go to the products and only
  22547. 13:38:28select the products where the price is
  22548. 13:38:31higher than 20. So it's only those two
  22549. 13:38:33rows and in the output we will get the
  22550. 13:38:35final results the two products as well.
  22551. 13:38:38So product ID and product price. So
  22552. 13:38:40that's it. It's very simple. This is how
  22553. 13:38:41SQL executed our query. So as usual
  22554. 13:38:43first starting with the subquery passing
  22555. 13:38:46the value to the main query and at the
  22556. 13:38:48end so the main query going to be
  22557. 13:38:49executed with the informations from the
  22558. 13:38:51subquery and we will get at the end the
  22559. 13:38:53final results. So that's
  22560. 13:38:55[Music]
  22561. 13:38:58it. All right. So now we're going to
  22562. 13:39:00talk about the second group of operators
  22563. 13:39:02and we're going to start with the in
  22564. 13:39:04operator. So what is in operator? As we
  22565. 13:39:07learned before in the comparison
  22566. 13:39:08operators, we can go and filter the data
  22567. 13:39:10based on only one single value. But now
  22568. 13:39:13in some scenarios, we have to go and
  22569. 13:39:14filter the data based on multiple
  22570. 13:39:17values, not only one. In this case, we
  22571. 13:39:19can go and use the n operator. So if you
  22572. 13:39:21go and use the n operator, it's going to
  22573. 13:39:23go and check whether the value matches
  22574. 13:39:25any value from a list. So a list of
  22575. 13:39:28multiple values. If it matches any of
  22576. 13:39:30them, so we will get a true. Okay. Okay.
  22577. 13:39:32So now let's have a quick look to the
  22578. 13:39:34syntax of the sub query using the in
  22579. 13:39:37operator. So we start with the classic
  22580. 13:39:39stuff where we say okay we would like to
  22581. 13:39:40retrieve the column one column two from
  22582. 13:39:43the table one and we want to filter the
  22583. 13:39:45data based on the column from the table
  22584. 13:39:48one. Now after specifying the column
  22585. 13:39:50we're going to use the in operator and
  22586. 13:39:52after that we can go and specify static
  22587. 13:39:54values but since we are talking about
  22588. 13:39:56the subqueries the values going to come
  22589. 13:39:58from another query. So here we have
  22590. 13:40:01another select statements from table two
  22591. 13:40:03and we filter the data for this query.
  22592. 13:40:06And now the result of this subquery
  22593. 13:40:08going to be used in order to filter the
  22594. 13:40:10data using the in operator. And now the
  22595. 13:40:13big difference between the in operator
  22596. 13:40:15and the comparison operators that the
  22597. 13:40:17subquery is allowed to have multiple
  22598. 13:40:20rows. So there is no rule about having
  22599. 13:40:22like one single value scalar subquery.
  22600. 13:40:25We can have in the result a list of
  22601. 13:40:28multiple values. So this is the syntax
  22602. 13:40:30of the subquery using the in operator.
  22603. 13:40:33All right, let's practice using this
  22604. 13:40:35task. It says show the details of orders
  22605. 13:40:38made by customers in Germany. So let's
  22606. 13:40:40see how we can solve this task. First it
  22607. 13:40:42needs the details of orders. So as we
  22608. 13:40:46know we have the
  22609. 13:40:47table sales orders. So let's go and
  22610. 13:40:50execute it. So in the output we have all
  22611. 13:40:53orders and with all details. But for the
  22612. 13:40:55task we don't need all the orders. We
  22613. 13:40:57need only the orders that made by
  22614. 13:40:59customers from Germany. So now if you
  22615. 13:41:01check the table orders, you don't find
  22616. 13:41:03any informations about the countries,
  22617. 13:41:05right? So we have to go and get it from
  22618. 13:41:07another table. And as we know, we can
  22619. 13:41:09find these informations in the table
  22620. 13:41:11customers. So let's build another query.
  22621. 13:41:14So let's say select star from sales
  22622. 13:41:19customers like this. So let's go and
  22623. 13:41:22execute only the second query like this.
  22624. 13:41:25Now, as you can see in the customers, we
  22625. 13:41:27have the country column, and this is
  22626. 13:41:29exactly what we need. So, now let's make
  22627. 13:41:30a list of all customers from Germany.
  22628. 13:41:33So, we don't need all customers. We need
  22629. 13:41:35only the one that come from Germany.
  22630. 13:41:36That's why we're going to go and use the
  22631. 13:41:38work clause and we say country equal to
  22632. 13:41:41the value Germany like this. So, let's
  22633. 13:41:45go and execute it again and check the
  22634. 13:41:48results. Now, in the output, we have our
  22635. 13:41:50German customers number one and number
  22636. 13:41:52four. So now we're going to go and use
  22637. 13:41:54this information in order to filter the
  22638. 13:41:56table orders. So let's go back to the
  22639. 13:41:58table orders over here. And here we have
  22640. 13:42:00the customer ID informations. And as we
  22641. 13:42:02can see we need the orders where the
  22642. 13:42:04customer is either one or four. Now in
  22643. 13:42:07order to filter that we're going to go
  22644. 13:42:09to the first query and use the work
  22645. 13:42:11clause like this and say the customer
  22646. 13:42:15ID. So now since we have like two values
  22647. 13:42:17one on four we can go and use the
  22648. 13:42:20operator in. So let's go and use the in
  22649. 13:42:22and let's go and build the list. So
  22650. 13:42:25let's go and have the one and four. So
  22651. 13:42:28let's go and execute it. Now we can see
  22652. 13:42:30the results. We have the orders but only
  22653. 13:42:33from the customers one and four. So with
  22654. 13:42:36that we have solved the task. We have
  22655. 13:42:37the details of orders made by customers
  22656. 13:42:39in Germany. Right? And now of course
  22657. 13:42:41this is really bad solution because what
  22658. 13:42:43about if we get like in the future new
  22659. 13:42:45customer you don't want to go and keep
  22660. 13:42:48adding here like values and so on for
  22661. 13:42:50each time you have a new customer. We
  22662. 13:42:52want to make the values for this list to
  22663. 13:42:55be dynamic. So we don't need a static
  22664. 13:42:57value we need like dynamic values and we
  22665. 13:43:00can use the subqueries in order to
  22666. 13:43:02retrieve those informations. Right? And
  22667. 13:43:04we have it already in the second query.
  22668. 13:43:06So let's go back to the second query
  22669. 13:43:08over here. We need only those two values
  22670. 13:43:10one and four. That's why we're going to
  22671. 13:43:12go to the query and say okay let's
  22672. 13:43:15retrieve the customer ID. So let's go
  22673. 13:43:18and execute it again. And with that we
  22674. 13:43:20have with a one and four exactly like we
  22675. 13:43:22have it here in the first query. And of
  22676. 13:43:24course in the future if there's like
  22677. 13:43:25another customer that come from Germany
  22678. 13:43:27this list going to be little bit longer.
  22679. 13:43:29So this query going to always retrieve
  22680. 13:43:31all the customer ids that have the
  22681. 13:43:34country equal to Germany. So now what
  22682. 13:43:36we're going to do, we're going to take
  22683. 13:43:38this as a sub query. Let's go and get
  22684. 13:43:41everything from it and now put it
  22685. 13:43:43instead of those static values. So of
  22686. 13:43:45course we're going to go now and put few
  22687. 13:43:47spaces to the right side in order to
  22688. 13:43:49understand this is subquery and of
  22689. 13:43:52course here we don't use any aliases. So
  22690. 13:43:54now what we are doing the results from
  22691. 13:43:56this subquery going to be used in order
  22692. 13:43:59to filter our main query. So let me just
  22693. 13:44:02call it main
  22694. 13:44:04query like this and make this smaller.
  22695. 13:44:08So let's go and execute it. And now we
  22696. 13:44:10are getting the same results. We are
  22697. 13:44:12getting all the orders from only the
  22698. 13:44:14customers one and four where they come
  22699. 13:44:16from Germany. And this informations come
  22700. 13:44:18dynamically from the subquery and we
  22701. 13:44:21don't have to worry about new customers
  22702. 13:44:22from Germany. It's going to be added
  22703. 13:44:24here automatically. And this query going
  22704. 13:44:26to always return all the orders from
  22705. 13:44:28Germany. So this is the power of the
  22706. 13:44:30subquery together with the in operator
  22707. 13:44:32if you are having like multiple values
  22708. 13:44:34multiple rows. So we have solved the
  22709. 13:44:36task. All right. Now one more thing.
  22710. 13:44:38Let's say that the task is exactly the
  22711. 13:44:39opposite. It says show the details of
  22712. 13:44:42orders made by customers who don't come
  22713. 13:44:45from Germany. So now here there's like
  22714. 13:44:47two ways in order to do it. Either you
  22715. 13:44:49go to the subquery and you say you know
  22716. 13:44:51what the country should not be equal to
  22717. 13:44:54Germany. So if you go and execute it,
  22718. 13:44:57you will get all the customers ids that
  22719. 13:44:59are not from Germany. And if you execute
  22720. 13:45:01the whole thing, you will get all the
  22721. 13:45:03orders where the customers are not from
  22722. 13:45:04Germany. So either you do that or you
  22723. 13:45:07stay with the equal to Germany, but you
  22724. 13:45:09go and convert the whole logic by using
  22725. 13:45:12the operator not. So now we are saying
  22726. 13:45:14the customer ID should not be equal to
  22727. 13:45:17one of those values. So it should not be
  22728. 13:45:20equal to one or four. And for that we
  22729. 13:45:22are using the notin operator. So let's
  22730. 13:45:25go and execute it. So now with that we
  22731. 13:45:27are getting all the orders where the
  22732. 13:45:29customers don't come from Germany by
  22733. 13:45:31just using notin operator. So that's all
  22734. 13:45:34about the notin and the in operators.
  22735. 13:45:37All right. So now let's see step by step
  22736. 13:45:38how is execute our query. So we are
  22737. 13:45:41targeting two tables the customers and
  22738. 13:45:43the orders. So the first step is that
  22739. 13:45:44SQL going to go and identify the
  22740. 13:45:46subquery and it's going to go and
  22741. 13:45:48execute it. So the subquery here is
  22742. 13:45:50filtering the data based on the country.
  22743. 13:45:53So the query going to be executed and in
  22744. 13:45:55the output we will get only two rows. So
  22745. 13:45:57it is one column with multiple rows.
  22746. 13:45:59This is the row subquery and this is our
  22747. 13:46:02intermediate results where it's going to
  22748. 13:46:03be passed to the main query. So our main
  22749. 13:46:06query going to look like this. We are
  22750. 13:46:07selecting few informations from the
  22751. 13:46:09orders and we are filtering the table
  22752. 13:46:11orders based on the customer ID where we
  22753. 13:46:14are saying the customer ID must be one
  22754. 13:46:16of those values one or four. So the
  22755. 13:46:18subquery here is supporting the main
  22756. 13:46:21query with the informations for the
  22757. 13:46:23filter. Now once SQL have everything
  22758. 13:46:25going to go and execute our main query
  22759. 13:46:28and this going to be like the following.
  22760. 13:46:30So we will start with the first row and
  22761. 13:46:32here the customer ID is equal to two. So
  22762. 13:46:34the value two is not equal to 1 or four.
  22763. 13:46:37That's why this row will be excluded
  22764. 13:46:39from the final results. Now let's move
  22765. 13:46:42to the second row. We have here the
  22766. 13:46:43value three and the value three is not
  22767. 13:46:46equal to one of those values. That's why
  22768. 13:46:48this value going to be as well failing.
  22769. 13:46:51So we will not have it at the output.
  22770. 13:46:53And then it's still going to go to the
  22771. 13:46:54next one. Now this time the customer ID
  22772. 13:46:56is one and it is equal to one of those
  22773. 13:46:59values. It's equal to one. So we have a
  22774. 13:47:01match. That's why this row will be
  22775. 13:47:03included to the results. And the same
  22776. 13:47:05thing for the next row because we have
  22777. 13:47:07the customer ID one and so on. Now after
  22778. 13:47:10SQL checking all those customer ids
  22779. 13:47:12whether they are in the list one or four
  22780. 13:47:14we will get the final results where we
  22781. 13:47:16have here all the orders where the
  22782. 13:47:18customer ID either one or four. So this
  22783. 13:47:21is how SQL executed the in operator
  22784. 13:47:24using the
  22785. 13:47:28subqueries. Okay. So now moving on to
  22786. 13:47:30the any operator. So we can go and use
  22787. 13:47:32the any operator in order to compare a
  22788. 13:47:34value if it matches any value from a
  22789. 13:47:38list. So that means we can go and use it
  22790. 13:47:40in order to check whether a condition is
  22791. 13:47:42true for at least one of the values in a
  22792. 13:47:45list. Okay. So now let's check quickly
  22793. 13:47:47the syntax of the subquery using the any
  22794. 13:47:49and all operators. So as we learned
  22795. 13:47:51before we can go and use a subquery
  22796. 13:47:53inside the wear clause in order to
  22797. 13:47:55filter the main query using like the
  22798. 13:47:57comparison operators like here less
  22799. 13:47:59than. Now the syntax of the any operator
  22800. 13:48:02is that you're going to go and use the
  22801. 13:48:04comparison operator and after that
  22802. 13:48:07immediately you use the keyword any. And
  22803. 13:48:09for the all operator going to be exactly
  22804. 13:48:11the same where you're going to go and
  22805. 13:48:13put after the comparison operator the
  22806. 13:48:15keyword all. So the syntax is very
  22807. 13:48:17simple. We just add those keywords. So
  22808. 13:48:20let's practice using the following task.
  22809. 13:48:22Find female employees whose salaries are
  22810. 13:48:25greater than the salaries of any male
  22811. 13:48:28employee. So that means we want to go
  22812. 13:48:30and compare the salaries between the
  22813. 13:48:31male and female and specifically we are
  22814. 13:48:34searching for female employees whose
  22815. 13:48:36salary is greater than at least one male
  22816. 13:48:39employee. So let's solve it step by
  22817. 13:48:41step. Let's go and start selecting few
  22818. 13:48:43informations like for example the
  22819. 13:48:45employee
  22820. 13:48:46ID and first
  22821. 13:48:49name, gender, salary from the table
  22822. 13:48:53sales employees. So let's go and execute
  22823. 13:48:57it. So now we have like five employees.
  22824. 13:48:59Three of them are male and two are
  22825. 13:49:01female. So now since we want to compare
  22826. 13:49:03the data between male and female let's
  22827. 13:49:05go and create two queries. The first one
  22828. 13:49:07is filtering the data based on the
  22829. 13:49:10gender. So the first one is for the
  22830. 13:49:12female. So and we can go and remove this
  22831. 13:49:15information over here. Let me just make
  22832. 13:49:17this little bit smaller and zoom out.
  22833. 13:49:20And the second query it's going to be
  22834. 13:49:23the exact opposite. Let's go and get
  22835. 13:49:25employee informations for the male. So
  22836. 13:49:28let's go and execute it. Now the first
  22837. 13:49:30results are the female employees and the
  22838. 13:49:32second one are So now for the first
  22839. 13:49:34result is for the female employees and
  22840. 13:49:36the second one is for the male
  22841. 13:49:38employees. So now what do we need in the
  22842. 13:49:40output? We need the female employees.
  22843. 13:49:42That means this is going to be our main
  22844. 13:49:46query. So we are focusing on the female
  22845. 13:49:49employees and we are using the male
  22846. 13:49:51employees only as a filter and what we
  22847. 13:49:54need we need only the salary
  22848. 13:49:55informations that's why we can prepare
  22849. 13:49:58it like this. I will just put everything
  22850. 13:50:01in one line to make it clear. So this
  22851. 13:50:04going to be our sub query. So now we're
  22852. 13:50:06going to go and work with the main query
  22853. 13:50:08where we're going to add one more filter
  22854. 13:50:10where we're going to filter the data
  22855. 13:50:12based on the salary. Right? So we're
  22856. 13:50:14going to say if the salary is greater
  22857. 13:50:17than and now we need the values from the
  22858. 13:50:20subquery right so this is our subquery
  22859. 13:50:22we're going to put it like this and
  22860. 13:50:24don't forget about the parenthesis at
  22861. 13:50:26the start and at the ends and I would
  22862. 13:50:28like still to have those two uh queries
  22863. 13:50:31so let's go ahead execute it and now we
  22864. 13:50:34will get an error and that's because our
  22865. 13:50:36sub query is returning multiple rows and
  22866. 13:50:39this is not acceptable we are using the
  22867. 13:50:41comparison operator and SQL expect from
  22868. 13:50:44the subquery to have scalar subquery. So
  22869. 13:50:47only one single value. But now in order
  22870. 13:50:49to solve this issue, we can go and use
  22871. 13:50:52the logical operators either all or any.
  22872. 13:50:54So now since we are saying it's enough
  22873. 13:50:56for the salary of the female employee to
  22874. 13:50:58be higher than at least one male
  22875. 13:51:00employee, we will go with the operator
  22876. 13:51:03any. So let's go after the comparison
  22877. 13:51:06operator and have the keyword any. And
  22878. 13:51:08let's go and execute it again. And now
  22879. 13:51:10as you can see in the output we got only
  22880. 13:51:12one female employee where her salary is
  22881. 13:51:15higher to one of those male employees.
  22882. 13:51:18So let me just go and get the first name
  22883. 13:51:20as well from the
  22884. 13:51:22second query just to have it like this.
  22885. 13:51:24So now if you go and compare the salary
  22886. 13:51:26of Mary it is not higher than Michael
  22887. 13:51:29but it is higher than Frank and Kevin.
  22888. 13:51:32And since we are using the any operator
  22889. 13:51:34it's enough for Mary to have salary
  22890. 13:51:36higher to one of those values. In this
  22891. 13:51:38case, it's higher than both Frank and
  22892. 13:51:40Kevin. And the condition is fulfilled.
  22893. 13:51:42That's why we are getting the marry. And
  22894. 13:51:44the other female, let me just check. Do
  22895. 13:51:47we have else? So, we have Carol is
  22896. 13:51:49salary is less than all the salaries of
  22897. 13:51:51the male employees. So, it must be at
  22898. 13:51:53least higher than one of the male
  22899. 13:51:56employees. So, with that, we have solved
  22900. 13:51:57the task, right? All right. So, now we
  22901. 13:51:59have another operator that is similar.
  22902. 13:52:01We call it the all operator. We can go
  22903. 13:52:04and use it in order to compare a value
  22904. 13:52:06if it matches all values in a list. So
  22905. 13:52:09that means we can go and use it if we
  22906. 13:52:11need to check whether a condition is
  22907. 13:52:13true every value in a list. I know that
  22908. 13:52:16might sound a little bit complicated but
  22909. 13:52:18don't worry about it. We can have
  22910. 13:52:19examples. Now let's say that our task
  22911. 13:52:21says find female employees whose salary
  22912. 13:52:24are greater than the salaries of all
  22913. 13:52:28male employees. So that means now the
  22914. 13:52:30condition is more restrictive. Mary
  22915. 13:52:32should now has a salary higher than
  22916. 13:52:35every male employee. So it should be
  22917. 13:52:37higher to all those values that we have
  22918. 13:52:40from the male employees. And of course
  22919. 13:52:42in this scenario it's not because we
  22920. 13:52:44have Michael. Mary has less salaries
  22921. 13:52:47than Michael. And this is a problem
  22922. 13:52:49because Mary should has higher salary
  22923. 13:52:52than everyone. So let's go and try it.
  22924. 13:52:54If I go and write here all and let's go
  22925. 13:52:57and execute it, you will see we will not
  22926. 13:52:59find any results that fulfill this
  22927. 13:53:01requirement. So we don't have any female
  22928. 13:53:03employee who her salary is higher than
  22929. 13:53:06all male employees and that's because we
  22930. 13:53:08have a very small data sets. So this is
  22931. 13:53:10how we use all and any operators in our
  22932. 13:53:13subqueries in SQL. All right. So with
  22933. 13:53:15that we have covered almost everything
  22934. 13:53:17about how to use the subqueries in
  22935. 13:53:20different locations and clauses. But we
  22936. 13:53:22didn't talk about the exist operator and
  22937. 13:53:24that's because I would like you to
  22938. 13:53:25understand a very important concept in
  22939. 13:53:27the subqueries where we have two
  22940. 13:53:29different types of the subqueries based
  22941. 13:53:31on the dependencies the non-correlated
  22942. 13:53:34and correlated subqueries. And after
  22943. 13:53:36that we're going to go back to the exist
  22944. 13:53:41operator. All right friends. So now we
  22945. 13:53:44come to the part where it is a little
  22946. 13:53:45bit complicated about the subqueries.
  22947. 13:53:47Now we're going to talk about the
  22948. 13:53:49dependencies between the subquery and
  22949. 13:53:51the main query. So far all the examples
  22950. 13:53:54and the subqueries that we have learned
  22951. 13:53:56where a noncorrelated subquery. A
  22952. 13:53:59non-correlated subquery means a subquery
  22953. 13:54:02that can run independently from the main
  22954. 13:54:05query. So that means the subquery is
  22955. 13:54:07like standalone query. But in the other
  22956. 13:54:09hand we have the exact opposite type of
  22957. 13:54:12the subquery. We have the correlated
  22958. 13:54:14subquery. A correlated subquery is a
  22959. 13:54:17subquery that relies on values from the
  22960. 13:54:20main query for each row it processes. So
  22961. 13:54:24that means the subquery here is
  22962. 13:54:26completely depending on the main query.
  22963. 13:54:29So I know this might be a little bit
  22964. 13:54:30confusing. That's why we can have the
  22965. 13:54:32following very simple sketch in order to
  22966. 13:54:34exactly understand how this works. So as
  22967. 13:54:37usual we have a database tables and now
  22968. 13:54:40this time going to go and start
  22969. 13:54:42executing the main query first. This is
  22970. 13:54:45the first thing happens. So the main
  22971. 13:54:47query going to go and query the database
  22972. 13:54:50in order to get results and SQL going to
  22973. 13:54:53process the results row by row. So now
  22974. 13:54:55what going to happen? The main query
  22975. 13:54:57going to go and pass the first row
  22976. 13:54:59informations to the sub query. So now
  22977. 13:55:02the subquery going to get the data from
  22978. 13:55:04the main query. So SQL going to execute
  22979. 13:55:06the subquery. So here the subquery going
  22980. 13:55:09to return a value like for example one.
  22981. 13:55:11So here it's very important to
  22982. 13:55:13understand that now the SQL or the main
  22983. 13:55:15query going to check is there a result
  22984. 13:55:18from the sub query in this example yes
  22985. 13:55:20we have a results. So here SQL is
  22986. 13:55:22checking the output for the subquery for
  22987. 13:55:26the first row. So if there is a result
  22988. 13:55:28SQL going to go and return the row in
  22989. 13:55:31the final result. So this is the whole
  22990. 13:55:34iteration happened only for the first
  22991. 13:55:36row. So we're going to process the whole
  22992. 13:55:38thing again from the start for the
  22993. 13:55:40second row. So the main query going to
  22994. 13:55:42get the second row from the database and
  22995. 13:55:44it going to pass it to the subquery.
  22996. 13:55:47Once the subquery gets this new
  22997. 13:55:49informations, SQL going to go and
  22998. 13:55:51execute the subquery once again. So now
  22999. 13:55:54let's say that after executing the
  23000. 13:55:56subquery, there were no results. So the
  23001. 13:55:58subquery is not returning anything after
  23002. 13:56:01the execution. So now what can happen?
  23003. 13:56:04SQL and the main query going to check
  23004. 13:56:06okay there is no result from the sub
  23005. 13:56:08query and this means this row should be
  23006. 13:56:11excluded and not presented in the
  23007. 13:56:13output. So we will not see this row at
  23008. 13:56:15the output. So as you can see SQL is
  23009. 13:56:18executing the subquery once again for
  23010. 13:56:21the second row. So this will keep
  23011. 13:56:23happening as long as we have row. For
  23012. 13:56:25example, we have another row. The main
  23013. 13:56:27query going to pass it to the subquery.
  23014. 13:56:29The subquery going to be executed for
  23015. 13:56:31the third time and the result of the
  23016. 13:56:33subquery is going to be one. So the same
  23017. 13:56:35thing going to happen. SQL going to
  23018. 13:56:37check it. Okay, we have a value. So this
  23019. 13:56:39row is allowed to be in the final
  23020. 13:56:41results and so on. The cycle going to
  23021. 13:56:43keep repeating for each row that's going
  23022. 13:56:46to be retrieved from the main query and
  23023. 13:56:48once we have processed all the rows, the
  23024. 13:56:51final result going to be presented in
  23025. 13:56:53the output. So what we have understood
  23026. 13:56:54so far the correlated subqueries is
  23027. 13:56:57always depending on the main query and
  23028. 13:57:00the subquery going to be executed for
  23029. 13:57:03each row that we're going to get from
  23030. 13:57:05the main query. So in this example we
  23031. 13:57:07have four rows and the subquery is
  23032. 13:57:09executed four times. So this is how the
  23033. 13:57:12correlated subquery works. It's a little
  23034. 13:57:14bit more complicated than the
  23035. 13:57:16non-correlated subquery. The
  23036. 13:57:18non-correlated subqueries are really
  23037. 13:57:20straightforward. So first the subquery
  23038. 13:57:22going to go and execute the database
  23039. 13:57:25only once and the output of the subquery
  23040. 13:57:27going to be like an intermediate results
  23041. 13:57:30that going to be used from the main
  23042. 13:57:32query. So the main query going to go and
  23043. 13:57:34query the intermediate results and in
  23044. 13:57:36the output we're going to get the final
  23045. 13:57:38results. So as you can see in the
  23046. 13:57:40execution of the non-correlated subquery
  23047. 13:57:42it is straightforward. There's no
  23048. 13:57:44iterations everything going to be
  23049. 13:57:46executed only once. So now if you
  23050. 13:57:48compare them side by side you can see
  23051. 13:57:50that with the non-correlated subquery it
  23052. 13:57:52is completely independent from the main
  23053. 13:57:55query. So that means the subquery going
  23054. 13:57:57to be executed only once and after that
  23055. 13:58:00SQL going to go and as well execute the
  23056. 13:58:02main query only once using the result
  23057. 13:58:05from the subquery. But on the left side
  23058. 13:58:07the subquery is going to be executed
  23059. 13:58:09multiple times and it is completely
  23060. 13:58:11depending on the main query and there is
  23061. 13:58:14like an iteration for each row that's
  23062. 13:58:16going to be retrieved from the main
  23063. 13:58:18query. So the process going to be
  23064. 13:58:20cycling until all the rows are processed
  23065. 13:58:23and this is exactly how the correlated
  23066. 13:58:25and the non-correlated subqueries work
  23067. 13:58:28in SQL. All right. So now let's have the
  23068. 13:58:30following task and it says show all
  23069. 13:58:31customer details and find the total
  23070. 13:58:34orders of each customer. We have already
  23071. 13:58:36solved this task and you know in scale
  23072. 13:58:38we don't have only one query in order to
  23073. 13:58:40solve something. We have multiple ways
  23074. 13:58:42in order to do it. So we solved this
  23075. 13:58:44task before using the subqueries and the
  23076. 13:58:47joins. Now we're going to go and solve
  23077. 13:58:48this task using subquery in the select
  23078. 13:58:51clause and as well using the correlated
  23079. 13:58:54subqueries. So again let's do it step by
  23080. 13:58:57step. It's very simple. First we need
  23081. 13:58:59all the customer details. So as we
  23082. 13:59:02learned select star from sales
  23083. 13:59:05customers. So if you execute it you will
  23084. 13:59:07get all the details of all customers.
  23085. 13:59:09Now we need to find the total number of
  23086. 13:59:12orders of each customer. Now before we
  23087. 13:59:14have solved this using a simple query
  23088. 13:59:16where we have used the count function
  23089. 13:59:19together with a group I but this time
  23090. 13:59:21we're going to do it little bit
  23091. 13:59:22different. So let's go and write query
  23092. 13:59:25saying select count star from the table
  23093. 13:59:30sales orders. So now let's go and
  23094. 13:59:34execute it. With that we have the total
  23095. 13:59:36number of orders. So let's go and take
  23096. 13:59:38this sub query and use it in the select.
  23097. 13:59:42So we are using it as a scalar subquery.
  23098. 13:59:45So let's just put it over here. And this
  23099. 13:59:47is the main query. And in order to make
  23100. 13:59:50this as a subquery, what we're going to
  23101. 13:59:52do, we're going to have the parenthesis
  23102. 13:59:54and we're going to say the total sales.
  23103. 13:59:56So now let's go and execute it. So now
  23104. 13:59:58as you can see, we have here all the
  23105. 14:00:00details about the customers and we have
  23106. 14:00:01the total sales. But we have one issue.
  23107. 14:00:03We don't need just the total order. We
  23108. 14:00:05need the total orders for each customer.
  23109. 14:00:08So each customer has different total
  23110. 14:00:10orders. So we cannot have like the
  23111. 14:00:12following setup. We cannot say group by
  23112. 14:00:15customer ID. And then you have like here
  23113. 14:00:18the customer ID and so on. So if you go
  23114. 14:00:21and execute it, you will get a problem.
  23115. 14:00:23And that's because if you go and execute
  23116. 14:00:25this subquery over here, you will get
  23117. 14:00:27like multiple rows and multiple columns.
  23118. 14:00:30So you have like a table query. And this
  23119. 14:00:32type of subquery is not allowed to be
  23120. 14:00:34used in the select clause, right? We
  23121. 14:00:36have to have only scalar
  23122. 14:00:38subquery. So that's why we cannot do
  23123. 14:00:41that. So we have to go and remove all
  23124. 14:00:43those stuff.
  23125. 14:00:45But we can go and solve it using the
  23126. 14:00:47correlated subqueries. So now the
  23127. 14:00:49subquery is completely independent from
  23128. 14:00:52the main query. So in order to correlate
  23129. 14:00:55it, what we're going to do, we're going
  23130. 14:00:56to go and connect it. So I'm going to
  23131. 14:00:57give aliases for the tables and I'm
  23132. 14:01:00going to say where the customer ID equal
  23133. 14:01:04to the customer ID from the main query
  23134. 14:01:07from the customers. So again we are
  23135. 14:01:09connecting the customer ID from the
  23136. 14:01:11orders in the subquery with the customer
  23137. 14:01:14ID from the table customers that comes
  23138. 14:01:17from the main query. So now we are
  23139. 14:01:19saying okay execute this only for a
  23140. 14:01:22specific customer not for the whole
  23141. 14:01:24table. So let's go and execute it. So
  23142. 14:01:27now in the output we have the total
  23143. 14:01:29sales for each customer and we don't
  23144. 14:01:31have here like the total sales in the
  23145. 14:01:33whole table orders and that's because
  23146. 14:01:35what is happening for each row the
  23147. 14:01:37subquery going to be executed. So for
  23148. 14:01:39the customer number one this query going
  23149. 14:01:42to be executed like this count the total
  23150. 14:01:44number of orders where the customer ID
  23151. 14:01:48equal to the one. So let me just show
  23152. 14:01:50you what this means. If I go and remove
  23153. 14:01:52this from here and just put the number
  23154. 14:01:54one. So if I go and execute this, you
  23155. 14:01:57will see the customer ID one has three
  23156. 14:02:00orders. And let's just put it back and
  23157. 14:02:03execute. And the same thing going to
  23158. 14:02:04happen for each customer. So for each
  23159. 14:02:06customer, for each row, this subquery
  23160. 14:02:09going to be executed and it can be
  23161. 14:02:11filtered with the customer ID that comes
  23162. 14:02:13from the main query. So this is another
  23163. 14:02:15way in how to solve this task using the
  23164. 14:02:17correlated subqueries. So now let's
  23165. 14:02:19summarize and understand quickly what
  23166. 14:02:21are the differences between the
  23167. 14:02:22non-correlated and the correlated
  23168. 14:02:24subqueries. So now if you are talking
  23169. 14:02:25about the definition the non-correlated
  23170. 14:02:28subquery are subqueries that are
  23171. 14:02:30independent of the main query but in the
  23172. 14:02:33other hand the correlated subqueries are
  23173. 14:02:35dependent of the main query. And now if
  23174. 14:02:37you're talking about the execution the
  23175. 14:02:39non-correlated subquery is going to be
  23176. 14:02:41executed only once and then the results
  23177. 14:02:44going to be used by the main query but
  23178. 14:02:46by the correlated subqueries the
  23179. 14:02:48subquery going to be executed for each
  23180. 14:02:50row that we have from the main query.
  23181. 14:02:52And as we learned for the non-correlated
  23182. 14:02:54subqueries we can execute it on its own.
  23183. 14:02:57So we can go and select it and execute
  23184. 14:02:59it. But the correlated subqueries we
  23185. 14:03:01cannot execute it on its own. So we have
  23186. 14:03:03to execute always the whole thing. And
  23187. 14:03:06if you are talking about which one is
  23188. 14:03:07easier, I think it's clear that the
  23189. 14:03:09noncorrelated subqueries are easier to
  23190. 14:03:12write and to read. And in the other
  23191. 14:03:13hand, the correlated subqueries are
  23192. 14:03:15harder to read and as well it's complex.
  23193. 14:03:18Now, if you're talking about the
  23194. 14:03:19performance of the database since the
  23195. 14:03:21correlated subqueries can be executed
  23196. 14:03:23only once, this of course going to lead
  23197. 14:03:25you to have better performance because
  23198. 14:03:27things are really straightforward and
  23199. 14:03:28not complicated. But in the other hand
  23200. 14:03:30with the correlated subqueries there is
  23201. 14:03:32more effort because SQL has to check a
  23202. 14:03:35lot of stuff and the subquery going to
  23203. 14:03:36be executed many times. So the
  23204. 14:03:38noncorrelated subqueries are faster. We
  23205. 14:03:40use the noncorrelated subqueries in
  23206. 14:03:42order to do static comparison. So the
  23207. 14:03:46value that we are getting from the
  23208. 14:03:47subquery is executed only once and we
  23209. 14:03:49will get only one static value in order
  23210. 14:03:52to use it for filtering and so on. But
  23211. 14:03:54in the other hand we use correlated
  23212. 14:03:55subqueries in order to do rowby row
  23213. 14:03:57comparison. And since we don't have here
  23214. 14:03:59a static value each time the subquery
  23215. 14:04:01going to run we're going to have
  23216. 14:04:02different results. This going to add
  23217. 14:04:04more dynamic to the filters and we don't
  23218. 14:04:06have a static value. So those are the
  23219. 14:04:08big differences between the
  23220. 14:04:09non-correlated and the correlated
  23221. 14:04:10subqueries. All right. So now after we
  23222. 14:04:13understood the concept of the two types
  23223. 14:04:15correlated and non-correlated subqueries
  23224. 14:04:17we're going to go now and cover the last
  23225. 14:04:20operator for the subqueries. We have the
  23226. 14:04:22exists. So what is exist
  23227. 14:04:27operator? All right. So now we're going
  23228. 14:04:29to talk about a very interesting
  23229. 14:04:31operator function in SQL the exists. So
  23230. 14:04:34now in some scenarios as you are
  23231. 14:04:35querying the data from one table you
  23232. 14:04:38would need to go and check whether the
  23233. 14:04:39rows of this table exist in another
  23234. 14:04:42table. So that means you are checking
  23235. 14:04:44like the existence of your rows in
  23236. 14:04:46different table. And exactly in this
  23237. 14:04:48scenario we go and use subqueries
  23238. 14:04:51together with the operator exists. So
  23239. 14:04:53the exist operator is very simple. It
  23240. 14:04:55just simply check whether the subquery
  23241. 14:04:58returns any results any rows. All right.
  23242. 14:05:00So now let's understand the syntax of
  23243. 14:05:02the correlated subqueries using the
  23244. 14:05:04exist operator. This can be a little bit
  23245. 14:05:07complicated but we're going to do it
  23246. 14:05:08step by step. Don't worry about it. So
  23247. 14:05:10let's start with the easy stuff. In the
  23248. 14:05:12main query we're going to go and write a
  23249. 14:05:14simple select. We are selecting few
  23250. 14:05:16columns from the table two. And now we
  23251. 14:05:18don't need all the data from table two.
  23252. 14:05:20We want to filter the table using the
  23253. 14:05:22wear clause. Now what we're going to do
  23254. 14:05:24after the wear clause, we're going to
  23255. 14:05:25write immediately another keyword called
  23256. 14:05:27exists. So we don't specify any column
  23257. 14:05:30before the exist like we have done in
  23258. 14:05:32the comparison operator or the in
  23259. 14:05:33operator. We don't need that because we
  23260. 14:05:35are not filtering based on a value. We
  23261. 14:05:37are filtering based on the logic. That's
  23262. 14:05:39why we have the word exist immediately.
  23263. 14:05:42And now directly after they exist, we're
  23264. 14:05:44going to go and define the subquery like
  23265. 14:05:46this. So we're going to start saying
  23266. 14:05:47select one from the table number one.
  23267. 14:05:50Well, it is not like a must or
  23268. 14:05:52something. But it is very commonly used
  23269. 14:05:54to specify here a one. We are not using
  23270. 14:05:56the subquery in order to retrieve
  23271. 14:05:58informations from the table one. We are
  23272. 14:06:00just testing whether the subquery going
  23273. 14:06:03to return a value or not. And we don't
  23274. 14:06:05care about the returned value. It could
  23275. 14:06:07be one, it could be column, it could be
  23276. 14:06:09anything. So we don't care about the
  23277. 14:06:12data that is retrieved. We are just care
  23278. 14:06:14whether the subquery is returning
  23279. 14:06:16anything. So that's why we go and write
  23280. 14:06:18any value like here a one. So now we are
  23281. 14:06:20not done yet. This subquery is not yet
  23282. 14:06:23connected to the main query. We have
  23283. 14:06:25somehow to go and connect them together.
  23284. 14:06:27And we can do that using the wear clause
  23285. 14:06:30where we go and connect the ID from the
  23286. 14:06:32table one from the subquery with the ID
  23287. 14:06:35from the outer query from the main
  23288. 14:06:38query. And with that we are building
  23289. 14:06:39like a relationship between the subquery
  23290. 14:06:43and the main query. So with that the
  23291. 14:06:45subquery is now depending on the values
  23292. 14:06:48from the main query because here we have
  23293. 14:06:50the table 2 id. So the ids from the main
  23294. 14:06:53query going to filter the subquery. So
  23295. 14:06:57this is the syntax of correlated sub
  23296. 14:06:59queries using the exist where we are
  23297. 14:07:01making the subquery depending totally on
  23298. 14:07:04the main query. So let's understand how
  23299. 14:07:06exist works. So now for each row that we
  23300. 14:07:09have from the main query, it's going to
  23301. 14:07:11trigger and cause an execution of the
  23302. 14:07:14subquery. This subquery going to help us
  23303. 14:07:16to evaluate this row. So we are testing
  23304. 14:07:18this row. Now if the subquery doesn't
  23305. 14:07:21return anything, so there is no results,
  23306. 14:07:23what can happen? The row that we are
  23307. 14:07:25evaluating from the main query will be
  23308. 14:07:28excluded from the final results. But now
  23309. 14:07:30in the other hand if the subquery is
  23310. 14:07:33returning a value so we have like some
  23311. 14:07:35kind of results then this row that we
  23312. 14:07:37are evaluating going to be included in
  23313. 14:07:40the final results. So the subquery is
  23314. 14:07:42used in order to do a test. Do we have a
  23315. 14:07:45results or we don't and based on this
  23316. 14:07:47SQL either going to include or exclude
  23317. 14:07:50the row from the final results. So this
  23318. 14:07:52is the logic behind the exist in SQL.
  23319. 14:07:55All right. So now we're going to go and
  23320. 14:07:56solve the same task using the exists. So
  23321. 14:07:58the task says show the details of orders
  23322. 14:08:01made by the customers in Germany. So we
  23323. 14:08:04have already solved this task using the
  23324. 14:08:05in operator and the subquery. Now we're
  23325. 14:08:08going to go and solve it using the
  23326. 14:08:09exists. So again we're going to have the
  23327. 14:08:11same logical steps that we have done
  23328. 14:08:12before. So first we're going to go and
  23329. 14:08:14select all the details from the table
  23330. 14:08:17sales orders. So let's execute it. And
  23331. 14:08:20with that we have all the orders and all
  23332. 14:08:22the details. But of course we don't need
  23333. 14:08:25all those informations. We need only the
  23334. 14:08:27orders that's made by customers from
  23335. 14:08:29Germany. So that is the first query.
  23336. 14:08:31Let's go and construct the second query.
  23337. 14:08:34We're going to say select star from
  23338. 14:08:37sales customers. But we don't need all
  23339. 14:08:40the customers. We need only the
  23340. 14:08:41customers from country equal to the
  23341. 14:08:45value Germany. So let's go and execute
  23342. 14:08:49it. So now we have all customers that
  23343. 14:08:52come from Germany. Now we have to go and
  23344. 14:08:54put those two queries together in order
  23345. 14:08:57to get the final results. So as we
  23346. 14:08:59learned before the second query going to
  23347. 14:09:01be our subquery. So it's going to be
  23348. 14:09:03supporting the first query in order to
  23349. 14:09:05filter the data. So the first query
  23350. 14:09:07going to be our main query. Let me just
  23351. 14:09:10make this smaller and the text as well.
  23352. 14:09:13Now we don't need all the orders, right?
  23353. 14:09:16We need only the orders where the
  23354. 14:09:17customer come from Germany. So we need
  23355. 14:09:19the work clause. So now we can have the
  23356. 14:09:21filter logic like this. Show the order
  23357. 14:09:24details only if the customer ID exist
  23358. 14:09:27from the subquery. And now we have to go
  23359. 14:09:30and put our subquery. So our subquery
  23360. 14:09:32going to be this one over here. So let's
  23361. 14:09:36just move it to the right side. And in
  23362. 14:09:39order to have it as a subquery, we have
  23363. 14:09:40to close the parenthesis. And now since
  23364. 14:09:43exist is correlated subquery, we cannot
  23365. 14:09:45have it like this. we have to go and
  23366. 14:09:47connect the subquery together with the
  23367. 14:09:50main query. So now the subquery is
  23368. 14:09:52currently independent from the main
  23369. 14:09:54query because we want to check each
  23370. 14:09:56order information from the order table
  23371. 14:09:58to check whether the customer exist in
  23372. 14:10:01the sub query. We're going to go and add
  23373. 14:10:03the condition like the following. And
  23374. 14:10:06now it's like the joins we have to go
  23375. 14:10:07and connect the customer ids together.
  23376. 14:10:10So we're going to go over here and give
  23377. 14:10:11it like an alias and as well for the
  23378. 14:10:13subquery. And now we're going to say
  23379. 14:10:15customer ID from the orders should be
  23380. 14:10:19equal to the customer
  23381. 14:10:21ID from the subquery the table customers
  23382. 14:10:25like this. So again this customer ID
  23383. 14:10:28come from the subquery and this customer
  23384. 14:10:30ID comes from the main query. So now
  23385. 14:10:33since we are using the subquery only in
  23386. 14:10:36order to test the existence of the
  23387. 14:10:38customer. So if the subquery returns
  23388. 14:10:40anything or not, it doesn't matter what
  23389. 14:10:42you are selecting in the subquery. So so
  23390. 14:10:45you can go with the star or a column or
  23391. 14:10:47any static value. But for some reason
  23392. 14:10:50all the SQL developers decided to go
  23393. 14:10:52with the static value one. And of course
  23394. 14:10:54you can go and add like a column like
  23395. 14:10:56the customer ID but it's like
  23396. 14:10:58unnecessary step for the SQL in order to
  23397. 14:11:00retrieve the information from the
  23398. 14:11:02customer ID. So it's going to be way
  23399. 14:11:04faster for SQL if you say okay select
  23400. 14:11:06one. So let's stick with the best
  23401. 14:11:08practices. Use the one value if you are
  23402. 14:11:11working with exist. So this is our sub
  23403. 14:11:14query and I think we have everything.
  23404. 14:11:17Let's go and execute it. Now as you can
  23405. 14:11:19see in the output we got all the orders
  23406. 14:11:21where the customers come from Germany.
  23407. 14:11:23Now of course if you want to go and try
  23408. 14:11:25another value and execute you will get
  23409. 14:11:28exactly the same results. So it doesn't
  23410. 14:11:30matter which value you are using. So
  23411. 14:11:32with that we have solved the task this
  23412. 14:11:33time using the exists. Now if the task
  23413. 14:11:35says show the details of orders made by
  23414. 14:11:38customers that don't come from Germany
  23415. 14:11:40it's going to be very simple. We're
  23416. 14:11:42going to go and use the operator not
  23417. 14:11:44before the exist. So where not exists.
  23418. 14:11:47So now we are flipping the whole logic
  23419. 14:11:49and we are saying there should be no
  23420. 14:11:51matching with the subquery. So now if
  23421. 14:11:54you go and execute it you will get all
  23422. 14:11:56the orders where the customers don't
  23423. 14:11:59come from Germany by simply using the
  23424. 14:12:01not logic. And there is one more thing
  23425. 14:12:03that is annoying about the correlated
  23426. 14:12:05subqueries. If you compare to the
  23427. 14:12:06non-correlated subqueries as we learned
  23428. 14:12:09before, let me go back to the n
  23429. 14:12:11operator. Now this is a non-correlated
  23430. 14:12:13subquery. And if I go and select only
  23431. 14:12:16the subquery, I can go and execute it
  23432. 14:12:18independently. So I can go and check the
  23433. 14:12:21intermediate results and like validate
  23434. 14:12:23my query. But the problem with the
  23435. 14:12:25correlated subquery, I cannot go and
  23436. 14:12:27highlight the subquery and then go and
  23437. 14:12:29execute it. And that's because in the
  23438. 14:12:31syntax of the subquery we are adding a
  23439. 14:12:34column that is outside our subquery that
  23440. 14:12:36come from the main query. So this piece
  23441. 14:12:39of information currently for the SQL is
  23442. 14:12:41unknown and that's why we are getting
  23443. 14:12:43this error because SQL saying okay I
  23444. 14:12:45don't know where this column come from.
  23445. 14:12:47So this is little bit annoying using the
  23446. 14:12:49correlated subqueries you cannot go and
  23447. 14:12:51test the intermediate results. But how I
  23448. 14:12:53usually do it I go and test like an
  23449. 14:12:55intermediate result for only one row. So
  23450. 14:12:57for example, I'm going to go and pick
  23451. 14:12:58like a customer here. For example, two.
  23452. 14:13:01So I'm going to go and say okay, the
  23453. 14:13:04customer ID should be equal to two. So
  23454. 14:13:06let me just remove this from here. I got
  23455. 14:13:09this value from the main query. So if I
  23456. 14:13:12go now and execute it, I can see here.
  23457. 14:13:14Okay, the subquery is not returning
  23458. 14:13:16anything because there is no such a
  23459. 14:13:18value. So with that, I'm just testing
  23460. 14:13:20like one row. And of course in order to
  23461. 14:13:22make this working I have to go and add
  23462. 14:13:24as well the column from the main query.
  23463. 14:13:28So this is why correlated subqueries are
  23464. 14:13:30a little bit more hard to understand
  23465. 14:13:32compared to the non-correlated because
  23466. 14:13:34we cannot go and test the intermediate
  23467. 14:13:36results like we can do there. So this is
  23468. 14:13:38another way on how to solve this task
  23469. 14:13:40using a correlated subqueries with the
  23470. 14:13:43operator exists. Okay. So now let's see
  23471. 14:13:45step by step how SQL executed the
  23472. 14:13:47correlated subqueries using the exists
  23473. 14:13:50operator. So now this time SQL will not
  23474. 14:13:52start with the subquery. SQL going to go
  23475. 14:13:55and start immediately with the main
  23476. 14:13:56query. SQL first going to identify the
  23477. 14:13:59main query and it going to go and
  23478. 14:14:01execute it. But it's going to executed
  23479. 14:14:03row by row. So the first row going to be
  23480. 14:14:05the first customer. So now SQL going to
  23481. 14:14:07go and put the first customer under the
  23482. 14:14:10test. So now the next step is that SQL
  23483. 14:14:12going to go and pass the value of the
  23484. 14:14:14customer ID from the main query to the
  23485. 14:14:17subquery. So we are doing now exactly
  23486. 14:14:19the opposite. So now what going to
  23487. 14:14:21happen? SQL going to prepare the
  23488. 14:14:22subquery with the following information.
  23489. 14:14:24So we are saying the customer ID equal
  23490. 14:14:27to one and then SQL going to go and
  23491. 14:14:29execute it. So now once SQL executed
  23492. 14:14:31this query, we will get the result of
  23493. 14:14:33one and that's because we have here
  23494. 14:14:35multiple times where the customer ID is
  23495. 14:14:38equal to one. So there is rows in the
  23496. 14:14:41order table where the customer ID equal
  23497. 14:14:43to one. So now what going to happen? the
  23498. 14:14:45row from the main query going to pass
  23499. 14:14:47the test and this customer going to be
  23500. 14:14:50included in the final results. So now
  23501. 14:14:52the next step with that is going to go
  23502. 14:14:53and start testing the second customer.
  23503. 14:14:56So we're going to put this customer
  23504. 14:14:58under the test. Now we're going to go
  23505. 14:15:00and pass the value to the subquery. So
  23506. 14:15:02here we're going to have the value of
  23507. 14:15:03two and then SQL going to go and execute
  23508. 14:15:05this query and of course we will get a
  23509. 14:15:07result because we have here multiple
  23510. 14:15:09times where the customer ID equal to
  23511. 14:15:11two. So that's why in the output of this
  23512. 14:15:13subquery we will get one. So now it's
  23513. 14:15:15still going to say great we have a value
  23514. 14:15:17from the subquery that's why it is safe
  23515. 14:15:20to show this customer in the output. And
  23516. 14:15:22now it's still going to go to the next
  23517. 14:15:24row and so on. So for the next two
  23518. 14:15:26customers the same things going to
  23519. 14:15:28happen. All of those customers will have
  23520. 14:15:31a value from the subquery and that's why
  23521. 14:15:33they are all like passing the test. So
  23522. 14:15:36we will have it in the output. Now skill
  23523. 14:15:38going to go to the last row from the
  23524. 14:15:40table customers. So we have the Anna and
  23525. 14:15:43we're going to put Anna to the test. So
  23526. 14:15:45now what going to happen? SQL going to
  23527. 14:15:46go and pass the value five to the
  23528. 14:15:49subquery and SQL going to go and execute
  23529. 14:15:51this query to the table orders. Now once
  23530. 14:15:54SQL execute this query there will be
  23531. 14:15:56nothing returned and that's because we
  23532. 14:15:59don't have here in the table orders a
  23533. 14:16:01customer ID equal to five. And now SQL
  23534. 14:16:03going to say well we are not getting any
  23535. 14:16:05results from the subquery. That's why
  23536. 14:16:08this customer going to fail and SQL will
  23537. 14:16:11not show it at the output. So it will be
  23538. 14:16:14completely removed. So the customer Anna
  23539. 14:16:16is excluded because the subquery is not
  23540. 14:16:18returning anything. Customer ID number
  23541. 14:16:20five Anna does not exist in the table
  23542. 14:16:24orders. So it's going to fail the test
  23543. 14:16:25and we will have in the final results
  23544. 14:16:28only for customers. So this is exactly
  23545. 14:16:30the purpose of the exist. we are
  23546. 14:16:32checking and testing the existence of
  23547. 14:16:34our rows from another table from another
  23548. 14:16:37query. So this is how SQL executes the
  23549. 14:16:40correlated subqueries using the operator
  23550. 14:16:43[Music]
  23551. 14:16:47exists. All right friends, so with that
  23552. 14:16:49you have covered everything about the
  23553. 14:16:51subqueries, all the different categories
  23554. 14:16:53and types of the subqueries and now
  23555. 14:16:55we're going to do a quick recap about
  23556. 14:16:56the subqueries. So as we learned
  23557. 14:16:58subqueries is just simply a query inside
  23558. 14:17:01another query. And we use the subqueries
  23559. 14:17:04in order to break down a complex queries
  23560. 14:17:07into smaller, simpler, easy to manage
  23561. 14:17:10pieces that makes everything easier to
  23562. 14:17:12develop and as well to read. And as we
  23563. 14:17:14learned there are like many different
  23564. 14:17:16use cases for the subqueries. So we use
  23565. 14:17:18subqueries in order to create temporary
  23566. 14:17:21result sets to be used later from
  23567. 14:17:23another query. And we learned that we
  23568. 14:17:25can use the subqueries in order to
  23569. 14:17:27prepare the data before joining the
  23570. 14:17:30tables. And another very important use
  23571. 14:17:32case for the subquery is that we can use
  23572. 14:17:34it in order to filter our data using a
  23573. 14:17:37dynamic and as well complex filter
  23574. 14:17:40logics. And as we learned, we can go and
  23575. 14:17:42use the correlated subqueries using the
  23576. 14:17:44exist operator in order to check the
  23577. 14:17:47existence of data and rows from another
  23578. 14:17:50tables. and as well using the correlated
  23579. 14:17:52subqueries help us to do rowby row
  23580. 14:17:55comparison. All right my friends, so
  23581. 14:17:56with that we have covered an important
  23582. 14:17:58technique on how to nest your queries in
  23583. 14:18:00SQL. Now in the next step we're going to
  23584. 14:18:02talk about one of the most famous
  23585. 14:18:04technique on how to do multi steps in
  23586. 14:18:06SQL the city common table expression. So
  23587. 14:18:09let's go.
  23588. 14:18:14A city common table expression is a
  23589. 14:18:17temporary named result set like a
  23590. 14:18:19virtual table that could be used
  23591. 14:18:21multiple times within your query to
  23592. 14:18:24simplify and organize complex query. So
  23593. 14:18:27let's understand what this means using
  23594. 14:18:29the following sketch. So we have our
  23595. 14:18:31database tables like orders, customers
  23596. 14:18:33and so on. And in very simple scenario
  23597. 14:18:35we write a simple SQL in order to query
  23598. 14:18:38and retrieve the data from the database
  23599. 14:18:40and then in the output we will get the
  23600. 14:18:42result of the query. So this is the
  23601. 14:18:44simplest version of querying data. Now
  23602. 14:18:46things get complicated in our project
  23603. 14:18:48and we could have the following
  23604. 14:18:50technique in our query. So we still have
  23605. 14:18:52this section where we are saying select
  23606. 14:18:54from. But now inside our query we can
  23607. 14:18:57write another query like for example
  23608. 14:18:59select from where which is completely
  23609. 14:19:02nothing to do with the first query and
  23610. 14:19:04we can give this new query inside our
  23611. 14:19:06query a name CTE and we can call this
  23612. 14:19:09query a CTE query common table
  23613. 14:19:12expression. And the first query outside
  23614. 14:19:14this CDE we call it a main query. Now if
  23615. 14:19:17you check this we have like a query
  23616. 14:19:19inside another query. So now let's see
  23617. 14:19:21what is going to do with this. The first
  23618. 14:19:23thing is going to go and execute the
  23619. 14:19:25city query. So the city query going to
  23620. 14:19:28be executed and we're going to go and
  23621. 14:19:30retrieve few informations from our
  23622. 14:19:31database tables. Now the output going to
  23623. 14:19:34be available only in the query and the
  23624. 14:19:36output going to have the shape of like a
  23625. 14:19:38table like for example the sales. So now
  23626. 14:19:40the sales table and the orders tables
  23627. 14:19:43both of them are tables but one is
  23628. 14:19:45stored in the database and the other one
  23629. 14:19:48is an intermediate virtual table. So now
  23630. 14:19:51what can happen in the main query we can
  23631. 14:19:53go and start querying the sales table
  23632. 14:19:56the result from the CTE as any other
  23633. 14:19:59normal table like we do to the database
  23634. 14:20:01tables. So the main query going to go
  23635. 14:20:03and retrieve few informations and maybe
  23636. 14:20:05do some manipulations on top of the
  23637. 14:20:07sales table or let's say the CTE results
  23638. 14:20:10and of course the main query as well can
  23639. 14:20:12go and say you know what let's go and
  23640. 14:20:13query as well few tables from the
  23641. 14:20:16database. So the main query has two
  23642. 14:20:18sources of tables. Either get it
  23643. 14:20:20directly from the database or get it
  23644. 14:20:22from the table that is created inside
  23645. 14:20:25the query and then once everything is
  23646. 14:20:27done the final results of the main query
  23647. 14:20:29going to be presented for the user as a
  23648. 14:20:32final result. So as you can see the CTA
  23649. 14:20:34query has one task where it generates
  23650. 14:20:37like a table that lives inside our query
  23651. 14:20:40and we can go and use it as we want. So
  23652. 14:20:42now this intermediate table that is
  23653. 14:20:44created from the city has two features.
  23654. 14:20:46First this table will not live long. So
  23655. 14:20:49once the query ends what going to happen
  23656. 14:20:51is going to go and destroy this table.
  23657. 14:20:54So it will not be available afterward
  23658. 14:20:56and we are not able to query it anymore.
  23659. 14:20:58So SQL is doing here like a cleanup and
  23660. 14:21:00the second character about this let's
  23661. 14:21:02imagine that we have another side query
  23662. 14:21:05and it's retrieving tables directly from
  23663. 14:21:07the database tables. Now if you say
  23664. 14:21:09let's go and join those tables as well
  23665. 14:21:12with the sales from the first query well
  23666. 14:21:14it will not be working because SQL going
  23667. 14:21:16to say I don't know what you are talking
  23668. 14:21:18about and that's because the sales is
  23669. 14:21:21only locally available for the main
  23670. 14:21:24query in the same query. So that means
  23671. 14:21:28it's not globally available like the
  23672. 14:21:30database tables for any query. It is
  23673. 14:21:32dedicated only for the main query within
  23674. 14:21:35the same query. And now you might tell
  23675. 14:21:37me bar wait I have heard this story
  23676. 14:21:40before right? So this is an identical
  23677. 14:21:42story to the one that you have told us
  23678. 14:21:44about the subqueries. So what is exactly
  23679. 14:21:46the difference between the subquery and
  23680. 14:21:48the CTE? Well, you are totally right.
  23681. 14:21:50The story is identical between the
  23682. 14:21:52subqueries and the CTE but still there
  23683. 14:21:54are differences between them. So let me
  23684. 14:21:56show you few differences. Now let's put
  23685. 14:21:58them side by side. We have on the left
  23686. 14:22:00side the subqueries on the right side we
  23687. 14:22:02have the CTE. So now if you look on how
  23688. 14:22:04we wrote the CT and the subqueries you
  23689. 14:22:07can see that on the subquery we are
  23690. 14:22:08writing it from bottom to top. So first
  23691. 14:22:11we have this inner query the subquery
  23692. 14:22:14and then on top of it we have the main
  23693. 14:22:16query. But now on the other hand the CTE
  23694. 14:22:18we are writing it from top to bottom. So
  23695. 14:22:20first we write this inner query the CTE
  23696. 14:22:23query and then beneath it we're going to
  23697. 14:22:25go and write the main query. So this is
  23698. 14:22:27the first difference between them on the
  23699. 14:22:30way we write the query. So if I'm
  23700. 14:22:32thinking about subqueries, I start from
  23701. 14:22:34bottom to top. If I'm thinking about
  23702. 14:22:35CTE, I think from top to bottom. But
  23703. 14:22:38still you say, you know what, I don't
  23704. 14:22:39care how we write it. They are doing the
  23705. 14:22:41same thing. The subquery is introducing
  23706. 14:22:44an intermediate result that is used
  23707. 14:22:46later from the main query. And the same
  23708. 14:22:49thing for the CTE. It present like
  23709. 14:22:51intermediate table that is used as well
  23710. 14:22:53from the main query. Now let me tell you
  23711. 14:22:55the big differences between them is that
  23712. 14:22:57in the subquery the result can be used
  23713. 14:23:00only once. So you cannot have another
  23714. 14:23:02place in your main query where you go
  23715. 14:23:05and reuse the result from the subquery.
  23716. 14:23:07So you can use it maximum only in one
  23717. 14:23:10position and only once. But in the other
  23718. 14:23:12hand with the city technique, you can
  23719. 14:23:14think about the sales table as a virtual
  23720. 14:23:17table and not only you can use it in one
  23721. 14:23:19place in the main query, you can go and
  23722. 14:23:22use it in many other places. So you can
  23723. 14:23:25go and join it again. So that means I'm
  23724. 14:23:27using the output from the CTE query in
  23725. 14:23:30two different places in the main query
  23726. 14:23:32or maybe from three different places. So
  23727. 14:23:34you can have another place where you go
  23728. 14:23:36as well and query the sales table that
  23729. 14:23:39is only available in our query. So this
  23730. 14:23:41is the main and the most important
  23731. 14:23:43difference between the subquery and the
  23732. 14:23:44CTE. It's from the name common table
  23733. 14:23:46expression. We think about the result of
  23734. 14:23:48the CTE as a table. So we can go and
  23735. 14:23:52select it. We can go and join it with
  23736. 14:23:54any other table. So it is like a hidden
  23737. 14:23:56virtual table lives inside our query.
  23738. 14:23:59But the subqueries it's totally
  23739. 14:24:01different. It's a result only for one
  23740. 14:24:03position in the main query and it's used
  23741. 14:24:06only once. So that means if you want the
  23742. 14:24:08subquery in two three different places,
  23743. 14:24:10you have to go and write the subquery
  23744. 14:24:12three different times. So now you
  23745. 14:24:14understand why do we have CTE and why do
  23746. 14:24:17we have
  23747. 14:24:21subqueries. All right. So with that you
  23748. 14:24:23have understood what is CTE. Now the
  23749. 14:24:25question is why do we need CTE in the
  23750. 14:24:27first place? What is the main purpose of
  23751. 14:24:30the CTE? Let's go back to the sketch.
  23752. 14:24:32Now let's say in our complex SQL task we
  23753. 14:24:35have to do the following step. Step one
  23754. 14:24:37we have to go and join the tables
  23755. 14:24:38together in order to prepare all the
  23756. 14:24:40data that we need for the next step. And
  23757. 14:24:42now in the second step we have to go and
  23758. 14:24:44aggregate the data. Maybe we are doing
  23759. 14:24:46summarizations. Now in our task we have
  23760. 14:24:48to do as well different types of
  23761. 14:24:50aggregations based on different data.
  23762. 14:24:52And now what might happen is that we
  23763. 14:24:54have to go and join again the same
  23764. 14:24:56tables in order to prepare the data and
  23765. 14:24:58perform different type of aggregations
  23766. 14:25:00like for example the average which going
  23767. 14:25:02to be in the last step. Now we have
  23768. 14:25:04learned before we can go and use the
  23769. 14:25:06subqueries in order to make this logical
  23770. 14:25:08flow. So for step one, step two, step
  23771. 14:25:11three, we will have subqueries and the
  23772. 14:25:13final step going to be in the main
  23773. 14:25:15query. But now if we keep doing this
  23774. 14:25:17we're gonna have a problem and that is
  23775. 14:25:19we are repeating the same step more than
  23776. 14:25:22once. So we are joining the table twice
  23777. 14:25:24in step number one and three for
  23778. 14:25:26different purposes which cause us to
  23779. 14:25:28have two different subqueries that looks
  23780. 14:25:31exactly the same and this is exactly the
  23781. 14:25:34weak point of the subqueries. It might
  23782. 14:25:36introduce redundancies. So that means
  23783. 14:25:39the subqueries alone will not help you
  23784. 14:25:41to eliminate all the duplicates in your
  23785. 14:25:44code. But still we have different
  23786. 14:25:45techniques in order to solve this issue.
  23787. 14:25:47So what we going to do? We're going to
  23788. 14:25:49have only one step in order to join the
  23789. 14:25:52tables. And then this data going to be
  23790. 14:25:53used in the step two in order to
  23791. 14:25:55aggregate the data. And then we don't
  23792. 14:25:57need the step three of joining again the
  23793. 14:25:59data. We're going to reuse the step one.
  23794. 14:26:02And we're going to use the same data for
  23795. 14:26:04the step four which is aggregating the
  23796. 14:26:06data using average. And we can do this
  23797. 14:26:09with the help of the amazing CTE. So now
  23798. 14:26:11if you compare the steps in the
  23799. 14:26:13subqueries with the steps with the CTE
  23800. 14:26:15you can see with the CTE we are reducing
  23801. 14:26:18the number of steps which can lead to
  23802. 14:26:20reduce the size of the query. So now
  23803. 14:26:22again here in subquery we think about
  23804. 14:26:24the steps from bottom to top but in the
  23805. 14:26:27city it's the way around we think from
  23806. 14:26:30top to bottom. So that means the first
  23807. 14:26:31step on the top it's going to be joining
  23808. 14:26:33the tables and then below it going to be
  23809. 14:26:35step two and step three. And of course
  23810. 14:26:37since we are repeating the join we're
  23811. 14:26:38going to put it in CTE and then we can
  23812. 14:26:40use it twice in different places in the
  23813. 14:26:43main query. So as you can see there are
  23814. 14:26:45a lot of benefits of the CTE. It's like
  23815. 14:26:47the subqueries. We are breaking down
  23816. 14:26:49complex queries into smaller pieces that
  23817. 14:26:52are easier to write manage understand
  23818. 14:26:55and as well we have like a logical flow
  23819. 14:26:57from step one to three but with one more
  23820. 14:26:59benefit that we reduce the redundancies
  23821. 14:27:03of our code. So we don't have to join
  23822. 14:27:05the tables twice. Now I'm going to show
  23823. 14:27:06you a simple example how the CTE makes
  23824. 14:27:09our life easier in our query. We might
  23825. 14:27:11have to do different stuff like for
  23826. 14:27:13example we have to go and find the top
  23827. 14:27:15customers. So we can put this in one CTE
  23828. 14:27:18and we might need as well to calculate
  23829. 14:27:20what are the top products and we can put
  23830. 14:27:22as well this in another city. So you
  23831. 14:27:25don't have to put everything in one big
  23832. 14:27:26city. Then you can have the same issue
  23833. 14:27:28of having complex query. And let's say
  23834. 14:27:30that we have as well to find and
  23835. 14:27:31calculate the daily revenue. And for
  23836. 14:27:34this as well, we have to put it in one
  23837. 14:27:35CTE. Now once we have all those parts,
  23838. 14:27:38we can put everything together in the
  23839. 14:27:40main query. So now if you look to this
  23840. 14:27:42structure, you can see it's really easy
  23841. 14:27:44to understand this code. It's easy to
  23842. 14:27:47read. So CTE improves the readability of
  23843. 14:27:50our queries. So that means your code is
  23844. 14:27:52divided into clear sections making it
  23845. 14:27:55easier to understand what each part
  23846. 14:27:57does. Now if you keep looking to this we
  23847. 14:27:59have another advantage of the CTE
  23848. 14:28:02introduces modularity. So that means it
  23849. 14:28:04breaks your code into smaller manageable
  23850. 14:28:07parts. So this means instead of writing
  23851. 14:28:10one huge complex query you break it down
  23852. 14:28:13into smaller chunks using CTE. Each city
  23853. 14:28:16is like self-contained and handles
  23854. 14:28:19specific part of the problem and then
  23855. 14:28:21you can combine them all together in the
  23856. 14:28:23final query. It's like we are putting
  23857. 14:28:25together a puzzle piece by piece. And
  23858. 14:28:27now one very important advantage of the
  23859. 14:28:29CTE is the reusability. So that means we
  23860. 14:28:32can have a result set that is used
  23861. 14:28:34multiple times inside our query. So that
  23862. 14:28:37means you write the logic the code only
  23863. 14:28:39once and then use it in different places
  23864. 14:28:41inside your query. This is very
  23865. 14:28:43important. Not only you are wasting time
  23866. 14:28:45writing the same stuff over and over,
  23867. 14:28:47but also it reduces the errors and
  23868. 14:28:49mistakes that you might do if you are
  23869. 14:28:51repeating the same code. Especially if
  23870. 14:28:53later you want to go and change the
  23871. 14:28:54logic then you have to go and visit each
  23872. 14:28:57time you have done this logic and then
  23873. 14:28:59do the changes and you might forget some
  23874. 14:29:01places. That's why the CTE is amazing.
  23875. 14:29:04You can write the logic once and then
  23876. 14:29:06you go and reuse it in different places.
  23877. 14:29:08So these are the advantages of using
  23878. 14:29:10this technique the CTE inside your
  23879. 14:29:13[Music]
  23880. 14:29:16queries. So again you are at the client
  23881. 14:29:19side and you are data analyst. You are
  23882. 14:29:21writing a query where you are defining a
  23883. 14:29:23CTE called details and inside it you
  23884. 14:29:25have some logic and now in the main
  23885. 14:29:27query you are selecting the data from
  23886. 14:29:29the orders and as well you are joining
  23887. 14:29:31it with the details with the CTE
  23888. 14:29:33multiple times using multiple
  23889. 14:29:35conditions. Now once you go and execute
  23890. 14:29:37this query the database engine going to
  23891. 14:29:39read the query and say aha we have here
  23892. 14:29:41a CTE and it has the main priority. So
  23893. 14:29:44that means it going to go and execute
  23894. 14:29:46the CTE first. And now let's say that in
  23895. 14:29:48the city you are retrieving data from
  23896. 14:29:50the table orders and the table orders of
  23897. 14:29:52course in the disk storage inside the
  23898. 14:29:54user data. And now once the city is
  23899. 14:29:57completely executed the database engine
  23900. 14:29:59going to go and place the results in the
  23901. 14:30:01cache and it's going to name this result
  23902. 14:30:03as details. It's like a table name. So
  23903. 14:30:06the database engine is done with the
  23904. 14:30:07CTE. It's going to go now and grab the
  23905. 14:30:09main query and it's going to start
  23906. 14:30:11executing it step by step. So the first
  23907. 14:30:13step is that to get the data from the
  23908. 14:30:15orders. So since the orders exist in the
  23909. 14:30:17disk storage, it going to go and
  23910. 14:30:19retrieve it from there. Now the database
  23911. 14:30:21engine going to check the details. Okay,
  23912. 14:30:22we have it in the cache. That means we
  23913. 14:30:25don't have to search for it in the disk
  23914. 14:30:26storage and it going to start retrieving
  23915. 14:30:28the data from the details with high
  23916. 14:30:30speed. And now it's going to go to the
  23917. 14:30:32second step as well joining the data
  23918. 14:30:34with the details. So again the database
  23919. 14:30:36engine going to go to the cache and
  23920. 14:30:37going to see the table details and
  23921. 14:30:39retrieve the data based maybe in
  23922. 14:30:40different conditions. And then to the
  23923. 14:30:42third time as well we are joining to the
  23924. 14:30:44details and we're going to get the data
  23925. 14:30:45from the cache. So as you can see from
  23926. 14:30:47the main query we are using the result
  23927. 14:30:50from the CTE multiple times in different
  23928. 14:30:52places and the retrieval of all those
  23929. 14:30:54informations is happening in high speed.
  23930. 14:30:57So this is one big benefit of using the
  23931. 14:30:59CTE is to utilize using the high-speed
  23932. 14:31:02memory of the cache. So that means
  23933. 14:31:04retrieving the data from the cache from
  23934. 14:31:06the details is way faster than
  23935. 14:31:08retrieving the data from the disk
  23936. 14:31:10storage from the orders. Now once the
  23937. 14:31:12main query is completely executed the
  23938. 14:31:14result going to be returned to the
  23939. 14:31:16database engine and then it's going to
  23940. 14:31:18send it back to the client side and we
  23941. 14:31:20will see the results in the output. So
  23942. 14:31:22that's it. It's amazing right? This is
  23943. 14:31:24how the database server execute the
  23944. 14:31:26amazing technique the CTE behind the
  23945. 14:31:29scenes.
  23946. 14:31:33All right. So now for the CTE, we don't
  23947. 14:31:35have only one CTE. We have different
  23948. 14:31:37types of CTE. So mainly there are like
  23949. 14:31:40two types of CTE. We have the
  23950. 14:31:42nonrecursive CTE and recursive CTE. And
  23951. 14:31:45we can say for the nonrecursive CTE, we
  23952. 14:31:48have two subtypes. The first type is the
  23953. 14:31:51standalone CTE and the second one is the
  23954. 14:31:54nested CTE. And now what we're going to
  23955. 14:31:56do, we're going to deep dive into each
  23956. 14:31:57type. And we will start with the easiest
  23957. 14:32:00form of the CTE, the standalone CTE. It
  23958. 14:32:03is the simplest
  23959. 14:32:08form. So what is standalone CTE? It is a
  23960. 14:32:11CTE query that is defined and used
  23961. 14:32:14independently in the query. So that
  23962. 14:32:16means it is self-contained and it
  23963. 14:32:18doesn't depend on anything. It doesn't
  23964. 14:32:20depend on any other CTE or queries. So
  23965. 14:32:24that means we can run the standalone
  23966. 14:32:26query independently from anything inside
  23967. 14:32:28our query. So let's understand what this
  23968. 14:32:30means. We have our CTE. It's going to go
  23969. 14:32:32and query the database tables and in the
  23970. 14:32:35output we will get an intermediate
  23971. 14:32:37results and then the output can be used
  23972. 14:32:39from the main query. So the main query
  23973. 14:32:41going to query the intermediate results
  23974. 14:32:43and present in the output the final
  23975. 14:32:45results. So now if you check our CTE, it
  23976. 14:32:47is completely independent from anything
  23977. 14:32:49else. So it simply query the database
  23978. 14:32:52and it has one output. So since this CTE
  23979. 14:32:55is independent from anything else we
  23980. 14:32:57call it a standalone CTE. Now if you
  23981. 14:33:00compare this CT with the main query you
  23982. 14:33:02can see that the main query cannot be
  23983. 14:33:04executed alone. And that's because it
  23984. 14:33:06needs the result from the first query.
  23985. 14:33:09So we cannot say the main query is
  23986. 14:33:11independent cannot be executed alone. It
  23987. 14:33:14always depend on the city query. So that
  23988. 14:33:17means city first need to be executed
  23989. 14:33:19then the main query can be executed. So
  23990. 14:33:21this is what we mean with the standalone
  23991. 14:33:24city. It doesn't depend on anything
  23992. 14:33:26else. So now we can understand the
  23993. 14:33:28syntax of the CTE. So we have a very
  23994. 14:33:30simple query select from where. So it is
  23995. 14:33:32a very simple select statement. Now in
  23996. 14:33:35order to put it inside a CTE we can go
  23997. 14:33:38and use the with clause. So it starts
  23998. 14:33:41with the keyword with then the CTE name.
  23999. 14:33:44It's like a table name and then we have
  24000. 14:33:46the keyword as in order to say this CTE
  24001. 14:33:49is defined like the following. So this
  24002. 14:33:52is the definition of the CTE and it has
  24003. 14:33:54two parenthesis the starting and the
  24004. 14:33:56ending. So with this you are telling a
  24005. 14:33:58scale okay now we are talking about CTE
  24006. 14:34:01and it has a name. So if you are using a
  24007. 14:34:03query inside with clause we call this a
  24008. 14:34:06CTE query it is where you define the
  24009. 14:34:08CTE. Now of course we don't want only to
  24010. 14:34:11define a CTE. We want to use it. So
  24011. 14:34:13outside of this definition we can go and
  24012. 14:34:15use it like this. So we are saying
  24013. 14:34:17select from the CTE name. So that means
  24014. 14:34:21we want to select the data from the
  24015. 14:34:23result of the CTE. And here it's very
  24016. 14:34:25important to use exactly the same name
  24017. 14:34:27as you define it in the width clause. So
  24018. 14:34:30if you leave it like this, we can call
  24019. 14:34:32this the main query. It is the place
  24020. 14:34:34where we use the CTE. So this is the
  24021. 14:34:37syntax of a very simple CTE in SQL.
  24022. 14:34:40Okay. So now what we're going to do,
  24023. 14:34:42we're going to have like a task that's
  24024. 14:34:44going to keep progressing through this
  24025. 14:34:45section. So we're going to start with
  24026. 14:34:47the first step and we will keep adding
  24027. 14:34:49steps as we progress in the CTE. So now
  24028. 14:34:51the first step in this task says find
  24029. 14:34:54the total sales per customer. And now of
  24030. 14:34:56course since we have only one step, it
  24031. 14:34:58makes no sense to use the CTE. But we
  24032. 14:35:00will use it since we know that there
  24033. 14:35:02will be different steps later. So let's
  24034. 14:35:05start doing that. Now before I use any
  24035. 14:35:07CTE, I would like just to write our
  24036. 14:35:09query first. So we need the total sales
  24037. 14:35:11for each customers. It's very simple. So
  24038. 14:35:13we're going to go and select and what do
  24039. 14:35:15we need? Let's go and get the customer
  24040. 14:35:17ID and we need to do aggregations on the
  24041. 14:35:21sales. So summarize the sales and we're
  24042. 14:35:24going to call it total sales from the
  24043. 14:35:28table. And now since this is our first
  24044. 14:35:30query, we have to get the data from our
  24045. 14:35:32database. So we don't have any other
  24046. 14:35:34option. Our data going to be in the
  24047. 14:35:35sales orders. So let's go and get it.
  24048. 14:35:39And don't forget to group by for the
  24049. 14:35:41aggregation. We are grouping by the
  24050. 14:35:43customer ID. That's it. Let's go and
  24051. 14:35:46execute it. And as you can see in the
  24052. 14:35:47output, nothing is fancy. We are just
  24053. 14:35:49aggregating the sales by the customers.
  24054. 14:35:51So with that, we have solved the task.
  24055. 14:35:53But now I would like to put my query in
  24056. 14:35:55a CTE. And that's because later we're
  24057. 14:35:57going to add more steps. So let's put
  24058. 14:35:59our query in a city. And in order to do
  24059. 14:36:02that, we're going to start with the with
  24060. 14:36:04keyword. And now we have to define the
  24061. 14:36:07name of the CD. So I'm going to call it
  24062. 14:36:09city
  24063. 14:36:10total sales like this. And then
  24064. 14:36:13afterward we're going to say as and then
  24065. 14:36:15we have to go and add the parenthesis at
  24066. 14:36:17the start and as well at the end. And
  24067. 14:36:20with that we are telling SQL this query
  24068. 14:36:22is a CTE query. So that means the SQL
  24069. 14:36:26should store the result of this query in
  24070. 14:36:29a cache in memory to be used later in
  24071. 14:36:31the main query. our CTE and of course
  24072. 14:36:34what is missing is the main query and
  24073. 14:36:36you have to do it exactly after the
  24074. 14:36:38definition of the CTE. I will just make
  24075. 14:36:40here a small comment about the main
  24076. 14:36:42query. Uh let me just make this smaller
  24077. 14:36:45like this. And now we have to go and
  24078. 14:36:47have a very simple select
  24079. 14:36:49statements from. And now I would like to
  24080. 14:36:51get more details from the customers
  24081. 14:36:53table. So I will just go now to the
  24082. 14:36:57customers. So now we are not querying
  24083. 14:37:00the CTE right? We are just querying the
  24084. 14:37:02database table that we have and I would
  24085. 14:37:04like to get from the customer the
  24086. 14:37:06customer ID and the first name and let's
  24087. 14:37:11go and get as well the last
  24088. 14:37:13name. So now if we go and query this
  24089. 14:37:17what happens in the output we are
  24090. 14:37:18getting the data actually completely
  24091. 14:37:21from the database table the customers
  24092. 14:37:24and of course we are not using at all
  24093. 14:37:26the CTE inside our main query. Of
  24094. 14:37:28course, we can do that, but it's just
  24095. 14:37:29waste of like space in the memory
  24096. 14:37:31because SQL did execute this and stored
  24097. 14:37:34it in the database memory. And of
  24098. 14:37:36course, we would like to use the city in
  24099. 14:37:38our main query. So, let's go and do
  24100. 14:37:40that. So, let's go and do a join, but
  24101. 14:37:43this time we're going to join the data
  24102. 14:37:45from the CTE. So, let's go and get the
  24103. 14:37:47name and I will just call it CTS. So
  24104. 14:37:51what we are doing now we are joining the
  24105. 14:37:53physical table the customers with the
  24106. 14:37:56virtual table that we have created with
  24107. 14:37:58the CTE that exist only in our query and
  24108. 14:38:02of course not only we are joining the
  24109. 14:38:04tables we would like to get the
  24110. 14:38:06informations from the CTE. So CTS and we
  24111. 14:38:09need only the total sales. So total
  24112. 14:38:12sales. So that means those three columns
  24113. 14:38:16comes from our database table customers
  24114. 14:38:18and only this column the total sales
  24115. 14:38:20comes from our CTE. So let's go and
  24116. 14:38:22execute the whole thing. Now as you can
  24117. 14:38:24see in the output everything is working.
  24118. 14:38:26We have the three columns from the table
  24119. 14:38:28customers and we have the total sales
  24120. 14:38:31for each customer and this total sales
  24121. 14:38:33comes from our city. Now as you can see
  24122. 14:38:35the last customer has a null over here
  24123. 14:38:38and that's because in the table orders
  24124. 14:38:40we don't have the customer five. And now
  24125. 14:38:42you might say you know what I would like
  24126. 14:38:43to see the intermediate result from the
  24127. 14:38:45CTE because what we are seeing now in
  24128. 14:38:47the output is the final result from the
  24129. 14:38:50main query. So now what we can do in
  24130. 14:38:52order to see the result of the CTE we're
  24131. 14:38:55going to mark the query in the CTE of
  24132. 14:38:57course without any parenthesis or the
  24133. 14:38:59width. So just the query and execute it.
  24134. 14:39:02And with that you can see in the output
  24135. 14:39:04the intermediate results that we are
  24136. 14:39:06passing to the main query. And as you
  24137. 14:39:08can see we don't have here customer
  24138. 14:39:10number five. That's why in the final
  24139. 14:39:12results we are getting null and that's
  24140. 14:39:14of course because we are using the lift
  24141. 14:39:16join. So if I execute the whole thing
  24142. 14:39:19you can see we are getting the customer
  24143. 14:39:20five over here with the null. So as you
  24144. 14:39:22can see is very simple. We just treat it
  24145. 14:39:24as any normal database table. But this
  24146. 14:39:26table is created from our query that we
  24147. 14:39:29have defined in the city over here. Now
  24148. 14:39:31of course in the city you can use any
  24149. 14:39:34kind of clauses like select from join
  24150. 14:39:37group by having everything that you want
  24151. 14:39:39window functions all aggregate functions
  24152. 14:39:41but there is only one restriction you
  24153. 14:39:44cannot go and use the order by clause so
  24154. 14:39:47you cannot sort the data in the city so
  24155. 14:39:50let's go and try it out let's go and say
  24156. 14:39:53order by and let's say I want to sort by
  24157. 14:39:56the order ID for example so let's go and
  24158. 14:39:58execute it you can see here SQL is
  24159. 14:40:00saying Okay, I cannot do it for you
  24160. 14:40:03because order by is not allowed in many
  24161. 14:40:05things. So you cannot use it in views,
  24162. 14:40:07in sub queries, in comment table
  24163. 14:40:10expressions, the CTE over here. So it is
  24164. 14:40:12not allowed. You cannot use order by in
  24165. 14:40:15the CTE. But of course you can go and
  24166. 14:40:17sort the data in the main query. So if
  24167. 14:40:20you go over here and say order by
  24168. 14:40:23customer ID. So if we execute it, it's
  24169. 14:40:27going to be working. So in the main
  24170. 14:40:29query you can use order by but in the
  24171. 14:40:31CTE this is the only thing that you
  24172. 14:40:33cannot use inside the city. So that's
  24173. 14:40:35it. This is our first CTE in this
  24174. 14:40:38section. All right. So this is the
  24175. 14:40:40simplest form of the CTE the standalone.
  24176. 14:40:42Now we can have not only one CTE, we can
  24177. 14:40:45have multiple
  24178. 14:40:50CTE. So it's going to look like this. We
  24179. 14:40:52have our database and this time we don't
  24180. 14:40:54have only one CTE. We have multiple
  24181. 14:40:57CTEes in our query and each CTE is going
  24182. 14:41:01directly to the database and it will
  24183. 14:41:03query the database in order to prepare
  24184. 14:41:06the intermediate results. So in this
  24185. 14:41:08example four CDEs is going to the
  24186. 14:41:10database and preparing four different
  24187. 14:41:13intermediate results and of course SQL
  24188. 14:41:15going to execute it from the top to the
  24189. 14:41:16bottom. So first the CD 1 then 2 3 four
  24190. 14:41:19but they have nothing to do with each
  24191. 14:41:21others. So now once we have all the four
  24192. 14:41:23intermediate results the main query
  24193. 14:41:25going to go and retrieve all those
  24194. 14:41:26informations and do some magic in order
  24195. 14:41:28to prepare the final result for the end
  24196. 14:41:31user. So now by looking to this sketch
  24197. 14:41:33you can understand all those CTE are
  24198. 14:41:35independent from each others. So there
  24199. 14:41:37is no nesting or something. Each CTE is
  24200. 14:41:40self-contained and it could be executed
  24201. 14:41:42on its own without depending on any
  24202. 14:41:45other results from any other CTE or any
  24203. 14:41:48other query. So it goes directly to the
  24204. 14:41:50database and get the data. So that's why
  24205. 14:41:53all of them are standalone CDs. And
  24206. 14:41:55since we have multiple CDs, then it is
  24207. 14:41:57standalone multiple CDs. That's it. It's
  24208. 14:42:00simple. So now let's check the syntax of
  24209. 14:42:02the multiple standalone cities. So we're
  24210. 14:42:04going to start writing our first city.
  24211. 14:42:06So it start with the with clause and
  24212. 14:42:08then we have the city name and then the
  24213. 14:42:10logic of our city. So nothing new. This
  24214. 14:42:12is how we define the city. And then in
  24215. 14:42:15order to use it, we're going to have our
  24216. 14:42:16main query where we select from our new
  24217. 14:42:19city and we make sure we are using the
  24218. 14:42:21name of our city. So nothing new. Now in
  24219. 14:42:24order to add another city to our query,
  24220. 14:42:27what we're going to do, we're going to
  24221. 14:42:28go after the definition of the city. And
  24222. 14:42:31below it, we're going to go and start
  24223. 14:42:33defining the city too. But this time, as
  24224. 14:42:36you can see, we are not using the width
  24225. 14:42:38clause. We are using a comma. So that
  24226. 14:42:40means only the first city going to be
  24227. 14:42:43using the with clause in order to tell
  24228. 14:42:45SQL we are talking about CTE. All the
  24229. 14:42:48other CDEs you're going to separate it
  24230. 14:42:50using the comma. So the syntax going to
  24231. 14:42:52be comma instead of with then the name
  24232. 14:42:55of the CTE and then we're going to say
  24233. 14:42:57as the following definition. So we're
  24234. 14:42:59going to write here the query of the
  24235. 14:43:01second CTE. So now of course if you want
  24236. 14:43:03to go and add more CTE you go and use
  24237. 14:43:06the comma below it and as well you
  24238. 14:43:08define the third city. So you can have
  24239. 14:43:10as much cities as you want and always
  24240. 14:43:13separate it with comma but only the
  24241. 14:43:15first city start with the width. And of
  24242. 14:43:17course in the main query we can go and
  24243. 14:43:18use the results from the city 2 where we
  24244. 14:43:21are for example here joining the data
  24245. 14:43:23between the city 1 and city 2. So as you
  24246. 14:43:25can see in the main query here we are
  24247. 14:43:27like collecting the data from these
  24248. 14:43:28different cities in order to do the
  24249. 14:43:31final step in the main query. It start
  24250. 14:43:34with the width. So SQL understands okay
  24251. 14:43:36now we are talking about CTE and once
  24252. 14:43:38SQL sees after the parenthesis a comma
  24253. 14:43:40SQL can understands okay now we are
  24254. 14:43:42talking about another city and now if
  24255. 14:43:44you don't go and use a comma after the
  24256. 14:43:46parenthesis SQL can understands okay we
  24257. 14:43:49don't have any more CDEs the next query
  24258. 14:43:51it's about the main query so this is how
  24259. 14:43:54you create multiple standalone CTE all
  24260. 14:43:56right so now back to our task where we
  24261. 14:43:58are creating like a report step by step
  24262. 14:44:00so now we have in the task a second step
  24263. 14:44:02where it says find the last order date
  24264. 14:44:06for each customer. So now we have to go
  24265. 14:44:07and add one more information about our
  24266. 14:44:09customer. So when the last time the
  24267. 14:44:12customer did order. So how we going to
  24268. 14:44:13do it? Now we have to add this to our
  24269. 14:44:16query. And I would like to use as well
  24270. 14:44:18the CTE in order to have this logic. So
  24271. 14:44:20as we learned from the first task, this
  24272. 14:44:22is the first step in order to find the
  24273. 14:44:25total sales for each customer. And here
  24274. 14:44:27we have the main query. Now I would like
  24275. 14:44:29to put now in between another CTE. And
  24276. 14:44:32as we learned from the syntax, we have
  24277. 14:44:34to go and add a comma. We cannot go and
  24278. 14:44:36use the width again. And we have to give
  24279. 14:44:38it a name. So let's call it CTE and last
  24280. 14:44:42order. So latex and we have to define
  24281. 14:44:44it. So as and then double parenthesis.
  24282. 14:44:48And now in between we have to go and add
  24283. 14:44:49our logic. So now we have to focus only
  24284. 14:44:51in this logic. So forget about the other
  24285. 14:44:54CTE and the main query. So we have to
  24286. 14:44:57find the last order date for each
  24287. 14:44:59customer. So we're going to go and query
  24288. 14:45:01again the table orders. So what do we
  24289. 14:45:04need? We need the customer ID. We need
  24290. 14:45:06the order
  24291. 14:45:08date from our table sales orders. So
  24292. 14:45:13that's it for now. Let's just select it
  24293. 14:45:16and execute it. And now with that you
  24294. 14:45:18can see all the customers and as well
  24295. 14:45:20all the orders. But we would like to
  24296. 14:45:22have the highest order for each
  24297. 14:45:24customer. And we can go and use our
  24298. 14:45:26aggregate function, the max function. So
  24299. 14:45:29what we're going to do it's like here at
  24300. 14:45:30the top. So we have to go and use the
  24301. 14:45:33function max and group up by the
  24302. 14:45:36customer ID. So group up the customer
  24303. 14:45:41ID. Uh let me just shift it like this.
  24304. 14:45:44And let's give it the name last order.
  24305. 14:45:47So like this. And as you can see I'm
  24306. 14:45:49just selecting now only my query. I'm
  24307. 14:45:52not selecting everything. And I keep
  24308. 14:45:54executing in order just to check the
  24309. 14:45:56results before we integrate it in the
  24310. 14:45:59main query. So now as you can see we
  24311. 14:46:01have for each customer one row and we
  24312. 14:46:03have as well the highest order for each
  24313. 14:46:05customer. So with that we have solved
  24314. 14:46:07this subtask. So as you can see it's
  24315. 14:46:09really easy to extend. I'm just making
  24316. 14:46:11like another box and I'm adding inside
  24317. 14:46:14it the business logic that I want and
  24318. 14:46:16this going to solve one problem from the
  24319. 14:46:18whole task. So you feel now exactly the
  24320. 14:46:21power of the CTE. We are making complex
  24321. 14:46:23logic but still it's easy to add. Now
  24322. 14:46:26imagine you are not doing this. You are
  24323. 14:46:27always extending one big query. It's
  24324. 14:46:30going to be really hard to extend and
  24325. 14:46:31that's why a lot of SQL developers
  24326. 14:46:34really love using CTE and they like use
  24327. 14:46:37it in each query or in each task that
  24328. 14:46:39they have. So we have solved this task
  24329. 14:46:42and we have to go now integrated in the
  24330. 14:46:44main query. It's going to be very
  24331. 14:46:45simple. So we're going to get over here
  24332. 14:46:48and we will go and just add another
  24333. 14:46:50join. So we're going to join it with the
  24334. 14:46:52city and as you can see SQL now is
  24335. 14:46:54offering it as a table even though it is
  24336. 14:46:57not a physical table that exists in our
  24337. 14:46:59database. It only lives inside our data
  24338. 14:47:02but still SQL treat it as a table. And
  24339. 14:47:04this is exactly what we are doing. We
  24340. 14:47:06treat those informations as table. So
  24341. 14:47:08city the last order and I will call it
  24342. 14:47:11CL. And then of course we have to go and
  24343. 14:47:14do the same condition like here. So the
  24344. 14:47:18CLLO customer ID should be equal to the
  24345. 14:47:21customer ID from the first table, the
  24346. 14:47:23customers. And of course we have to go
  24347. 14:47:25and add this new information to the main
  24348. 14:47:27query. So
  24349. 14:47:28CL the last order. So now what we're
  24350. 14:47:31going to do, we're going to go and
  24351. 14:47:33execute the whole thing. So we have now
  24352. 14:47:35two CDs and as well our main query. So
  24353. 14:47:37let's go and execute it. Now again let's
  24354. 14:47:39check the data. The first three columns
  24355. 14:47:41comes from the physical table customers.
  24356. 14:47:44The fourth one, the total sales comes
  24357. 14:47:46from our first city over here. So from
  24358. 14:47:50here and the last order comes from our
  24359. 14:47:52new city that we just defined the city
  24360. 14:47:55number two. So as you can see guys,
  24361. 14:47:56everything feels like organized and
  24362. 14:47:58structures and we have like flow and of
  24363. 14:48:01course those cities are standalone
  24364. 14:48:03cities. So we can go always and select
  24365. 14:48:06the city and execute it separately. It
  24366. 14:48:08doesn't need anything else from outside
  24367. 14:48:11this query. It just needs the tables
  24368. 14:48:13inside your database. So guys again here
  24369. 14:48:15pay attention if you want to add more
  24370. 14:48:17CDs use the comma. You cannot go and use
  24371. 14:48:19for example here I another width. So if
  24372. 14:48:21I execute it I will get an error. So you
  24373. 14:48:24have to separate it with this comma. And
  24374. 14:48:25another mistake that I do frequently
  24375. 14:48:27that I forget and go add here like to
  24376. 14:48:30the last CTE a comma and this happens to
  24377. 14:48:33me if I'm using a lot of CDEs. So if I
  24378. 14:48:36go and do it like this, I will get as
  24379. 14:48:38well an error because the main query
  24380. 14:48:41doesn't need a comma. So the last city
  24381. 14:48:43should not has a comma after the
  24382. 14:48:44parenthesis. So I just removed it and
  24383. 14:48:47execute. So guys with us we have now
  24384. 14:48:49multiple cities inside our
  24385. 14:48:54query. All right. So now what is a
  24386. 14:48:56nested CTE? It is a city inside another
  24387. 14:49:00city. So it's kind of like subqueries, a
  24388. 14:49:02query inside another query. So not only
  24389. 14:49:05a main query can use the result of CTE
  24390. 14:49:08another CTE can use the result from a
  24391. 14:49:10CTE and of course the nested CTE is like
  24392. 14:49:12a main query is depend on other query
  24393. 14:49:15that means you cannot go and select it
  24394. 14:49:17and run it independently from the query.
  24395. 14:49:20So always you have to run the CTE inside
  24396. 14:49:22it first before seeing the result of the
  24397. 14:49:25nested CTE. Okay. So now let's
  24398. 14:49:27understand what this means. Again we
  24399. 14:49:28have our database and we have a city
  24400. 14:49:31query that goes directly to the database
  24401. 14:49:33and queries the data from there and in
  24402. 14:49:36the output we will get the intermediate
  24403. 14:49:38results. And now in this scenario this
  24404. 14:49:40time we will not have only one
  24405. 14:49:41intermediate results because we have
  24406. 14:49:43many different steps. We need another
  24407. 14:49:46intermediate results before everything
  24408. 14:49:47is prepared for the main query. So that
  24409. 14:49:50means we have another step that's going
  24410. 14:49:52to be built up on top of the first
  24411. 14:49:55intermediate results. So that means we
  24412. 14:49:57can have another CTE that's going to be
  24413. 14:50:00quering the results from the first CTE
  24414. 14:50:02and build on top of it another
  24415. 14:50:04intermediate result. So as you can see
  24416. 14:50:06here we have CTE1 and CTE2 and that
  24417. 14:50:10means now we have like two intermediate
  24418. 14:50:12results. And now of course we can go and
  24419. 14:50:14add CTE 3 4 and so on. But now let's say
  24420. 14:50:17that the CTE2 going to prepare the final
  24421. 14:50:20intermediate result for the main query.
  24422. 14:50:22So now the main query going to go and
  24423. 14:50:24query the second intermedator results
  24424. 14:50:26and it's going to do the final step
  24425. 14:50:28where the final result can be presented
  24426. 14:50:30for the user and of course if it is
  24427. 14:50:32needed the main query can access not
  24428. 14:50:35only the second intermediate result from
  24429. 14:50:37the second CTE but also the first
  24430. 14:50:40intermediate result from the CTE1. Now
  24431. 14:50:42we call the first CTE a standalone CTE
  24432. 14:50:45because it doesn't depend on any
  24433. 14:50:47intermediate results. It goes directly
  24434. 14:50:49to the database and gets the data. But
  24435. 14:50:52now since the second city is completely
  24436. 14:50:54depending on the city one. So this time
  24437. 14:50:57we're going to call this CTE a nested
  24438. 14:50:59CTE because we cannot go and execute it
  24439. 14:51:02on its own. It always depends on the
  24440. 14:51:04city one. And of course the main city is
  24441. 14:51:06depending on everything. So as you can
  24442. 14:51:07see we're using the CTE we're going to
  24443. 14:51:09go and build like a chain. So this is
  24444. 14:51:11what we mean with the standalone city
  24445. 14:51:14and nested city. Okay. So now let's
  24446. 14:51:16understand the syntax of the nested
  24447. 14:51:17city. So we start as usual with the
  24448. 14:51:20definition of the first city using the
  24449. 14:51:22with clause and then the name of the
  24450. 14:51:24city and the definition of the city. So
  24451. 14:51:26here it's nothing new. Now we go and
  24452. 14:51:29define the second city as we learned
  24453. 14:51:31using the comma then the name of the CTE
  24454. 14:51:34and the definition. So this is our CTE
  24455. 14:51:36number two. So now the second CTE is
  24456. 14:51:39depending on the results of the first
  24457. 14:51:41CTE. So how we going to do it? It's very
  24458. 14:51:43simple. Now for the CTE number two,
  24459. 14:51:46we're going to select the data from the
  24460. 14:51:48CTE number one. And with that, we are
  24461. 14:51:50making the second city depending on the
  24462. 14:51:53first one. So this means the second CTE
  24463. 14:51:55is getting the data from the first one
  24464. 14:51:57and it's querying the data in order to
  24465. 14:51:59do the second step. And with that we are
  24466. 14:52:02nesting one CTE in another. And the CTE2
  24467. 14:52:06is completely depending on the first
  24468. 14:52:08one. So again we call the first CTE as a
  24469. 14:52:10standalone CTE because it doesn't depend
  24470. 14:52:13on anything. We can execute it on its
  24471. 14:52:16own and it just need the data directly
  24472. 14:52:18from the database. But the second city
  24473. 14:52:20since is completely depending on the
  24474. 14:52:22city number one we call it a nested
  24475. 14:52:25city. So they are very similar. We are
  24476. 14:52:27just selecting the data from the city
  24477. 14:52:29number one. And now comes our main
  24478. 14:52:31query. And of course it's going to go
  24479. 14:52:33and use the data from the second step.
  24480. 14:52:36So it's going to go and select the data
  24481. 14:52:37from the city number two. But it's still
  24482. 14:52:40of course it's not a rule. It can go and
  24483. 14:52:42access the data and select the data from
  24484. 14:52:44the city number one. So this is how we
  24485. 14:52:46can create a nested city in SQL. All
  24486. 14:52:49right guys, back to our project where we
  24487. 14:52:51are creating a report about the
  24488. 14:52:52customers and we would like to add one
  24489. 14:52:54more step. So the task is rank the
  24490. 14:52:57customers based on total sales per
  24491. 14:53:00customer. So this is one more step
  24492. 14:53:02inside our projects and we would like to
  24493. 14:53:04go and use as well the CTEs in order to
  24494. 14:53:07implement this step. So now what do we
  24495. 14:53:09need? We need to rank the customers
  24496. 14:53:11based on total sales for each customer.
  24497. 14:53:13So here like we have two steps. First we
  24498. 14:53:16have to calculate the total sales per
  24499. 14:53:18customer and then we have to go and rank
  24500. 14:53:20it based on this information and of
  24501. 14:53:22course the sales are stores inside the
  24502. 14:53:24orders. So now let's go and start
  24503. 14:53:26implementing the CDE. So we're going to
  24504. 14:53:29have a comma and we're going to call it
  24505. 14:53:31CTE customer
  24506. 14:53:34rank as and then we're going to go have
  24507. 14:53:36the parenthesis and inside it we're
  24508. 14:53:39going to develop now the logic. So first
  24509. 14:53:41we have to go and aggregate the data by
  24510. 14:53:43the total sales. So select customer ID
  24511. 14:53:47and then sum the
  24512. 14:53:50sales from the table sales orders and
  24513. 14:53:54then of course group
  24514. 14:53:56by the customer id. And now I can hear
  24515. 14:54:00you even telling me bar we have already
  24516. 14:54:02done this. We have already this logic.
  24517. 14:54:04So why we are repeating? If we go to the
  24518. 14:54:06first CTE you can see we have already
  24519. 14:54:09done that. And you are totally right. We
  24520. 14:54:11have already the logic. So it makes no
  24521. 14:54:13sense to repeat it again. And if we do
  24522. 14:54:15this then we didn't understood the power
  24523. 14:54:18of the city. So we don't have to repeat
  24524. 14:54:20the same logic and we can reuse the city
  24525. 14:54:24inside another city. So now we don't
  24526. 14:54:26need all those stuff. We can go and
  24527. 14:54:28focus immediately with ranking the
  24528. 14:54:30customers. So first let me just select
  24529. 14:54:32the data from the first city. So I'm
  24530. 14:54:35going to go and select. So what do we
  24531. 14:54:37have? We have customer
  24532. 14:54:39ID and we have total
  24533. 14:54:42sales. And we're going to select it this
  24534. 14:54:44time not from any physical table. We're
  24535. 14:54:47going to select our city. So like this.
  24536. 14:54:50And now what we're going to do, we're
  24537. 14:54:51going to go and select the whole thing
  24538. 14:54:53and execute it. Well, this is the issue
  24539. 14:54:56of nesting cities. Sadly, this CTE is
  24540. 14:55:00completely depending on the first city.
  24541. 14:55:02So we cannot go and execute it on its
  24542. 14:55:04own. And this is of course very annoying
  24543. 14:55:07because each time I execute the query by
  24544. 14:55:10the end of the query SQL gonna go and
  24545. 14:55:12destroy all the CTE. So in the memory we
  24546. 14:55:16will not find the CT and that's why once
  24547. 14:55:19I executed it SQL don't know anything
  24548. 14:55:22about this city. And in order now to see
  24549. 14:55:25the result of this we have always to
  24550. 14:55:27execute as well with it the city that
  24551. 14:55:30I'm using. So what I usually do I go
  24552. 14:55:33over here and make everything in comment
  24553. 14:55:36in the main query and now I can go and
  24554. 14:55:39execute the whole thing and now I will
  24555. 14:55:41see in the output the outcome of this
  24556. 14:55:43nested city. So this is the big
  24557. 14:55:46difference between the standalone cities
  24558. 14:55:48like here and the nested. So now let's
  24559. 14:55:50go back to our task. We have to rank
  24560. 14:55:52those sales based on the total sales. So
  24561. 14:55:55we can go and use the rank function from
  24562. 14:55:58the window function. So rank over and
  24563. 14:56:02now we don't have to partition the data.
  24564. 14:56:04We just want to sort the data by the
  24565. 14:56:07total sales
  24566. 14:56:10descending. So like this the highest
  24567. 14:56:12sales going to get the rank number one.
  24568. 14:56:14So let's go and give it the name as
  24569. 14:56:17customer rank. Now as you can see we
  24570. 14:56:19have a really nice rank beside those
  24571. 14:56:21informations. Customer three has the
  24572. 14:56:23highest sales and customer two has the
  24573. 14:56:26lowest total sales. So with that, as you
  24574. 14:56:28can see, we didn't repeat ourself. We
  24575. 14:56:30just reused another CTE in our current
  24576. 14:56:33city. And this is exactly why this
  24577. 14:56:35technique is very amazing in order to
  24578. 14:56:38reduce redundancies and to reduce the
  24579. 14:56:40complexity of the whole query. So nested
  24580. 14:56:43are annoying to execute, but they reduce
  24581. 14:56:46the redundancies of our code. Now we are
  24582. 14:56:48done with our logic. We tested
  24583. 14:56:50everything. So what we're going to do,
  24584. 14:56:51we're going to go and integrate it in
  24585. 14:56:53our main query. So let me just remove
  24586. 14:56:56the comments from here and let's go and
  24587. 14:56:58add it in the main query. So we will do
  24588. 14:57:01the same thing. We're going to go and do
  24589. 14:57:02a left join with the last city that we
  24590. 14:57:05just created. So let me just call it
  24591. 14:57:08CCR and the same conditions. We are
  24592. 14:57:11always joining on the customer ID. But
  24593. 14:57:13don't forget to rename the alias. So it
  24594. 14:57:17is CCR customer ID equal to the customer
  24595. 14:57:21ID from the first table. And of course
  24596. 14:57:23we have to go and select the new
  24597. 14:57:25information. So CCR dot customer rank.
  24598. 14:57:30And now let's go and execute the whole
  24599. 14:57:32thing. Now as you can see in the results
  24600. 14:57:34those three columns comes from the
  24601. 14:57:36customers table. The total sales comes
  24602. 14:57:39from the first city. The last order from
  24603. 14:57:42the second city and the customer rank
  24604. 14:57:44comes from our nested city that we just
  24605. 14:57:47created. So guys, it is not a simple
  24606. 14:57:50task creating such a reports because it
  24607. 14:57:53involves different aggregations and
  24608. 14:57:55different functions, but our work is
  24609. 14:57:57organized. As you can see, it's very
  24610. 14:57:59simple. We have step one, step two, step
  24611. 14:58:01three, and the main query. And it's
  24612. 14:58:03really easy to add more components to
  24613. 14:58:05our query. Now, I would like really to
  24614. 14:58:08keep practicing using those nested
  24615. 14:58:10queries. So, we have the following task.
  24616. 14:58:11We would like to add one more step in
  24617. 14:58:13our report. segment the customers based
  24618. 14:58:16on their total sales. So I would like to
  24619. 14:58:19implement this as well using CTE. So
  24620. 14:58:22let's go and solve it. We want to go and
  24621. 14:58:24add a new CTE. It's going to be CTE
  24622. 14:58:27customer
  24623. 14:58:29segments as and then we have to go and
  24624. 14:58:32define our logic. Now if you check our
  24625. 14:58:35task, it has two parts. We have to find
  24626. 14:58:37the total sales and then we have to
  24627. 14:58:40segment the customers based on this
  24628. 14:58:41information. So it is something very
  24629. 14:58:44similar to what we have done in the step
  24630. 14:58:46three. So that means we don't have to go
  24631. 14:58:49and calculate again the total sales. We
  24632. 14:58:50have to go and use as well our amazing
  24633. 14:58:53first city. So let's go and do it. What
  24634. 14:58:56do we need? We need the customer ID like
  24635. 14:59:00this. And let's do basic segmentations
  24636. 14:59:03using the case win. So let's say case
  24637. 14:59:05when the total sales if it's higher than
  24638. 14:59:10100 then let's say the customer going to
  24639. 14:59:13belong to the group high and let's go
  24640. 14:59:16and add another category. If it's not
  24641. 14:59:19higher than 100 if it is higher than
  24642. 14:59:2450 then the customer going to belong to
  24643. 14:59:27medium. And if the total sales is less
  24644. 14:59:30or equal to 50. So what's going to
  24645. 14:59:33happen? We're going to say else the
  24646. 14:59:35customer belong to the low category. So
  24647. 14:59:38that's it. We're going to have an end
  24648. 14:59:40and let's call it customer
  24649. 14:59:43segments. All right. But of course we
  24650. 14:59:45have to go and select it from a table
  24651. 14:59:47and it's going to be our city. So total
  24652. 14:59:51sales and let's put it in our new city.
  24653. 14:59:54And I would like to test it before like
  24654. 14:59:56putting it inside our main query. That's
  24655. 14:59:58why I will put everything in comments in
  24656. 15:00:01my main query since it is a nested city
  24657. 15:00:04sadly. And we will just go and select
  24658. 15:00:06our new nested city like we have done
  24659. 15:00:10before. So let's go and execute it. Now
  24660. 15:00:13as you can see in the output we have two
  24661. 15:00:15customers with the category high and two
  24662. 15:00:18customers with the medium. But in order
  24663. 15:00:20to make sure that everything working
  24664. 15:00:22perfectly, I would like to go and add
  24665. 15:00:23the total sales just to see the numbers.
  24666. 15:00:26So let's go and execute it. Well, you
  24667. 15:00:28can see everything is correct. So those
  24668. 15:00:30customers having higher than 100 in the
  24669. 15:00:33total sales and those two having higher
  24670. 15:00:35than 50. But let's go and change stuff
  24671. 15:00:37around. I would like to have it like 80
  24672. 15:00:39as a medium just in order to have a low.
  24673. 15:00:42So with that the customer number two
  24674. 15:00:44having a lower sales than 80. That's why
  24675. 15:00:46we are getting the segment low.
  24676. 15:00:48Everything is done and we have segmented
  24677. 15:00:49the users into different categories. So
  24678. 15:00:52I don't need to test anymore. Let's go
  24679. 15:00:54integrate it in our main query. So we're
  24680. 15:00:57going to do the same things over here.
  24681. 15:00:58We're going to say lift join and we're
  24682. 15:01:01going to get our new CTE. So CCS and we
  24683. 15:01:07have to do the join condition. Don't
  24684. 15:01:11forget to change it. And we have to
  24685. 15:01:13select our new nice information. It's
  24686. 15:01:15going to be the customer segments. And
  24687. 15:01:17now we can go and execute the whole
  24688. 15:01:20thing. So we have now like four
  24689. 15:01:22different cities and one main query. And
  24690. 15:01:25now we can see in the output we got all
  24691. 15:01:26three informations from the table
  24692. 15:01:28customers. The first city, the second,
  24693. 15:01:30third and this is our new column that we
  24694. 15:01:33just created. So again we have done this
  24695. 15:01:35using a necessityd like this. Let me
  24696. 15:01:39just add
  24697. 15:01:41it and it was really easy to extend and
  24698. 15:01:44to add to our report. All right guys, so
  24699. 15:01:46with us we have done like a many
  24700. 15:01:47projects where we have analyzed the
  24701. 15:01:49customer information based on different
  24702. 15:01:52aspects from our data and we have done
  24703. 15:01:54it like step by step and now you have
  24704. 15:01:56like a feeling on how to write complex
  24705. 15:01:58SQL queries using the help of the CTE
  24706. 15:02:01and we have done it like step by step.
  24707. 15:02:03So as you can see if you go through the
  24708. 15:02:05scripts you can understand okay it is
  24709. 15:02:07divided into multiple steps and each
  24710. 15:02:09block is responsible for one specific
  24711. 15:02:12problem of the whole report and this is
  24712. 15:02:14exactly the power of the CTE it
  24713. 15:02:16introduce modularity. So each CTE is
  24714. 15:02:20self-contained and talk about one issue
  24715. 15:02:23and this is amazing way on how to
  24716. 15:02:25organize your project using SQL and how
  24717. 15:02:27to structure your work.
  24718. 15:02:33All right, my friends. So, now let's
  24719. 15:02:34have a little break in order to have a
  24720. 15:02:35real talk about the city. But first,
  24721. 15:02:37some
  24722. 15:02:39coffee. And now I can say that I'm
  24723. 15:02:41working with SQL since really long long
  24724. 15:02:43time ago, over 15 years. And I can say
  24725. 15:02:46as well, I have met a lot of SQL
  24726. 15:02:48developers in different projects. And if
  24727. 15:02:50there is one thing that all those SQL
  24728. 15:02:52developers love is the CTE, they love
  24729. 15:02:55using it everywhere. like each time they
  24730. 15:02:57write a query they going to be writing
  24731. 15:02:59SQL CTE and of course it's fine it's not
  24732. 15:03:02a bad thing but the problem with that
  24733. 15:03:04they overuse it of course not all of
  24734. 15:03:06them but a lot of SQL developers overuse
  24735. 15:03:09using the CTE of course the CTE is very
  24736. 15:03:12powerful but with power comes great
  24737. 15:03:14responsibility
  24738. 15:03:16remember with great power comes great
  24739. 15:03:20responsibility so my advice for you
  24740. 15:03:22especially if you are new to the CTS try
  24741. 15:03:25to not add a new CTE each time you are
  24742. 15:03:28doing something new and I saw it a lot
  24743. 15:03:30like for each new calculation for each
  24744. 15:03:32new column they jump immediately and
  24745. 15:03:34create a new CT and what happens at the
  24746. 15:03:36end we can have like massive number of
  24747. 15:03:39CTE inside one query and the developer
  24748. 15:03:41thinks now everything is organized and
  24749. 15:03:43easy to read but believe me it's exactly
  24750. 15:03:46the opposite if you open any code and
  24751. 15:03:48you have a lot of CDEs and especially if
  24752. 15:03:51they are necessities it is impossible to
  24753. 15:03:53understand what is going on even if the
  24754. 15:03:56developer like describe each CTE and the
  24755. 15:03:58task of the CTE, it's going to be really
  24756. 15:04:00hard to understand and as well to read.
  24757. 15:04:02If everything is like nested and you
  24758. 15:04:04have like I don't know 20 cities in one
  24759. 15:04:06query. So it's going to be impossible to
  24760. 15:04:08read and to understand and as well
  24761. 15:04:10you're going to be using a lot of memory
  24762. 15:04:12and you might get bad performance. So my
  24763. 15:04:15advice for you try always as you are
  24764. 15:04:17creating new CDs to think about how
  24765. 15:04:19about to merge two CDEs in one. So it is
  24766. 15:04:22really always important to rethink and
  24767. 15:04:24refactor your CDEs in order to merge it
  24768. 15:04:27into one and to reduce the number of
  24769. 15:04:29CTE. But now if you ask me how many CTEs
  24770. 15:04:31are okay in one query, well I don't have
  24771. 15:04:34a magic number for that. But normally I
  24772. 15:04:36tend to say between three and five CTE
  24773. 15:04:39it's fine. So it's going to be easy to
  24774. 15:04:41understand and to read and so on. But
  24775. 15:04:43once you get more than five CTE then you
  24776. 15:04:46have to rethink your code. Maybe you
  24777. 15:04:48have to create another complete query so
  24778. 15:04:51you don't have to put everything in one
  24779. 15:04:52query. So this is my advice for you. Try
  24780. 15:04:55to not overuse the CTEs in your
  24781. 15:04:57projects. Not for each step always
  24782. 15:04:59refactor the CTE, consolidate them and
  24783. 15:05:02try to not have more than five CTEs in
  24784. 15:05:04one query. So that's my advice for you.
  24785. 15:05:06Be responsible using the CTE. And let's
  24786. 15:05:09go back to our course.
  24787. 15:05:14So with that we have learned the
  24788. 15:05:16standalone CTE and the NIST CDE and both
  24789. 15:05:18of them belongs to a type called
  24790. 15:05:21nonrecursive CTE. So what is a
  24791. 15:05:23non-recursive CDE? It means it is a city
  24792. 15:05:26that is executed only once. So there is
  24793. 15:05:29no repetitions or looping or anything.
  24794. 15:05:31So the SQL going to execute it in one go
  24795. 15:05:33and that's it. But in the other hand the
  24796. 15:05:35recursive city is exactly the opposite.
  24797. 15:05:38So a recursive city it is a
  24798. 15:05:40selfreferencering query that repeatedly
  24799. 15:05:43processing the data until a certain
  24800. 15:05:46condition is met and we usually use the
  24801. 15:05:48recursive city if we have like
  24802. 15:05:50hierarchical structure and we want to
  24803. 15:05:52navigate and travel through the
  24804. 15:05:54hierarchy. I know this might be
  24805. 15:05:56confusing but don't worry about it.
  24806. 15:05:57We're going to have very simple
  24807. 15:05:58examples. Now again we have our tables
  24808. 15:06:00in the database and we have a CTE. Now
  24809. 15:06:03the query of the CTE going to be
  24810. 15:06:04executed for the first time and in the
  24811. 15:06:07results we're going to have the initial
  24812. 15:06:08data from the CTE but it is not
  24813. 15:06:11everything yet. Now this intermediate
  24814. 15:06:13result is not ready yet for the main
  24815. 15:06:15query but instead of that it's going to
  24816. 15:06:18go back to the CTE and CTE going to
  24817. 15:06:21check whether the current results is
  24818. 15:06:23meeting a specific condition. So now if
  24819. 15:06:26the check says no it's not meeting the
  24820. 15:06:29condition what's going to happen the
  24821. 15:06:31city query going to be executed for the
  24822. 15:06:33second time. So as you can see we are
  24823. 15:06:35looping through the CTE. Now the result
  24824. 15:06:38of the second iteration the second
  24825. 15:06:40execution will be added to the
  24826. 15:06:43intermediate result. So now the
  24827. 15:06:44intermediate result has more data and
  24828. 15:06:47again before we can use it from the main
  24829. 15:06:49query it going to be checked from the
  24830. 15:06:51CTE. Does the result fulfill the
  24831. 15:06:54condition? If it's still no, then go and
  24832. 15:06:57execute the CTE again. So we're going to
  24833. 15:06:59have a third iteration and a new data
  24834. 15:07:01going to be added to the intermediate
  24835. 15:07:03result. So this is our third iteration.
  24836. 15:07:06Now it's going to be checked again from
  24837. 15:07:07the CTE. Did we fulfill the condition?
  24838. 15:07:10If the answer is yes, then the loop
  24839. 15:07:13going to break and everything else. So
  24840. 15:07:15there will be no fourth iteration of the
  24841. 15:07:16CTE. So with that, the CTE says okay,
  24842. 15:07:19I'm done. This is the final result of
  24843. 15:07:22the intermediate result. then the loop
  24844. 15:07:24going to break and everything ends and
  24845. 15:07:27the city will not be executed for the
  24846. 15:07:29first time and now the city going to say
  24847. 15:07:31okay I'm done now my intermediate result
  24848. 15:07:34is ready to be used from the main query
  24849. 15:07:36and now nothing new happens the main
  24850. 15:07:38query going to go and retrieve the data
  24851. 15:07:40from the intermediate results and do
  24852. 15:07:42some magic in order to prepare the final
  24853. 15:07:44results so that means there will be no
  24854. 15:07:46iterations or looping inside the main
  24855. 15:07:48query the looping going to be happen
  24856. 15:07:50only in the CTE and that's why we call
  24857. 15:07:52it recursive CTE. So now if you compare
  24858. 15:07:55it with the other types, all other types
  24859. 15:07:57are always in one direction and all the
  24860. 15:07:59CTE is going to be executed only once
  24861. 15:08:02but the recursive CTE going to be keep
  24862. 15:08:04looping until the condition is met and
  24863. 15:08:07only then it's going to forward the data
  24864. 15:08:09to the main query. And normally we use
  24865. 15:08:11the recursive CTE if you are navigating
  24866. 15:08:14through hierarchical structure. So if
  24867. 15:08:16you have in your data like hierarchal
  24868. 15:08:17structures, you can go and use the
  24869. 15:08:19recursive CTE in order to navigate
  24870. 15:08:21through it. So this is the recursive
  24871. 15:08:24city. Okay. So now let's check the
  24872. 15:08:25syntax of the recursive CTE. It is a
  24873. 15:08:27little bit complicated but we're going
  24874. 15:08:28to do it step by step. So what do we
  24875. 15:08:30have? We have a query and we would like
  24876. 15:08:32to put it in a city. So we're going to
  24877. 15:08:34have the usual stuff with clause the
  24878. 15:08:37name of the city and as and then the
  24879. 15:08:40query. So this is the definition of our
  24880. 15:08:42city. But now if you leave it like this
  24881. 15:08:44SQL going to execute it only once. But
  24882. 15:08:46we would like to make a loop iteration.
  24883. 15:08:48So in order to do that we have to go and
  24884. 15:08:50define a second select statement inside
  24885. 15:08:53our CTE like this. So we are selecting
  24886. 15:08:56the data and here we have to define a
  24887. 15:08:58breaking condition. So here in the
  24888. 15:09:00second query we are defining a condition
  24889. 15:09:02in order to break the loop otherwise
  24890. 15:09:05it's going to loop for infinite or the
  24891. 15:09:07system going to break. You could use it
  24892. 15:09:08in the wear clause or you can use it
  24893. 15:09:10even in an inner join because both of
  24894. 15:09:12them are filtering the data and you can
  24895. 15:09:14use it in order to break the condition.
  24896. 15:09:16All right. So now still there is
  24897. 15:09:18something missing. How we going to make
  24898. 15:09:19like things looping? Well, we have to
  24899. 15:09:21reference this CTE to itself. So what we
  24900. 15:09:24going to do? We're going to say the
  24901. 15:09:26second query going to select the data
  24902. 15:09:28from the same CTE. So that means we have
  24903. 15:09:31now a query that is quering itself. And
  24904. 15:09:33this is of course what we want. We want
  24905. 15:09:35to make iterations and we want to make a
  24906. 15:09:37loop. That's why we have to go and
  24907. 15:09:39reference it to itself. And now in SQL
  24908. 15:09:41you cannot have it like this. You cannot
  24909. 15:09:43have like two select statements in one
  24910. 15:09:45query. you have to connect it somehow.
  24911. 15:09:47That's why we can go and use the union
  24912. 15:09:49all or union depend if you want to have
  24913. 15:09:51duplicates or not. So now we call the
  24914. 15:09:53first query the anchor query. The anchor
  24915. 15:09:56query going to be the first query that
  24916. 15:09:58interacts with the database and provide
  24917. 15:10:00us the initial intermediate results. So
  24918. 15:10:03it is the starting point of the
  24919. 15:10:05iteration and we can say it is the first
  24920. 15:10:08step in the process. So this going to be
  24921. 15:10:10executed only once and it going to
  24922. 15:10:12provide us the initial step the first
  24923. 15:10:14step in the process. Now we call the
  24924. 15:10:16second step as a recursive query and we
  24925. 15:10:19call it like this because this query
  24926. 15:10:21going to be executed multiple times and
  24927. 15:10:24it will keep repeating and add data to
  24928. 15:10:26the intermediate results until the
  24929. 15:10:29condition is met or let's say there will
  24930. 15:10:31be no more data that is available to be
  24931. 15:10:34processed. So this is the syntax of the
  24932. 15:10:36city query for the main query nothing is
  24933. 15:10:38changed. So we have to go and use the
  24934. 15:10:41city name in the main query. So this is
  24935. 15:10:44the syntax of the recursive city. So
  24936. 15:10:47think about it like this. SQL going to
  24937. 15:10:48go and execute the anchor query only
  24938. 15:10:51once and then after that going to go
  24939. 15:10:53through the recursive query and keep
  24940. 15:10:56looping and looping and iterating until
  24941. 15:10:59a certain condition is met and then SQL
  24942. 15:11:02going to go out from the CTE. So this is
  24943. 15:11:04actually what we mean with the anchor
  24944. 15:11:05and recursive queries. All right. Right.
  24945. 15:11:07So now let's have a simple task in order
  24946. 15:11:09to understand the recursive city. So the
  24947. 15:11:11task says generate a sequence of numbers
  24948. 15:11:14from 1 to 20. So now let's do it step by
  24949. 15:11:17step. So that means we have to create a
  24950. 15:11:19loop from 1 to 20 and after 20 the loop
  24951. 15:11:22should stop. So let's go and do it. Now
  24952. 15:11:25the first step of the recursive CTE is
  24953. 15:11:27to build the anchor query. So the anchor
  24954. 15:11:30query is responsible for the first
  24955. 15:11:32iteration. So that means the first row
  24956. 15:11:34of the output. So what is the first
  24957. 15:11:36value between 1 and 20? It is the one.
  24958. 15:11:39So let's go and write a query that
  24959. 15:11:41generate the value one. So select and
  24960. 15:11:45we're going to say one as I'm going to
  24961. 15:11:47give it the name my number. So that's
  24962. 15:11:51it. Let's go and execute it. Now you can
  24963. 15:11:53see in the output we have the first
  24964. 15:11:55member of our sequence. And this is
  24965. 15:11:57exactly the task of the anchor query. It
  24966. 15:12:00retrieves the first step in the
  24967. 15:12:02iteration. So let's go and call
  24968. 15:12:05it
  24969. 15:12:07anchor query. Now the next step with
  24970. 15:12:10that we have to go and build the
  24971. 15:12:11iteration. So we need a CTE. So I will
  24972. 15:12:14build now the city. So we're going to
  24973. 15:12:16say with we're going to call it series
  24974. 15:12:19and then we're going to put everything
  24975. 15:12:21in parenthesis and then we're going to
  24976. 15:12:23go to the main query. So this is the
  24977. 15:12:25main query and we will go and select
  24978. 15:12:28everything from the Sirius the city. So
  24979. 15:12:32let's go and execute it just to make
  24980. 15:12:34sure that everything is working fine. So
  24981. 15:12:36we didn't create any loop or anything.
  24982. 15:12:38We have just created a city on top on
  24983. 15:12:41the anchor query and we just call it
  24984. 15:12:43from the main query. So now we come to
  24985. 15:12:45the second step of building the
  24986. 15:12:47recursive city. We have to build the
  24987. 15:12:49recursive query. So let's do it. I will
  24988. 15:12:52just make this little bit smaller. And
  24989. 15:12:53now before we start writing the query,
  24990. 15:12:55we have to go and use union
  24991. 15:12:58all in order to go and connect the
  24992. 15:13:00anchor query with the recursive query.
  24993. 15:13:03And let me say this is the
  24994. 15:13:05recursive query. So how we going to
  24995. 15:13:08build it? Let's go and start with the
  24996. 15:13:10select. And now next what I usually do I
  24997. 15:13:12just make sure that we are making a
  24998. 15:13:14recursive city. So I go with selecting
  24999. 15:13:16from and then we're going to use the
  25000. 15:13:19name of the current city so that we are
  25001. 15:13:21referencing the city to itself in order
  25002. 15:13:23to make the city recursive and to do the
  25003. 15:13:26looping. Now here comes the tricky part.
  25004. 15:13:29So we need to create like the sequence.
  25005. 15:13:32Now what is the current value? The
  25006. 15:13:33current value is one. Right? Now what do
  25007. 15:13:35we need? We need the second value in the
  25008. 15:13:37sequence which is two. So we can do it
  25009. 15:13:40by 1 + 1. So if you do it like this you
  25010. 15:13:43will get the output two. But actually
  25011. 15:13:45what we are doing here we are always
  25012. 15:13:47taking the current value and we are
  25013. 15:13:49saying plus one in order to generate the
  25014. 15:13:52next value. So in order to do that
  25015. 15:13:54instead of saying one we're going to
  25016. 15:13:56take the my number the current value and
  25017. 15:13:58we're going to add to it plus one in
  25018. 15:14:01order to generate the second value in
  25019. 15:14:03the sequence. So that means my number
  25020. 15:14:05always holds the current value and we do
  25021. 15:14:09the operation + one in order to generate
  25022. 15:14:11the next sequence. So having it like
  25023. 15:14:14this what we are doing we are generating
  25024. 15:14:16the sequence of numbers. Now if you go
  25025. 15:14:18and execute it like this let me just
  25026. 15:14:20execute it what will happen it going to
  25027. 15:14:23breaks because SQL will not allow it and
  25028. 15:14:25SQL set it to 100 iterations. So more
  25029. 15:14:28than 100 SQL going to break the query so
  25030. 15:14:30that we don't have infinite number of
  25031. 15:14:33looping. So this is bad because we
  25032. 15:14:35didn't define the breaking mechanism of
  25033. 15:14:37the looping. So now we have to define as
  25034. 15:14:39well in the recursive query how the loop
  25035. 15:14:42going to ends and we usually use a
  25036. 15:14:44condition. For example, we can go and
  25037. 15:14:45use the wear clause and we can say okay
  25038. 15:14:48keep looping and keep generating but
  25039. 15:14:50always check whether the value of the my
  25040. 15:14:53number is less than 20. And you might
  25041. 15:14:58ask okay it should be less or equal to
  25042. 15:15:0020 right? Well no because if you are
  25043. 15:15:03making less and equal to 20 what going
  25044. 15:15:05to happen once the my number is equal to
  25045. 15:15:0720 you are allowing one more iterations
  25046. 15:15:10where you will get in the output 21. So
  25047. 15:15:13that's why we are making it with 20. So
  25048. 15:15:15now let's go and execute it and let's
  25049. 15:15:18check the sequence. It start with 1 2 3
  25050. 15:15:204 5 and until we reach the 20. So with
  25051. 15:15:23that we have solved the task. Again here
  25052. 15:15:25it's not that hard right? We are just
  25053. 15:15:28providing the initial step and then we
  25054. 15:15:30are providing the loop where we are
  25055. 15:15:32defining inside it how the loop going to
  25056. 15:15:34ends. Now there is one more thing that
  25057. 15:15:36you can do with the recursive CTE is to
  25058. 15:15:38define the limit of iterations. So for
  25059. 15:15:41example in your code if you say okay if
  25060. 15:15:43this iterates more than 10 times then
  25061. 15:15:46the SQL should breaks and stops. So you
  25062. 15:15:49can define for the SQL the maximum
  25063. 15:15:51number of recursions. So how we can do
  25064. 15:15:54that? We can do that in the main query.
  25065. 15:15:56So if you go over here and say option
  25066. 15:15:59then two parenthesis and then max
  25067. 15:16:02recursion and after that you can define
  25068. 15:16:05the limit. So for example let's go with
  25069. 15:16:07the 10. Now of course we are iterating
  25070. 15:16:09in our code now more than 20 but here we
  25071. 15:16:12are making the rule it should not
  25072. 15:16:13iterate more than 10. So let's go and
  25073. 15:16:16execute it. So now we can see that our
  25074. 15:16:17SQL breaks and it says the maximum
  25075. 15:16:20recursion is 10. So as you can see now
  25076. 15:16:22in the output we are getting the error
  25077. 15:16:24of having more than 10 iterations which
  25078. 15:16:26is not allowed. So with that you can
  25079. 15:16:28control how many recursions you can
  25080. 15:16:30have. Let's say that you would like to
  25081. 15:16:31have like thousand iteration. So if you
  25082. 15:16:34go over here and say you know what I
  25083. 15:16:35would like to have a sequence of 1,000.
  25084. 15:16:37If you let me just comment this out. So
  25085. 15:16:40if you execute it you will get an error
  25086. 15:16:42because the default is 100. But of
  25087. 15:16:45course you can go and increase the
  25088. 15:16:47maximum recursion. For example let's go
  25089. 15:16:49with 5,000s. in the output it will work
  25090. 15:16:52and you will get a sequence of 1,000. So
  25091. 15:16:54with this you can control how many
  25092. 15:16:56iterations are allowed in your query. So
  25093. 15:16:58that you have like a control on it.
  25094. 15:17:00Okay. So now we can understand step by
  25095. 15:17:02step how SQL executed the recursive
  25096. 15:17:04query. And here we have like flow
  25097. 15:17:06diagram in order to understand the
  25098. 15:17:08process the steps of executing the
  25099. 15:17:10recursive query. So let's go and do it.
  25100. 15:17:12Now in the start we have the first step
  25101. 15:17:14is to run the anchor query. So our
  25102. 15:17:17anchor query is just a select for the
  25103. 15:17:19value one. So in the output we will get
  25104. 15:17:22the value one in my number and as you
  25105. 15:17:24can see the anchor query going to be
  25106. 15:17:26executed only once. So there is no
  25107. 15:17:29iterations or anything. SQL executed
  25108. 15:17:31once and then goes to the next step. So
  25109. 15:17:34what is the next step? It's going to
  25110. 15:17:35execute the recursive query. So it's
  25111. 15:17:38going to go over here and now what going
  25112. 15:17:39to happen? We will get the current value
  25113. 15:17:41of my number. The current value is one.
  25114. 15:17:44and then we're going to add to it a one.
  25115. 15:17:46So 1 + 1 we will get from the recursive
  25116. 15:17:49query the two which is added to our
  25117. 15:17:52results. Now it's going to check the
  25118. 15:17:54condition is my number now smaller than
  25119. 15:17:5820. Well yes it's smaller than 20 and
  25120. 15:18:01what's going to happen since it's true
  25121. 15:18:03is going to go and reexecute the
  25122. 15:18:06recursive query. So now we are doing the
  25123. 15:18:08second iteration. So again it's going to
  25124. 15:18:10go to the recursive query and going to
  25125. 15:18:12say okay what is the current value of my
  25126. 15:18:14number? It is two. So 2 + 1 the second
  25127. 15:18:18iteration will give us the value three.
  25128. 15:18:21So as you can see each time the
  25129. 15:18:22recursive query is executed it is adding
  25130. 15:18:25more values to our result. So the same
  25131. 15:18:28question can be asked is now my number
  25132. 15:18:31smaller than 20. Well yes it is smaller.
  25133. 15:18:34Well what can happen is still going to
  25134. 15:18:36reexecute the recursive query. So SQL
  25135. 15:18:39going to keep looping and iterating and
  25136. 15:18:41adding values to the output until we
  25137. 15:18:45reach the value 20. So now SQL going to
  25138. 15:18:48ask is 20 my number now smaller than 20.
  25139. 15:18:52Well no. So it is false and what's going
  25140. 15:18:55to happen the chain will break and we
  25141. 15:18:57will not loop anymore. So it's going to
  25142. 15:19:00be the end of the city and this going to
  25143. 15:19:02be the final results that's going to be
  25144. 15:19:04used from the main query. So this is how
  25145. 15:19:07SQL executed this recursive CD. Okay. So
  25146. 15:19:10now let's have another task for the
  25147. 15:19:11recursive CD. This time it's going to be
  25148. 15:19:13a little bit more advanced. So the task
  25149. 15:19:15says show the employee hierarchy by
  25150. 15:19:18displaying each employees level within
  25151. 15:19:20the organization. So that means we have
  25152. 15:19:22to show for each employee for each row a
  25153. 15:19:25level that tells us the hierarchy of the
  25154. 15:19:27employee. So first let's go and explore
  25155. 15:19:30the table employees. So let's go and
  25156. 15:19:32select everything prompt sales
  25157. 15:19:36employees. Okay, let's go execute it. So
  25158. 15:19:39now by looking to the results we have
  25159. 15:19:40like few informations about the
  25160. 15:19:42employee. We have information about
  25161. 15:19:43which department the gender salaries but
  25162. 15:19:46here we have the key. It is the manager
  25163. 15:19:48ID. So this is like self referencing to
  25164. 15:19:51the same table. So for example the first
  25165. 15:19:54employee the value is null. That means
  25166. 15:19:56this employee has no manager which makes
  25167. 15:19:59this employee like the big boss, the
  25168. 15:20:01CEO. Then now by looking to the next two
  25169. 15:20:04employees, they have a manager ID one.
  25170. 15:20:06So who is the manager of those two? It's
  25171. 15:20:09going to be the first row, the manager
  25172. 15:20:11ID number one. So the manager ID number
  25173. 15:20:13one is the post of those two employees.
  25174. 15:20:16And then for the fourth one, we can see
  25175. 15:20:18the manager ID number two. So the
  25176. 15:20:20manager of Michael is actually Kevin,
  25177. 15:20:23the second row. And for Carol the
  25178. 15:20:25manager ID is three. That means Mary is
  25179. 15:20:28the manager of Carol. And this is
  25180. 15:20:30exactly what we can do with the
  25181. 15:20:32recursive CTE. We can use such
  25182. 15:20:34informations in order to create like a
  25183. 15:20:36loop. So let's go and do it step by
  25184. 15:20:38step. First we're going to start with
  25185. 15:20:40the anchor query as usual. So this is
  25186. 15:20:44the anchor query and here the first step
  25187. 15:20:47or the first record going to be the
  25188. 15:20:49highest manager which is the CEO, right?
  25189. 15:20:52The first record. So in order to select
  25190. 15:20:55now the only the first record what we
  25191. 15:20:57can say we can say where manager id is
  25192. 15:21:03null. So let's go and execute it. And
  25193. 15:21:06with that we have now the first row and
  25194. 15:21:08we can use this as the first step in our
  25195. 15:21:10iteration. So now let's go and pick few
  25196. 15:21:11informations in the select like the
  25197. 15:21:13employee ID and the first name and as
  25198. 15:21:17well let's go and get the manager ID.
  25199. 15:21:19And now we have to start creating the
  25200. 15:21:21levels. Right? So this is the first
  25201. 15:21:24level. So I'm going to have the value
  25202. 15:21:25one as let's have it like level. So our
  25203. 15:21:29CEO has the level number one. So let's
  25204. 15:21:32go and execute it. So now as you can see
  25205. 15:21:34Frank is the CEO and he is in the level
  25206. 15:21:38number one. So this is our anchor query.
  25207. 15:21:40Now we have to do the iteration right.
  25208. 15:21:43So we have to go and start creating the
  25209. 15:21:44city. So let's call it with CD employee
  25210. 15:21:50hierarchy and then as and then this is
  25211. 15:21:54the definition of our CD. So let me just
  25212. 15:21:57make it like this. And of course what do
  25213. 15:21:59we need? We need the main query.
  25214. 15:22:02So main query we will select
  25215. 15:22:07everything from our new city like this.
  25216. 15:22:11So let's go and test it. All right. So
  25217. 15:22:14now we have prepared the CTE and the
  25218. 15:22:16main query and of course the next step
  25219. 15:22:17with that we're going to go and build
  25220. 15:22:19the recursive query but first we need
  25221. 15:22:21the union all in order to connect the
  25222. 15:22:25two queries and recursive query and now
  25223. 15:22:29we can start building the logic. So now
  25224. 15:22:31we want to find all the employees where
  25225. 15:22:33their manager is the employee ID number
  25226. 15:22:36one right because they going to have the
  25227. 15:22:38second level in the hierarchy. So what
  25228. 15:22:40we're going to do, we're going to go and
  25229. 15:22:41select and we need the same stuff. So we
  25230. 15:22:44would like to get the employee ID, the
  25231. 15:22:46first name, and the manager ID. And we
  25232. 15:22:48need the level. So this going to be the
  25233. 15:22:50level number two. It's not correct yet.
  25234. 15:22:52I'm just want to show what this means
  25235. 15:22:55because we need to get the employee ID
  25236. 15:22:57and the first name and so on. We cannot
  25237. 15:22:59get it yet from the CT because in the
  25238. 15:23:01city we have only one employee. So we
  25239. 15:23:03still have to go to the database and
  25240. 15:23:05grab the next employees. So now I will
  25241. 15:23:08give this as an alias like E and I will
  25242. 15:23:11select it as well from those employees.
  25243. 15:23:13So so far we are not doing any recursive
  25244. 15:23:16yet right in the recursive query we're
  25245. 15:23:18still querying the database but now we
  25246. 15:23:21don't need all the employees from this
  25247. 15:23:23table we need all the employees where
  25248. 15:23:25the manager ID equal to one right now.
  25249. 15:23:28Of course, in order to get those
  25250. 15:23:29employees where the manager equal to
  25251. 15:23:32one. So we can do it with the workclouds
  25252. 15:23:34for example and say manager ID equal to
  25253. 15:23:38one. Let me just select this and query
  25254. 15:23:40it. Now we will get those two employees
  25255. 15:23:43where their manager is the CEO the top
  25256. 15:23:45manager. But of course we cannot do it
  25257. 15:23:47like this. What we're going to do we're
  25258. 15:23:49going to join this table with our
  25259. 15:23:51current CTE in order to make a loop. So
  25260. 15:23:54let me show you what I mean. We will
  25261. 15:23:55remove this. We're going to use the
  25262. 15:23:57inner join and we're going to reference
  25263. 15:24:01it from the CTE and let's give this the
  25264. 15:24:04name C H and we connect it like this. So
  25265. 15:24:08on we're going to say the manager ID of
  25266. 15:24:11the employee should be equal to the
  25267. 15:24:14employee ID. So the employee ID at the
  25268. 15:24:17start going to be the number one. So
  25269. 15:24:19it's going to be like
  25270. 15:24:20this employee ID. Now we are connecting
  25271. 15:24:24the manager ID with the employee ID and
  25272. 15:24:27we are as well reusing the CD inside
  25273. 15:24:30itself in order to make the iterations
  25274. 15:24:32and here we don't need the work clause
  25275. 15:24:34because the inner join going to filter
  25276. 15:24:36the data automatically as we learned the
  25277. 15:24:38inner join going to show only the
  25278. 15:24:40matching rows from the left and to right
  25279. 15:24:42so that mean there will be filtering. So
  25280. 15:24:44we are almost there but of course we
  25281. 15:24:46don't want to show it as a two. What
  25282. 15:24:48we're going to do, we're going to show
  25283. 15:24:49it like this. Level + one. So the
  25284. 15:24:52current level is one. The second
  25285. 15:24:54iteration going to be two. And the third
  25286. 15:24:56iteration going to be three. So I think
  25287. 15:24:58we have everything for our iteration.
  25288. 15:25:01Let me just check and make this smaller.
  25289. 15:25:04Now again we have here our anchor query.
  25290. 15:25:06This is only for the top level manager.
  25291. 15:25:08And then here we are just connecting the
  25292. 15:25:11managers with the employees. And we are
  25293. 15:25:13reusing the CTE in order to make the
  25294. 15:25:16effect of the loop. And as well we are
  25295. 15:25:18using the inner join in order to break
  25296. 15:25:20the loop once there are no more rows to
  25297. 15:25:23process. So let's go and execute it. Now
  25298. 15:25:26let's check the output. This is our top
  25299. 15:25:28manager. So level one. This information
  25300. 15:25:30comes from the anchor query. Then the
  25301. 15:25:32second iteration it is the employees
  25302. 15:25:35where the manager ID equal to one. So
  25303. 15:25:38it's going to be those two employees. So
  25304. 15:25:40those employees in our hierarchy are the
  25305. 15:25:43second level in our organization. And
  25306. 15:25:45then we're going to search for employees
  25307. 15:25:47where their manager ID is equal to
  25308. 15:25:50either two or three. And this is going
  25309. 15:25:52to be those two employees, Carol and
  25310. 15:25:54Miracle. And now to the third iteration,
  25311. 15:25:57we're going to search for all employees
  25312. 15:25:58where their manager ID equal to either
  25313. 15:26:01two or three. And now to the third
  25314. 15:26:03iteration, we're going to search for all
  25315. 15:26:05employees where their manager ID equal
  25316. 15:26:07to either two or three. And this going
  25317. 15:26:10to result having those two employees
  25318. 15:26:12because their manager ID is equal to
  25319. 15:26:14three or two and they're going to get
  25320. 15:26:16the level of three. And then after that
  25321. 15:26:18SQL going to try to search for employees
  25322. 15:26:20where their manager ID equal to five and
  25323. 15:26:23four and SQL will not find anything and
  25324. 15:26:25that's why it kind of breaks. So with
  25325. 15:26:28that we have solved the task. All right.
  25326. 15:26:29I totally understand if this is
  25327. 15:26:31complicated but now we're going to do it
  25328. 15:26:33step by step in order to understand how
  25329. 15:26:35SQL executed this and why we have done
  25330. 15:26:38it in this way. So again we have our
  25331. 15:26:39flow diagram. We start by running the
  25332. 15:26:42anchor query then the recursive query
  25333. 15:26:45and then we have a check. If the check
  25334. 15:26:47fails we iterate otherwise we end. So
  25335. 15:26:50let's do it step by step. Here we have
  25336. 15:26:51the table employees and beneath it we
  25337. 15:26:54have the result of the city. So the
  25338. 15:26:56first step it says we run the anchor
  25339. 15:26:58query and we run it only once. So it's
  25340. 15:27:00going to go to the anchor query and
  25341. 15:27:02start executing it. So here we are
  25342. 15:27:04selecting from the table employees but
  25343. 15:27:06we are making a filter on the manager
  25344. 15:27:08ID. So the manager ID should be null. So
  25345. 15:27:11that means we will get the record of
  25346. 15:27:14Frank and Frank going to be at the
  25347. 15:27:16output and we are saying the level of
  25348. 15:27:19this employee is one. So we will have
  25349. 15:27:21here at the level one. So this is the
  25350. 15:27:24output of the anchor query and that's
  25351. 15:27:26it. This will never be executed. Now we
  25352. 15:27:28go to the next step. Now we will run the
  25353. 15:27:31recursive query. So what's going to
  25354. 15:27:33happen in the recursive query we are
  25355. 15:27:35saying okay I would like to select as
  25356. 15:27:36well data from the employees and join it
  25357. 15:27:39with the city results but the join
  25358. 15:27:41should be an inner join so only the
  25359. 15:27:43matching data between the CTE and the
  25360. 15:27:45employees and now comes the join
  25361. 15:27:48condition and this is the key for this
  25362. 15:27:50iteration we are saying the manager ID
  25363. 15:27:52of the employee should be matching to
  25364. 15:27:55the employee ID from the CTE. So SQL
  25365. 15:27:58going to go and join the table with the
  25366. 15:28:00CTE. So now we have here only employee
  25367. 15:28:02number ID one. So it's still going to do
  25368. 15:28:04it step by step searching for any
  25369. 15:28:06matches. So for the first one we don't
  25370. 15:28:09have a match because the manager ID is
  25371. 15:28:11not equal to one. So that's why it will
  25372. 15:28:13not be included in the result. The
  25373. 15:28:16second row here the manager ID is equal
  25374. 15:28:18to one and this is a match with the
  25375. 15:28:20employee ID. So SQL going to take it and
  25376. 15:28:23put it at the output. Not only that, SQL
  25377. 15:28:26going to increase the level. So we have
  25378. 15:28:28here the current value is one. So level
  25379. 15:28:31+ one. What can happen? We will get the
  25380. 15:28:33value two. We are still in the same
  25381. 15:28:35iteration. We are not iterating yet. So
  25382. 15:28:37this is the first iteration of the
  25383. 15:28:40recursive query. So until the whole join
  25384. 15:28:43is done to the next row, we have a match
  25385. 15:28:46as well because the manager ID is equal
  25386. 15:28:48to one. And we're going to have the same
  25387. 15:28:51thing. The level going to be as well too
  25388. 15:28:53because the value of the level didn't
  25389. 15:28:54change. It's still the current value is
  25390. 15:28:56equal to one. And this going to keep
  25391. 15:28:58going. So two, three, we don't have any
  25392. 15:29:00matches. And with that, SQL is done
  25393. 15:29:03executing the recursive query. All
  25394. 15:29:05right. So now the SQL going to say,
  25395. 15:29:07okay, did we process everything? Well,
  25396. 15:29:10no. We still have missing output. We
  25397. 15:29:12still have missing employees. That's why
  25398. 15:29:14we didn't fulfill the condition. And
  25399. 15:29:16we're going to run this again. So now in
  25400. 15:29:18the second iteration, it's going to join
  25401. 15:29:20as well again the city result with the
  25402. 15:29:23employees by matching the manager ID and
  25403. 15:29:26the employee ID. But this time it's
  25404. 15:29:27going to focus only on those two ids. So
  25405. 15:29:30the two and three. So SQL going to go
  25406. 15:29:32and find any matching where the major ID
  25407. 15:29:35equal to two or three. So it's going to
  25408. 15:29:38do it step by step. The first one is
  25409. 15:29:40not. The second one is as well not. The
  25410. 15:29:43third one is not because the manager ID
  25411. 15:29:45is one. But now to the employee number
  25412. 15:29:49four we have a match. So it's still
  25413. 15:29:51going to take this one and put it in the
  25414. 15:29:54output like this. And now in this
  25415. 15:29:56iteration what is the current level? It
  25416. 15:29:58is two but we add to it one that's why
  25417. 15:30:01we will get in the output three. And
  25418. 15:30:04then SQL keep going. So we have here the
  25419. 15:30:06employee number five and the manager ID
  25420. 15:30:09is equal to three. So what happens? SQL
  25421. 15:30:11takes it as well and put it in the
  25422. 15:30:14output as the result of the CTE and as
  25423. 15:30:17well the current level is two + one.
  25424. 15:30:20We're going to have as well three. So
  25425. 15:30:22with that SQL done joining the tables
  25426. 15:30:25and going to ask again did we process
  25427. 15:30:27all employees? Well yes it's true that
  25428. 15:30:30means we don't have to do any more
  25429. 15:30:32iterations because if you do any
  25430. 15:30:34iterations SQL will not find anything.
  25431. 15:30:37So for example if you go over here let
  25432. 15:30:39me just remove this and let's say we are
  25433. 15:30:41joining with the four and five. So what
  25434. 15:30:43can happen isql going to search in the
  25435. 15:30:45manager's ID for four and five and it
  25436. 15:30:48will not find anything. So that means we
  25437. 15:30:50will not be adding anything to the CTE.
  25438. 15:30:52That's why SQL stops. So we have a
  25439. 15:30:54complete results and we have now all the
  25440. 15:30:56data from the employees in the output
  25441. 15:30:58and this results going to be passed to
  25442. 15:31:00the main query. So this is why we have
  25443. 15:31:02done it like this and this is how
  25444. 15:31:04executed this recursive query. I would
  25445. 15:31:07like to visual for you what this means
  25446. 15:31:09the level or the structure of the
  25447. 15:31:11organization. So the hierarchy looks
  25448. 15:31:13like this. The level one the top manager
  25449. 15:31:15is Frank. So this is the level number
  25450. 15:31:19one. And then we go to the level number
  25451. 15:31:21two. So we have those two employees. So
  25452. 15:31:24we have Kevin. So this is the level
  25453. 15:31:26number one. And then we have two
  25454. 15:31:28employees Kevin and Mary at the level
  25455. 15:31:31two. So they work together and their
  25456. 15:31:35boss is Frank. So it's going to look
  25457. 15:31:38like this. And they are at the level
  25458. 15:31:41two. We have then Michael that directly
  25459. 15:31:44reports to who? To Kevin because here we
  25460. 15:31:47have the employee ID two and two. So we
  25461. 15:31:50have one employee here and as well Carol
  25462. 15:31:52is as well at the level three and she
  25463. 15:31:55reports to Mary and both Michael and
  25464. 15:31:58Carol are at the level three. So this is
  25465. 15:32:01what we mean with the level. It can help
  25466. 15:32:03us to identify which employee at which
  25467. 15:32:05level in the organization. If you have
  25468. 15:32:08like hierarchy in your data and you can
  25469. 15:32:10see in one table things are referencing
  25470. 15:32:13each others like here the manager ID is
  25471. 15:32:16actually the employee ID. So it's like
  25472. 15:32:18we are referencing those ID to each
  25473. 15:32:20others. This means there is hierarchy
  25474. 15:32:23and there is a structure in this table
  25475. 15:32:25and you can use the recursive city in
  25476. 15:32:27order to build those levels and to
  25477. 15:32:30navigate as well through the hierarchy.
  25478. 15:32:33All right. So that's all for the
  25479. 15:32:34recursive city and with that we have
  25480. 15:32:35covered all the different types of
  25481. 15:32:38cities that we have in
  25482. 15:32:42SQL. So now let's have a quick recap. So
  25483. 15:32:45we have learned that the CTE the common
  25484. 15:32:47table expression is a temporary named
  25485. 15:32:50result like a virtual table that could
  25486. 15:32:52be used from different places in the
  25487. 15:32:54query and we have a lot of advantages
  25488. 15:32:56for the CTE. The main one is it breaks
  25489. 15:32:59the complexity of query into small
  25490. 15:33:01multiple pieces which makes our query
  25491. 15:33:04much easier to read and as well to
  25492. 15:33:06understand. So it improves readability.
  25493. 15:33:08Another advantage of the city is that
  25494. 15:33:10those small multiple pieces they are
  25495. 15:33:13really easy to manage and to develop. So
  25496. 15:33:15those pieces are like self-contained
  25497. 15:33:17which makes our queries more modular. So
  25498. 15:33:20it introduces modularity inside our
  25499. 15:33:23queries. And we also learned that the
  25500. 15:33:24CTE help us to reduce the redundancy
  25501. 15:33:27inside our queries where it makes the
  25502. 15:33:30result of one query usable in multiple
  25503. 15:33:33places inside our query. So it makes our
  25504. 15:33:36code smaller and reduce redundancy. And
  25505. 15:33:38one more advantage of the city is that
  25506. 15:33:40it help us to do looping and iterating
  25507. 15:33:43in SQL by using the recursive CTE. And
  25508. 15:33:46we have understood as well that we can
  25509. 15:33:48treat the CTE result as any other
  25510. 15:33:51physical table inside our database. So
  25511. 15:33:53we can treat it and handle it like any
  25512. 15:33:55other tables. Only one exception that
  25513. 15:33:57this table lives only in one query. So
  25514. 15:34:00we cannot query the CTE from an external
  25515. 15:34:03query. Now we have learned that the
  25516. 15:34:05result of the CTE could be used from the
  25517. 15:34:07main query. This is the classical one.
  25518. 15:34:10But not only we can use it in the main
  25519. 15:34:12query but also we can use it in another
  25520. 15:34:15CTE query which leads to having nested
  25521. 15:34:18cities. And of course we have learned as
  25522. 15:34:20well we can use the result of the CTE
  25523. 15:34:23within itself which makes the CTE
  25524. 15:34:25recursive and allows for looping and
  25525. 15:34:27iterating. And I can only keep
  25526. 15:34:29recommending to not use more than five
  25527. 15:34:32CTEs in one query. Otherwise you're
  25528. 15:34:34going to get the exact opposite and
  25529. 15:34:36benefits from cdes where your code going
  25530. 15:34:38to be really hard to understand and to
  25531. 15:34:40read and even to extend. Okay my friends
  25532. 15:34:42with that we have covered this amazing
  25533. 15:34:44and very important technique in SQL the
  25534. 15:34:46common table expressions the city. Now
  25535. 15:34:49in the next step we're going to talk
  25536. 15:34:50about a new type of objects that you can
  25537. 15:34:52use in databases. We don't have only
  25538. 15:34:54tables we have as well views. And views
  25539. 15:34:57are amazing in order to give you dynamic
  25540. 15:34:59and flexibility in your project. So
  25541. 15:35:01let's talk about
  25542. 15:35:06views. Now a view is not like a query
  25543. 15:35:09that we can use in SQL. It is an object
  25544. 15:35:11that we can find in the database. So
  25545. 15:35:14before we jump immediately to the view,
  25546. 15:35:15I would like to give you the big
  25547. 15:35:17picture, the whole structure of the
  25548. 15:35:19database. So let's go. We have like
  25549. 15:35:22hierarchy structure and the highest
  25550. 15:35:24level of this hierarchy is the SQL
  25551. 15:35:26server. The SQL server manages multiple
  25552. 15:35:29databases. It's like the control center
  25553. 15:35:31that keep everything running and
  25554. 15:35:33accessible. Now inside the SQL server,
  25555. 15:35:36we have multiple databases. So a
  25556. 15:35:38database is collection of informations
  25557. 15:35:40that are stored in structured way. It's
  25558. 15:35:43where all your data is kept and
  25559. 15:35:45organized in different tables and
  25560. 15:35:47objects. And each database is separated
  25561. 15:35:49from others and it has its own data. Now
  25562. 15:35:52inside each database we can find
  25563. 15:35:54multiple schemas. A schema is like a
  25564. 15:35:57logical way on how you group up related
  25565. 15:35:59objects like tables and views together
  25566. 15:36:02within a database. Like for example, if
  25567. 15:36:04you have a database called sales, we can
  25568. 15:36:06group up different tables about the
  25569. 15:36:08orders underneath the schema orders. And
  25570. 15:36:11maybe we have like multiple views and
  25571. 15:36:13tables about the customers where we can
  25572. 15:36:15put it in the schema customers. So if
  25573. 15:36:17you find like multiple tables and views
  25574. 15:36:19that are describing the same object, the
  25575. 15:36:22same topic, we put them all together
  25576. 15:36:24underneath one schema. So again, a
  25577. 15:36:26database could be like the sales
  25578. 15:36:28database and the HR database. They are
  25579. 15:36:30completely different types of data. And
  25580. 15:36:33underneath the sales, we can have like
  25581. 15:36:35different sections. We have the sections
  25582. 15:36:36about the orders and sections about the
  25583. 15:36:38customers. And now moving on, what we
  25584. 15:36:40can find inside the schema, we can find
  25585. 15:36:42tables. A table is where actually your
  25586. 15:36:45data is stored. It contains multiple
  25587. 15:36:47columns and rows. So it is where the
  25588. 15:36:49data physically lives. And now inside
  25589. 15:36:51the schemas, we have another type of
  25590. 15:36:53object. We call it view. And of course
  25591. 15:36:56in this section, we are focusing on the
  25592. 15:36:57views. So a view is like a virtual table
  25593. 15:37:00that has a structure and everything but
  25594. 15:37:03inside it we don't have any data. So the
  25595. 15:37:06view does not store any data and in
  25596. 15:37:08order to see the data we have to execute
  25597. 15:37:10the query behind the view and only after
  25598. 15:37:13that we're going to see some data but it
  25599. 15:37:15is not like the tables it doesn't store
  25600. 15:37:16the data permanently. Now inside the
  25601. 15:37:18tables we can define multiple stuff like
  25602. 15:37:21columns and as well keys and the same
  25603. 15:37:23thing for the views. Inside the views we
  25604. 15:37:25can define multiple columns and one last
  25605. 15:37:28level for each column we have like a
  25606. 15:37:30name and a data type. So as you can see
  25607. 15:37:32the databases are really organized and
  25608. 15:37:34we have like hierarchy where the top
  25609. 15:37:36node is the SQL server and the lowest
  25610. 15:37:39node is the columns and rows. So this is
  25611. 15:37:42what we call the database structure. Now
  25612. 15:37:44in order for you to build and manage
  25613. 15:37:46this structure we have set of commands
  25614. 15:37:49we call it DDL the shortcut of data
  25615. 15:37:52definition language. So the detail is a
  25616. 15:37:55set of commands that allow us to define
  25617. 15:37:58and manage the structure of the
  25618. 15:38:00database. So we have commands like
  25619. 15:38:02create where it help us to create
  25620. 15:38:05databases, schemas, tables, views.
  25621. 15:38:07Another command called alter. Of course
  25622. 15:38:09after you create something you would
  25623. 15:38:11like maybe later to do changes and
  25624. 15:38:13updates and of course we have the drop
  25625. 15:38:14in order to remove any database object
  25626. 15:38:17like dropping a schema, dropping a
  25627. 15:38:19database, tables, views. So as you can
  25628. 15:38:21see the DDL commands can help us to
  25629. 15:38:23manage the database structure. So from
  25630. 15:38:25this picture we have understood that we
  25631. 15:38:27can create views inside schemas in the
  25632. 15:38:30database. So now if you check the client
  25633. 15:38:32and the object explorer you can find the
  25634. 15:38:35exact hierarchy. So it start with the
  25635. 15:38:37SQL server. This is our local server
  25636. 15:38:39that's run at our machine and then we
  25637. 15:38:41can find inside it multiple databases
  25638. 15:38:44and one of them is our sales DB that you
  25639. 15:38:46have installed together with other
  25640. 15:38:47database like the adventure works. So
  25641. 15:38:49now if you go to the sales DB over here
  25642. 15:38:52you can go and drill to the next level
  25643. 15:38:54and now we can find here a lot of
  25644. 15:38:55objects and one of them that you know we
  25645. 15:38:57have tables and views and now you might
  25646. 15:38:59say okay but between the database and
  25647. 15:39:01tables we have schemas so where are the
  25648. 15:39:04schemas well actually if you go inside
  25649. 15:39:06the tables you're going to find our
  25650. 15:39:08tables customers employees and so on but
  25651. 15:39:10before it we have a name called sales
  25652. 15:39:13doc customers and you can find it
  25653. 15:39:15everywhere sales doc customers sales do
  25654. 15:39:17employees and so on the sales is the
  25655. 15:39:20schema that bring all those tables
  25656. 15:39:22together underneath one logical schema.
  25657. 15:39:25So we have a database called sales DB.
  25658. 15:39:28We have a schema called sales and we
  25659. 15:39:30have a table called customers. And now
  25660. 15:39:32if you would like to see all the schemas
  25661. 15:39:34inside this database, what you can do?
  25662. 15:39:36You can go to the securities over here
  25663. 15:39:37and then here we have like a folder
  25664. 15:39:39called schemas. If you go over there,
  25665. 15:39:41you will find the list of all schemas
  25666. 15:39:43that we have in this database. You might
  25667. 15:39:45say, but we didn't create all those
  25668. 15:39:46stuff. If we have only the sales that we
  25669. 15:39:48know. Well, as you create a database in
  25670. 15:39:51SQL server, you will get a lot of other
  25671. 15:39:53system default schemas that the server
  25672. 15:39:56can create. One of them is the
  25673. 15:39:58information schema where it holds a lot
  25674. 15:40:00of views about the catalog and the
  25675. 15:40:02metadata where you can find the list of
  25676. 15:40:04columns, tables, views and so on. So
  25677. 15:40:06here we have only one schema that we
  25678. 15:40:08have created for the user. It is the
  25679. 15:40:09sales. So let's go back. Now if you go
  25680. 15:40:12inside one of those tables you will find
  25681. 15:40:14here multiple stuff like we have
  25682. 15:40:16columns, keys, constraints and so on.
  25683. 15:40:19And if you go to the columns you will
  25684. 15:40:21end up at the lowest level of the
  25685. 15:40:23hierarchy. And here we have the columns
  25686. 15:40:25like the customer ID and we have some
  25687. 15:40:27extra informations like the data type
  25688. 15:40:29length and so on. So this is the
  25689. 15:40:31structure and the hierarchy of
  25690. 15:40:32databases.
  25691. 15:40:37Now I would like you to understand a
  25692. 15:40:39fundamental concept on the database in
  25693. 15:40:41order to understand the views the
  25694. 15:40:43three-level architecture of the
  25695. 15:40:44database. This architecture can describe
  25696. 15:40:47the different levels of data
  25697. 15:40:49abstractions in a database. So let's see
  25698. 15:40:52what this means. So the architecture is
  25699. 15:40:54divided into three levels. The first
  25700. 15:40:56level is the physical level. Then we
  25701. 15:40:58have the logical level and the third one
  25702. 15:41:00is the view level. Now let's understand
  25703. 15:41:03each level what it means. So now the
  25704. 15:41:05physical level it is the lowest level of
  25705. 15:41:07the database where the actual data is
  25706. 15:41:10stored in a physical storage and usually
  25707. 15:41:12who has access to this layer are the
  25708. 15:41:15database administrators because they are
  25709. 15:41:17the experts and they have to manage the
  25710. 15:41:19access and the security of this layer
  25711. 15:41:21because they are the expert that have to
  25712. 15:41:24manage a lot of stuff like optimizing
  25713. 15:41:25the performance making sure that
  25714. 15:41:27everything is secure and managing the
  25715. 15:41:30backup and recovery and to do all the
  25716. 15:41:32configurations and many other tasks. So
  25717. 15:41:34at the physical layer we have to deal
  25718. 15:41:36with a lot of stuff like the data files,
  25719. 15:41:39partitions, logs, cataloges, blocks and
  25720. 15:41:42caches and many other stuff that each
  25721. 15:41:44database needs in order to store your
  25722. 15:41:46data. So as you can see this layer is
  25723. 15:41:49very complicated and you need to be
  25724. 15:41:51really an expert of databases in order
  25725. 15:41:54to be able to manage all those stuff. So
  25726. 15:41:56we call this layer a physical layer or
  25727. 15:41:59sometimes we call it an internal layer.
  25728. 15:42:01So now let's move to the next level. we
  25729. 15:42:03have the logical level. So the logical
  25730. 15:42:05layer it is less complicated than the
  25731. 15:42:07physical layer. Here at this level you
  25732. 15:42:09have to deal on how to organize your
  25733. 15:42:11data and normally we have here like an
  25734. 15:42:14application developer or we have like
  25735. 15:42:16data engineers that access the logical
  25736. 15:42:19level in order to define the structure
  25737. 15:42:21of your data. So those developers can
  25738. 15:42:23focus on how to structure your data
  25739. 15:42:25rather than how the data is exactly
  25740. 15:42:28storing the data physically at the
  25741. 15:42:29storage. So they don't have to deal with
  25742. 15:42:31all those details. they leave it for the
  25743. 15:42:33database administrator and they can
  25744. 15:42:35focus only on how to structure the data.
  25745. 15:42:38That's why we need for this kind of role
  25746. 15:42:41an abstraction level for them which is
  25747. 15:42:44the logical level. So now what actually
  25748. 15:42:46the developers are doing at this level?
  25749. 15:42:48Well, they are like creating tables and
  25750. 15:42:51defining the relationships between those
  25751. 15:42:53tables or they can go and define views.
  25752. 15:42:56they can create indexes on the tables in
  25753. 15:42:58order to optimize the performance of the
  25754. 15:43:00tables or maybe they are creating stored
  25755. 15:43:03procedures and functions and some other
  25756. 15:43:05codes in order to manage those tables.
  25757. 15:43:08So as you can see they are building the
  25758. 15:43:09data model they are structuring your
  25759. 15:43:11data but they don't care at all where
  25760. 15:43:14are those data stored physically in the
  25761. 15:43:17database. So as you can see here things
  25762. 15:43:19are less complicated than the physical
  25763. 15:43:21layer and it is perfect abstraction for
  25764. 15:43:23developers to build projects. So we call
  25765. 15:43:25this the logical layer or sometimes we
  25766. 15:43:28call it the conceptual layer. Okay. So
  25767. 15:43:30now moving on to another level of
  25768. 15:43:32abstraction. We have the view level. So
  25769. 15:43:35the view level is the highest level of
  25770. 15:43:38abstraction in the database and it is
  25771. 15:43:40what the end users and applications can
  25772. 15:43:43access and can see. So for example, you
  25773. 15:43:46could have like one view for business
  25774. 15:43:48analyst. So you prepare and customize a
  25775. 15:43:51views that are suitable only for the
  25776. 15:43:54business analyst and you might say you
  25777. 15:43:55know what let's prepare another set of
  25778. 15:43:58views that are suitable for data
  25779. 15:44:00visualizations and reporting like you
  25780. 15:44:03can go and connect for example a PowerBI
  25781. 15:44:05in order to create dashboards. So they
  25782. 15:44:08are fully customized and prepared views
  25783. 15:44:10in order to be connected with the
  25784. 15:44:13PowerBI reports and you can keep doing
  25785. 15:44:15that by creating multiple set of views
  25786. 15:44:18that are suitable for specific purpose
  25787. 15:44:21and use case. So as you can see at this
  25788. 15:44:23level we are exposing our data for
  25789. 15:44:26multiple users and multiple
  25790. 15:44:27applications. So now the question is
  25791. 15:44:29what do we have to deal at the view
  25792. 15:44:31level? Well, you have their only views
  25793. 15:44:33that holds only the relevant
  25794. 15:44:35informations for the use case or users.
  25795. 15:44:38So the users at this level have only
  25796. 15:44:40views. They don't have to deal with the
  25797. 15:44:42tables, indexes, store procedures, any
  25798. 15:44:45files, logs, partitions or anything.
  25799. 15:44:48This is the highest level of abstraction
  25800. 15:44:51because the focus of this layer is to
  25801. 15:44:53make it friendly for the end users and
  25802. 15:44:55easy to consume. So we call this layer
  25803. 15:44:57the view layer or sometimes we call it
  25804. 15:45:00an external layer. So this is the
  25805. 15:45:02three-level architecture of the
  25806. 15:45:04databases or we call it the three
  25807. 15:45:06abstraction levels of the database. So
  25808. 15:45:08the physical layer has the highest
  25809. 15:45:10complexity, the lowest abstraction and
  25810. 15:45:13the view layer has the highest
  25811. 15:45:15abstraction. So this is one more reason
  25812. 15:45:17why the views are very important concept
  25813. 15:45:19in SQL
  25814. 15:45:21[Music]
  25815. 15:45:24databases. Okay. So with that we have
  25816. 15:45:26enough fundamentals in order to start
  25817. 15:45:28talking about the views. So the question
  25818. 15:45:29is what are views? A view is a virtual
  25819. 15:45:33table in SQL that is based on the result
  25820. 15:45:36of a query without actually storing the
  25821. 15:45:39data in the database. So in short this
  25822. 15:45:41means views are stored or persisted SQL
  25823. 15:45:46query in the database. So let's
  25824. 15:45:48understand what this exactly means. Now
  25825. 15:45:50so far what you have learned we have
  25826. 15:45:51like database table and all what you
  25827. 15:45:53have done we create a select query in
  25828. 15:45:55order to retrieve the data from this
  25829. 15:45:57table. So once we execute our query we
  25830. 15:45:59will get the result back. Now if you are
  25831. 15:46:01talking about views they have as well
  25832. 15:46:04like the structure of the table but
  25833. 15:46:06without any data inside it. And for each
  25834. 15:46:08view there is like a query attached to
  25835. 15:46:11it. So there is no data but we have like
  25836. 15:46:13a query in order to get data. We call
  25837. 15:46:16the normal table as a physical table and
  25838. 15:46:18the view we call it a virtual table. So
  25839. 15:46:21now how exactly we're going to get the
  25840. 15:46:22data. So now if you go and write query
  25841. 15:46:25by selecting data from the view not from
  25842. 15:46:27the table from the view what going to
  25843. 15:46:29happen SQL going to go and trigger the
  25844. 15:46:32queue that is attached to the view and
  25845. 15:46:34this query is responsible to query the
  25846. 15:46:37physical table and then the result going
  25847. 15:46:40to fill the structure of the view and we
  25848. 15:46:42will get back of course the results. So
  25849. 15:46:44we are directly querying a view but
  25850. 15:46:46actually we are indirectly querying a
  25851. 15:46:49physical table. So the view is like
  25852. 15:46:51between us and the data. So that means
  25853. 15:46:53my real data is stored inside the
  25854. 15:46:55database tables and the views are like
  25855. 15:46:58an abstraction layer between me and my
  25856. 15:47:00real data. And of course the data will
  25857. 15:47:03not be stored inside the view. Each time
  25858. 15:47:05I'm querying the view what's going to
  25859. 15:47:07happen the SQL query behind the view
  25860. 15:47:09going to be executed again. So it's
  25861. 15:47:11going to go and retrieve the data and
  25862. 15:47:13get it back to the view and then I will
  25863. 15:47:14see it in the output. So this is what we
  25864. 15:47:17mean with SQL
  25865. 15:47:21view. So now let's have a quick
  25866. 15:47:23comparison between tables and views.
  25867. 15:47:25Tables stores the actual data physically
  25868. 15:47:28at a database. So the tables where the
  25869. 15:47:30data is persisted with in the other hand
  25870. 15:47:32the views they are virtual tables and
  25871. 15:47:35they do not store any data inside the
  25872. 15:47:37database but they present the data from
  25873. 15:47:39the underlying tables. So that means
  25874. 15:47:41views don't persist any data physically.
  25875. 15:47:44Now the tables are hard to maintain and
  25876. 15:47:46as well hard to change. So it needs a
  25877. 15:47:49lot of efforts in order to do any change
  25878. 15:47:51like adding columns and moving columns
  25879. 15:47:53always requires a lot of efforts for the
  25880. 15:47:55migration especially if you have large
  25881. 15:47:57tables. But in the other hand the views
  25882. 15:48:00are way easier to maintain and very
  25883. 15:48:02flexible to change. All what you have to
  25884. 15:48:04do is only to change the query of the
  25885. 15:48:06view. So that means you can very quickly
  25886. 15:48:08change stuff in the views compared to
  25887. 15:48:10the tables. But if you are talking about
  25888. 15:48:12performance, tables are faster than
  25889. 15:48:14views. For example, if you go and do a
  25890. 15:48:16simple select on the table, you will get
  25891. 15:48:18the data back as soon as the database
  25892. 15:48:21fetches the data. But if you are
  25893. 15:48:22selecting something from the view, it is
  25894. 15:48:24actually two queries. The query that
  25895. 15:48:27comes from the user and as well the
  25896. 15:48:29second query is the view query. and the
  25897. 15:48:31query of the view could be very
  25898. 15:48:33complicated in order to extract the data
  25899. 15:48:36from the underlying table. So selecting
  25900. 15:48:38something from the view is always slower
  25901. 15:48:40than selecting something from a table.
  25902. 15:48:42Now if you have a table you can read
  25903. 15:48:44from the table and as well you can write
  25904. 15:48:46to a table but the views are read only
  25905. 15:48:49as the name says it is only a view. You
  25906. 15:48:51cannot go and write something to the
  25907. 15:48:52database using the view. Okay. So those
  25908. 15:48:55are the big differences between views
  25909. 15:48:57and tables.
  25910. 15:49:02All right. So with that we have a clear
  25911. 15:49:03understanding what are views. But now
  25912. 15:49:05you might ask me why do we need views?
  25913. 15:49:08That's why now what we're going to do
  25914. 15:49:09we're going to deep dive into multiple
  25915. 15:49:11scenarios and use cases that you might
  25916. 15:49:13encounter in your SQL projects. So let's
  25917. 15:49:16start with the first use case. The first
  25918. 15:49:18use case and the core reason why we use
  25919. 15:49:20views in our data projects is to store
  25920. 15:49:23central logic from a complex query in
  25921. 15:49:26the database so that everyone can access
  25922. 15:49:28it and with that we improve reusability
  25923. 15:49:31between multiple queries and we reduce
  25924. 15:49:33as well the complexity of the overall
  25925. 15:49:36projects. So let's understand what this
  25926. 15:49:37means. So now in our project we have
  25927. 15:49:39like two tables in the database orders
  25928. 15:49:41and customers and we have learned
  25929. 15:49:43previously that if we have like a
  25930. 15:49:45complex query we can go and use the
  25931. 15:49:47city. So for example in our city we are
  25932. 15:49:49joining tables and doing some
  25933. 15:49:51aggregations using the sum and the city
  25934. 15:49:53going to store the data in an
  25935. 15:49:54intermediate results and then we have
  25936. 15:49:56the main query. For example we are doing
  25937. 15:49:58the step two where we are ranking the
  25938. 15:50:01data. So the whole thing is in one query
  25939. 15:50:03and let's say that a financial analyst
  25940. 15:50:05was doing this type of analyszis. Now
  25941. 15:50:08what could happen is that you might have
  25942. 15:50:10another user for example a budget
  25943. 15:50:12analyst where he is doing exactly the
  25944. 15:50:14same first step. So he has as well a
  25945. 15:50:17city query where first the data are
  25946. 15:50:19joined and then aggregated using the
  25947. 15:50:21sum. But the last step in the main query
  25948. 15:50:23he's not doing ranking he's just doing
  25949. 15:50:25like max and min. And not only that, we
  25950. 15:50:28have a third user, the risk analyst,
  25951. 15:50:30where as well doing the same initial
  25952. 15:50:33step using the CTE, joining the tables
  25953. 15:50:35and doing the summarization. But here
  25954. 15:50:37the risk analyst in this scenario, he's
  25955. 15:50:40just comparing the data at the last step
  25956. 15:50:42in the main query. So now if you sit
  25957. 15:50:43back and look to this, you can see all
  25958. 15:50:45those three data workers, all of them
  25959. 15:50:47are doing the same first step. So all of
  25960. 15:50:49them are doing the same CTE. They are
  25961. 15:50:51joining the data and then doing
  25962. 15:50:53summarization. And of course this is a
  25963. 15:50:55complete waste of time that each one of
  25964. 15:50:57them has to create first the city from
  25965. 15:50:59the scratch in order to do some
  25966. 15:51:01analyszis. So it is complete redundancy
  25967. 15:51:04and makes no sense. So this is exactly
  25968. 15:51:06the disadvantage of only using cities in
  25969. 15:51:09the projects. Now what we can do instead
  25970. 15:51:11of that those three data workers going
  25971. 15:51:13to decide to say you know what let's put
  25972. 15:51:15the first step as view in the database.
  25973. 15:51:18So instead of using CTE each time we're
  25974. 15:51:21going to take this script and put it in
  25975. 15:51:23the database. So we have now a central
  25976. 15:51:26logic that is stored in the database
  25977. 15:51:28where everyone can use it. So we have
  25978. 15:51:30this query this logic only once and
  25979. 15:51:33everyone can benefit from it. So now the
  25980. 15:51:36financial analyst instead of going
  25981. 15:51:38directly to the physical tables they can
  25982. 15:51:40go to the view. So thus means she needs
  25983. 15:51:43only to write one script the rank
  25984. 15:51:45script. Same thing goes for the budget
  25985. 15:51:47analyst. he has only to write the query
  25986. 15:51:49for the max and min and as well for the
  25987. 15:51:51risk analyst he just need to compare the
  25988. 15:51:53data. So as you can see all those
  25989. 15:51:55queries are reduced and they can only
  25990. 15:51:57focus on the analyzes. So this is
  25991. 15:51:59exactly the magic of views in data
  25992. 15:52:02analytics. This logic this knowledge can
  25993. 15:52:04be centralized in the database and this
  25994. 15:52:07is way faster and better than having
  25995. 15:52:09this logic written each time someone
  25996. 15:52:11want to do any analyzes. So this is why
  25997. 15:52:14we need views in data projects.
  25998. 15:52:20So now if you compare views with CTE,
  25999. 15:52:22the CTE are used in order to reduce the
  26000. 15:52:25redundancy within one single query. So
  26001. 15:52:28it improves the reusability within one
  26002. 15:52:31query. Where in the other hand in the
  26003. 15:52:33views we are reducing the redundancies
  26004. 15:52:36from multiple queries. So we are
  26005. 15:52:38reducing the complexity of the whole
  26006. 15:52:40project. So the views are improving the
  26007. 15:52:43reusability in multiple queries. Now
  26008. 15:52:46think about it like this. We use views
  26009. 15:52:48in order to persist a logic in the
  26010. 15:52:51database. So the logic is so important
  26011. 15:52:54that we want to persist it in the
  26012. 15:52:55database. It's like in the tables we
  26013. 15:52:57persist data but with the views we are
  26014. 15:52:59persisting logic. But in the other hand
  26015. 15:53:02in the CTE the logic is not persisted.
  26016. 15:53:05It is temporary and going to be
  26017. 15:53:06calculated only on the fly within the
  26018. 15:53:09scope of one query. So this logic is
  26019. 15:53:12important only in this scenario and it
  26020. 15:53:14is not important for any other queries.
  26021. 15:53:17That's why it makes no sense to persist
  26022. 15:53:19it using the views. So you have to
  26023. 15:53:21decide is this logic is very important
  26024. 15:53:24then take it away from the city and put
  26025. 15:53:26it in the view. But if you think you
  26026. 15:53:28know what this logic is not really
  26027. 15:53:30important and only important in this one
  26028. 15:53:32query then stay with the city because
  26029. 15:53:34creating views always needs some extra
  26030. 15:53:37steps in order to maintain the view. You
  26031. 15:53:40have to create the view. You have to
  26032. 15:53:41drop the view if you don't need it. But
  26033. 15:53:43the CTE, there is almost no maintenance
  26034. 15:53:45for it. The database going to do
  26035. 15:53:47automatically the cleanup once the query
  26036. 15:53:49is done. So there is no extra activity
  26037. 15:53:52to drop a city or something. That's why
  26038. 15:53:55CTE is easier to use than views. So
  26039. 15:53:57those are the big difference between the
  26040. 15:53:59views and
  26041. 15:54:03cities. Okay. So now let's check quickly
  26042. 15:54:05the syntax of a view. So now we have a
  26043. 15:54:08query like select from where. So this is
  26044. 15:54:10a query a simple select statement. But
  26045. 15:54:13now in order to create a view an object
  26046. 15:54:15in database we have to go and use a DDL
  26047. 15:54:18command create. So we're going to say
  26048. 15:54:20create view cuz we want to create a view
  26049. 15:54:23then the name of the view and then it's
  26050. 15:54:25like the CTE we say as and then double
  26051. 15:54:28parenthesis. So as you can see it's very
  26052. 15:54:30simple and we call this a DDL command
  26053. 15:54:33where we are telling the database go and
  26054. 15:54:35create a view and the logic of the view
  26055. 15:54:37comes from this query. So it's very
  26056. 15:54:39simple. This is how you can create views
  26057. 15:54:41in database. Okay. So now let's have the
  26058. 15:54:43following task and it says find the
  26059. 15:54:45running total of sales for each month.
  26060. 15:54:47I'm going to start this task by solving
  26061. 15:54:49it using the CTE. So first I'm going to
  26062. 15:54:51go and do few aggregations on the top of
  26063. 15:54:53the month. So let's go and select. So
  26064. 15:54:56now what do we need? We need the order
  26065. 15:54:58dates but we need it as a month. I'm
  26066. 15:55:00going to go and use the date truncate
  26067. 15:55:03like this and say okay I would like to
  26068. 15:55:05have the date as the granularity of
  26069. 15:55:08month. So let's go and call it order
  26070. 15:55:12month. And now after that we're going to
  26071. 15:55:13do a few aggregations like for example
  26072. 15:55:15let's go and get the sum of sales and
  26073. 15:55:19we're going to call it total sales. And
  26074. 15:55:21that's it for the start. So now let's go
  26075. 15:55:23and call it from the table sales orders
  26076. 15:55:26and group by and we are grouping up by
  26077. 15:55:30by the month. So something like this.
  26078. 15:55:32Let's go and execute it. And now for
  26079. 15:55:34this we get for each month the total
  26080. 15:55:36sales. And now the next step that we
  26081. 15:55:37have to go and calculate the running
  26082. 15:55:39total for the sales. This is of course
  26083. 15:55:41not the running total. So that means
  26084. 15:55:43either we can go and use subqueries. So
  26085. 15:55:45this means this is our first step and we
  26086. 15:55:47need a second step. So either use
  26087. 15:55:48queries or cities. I will go with the
  26088. 15:55:50city over here. So I'm going to say with
  26089. 15:55:53city and
  26090. 15:55:56monthly summary and we're going to
  26091. 15:55:59define it like this. And now what we're
  26092. 15:56:01going to do, we're going to go and
  26093. 15:56:02define the main query. So the main query
  26094. 15:56:04going to be simple. So select and let's
  26095. 15:56:07go and get the order month. And now we
  26096. 15:56:10have to build the running total. So
  26097. 15:56:12we're going to go and use the window
  26098. 15:56:13function. So sum total sales. And then
  26099. 15:56:17we're going to say over we don't have to
  26100. 15:56:19partition the data. We will just sort it
  26101. 15:56:22by the order
  26102. 15:56:24month and we can leave it ascending. So
  26103. 15:56:27this is the running
  26104. 15:56:30total and we have to go and select of
  26105. 15:56:33course our CTE from here. So let's go
  26106. 15:56:36and execute it and with that we are
  26107. 15:56:38getting the running total. Of course we
  26108. 15:56:39can go and add the total sales in the
  26109. 15:56:41output in order to understand the
  26110. 15:56:43results. So here in the output we are
  26111. 15:56:44just building accumulative sales. So for
  26112. 15:56:47this scope everything is fine. and we
  26113. 15:56:49are using the CTE. But now imagine that
  26114. 15:56:51this logic is important for multiple
  26115. 15:56:54queries. So it's really nice to have
  26116. 15:56:56such a report where we are aggregating
  26117. 15:56:58the data at the level of the month and
  26118. 15:57:00this could be used from different users
  26119. 15:57:02and different queries. So now we say how
  26120. 15:57:04about to put this logic in one view so
  26121. 15:57:07that everyone can access it and we don't
  26122. 15:57:09have to repeat the same aggregations
  26123. 15:57:11over and over. And now before we put it
  26124. 15:57:13in view, someone comes and say how about
  26125. 15:57:15to add one more aggregation so that not
  26126. 15:57:17only the total sales we can add. So now
  26127. 15:57:19before we put it as view maybe some
  26128. 15:57:21other user says you know what we would
  26129. 15:57:23like to have one more aggregation not
  26130. 15:57:24only the total sales let's make the
  26131. 15:57:26scope a little bit bigger so that
  26132. 15:57:28everyone can believe it. So for example
  26133. 15:57:29we can go over here and say you know
  26134. 15:57:31what let's go and add the total number
  26135. 15:57:33of orders. So we can go over here and
  26136. 15:57:35say counts and let's get the order ID
  26137. 15:57:38and say this is the total orders or
  26138. 15:57:41maybe some other says let's get the
  26139. 15:57:43quantities as well. So we can go and
  26140. 15:57:46summarize the quantity like this and we
  26141. 15:57:50call it total
  26142. 15:57:51quantities. So with that we are like
  26143. 15:57:54doing a lot of aggregations on the month
  26144. 15:57:56level. Let's go and execute only the
  26145. 15:57:58CTE. So now we have really nice report
  26146. 15:58:00that is based on the months and can be
  26147. 15:58:03used from many different queries. So now
  26148. 15:58:05what we're going to do, we're going to
  26149. 15:58:06take this and put it in a view. Let's go
  26150. 15:58:08and select only this logic and create a
  26151. 15:58:11new query. And now what we're going to
  26152. 15:58:13do, we're going to put our query here
  26153. 15:58:14and we have to create now the DDL in
  26154. 15:58:16order to create a view. So it's going to
  26155. 15:58:19be like this. Create view. Let's give it
  26156. 15:58:21the name maybe starts with the V
  26157. 15:58:23underscore and this going to be the
  26158. 15:58:25monthly summary. So this is the name of
  26159. 15:58:28the view and as then we put everything
  26160. 15:58:32in parenthesis. It's like you are
  26161. 15:58:34building a CTE. So we have here our
  26162. 15:58:36logic and here is our DDL query in order
  26163. 15:58:40to create the view. So now let's go and
  26164. 15:58:42execute it. Now as you can see in the
  26165. 15:58:44output it says only that the command is
  26166. 15:58:46completed because this is not a select
  26167. 15:58:48query. This is a DDL command. So the SQL
  26168. 15:58:51going to tell you okay either I created
  26169. 15:58:53it successfully or not. So now the
  26170. 15:58:55question is where do I find now my view?
  26171. 15:58:58Well, if you go to the object explorer,
  26172. 15:59:00you can see over here underneath our
  26173. 15:59:02database sales DB, we have here
  26174. 15:59:05something called tables where we are
  26175. 15:59:06used to query those tables. But beneath
  26176. 15:59:09it, we have as well our views. So if you
  26177. 15:59:12check the views and expand it, now we
  26178. 15:59:14are not seeing M view because we just
  26179. 15:59:16created the view here. So go over here
  26180. 15:59:18and refresh. And once you do that, you
  26181. 15:59:21will see the newly created view. So this
  26182. 15:59:24is the one that we just created. So now
  26183. 15:59:26what we can do, we can go and create a
  26184. 15:59:27new query and let's go and just query
  26185. 15:59:30the view. So select star from so v month
  26186. 15:59:35monthly summary. Let's go and execute
  26187. 15:59:39it. And now as you can see we are
  26188. 15:59:40getting now the result of the view and
  26189. 15:59:42I'm accessing now this logic from
  26190. 15:59:45completely external query. So now I can
  26191. 15:59:47think about the view as any other table
  26192. 15:59:49that we have in the database. And again
  26193. 15:59:51the big differences between the views
  26194. 15:59:53and the tables. The tables has data has
  26195. 15:59:56actual data and everything there is
  26196. 15:59:58persisted but the view is just an
  26197. 16:00:00abstraction for me and behind it there
  26198. 16:00:03is like a query that goes to the table
  26199. 16:00:05and query the tables in order to present
  26200. 16:00:08the results. But for me I don't care
  26201. 16:00:09about all those details. I can go
  26202. 16:00:11immediately to the query over here and
  26203. 16:00:13start querying. So now in order to
  26204. 16:00:15create the total running sales I don't
  26205. 16:00:17have to create the CTE and sub queries.
  26206. 16:00:20I just go and get for example our main
  26207. 16:00:23query. Let's go back over here. So now
  26208. 16:00:26instead of using the CTE I can go
  26209. 16:00:28directly and access the view. So as you
  26210. 16:00:32can see now my query is very simple. I'm
  26211. 16:00:34doing immediately the step two without
  26212. 16:00:37having to prepare the data first. So if
  26213. 16:00:39I go and execute it I will get exact
  26214. 16:00:41results. And now if you compare the
  26215. 16:00:43query on top of the view like this with
  26216. 16:00:45the city query you can see that the CTE
  26217. 16:00:48has more steps and it is like little bit
  26218. 16:00:51more complicated than the query on top
  26219. 16:00:53of the view and this is exactly the
  26220. 16:00:55benefit of the view. We reduce the
  26221. 16:00:57complexity and it is very easy to
  26222. 16:00:59consume from the point of view of users.
  26223. 16:01:01So this is how you can put your logic in
  26224. 16:01:04central place using views and with that
  26225. 16:01:07we have learned how we create a view.
  26226. 16:01:09Now one more thing about the schemas. If
  26227. 16:01:11you check our tables over here, they
  26228. 16:01:13have all one schema. So we have sales
  26229. 16:01:15dot customers, sales do employees,
  26230. 16:01:18orders and so on. Our new view has the
  26231. 16:01:20schema of DBO. If you create any object
  26232. 16:01:23whether it's table or view and you don't
  26233. 16:01:26specify a schema in a default schema
  26234. 16:01:28called DBO. And now let's go back to our
  26235. 16:01:30DDL scripts. So as you can see over
  26236. 16:01:32here, we didn't specify any schema. We
  26237. 16:01:34just said okay, this is the view name.
  26238. 16:01:37And now in order to put our view in the
  26239. 16:01:39correct schema we don't want it to be in
  26240. 16:01:41the defaults. You have to go and specify
  26241. 16:01:43the schema name in the DDL. And now in
  26242. 16:01:45order to do that we go to the name of
  26243. 16:01:47the view and we write the schema name
  26244. 16:01:50and then separated with a dot. So the
  26245. 16:01:52first one is the schema name and the
  26246. 16:01:54second one is the view name. So now
  26247. 16:01:57let's go and execute it. Now if you
  26248. 16:01:59check over here you don't see anything
  26249. 16:02:00new. But if you refresh you will find
  26250. 16:02:03another view in the correct schema. So
  26251. 16:02:05we have sales dot vmon monthly summary
  26252. 16:02:08and this is exactly what we want. So
  26253. 16:02:10this is how you can assign a view or
  26254. 16:02:12even a table to the correct schema if
  26255. 16:02:15you don't want to use the default one
  26256. 16:02:16the view. All right. So now the next
  26257. 16:02:18step is that you say you know what I
  26258. 16:02:19would like to clean up. I don't need
  26259. 16:02:20those two views in my database. So how
  26260. 16:02:23to delete a view? We can go and use the
  26261. 16:02:25command drop. It is very simple. If you
  26262. 16:02:27go and create a new query and you say
  26263. 16:02:30drop and then you say what you want to
  26264. 16:02:32drop. you want to drop a view and then
  26265. 16:02:33you have to specify the name and schema
  26266. 16:02:36of the view. But now since it is the
  26267. 16:02:38default schema DBU, I don't have to
  26268. 16:02:40write it down. So we can start
  26269. 16:02:42immediately with the view name. So V
  26270. 16:02:45monthly summary. So that's it. It's very
  26271. 16:02:48simple. So now we go and execute it. It
  26272. 16:02:51says it's completed but as you can see
  26273. 16:02:53nothing has changed. We go and refresh.
  26274. 16:02:55And now we can see that the database did
  26275. 16:02:57remove the view with the schema DBU. So
  26276. 16:03:00it's very simple. This is how you can
  26277. 16:03:02drop a view in SQL. Okay. So now to the
  26278. 16:03:05next step. Let's go back to our DDL of
  26279. 16:03:07creating the view sales monthly summary.
  26280. 16:03:09And now you say you know what I would
  26281. 16:03:11like to change the logic inside the
  26282. 16:03:13view. So how we can update this content?
  26283. 16:03:16How I can update my query? If you say
  26284. 16:03:18let's go and for example delete this
  26285. 16:03:20column. I need only three columns. So
  26286. 16:03:23and you go execute it. The database say
  26287. 16:03:25I cannot do it for you because we have
  26288. 16:03:27already such a view. So SQL will not go
  26289. 16:03:30and replace stuff going to say no we
  26290. 16:03:33have the same name and I cannot do
  26291. 16:03:35anything for it. So how we can update
  26292. 16:03:37the view? Well in other databases like
  26293. 16:03:39ocris for example it's very simple. You
  26294. 16:03:42can go over here and say create or
  26295. 16:03:45replace view. So it's like you are
  26296. 16:03:47telling the database create this view or
  26297. 16:03:49if it already exists then replace it and
  26298. 16:03:52you will not get error in the postcress.
  26299. 16:03:54But in the SQL server it is little bit
  26300. 16:03:57more complicated. we don't have this
  26301. 16:03:58command. So here you have two ways.
  26302. 16:04:00Either you go over here and say you know
  26303. 16:04:02what let's first drop the view. So you
  26304. 16:04:06go with the same name over
  26305. 16:04:08here and then what you're going to do
  26306. 16:04:10you're going to go and mark the drop
  26307. 16:04:12view. So if you execute it like this the
  26308. 16:04:14view going to be dropped and then we
  26309. 16:04:16recreate the view like this. So what we
  26310. 16:04:18have done we destroy the view and then
  26311. 16:04:20we recreate it using the new logic. Or
  26312. 16:04:22you say you know what I would like to
  26313. 16:04:24have everything in one go like I don't
  26314. 16:04:26want to do it in two steps. I would like
  26315. 16:04:27to have everything in one command and
  26316. 16:04:29for that you have to use in SQL server
  26317. 16:04:31the TSQL the transacts SQL it is like an
  26318. 16:04:35extension for SQL only in SQL server
  26319. 16:04:37well it's like programming where you can
  26320. 16:04:39go and add variables or you can all go
  26321. 16:04:41and add checks we will not do a deep
  26322. 16:04:43dive in this language but I would like
  26323. 16:04:44to show you how to do it for the views
  26324. 16:04:46so just follow me with that I'm going to
  26325. 16:04:48go and replace the whole thing and then
  26326. 16:04:51we're going to say if and now we are
  26327. 16:04:53checking the system catalog if the
  26328. 16:04:55object ID
  26329. 16:04:57And now we go and specify the view name.
  26330. 16:05:00So let's go and copy the whole thing
  26331. 16:05:01with the schema as well. And then we're
  26332. 16:05:03going to say for SQL this is a view. So
  26333. 16:05:07if this object exists so we are saying
  26334. 16:05:09is not null. So that means it exist in
  26335. 16:05:12the catalog then what SQL should do?
  26336. 16:05:15Should drop this view. So we're going to
  26337. 16:05:17say drop view and it's like we have done
  26338. 16:05:19it first and then semicolon and then we
  26339. 16:05:23say for scale go and with that we are
  26340. 16:05:25saying for SQL the tscale is done. So
  26341. 16:05:28the logic is done and after that we have
  26342. 16:05:31the DDL for our view. So again what we
  26343. 16:05:33are doing we are checking before
  26344. 16:05:36creating the view whether the view
  26345. 16:05:38exist. If it exist then we are telling
  26346. 16:05:40the scale go and drop it and if it
  26347. 16:05:42doesn't exist that means we haven't
  26348. 16:05:44created this view yet. it is completely
  26349. 16:05:47brand new view then this step going to
  26350. 16:05:49be skipped so that there is nothing to
  26351. 16:05:51drop. So now if you go and execute the
  26352. 16:05:53whole thing it will work and of course
  26353. 16:05:54if you go and refresh over here you
  26354. 16:05:56still see the view. So SQL did destroy
  26355. 16:06:00the table first and then recreated. So
  26356. 16:06:02if you execute it again. So this is how
  26357. 16:06:04you replace your logic in view in SQL
  26358. 16:06:07server. And with that we have learned
  26359. 16:06:09all possible scenarios. How to create a
  26360. 16:06:11view, how to drop a view and how to
  26361. 16:06:14update the logic of a
  26362. 16:06:19view. Now back to our database
  26363. 16:06:21architecture and let's understand how
  26364. 16:06:23the database executes views. So now
  26365. 16:06:26let's say that the data engineer is
  26366. 16:06:28creating view called top end. So the
  26367. 16:06:30query going to be sent to the database
  26368. 16:06:32engine and once the database engine
  26369. 16:06:34understand this is a view this is not a
  26370. 16:06:36table. So now the database engine going
  26371. 16:06:38to go to the disk storage and to the
  26372. 16:06:40catalog and it will stores not only the
  26373. 16:06:43metadata about the view also the SQL
  26374. 16:06:47that is responsible for the view. So
  26375. 16:06:49it's going to take the SQL statements
  26376. 16:06:50that you have defined in the create view
  26377. 16:06:53and place it as well in the catalog. So
  26378. 16:06:55if you compare to the tables we have in
  26379. 16:06:57tables only metadata but in the views we
  26380. 16:07:00have both the metadata and as well the
  26381. 16:07:02query of the view and as well you can
  26382. 16:07:04see that the database engine will not
  26383. 16:07:07create a table in the user's data. So
  26384. 16:07:10there is nowhere data stored inside the
  26385. 16:07:12disk or the cache. So the actual data
  26386. 16:07:15the physical data will not be stored
  26387. 16:07:16anywhere. We are storing only metadata
  26388. 16:07:19and the query inside the system catalog.
  26389. 16:07:22So now we tell our data analyst okay we
  26390. 16:07:24have a new view and the data analyst can
  26391. 16:07:26go and write a query in order to
  26392. 16:07:28retrieve the data from the view. So he
  26393. 16:07:30going to say and say select from the
  26394. 16:07:32view and execute it. The database engine
  26395. 16:07:34going to take it and understand okay now
  26396. 16:07:36we are talking about view. So the
  26397. 16:07:37database first has to retrieve not the
  26398. 16:07:40data going to retrieve the query from
  26399. 16:07:43the catalog in order to understand what
  26400. 16:07:45do we have now to execute. Then the
  26401. 16:07:47database going to execute the query of
  26402. 16:07:49the view first and the data for this
  26403. 16:07:52query comes from a physical table called
  26404. 16:07:54orders. So now the database engine is
  26405. 16:07:56querying the order to retrieve the data
  26406. 16:07:58so that we have a data for the end user
  26407. 16:08:01and then it's going to be executed and
  26408. 16:08:02the result going to be sent back to the
  26409. 16:08:05data analyst. So as you can see there is
  26410. 16:08:06like two queries. The SQL engine first
  26411. 16:08:09has to execute the query from the view
  26412. 16:08:12and only after that the database engine
  26413. 16:08:15can execute the query that comes from
  26414. 16:08:17the user. So actually the data comes
  26415. 16:08:19always from a physical table but we are
  26416. 16:08:21not providing the data analyst an access
  26417. 16:08:23to the table. We are just providing an
  26418. 16:08:26access to the view. So this can happen
  26419. 16:08:28each time an end user selecting data
  26420. 16:08:30from the view. Always the database
  26421. 16:08:32engine going to grab the query from the
  26422. 16:08:34catalog, execute it first in order to
  26423. 16:08:36get the data and then execute what the
  26424. 16:08:39end user wants. And now if the data
  26425. 16:08:40engineer says no, let's go and drop the
  26426. 16:08:42view. So she writes a query in order to
  26427. 16:08:45drop the view. And the database engine
  26428. 16:08:46going to go to the system catalog and
  26429. 16:08:48delete both the metadata and the query.
  26430. 16:08:51So as you can see, if you are dropping a
  26431. 16:08:52view, you are not losing the actual
  26432. 16:08:55data. So there will be no user data lost
  26433. 16:08:57at all. So don't worry about it. What
  26434. 16:09:00you are losing is only the query and the
  26435. 16:09:02metadata about your view. It's only if
  26436. 16:09:04you drop a physical table like the
  26437. 16:09:07orders, you will lose your data. So
  26438. 16:09:09dropping views is not that bad like
  26439. 16:09:11dropping a database table. So this is
  26440. 16:09:13how the database works with the views
  26441. 16:09:15behind the scenes.
  26442. 16:09:20Now moving on to the second scenario to
  26443. 16:09:22the next use case of using views in
  26444. 16:09:24projects is that we use views in order
  26445. 16:09:26to hide complexity and to improve
  26446. 16:09:29abstraction. In many scenarios we work
  26447. 16:09:31with a very large and complex databases
  26448. 16:09:34and we can use views in order to reduce
  26449. 16:09:37the complexity and make things easier
  26450. 16:09:39for the users. So let's understand what
  26451. 16:09:41this means. Now I'm going to explain for
  26452. 16:09:42you a scenario that happens almost in
  26453. 16:09:45each project. Like if you get an access
  26454. 16:09:46to a database where you want to do
  26455. 16:09:48analyzes, you will be in scenario and
  26456. 16:09:50this can happen a lot where you're going
  26457. 16:09:52to find a large database where the
  26458. 16:09:54tables are very complex to understand.
  26459. 16:09:56They have a lot of columns. They have
  26460. 16:09:58like technical and cryptical names and
  26461. 16:10:00how tables are connected to each others
  26462. 16:10:02and relationship between them. It's
  26463. 16:10:04almost impossible to understand. then
  26464. 16:10:06you have to be deeply involved with the
  26465. 16:10:08data models with documentations and with
  26466. 16:10:11experts until you understand how to
  26467. 16:10:14query this database. So if you are not a
  26468. 16:10:16developer and from end user perspective
  26469. 16:10:19it can be nightmare where you are trying
  26470. 16:10:21to do multiple joins in order to make
  26471. 16:10:23simple analyzes and of course from the
  26472. 16:10:25database perspective this data model is
  26473. 16:10:28good enough for one application but if
  26474. 16:10:30you are opening your database for
  26475. 16:10:32multiple data analyszis projects this
  26476. 16:10:34can be a nightmare because you have to
  26477. 16:10:36go and explain for each user how to
  26478. 16:10:38query the data. So what we usually do
  26479. 16:10:41instead of giving a direct access to
  26480. 16:10:43such technical and hard to understand
  26481. 16:10:46data model we go as developers creating
  26482. 16:10:49multiple views since we are the expert
  26483. 16:10:51of the data model and these new views
  26484. 16:10:53going to be an abstraction of the
  26485. 16:10:56complexity that I have in my database
  26486. 16:10:58and we have to make sure that those
  26487. 16:11:00views are providing objects that are
  26488. 16:11:03friendly. So they have like a full
  26489. 16:11:05English name that makes sense and as
  26490. 16:11:08well the columns are friendly and we try
  26491. 16:11:10to not offer a lot of views so the user
  26492. 16:11:12don't have to do all the joins. So we
  26493. 16:11:14provide like few views that are friendly
  26494. 16:11:18and has a lot of informations that the
  26495. 16:11:20users needs for the analyzes. So with
  26496. 16:11:22that the users can have an access to
  26497. 16:11:24something more friendly and easy to
  26498. 16:11:26consume and then they can write simple
  26499. 16:11:28queries in order to do analyzes on top
  26500. 16:11:30of these friendly views. And this is
  26501. 16:11:33what we can give a name like we are
  26502. 16:11:35providing a data product from my complex
  26503. 16:11:39physical database. So here again how
  26504. 16:11:41important are the views to provide an
  26505. 16:11:44abstraction and easy to consume objects
  26506. 16:11:46for the users and with that I can hide
  26507. 16:11:49all my complexity and the script of the
  26508. 16:11:52view going to be developed from the
  26509. 16:11:54experts and only once so that the users
  26510. 16:11:57don't have to understand or to write
  26511. 16:11:59these complex SQL joins and with that
  26512. 16:12:02you can make your data projects way
  26513. 16:12:04easier than before. So this is another
  26514. 16:12:06important use case for the views where
  26515. 16:12:08we can use it in order to provide
  26516. 16:12:10abstraction and as well easy and
  26517. 16:12:12friendly objects for the end users.
  26518. 16:12:14Okay. So now let's have the following
  26519. 16:12:15task and it says provide view that
  26520. 16:12:18combines details from orders, products,
  26521. 16:12:22customers and employees. So now instead
  26522. 16:12:24of having all those tables from our
  26523. 16:12:26database, we have to provide one
  26524. 16:12:29combined view that has everything well
  26525. 16:12:32almost everything. So now let's see how
  26526. 16:12:33we can create such a view. So let's
  26527. 16:12:35start first by the table orders. I'm
  26528. 16:12:37going to go and
  26529. 16:12:39select first star from sales orders and
  26530. 16:12:44let's go and execute it. This is the
  26531. 16:12:46central table that connects everything.
  26532. 16:12:47You can see here we have the order ID,
  26533. 16:12:49product ID, sales, customers and so on.
  26534. 16:12:52So it is a great start point. So now
  26535. 16:12:54we're going to go and be picky about the
  26536. 16:12:55columns. I would not show all the
  26537. 16:12:57columns but I would say let's go and
  26538. 16:12:59show for example the order ID. This is
  26539. 16:13:01essential. It's nice to have a unique
  26540. 16:13:04identifier. Now the product ID, I will
  26541. 16:13:06not show it but I will just list it over
  26542. 16:13:08here. The same for the customer ID,
  26543. 16:13:11saleserson ID. Those stuff I would like
  26544. 16:13:14to replace later. So I will just make it
  26545. 16:13:17as comment so I don't forget about it
  26546. 16:13:19because it makes no sense to show the
  26547. 16:13:21product ID and customer ids and so on.
  26548. 16:13:23We would like to show the details about
  26549. 16:13:26each object because instead of having
  26550. 16:13:28the product ID, I would like to show for
  26551. 16:13:30example the product name itself and some
  26552. 16:13:32other informations from the table
  26553. 16:13:34products. And with that we are reducing
  26554. 16:13:36the complexity. So now what else we can
  26555. 16:13:38get from the table orders? We can go and
  26556. 16:13:40get the order date. I will put it here.
  26557. 16:13:42And maybe we can go and get stuff like
  26558. 16:13:45sales and
  26559. 16:13:46quantity. So like this. Of course, we
  26560. 16:13:50can go and put all the columns. But for
  26561. 16:13:52now, I will go with those informations.
  26562. 16:13:54Now, it's important since we're going to
  26563. 16:13:55have a lot of tables. Let's go and make
  26564. 16:13:57sure we are using aliases. So, now we're
  26565. 16:14:00going to have the O for each of those
  26566. 16:14:03columns. All right. Fine. So, now we
  26567. 16:14:05have four details from the table orders.
  26568. 16:14:08Now, what is next? We have the product
  26569. 16:14:10ID. So, let's go and get the
  26570. 16:14:11informations from the products. What
  26571. 16:14:14we're going to do, we're going to use a
  26572. 16:14:15left join just to make sure to not miss
  26573. 16:14:17any order. If you go with the inner
  26574. 16:14:20join, you might miss some orders. So I
  26575. 16:14:22will not do that. So let's join it with
  26576. 16:14:24the products like this.
  26577. 16:14:27And so now we have to go and join the
  26578. 16:14:30tables. So we can use the keys product
  26579. 16:14:34ID equal the order product ID. All
  26580. 16:14:38right. So now the question is which
  26581. 16:14:40informations we want to show for the
  26582. 16:14:42users. Let's go to the table orders. So
  26583. 16:14:45we have the product and category and the
  26584. 16:14:47price. I would say let's go and get the
  26585. 16:14:49product and category. That's enough. So
  26586. 16:14:51now instead of the ID I'm going to have
  26587. 16:14:54it like this. So it's going to be the
  26588. 16:14:56product and the
  26589. 16:14:58category. Now let's go and test it. I'm
  26590. 16:15:00going to execute it. Now as you can see
  26591. 16:15:02we don't have a product ID. We have the
  26592. 16:15:04product name which is more friendly. So
  26593. 16:15:06we have now those two columns from the
  26594. 16:15:07orders and those two from the products
  26595. 16:15:10and the last two as well from the
  26596. 16:15:11orders. So it looks really nice and
  26597. 16:15:13friendly and with that the user don't
  26598. 16:15:15need extra table called products. We
  26599. 16:15:18have everything in one. Now let's go and
  26600. 16:15:19do the same for the customers. So let's
  26601. 16:15:21go
  26602. 16:15:22and do the same thing. So let's join
  26603. 16:15:26sales customers see and as well join
  26604. 16:15:30them using the key customer ID equal to
  26605. 16:15:33the customer ID. Now we have to go and
  26606. 16:15:36grab a few columns from the customers.
  26607. 16:15:38Let's go and check. So we have a first
  26608. 16:15:40name, last name and country and score. I
  26609. 16:15:42would say I would go with the names and
  26610. 16:15:44the countries but instead of having
  26611. 16:15:46first name and last name I'm going to
  26612. 16:15:48put everything in one. So we have to go
  26613. 16:15:50and concatenate the informations. So
  26614. 16:15:53we're going to get the first
  26615. 16:15:54name then plus then empty between the
  26616. 16:15:58first name and the last name and then
  26617. 16:16:01the last name like
  26618. 16:16:03this. Now we will not call it a name.
  26619. 16:16:06We're going to go and call it the
  26620. 16:16:07customer name because later we're going
  26621. 16:16:09to have as well an employee name. All
  26622. 16:16:11right. So next we want to get the
  26623. 16:16:14country and we have to say this is the
  26624. 16:16:16country from the customers. So we're
  26625. 16:16:18going to call it customer country and
  26626. 16:16:21that's it. Let's go and execute it. Now
  26627. 16:16:23we can see we have again our orders
  26628. 16:16:26products and now we have the
  26629. 16:16:27informations from that customer. But
  26630. 16:16:29here we have issue that we have some
  26631. 16:16:31nulls and that's because there is no
  26632. 16:16:32last name. So what we're going to do,
  26633. 16:16:34we're going to go and handle the nulls
  26634. 16:16:36for the last name and as well for the
  26635. 16:16:38first name. So we're going to use the
  26636. 16:16:40kowalis. If the last name is null then
  26637. 16:16:44make an empty string and the same thing
  26638. 16:16:47for the first name. So first name. All
  26639. 16:16:50right. So now let's go and execute it.
  26640. 16:16:52So with that we are getting as well the
  26641. 16:16:55first name if the last name is missing
  26642. 16:16:57or if the first name is missing we can
  26643. 16:16:59get the last name. So looks good. So it
  26644. 16:17:01looks good with that. We have the
  26645. 16:17:02customer's details. The last thing we
  26646. 16:17:04have to go and get the employees. So the
  26647. 16:17:07employee here is called salesperson ID
  26648. 16:17:09which we can connect it directly to the
  26649. 16:17:11table employees. So if you go to the
  26650. 16:17:13employees over here, which columns do we
  26651. 16:17:15need? We have the first name, last name,
  26652. 16:17:17department and so on. I would say let's
  26653. 16:17:19go get the names and the departments. So
  26654. 16:17:21first let's go and join it. So lift join
  26655. 16:17:25sales
  26656. 16:17:27employees and we're going to join it
  26657. 16:17:29using the employee ID. and we're going
  26658. 16:17:31to join it with the sales person ID that
  26659. 16:17:36comes from the order table. So now
  26660. 16:17:38instead of the person ID we're going to
  26661. 16:17:40have as well the same thing. So I will
  26662. 16:17:42just go and copy paste this. So instead
  26663. 16:17:45of the alias we're going to have E and
  26664. 16:17:47as well E over here and we're going to
  26665. 16:17:49call it sales name and as well what we
  26666. 16:17:52going to have we're going to have the
  26667. 16:17:54department. So
  26668. 16:17:55department and that's it. Let's go and
  26669. 16:17:59execute it. So now we have a lot of
  26670. 16:18:01informations in our view. So we have the
  26671. 16:18:03first columns from the orders then from
  26672. 16:18:06the products and here we have from
  26673. 16:18:08customers and those two from the
  26674. 16:18:10employees and the last two again from
  26675. 16:18:12the orders. So that we have combined now
  26676. 16:18:14all the relevant informations from
  26677. 16:18:16multiple tables in our database in only
  26678. 16:18:19one view. This result is relative big
  26679. 16:18:21but still we have all the informations
  26680. 16:18:23in one and it is more friendly for the
  26681. 16:18:26users in order to consume our data
  26682. 16:18:28instead of going and joining like all
  26683. 16:18:30those four tables together. So now the
  26684. 16:18:32next step we're going to put the result
  26685. 16:18:34of this query in view in our database so
  26686. 16:18:37that our end users can start consuming
  26687. 16:18:39it. So how we going to do it? This is
  26688. 16:18:41our combined query and now we're going
  26689. 16:18:45to write the DDL for it. So create view
  26690. 16:18:47and now we're going to give it the name
  26691. 16:18:49order details and then as and we're
  26692. 16:18:53going to put the whole thing in two
  26693. 16:18:54parenthesis. So at the start and at the
  26694. 16:18:57end and of course don't forget the
  26695. 16:18:59schema. So our schema is sales sales dot
  26696. 16:19:04then we have the view name just in order
  26697. 16:19:06to have it in the correct schema and not
  26698. 16:19:08in dbo. So everything is ready. Let's go
  26699. 16:19:11ahead and execute it. So now let's go
  26700. 16:19:13and check our database. So if you go and
  26701. 16:19:15refresh, you will find our second view
  26702. 16:19:18order details. So now let's go and test
  26703. 16:19:20it. We're going to say select star
  26704. 16:19:24from sales v order details. Let's go and
  26705. 16:19:30execute it. And with that we are getting
  26706. 16:19:32now a combined view that are showing all
  26707. 16:19:35important informations from the
  26708. 16:19:36database. So this is what the users can
  26709. 16:19:38see. And with that the users don't care
  26710. 16:19:41about how many tables do we have in the
  26711. 16:19:43tables and how to join all those tables.
  26712. 16:19:46We have only one view and we can start
  26713. 16:19:48working on it. This is a very common use
  26714. 16:19:50case for the
  26715. 16:19:54views. Okay. Moving on to the next
  26716. 16:19:56scenario to the next use case. We use
  26717. 16:19:58SQL views in order to implement security
  26718. 16:20:01and to protect our data in the database.
  26719. 16:20:03In many scenarios, we have sensitive
  26720. 16:20:05informations in our data and we cannot
  26721. 16:20:07go and share it with everyone. So one of
  26722. 16:20:09the best practices is to create views in
  26723. 16:20:12order to protect your data before
  26724. 16:20:14sharing it with the users. So let's
  26725. 16:20:16understand what this means. So now let's
  26726. 16:20:18understand first the scenario without
  26727. 16:20:20views only tables. So now let's say that
  26728. 16:20:22you have the table orders four columns
  26729. 16:20:24and three rows and then you have like
  26730. 16:20:26for example a manager that has an access
  26731. 16:20:28directly to the database and start
  26732. 16:20:30writing some queries in order to
  26733. 16:20:32retrieve data. But in your project you
  26734. 16:20:34have multiple people that has an access
  26735. 16:20:36to your database like for example a data
  26736. 16:20:38analyst and as well she is writing a
  26737. 16:20:40script in order to retrieve data from
  26738. 16:20:42the orders and as well you have maybe a
  26739. 16:20:44students that has an access to your
  26740. 16:20:45database and querying the data like any
  26741. 16:20:48other role like a manager and data
  26742. 16:20:49analyst. So as you can see you have now
  26743. 16:20:51different rules in your project and all
  26744. 16:20:53of them having the same rights by
  26745. 16:20:56accessing directly your table. So a
  26746. 16:20:58manager or data analyst or a student
  26747. 16:21:01they are seeing the whole table all rows
  26748. 16:21:04and all columns. And of course in the
  26749. 16:21:06real projects this is a big problem.
  26750. 16:21:08Sometimes the data are sensitive and you
  26751. 16:21:10cannot give an access for everyone. And
  26752. 16:21:12of course if you are using only tables
  26753. 16:21:14this going to be a nightmare because you
  26754. 16:21:15can go and create multiple tables but
  26755. 16:21:17it's going to be really hard to make all
  26756. 16:21:19those tables in sync. But instead of
  26757. 16:21:21that we have views. So what you can do
  26758. 16:21:23you can go and remove all accesses to
  26759. 16:21:25the physical table but instead you can
  26760. 16:21:28go and create multiple views for each
  26761. 16:21:31role. For example you can go and create
  26762. 16:21:33a view called orders managers and maybe
  26763. 16:21:36you can give all the data and all the
  26764. 16:21:37columns because the managers are allowed
  26765. 16:21:40to see let's say sensitive data but
  26766. 16:21:42still it's nice to create a view maybe
  26767. 16:21:43you change your mind later and you go
  26768. 16:21:45and remove something. Now let's say that
  26769. 16:21:47for the data analyst you want to offer
  26770. 16:21:49all the data but there is only one
  26771. 16:21:51column that is very sensitive. So what
  26772. 16:21:53you can do you can go and create another
  26773. 16:21:55view called orders analyst. So in the
  26774. 16:21:57view only three columns are available
  26775. 16:21:59ABC and then you give access to all data
  26776. 16:22:02analyst and with that you have protected
  26777. 16:22:05this sensitive information. So we call
  26778. 16:22:07this column level security. And now we
  26779. 16:22:09come to our poor students. And here we
  26780. 16:22:11create another view where we are not
  26781. 16:22:13only protecting the column D but also we
  26782. 16:22:16are protecting few rows like for example
  26783. 16:22:19the row number three because we want to
  26784. 16:22:21offer only few informations to the
  26785. 16:22:23students. So we are protecting the
  26786. 16:22:24columns and as well the rows and for
  26787. 16:22:26that we can create another dedicated
  26788. 16:22:28view called for example orders students
  26789. 16:22:31and we can offer it to the students and
  26790. 16:22:33with that we are doing column level
  26791. 16:22:35security and as well row level security.
  26792. 16:22:38So we are offering multiple views very
  26793. 16:22:40easily without having to worry how to
  26794. 16:22:42load the data from one table to another.
  26795. 16:22:45So creating those views are really easy
  26796. 16:22:47and provide us a perfect tool in order
  26797. 16:22:50to manage the security of our data. So
  26798. 16:22:53this is one very common use case of
  26799. 16:22:55using views in data projects. All right.
  26800. 16:22:57So now let's have the following task and
  26801. 16:22:59it says provide a view for EU sales team
  26802. 16:23:02that combines details from all tables
  26803. 16:23:04and excludes data related to the USA. So
  26804. 16:23:08the first part of the task is similar to
  26805. 16:23:10what we have already done but we cannot
  26806. 16:23:12offer all data for the user. So this
  26807. 16:23:15time we are providing a view that is
  26808. 16:23:17specifically created for a team the
  26809. 16:23:19sales team. So the first part we have
  26810. 16:23:21already done it where we are combining
  26811. 16:23:23all details in one view. But the problem
  26812. 16:23:25with the view that we have created that
  26813. 16:23:27it shows all data. But now the
  26814. 16:23:29requirement change we cannot show all
  26815. 16:23:30data. We have to go and exclude the USA
  26816. 16:23:33data from our details. So let's see how
  26817. 16:23:35we can do that. It's very simple. We're
  26818. 16:23:37going to go and grab the same query. We
  26819. 16:23:38will not repeat that. So we have as well
  26820. 16:23:41here joining tables and prepare
  26821. 16:23:43everything. But instead of showing all
  26822. 16:23:46data, what we're going to do, we're
  26823. 16:23:47going to go and filter the data based on
  26824. 16:23:49the customer country. So it's very
  26825. 16:23:51simple. At the ends we will have a work
  26826. 16:23:54clause where the C country is not equal
  26827. 16:23:59to
  26828. 16:24:01USA. So we have now a filter. Let's go
  26829. 16:24:04and execute it. And with that, as you
  26830. 16:24:06can see in the output, we are getting
  26831. 16:24:08the orders that are not from USA. And
  26832. 16:24:11with that we are protecting the data of
  26833. 16:24:12the USA and the EU sales teams can
  26834. 16:24:16access only their data. So it looks nice
  26835. 16:24:18and protected. And with that we are
  26836. 16:24:20doing now role level security. That
  26837. 16:24:22means we are hiding now all the orders
  26838. 16:24:24all the rows that are not allowed to be
  26839. 16:24:26seen and consumed from this group of
  26840. 16:24:29users. So now what is the next step? It
  26841. 16:24:31is very simple. We're going to go and
  26842. 16:24:32put everything in one view. So with that
  26843. 16:24:34we have the query ready and we can go
  26844. 16:24:36and create the new view. So we're going
  26845. 16:24:39to call it create view. Then we need the
  26846. 16:24:42schema and the name going to be almost
  26847. 16:24:45the same. So order details but EU. And
  26848. 16:24:49then we have to have as punch
  26849. 16:24:51parenthesis like this. So everything is
  26850. 16:24:54ready. Let's go and execute it. And now
  26851. 16:24:56we can go and refresh in order to see
  26852. 16:24:58our new view. If you still don't see it,
  26853. 16:25:00you can go to the views over here and
  26854. 16:25:02refresh as well to the folder. So with
  26855. 16:25:04that I can see we have our new view.
  26856. 16:25:06Now, of course, the next step we go and
  26857. 16:25:08test it. So, let's create a new query.
  26858. 16:25:11Select star
  26859. 16:25:13from sales and v order details EU. So,
  26860. 16:25:19let's test it. And with that, as you can
  26861. 16:25:21see, we are getting the combined view
  26862. 16:25:23only for the data that is relevant for
  26863. 16:25:25the EU sales team. So, I'm not seeing
  26864. 16:25:28here any USA records. So, with that, we
  26865. 16:25:30are providing view that protects few
  26866. 16:25:33rows like the orders from USA. So as you
  26867. 16:25:35can see views are really great in order
  26868. 16:25:38to provide security to our data whether
  26869. 16:25:40we are protecting the columns or the
  26870. 16:25:42rows. For example in our view we can say
  26871. 16:25:44not only I want to remove the USA orders
  26872. 16:25:48but let's say the department information
  26873. 16:25:50is sensitive information and I would
  26874. 16:25:52like to hide it from the view. So you
  26875. 16:25:53can just simply remove it from the
  26876. 16:25:55select and with that you are doing
  26877. 16:25:56column level security. So now I have two
  26878. 16:25:58options that I can provide to the users.
  26879. 16:26:01The first option doesn't has any like
  26880. 16:26:03role level security. It is the first
  26881. 16:26:05view the order details. We don't have
  26882. 16:26:07there any filters. So it's going to show
  26883. 16:26:09all the orders. So here we give access
  26884. 16:26:11only to people that are allowed to see
  26885. 16:26:12all data. And we have another option the
  26886. 16:26:15details with the EU. It doesn't show all
  26887. 16:26:17data. It shows only a subset that is
  26888. 16:26:19relevant for the EU team. So now it's
  26889. 16:26:21really easy to control the security of
  26890. 16:26:23my data using the views. And this is
  26891. 16:26:26very important use case for the
  26892. 16:26:28[Music]
  26893. 16:26:31views. Okay. Okay, so moving on to the
  26894. 16:26:33next use case for the views, we can use
  26895. 16:26:35it in order to have more dynamic and
  26896. 16:26:37flexibility in our projects. So let's
  26897. 16:26:40understand what this means. If you have
  26898. 16:26:41a table and you have multiple users
  26899. 16:26:43accessing this table, now what can
  26900. 16:26:45happen? you might change your mind about
  26901. 16:26:47the design and the data model of your
  26902. 16:26:49database where you can say you know what
  26903. 16:26:51instead of having one table I'm going to
  26904. 16:26:53go and split it into two tables or maybe
  26905. 16:26:55another decision you say you know what
  26906. 16:26:57I'm going to go and rename a table or in
  26907. 16:26:59another day you decide you know what
  26908. 16:27:00let's go and rename few columns or maybe
  26909. 16:27:03add a column remove column so you are
  26910. 16:27:05doing changes to your physical data
  26911. 16:27:06model and you are changing stuff in the
  26912. 16:27:08tables you know what's going to happen
  26913. 16:27:10all those users that are accessing the
  26914. 16:27:12tables going to scream because all of
  26915. 16:27:15them having a complex SQL queries and
  26916. 16:27:18your small changes at the tables are
  26917. 16:27:20breaking everything in their queries and
  26918. 16:27:22what this means this means escalations
  26919. 16:27:25and you don't have anymore the freedom
  26920. 16:27:27to change anything in your database
  26921. 16:27:29without talking before to 100 people
  26922. 16:27:32before doing any change. So we don't do
  26923. 16:27:34that instead of that we use views. So
  26924. 16:27:36what's going to happen? You create a
  26925. 16:27:38view and you tell the users, okay, take
  26926. 16:27:40this view and consume it and leave me
  26927. 16:27:42alone. And now you have again your
  26928. 16:27:44freedom to do any changes you want. So
  26929. 16:27:46you go to your tables and do splitting,
  26930. 16:27:48renaming and changing everything you
  26931. 16:27:50want as long as you are updating the
  26932. 16:27:53query between the table and the view to
  26933. 16:27:56make sure that the users are not
  26934. 16:27:58noticing any change. So for example, if
  26935. 16:28:00you go and split the table into two
  26936. 16:28:01tables, then you have to put in the view
  26937. 16:28:03a join or union in order to reconstruct
  26938. 16:28:07the same structure that the users are
  26939. 16:28:09used to. And if you would like to rename
  26940. 16:28:11something in your database, like instead
  26941. 16:28:13of ID, you are now calling it a key. All
  26942. 16:28:15what you have to do now is to go to the
  26943. 16:28:17query of the view and rename it back
  26944. 16:28:20from a key to an ID. So no one going to
  26945. 16:28:22notice that you are doing changes to the
  26946. 16:28:24physical tables. So using views and
  26947. 16:28:27offering it to users is a gamecher for
  26948. 16:28:29you because giving the users views kind
  26949. 16:28:32of gives you more freedom dynamic and
  26950. 16:28:34flexibility to change anything in your
  26951. 16:28:36data model and the tables without
  26952. 16:28:39getting any headache. So this is amazing
  26953. 16:28:41use case for the
  26954. 16:28:45views. Okay, moving on. We have a lot of
  26955. 16:28:47use cases for the views. They are just
  26956. 16:28:49amazing. So the next one is we can use
  26957. 16:28:52views in order to introduce a second
  26958. 16:28:54version of my data model in another
  26959. 16:28:56language. So we could offer multiple
  26960. 16:28:58languages to the users. Let's understand
  26961. 16:29:00what this means. So now we have the
  26962. 16:29:02following scenario. We have again our
  26963. 16:29:03table orders where the data is persisted
  26964. 16:29:06and everything in English and of course
  26965. 16:29:08what happens sometimes you have like
  26966. 16:29:10international team that are accessing
  26967. 16:29:13your data. So you have team in USA and
  26968. 16:29:15maybe you have team from Germany that as
  26969. 16:29:17well are end users that want to access
  26970. 16:29:19the data. Of course it depend on the
  26971. 16:29:22number of users that are using your
  26972. 16:29:23database. But if you have a lot of users
  26973. 16:29:26that come from Germany and as well from
  26974. 16:29:28India, it might make sense that you go
  26975. 16:29:30and translate your data and the table
  26976. 16:29:33structure into another language. So for
  26977. 16:29:36example, instead of giving access to the
  26978. 16:29:37table orders, we can create another view
  26979. 16:29:41called bishong. That's the order in
  26980. 16:29:43German. But not only you are giving a
  26981. 16:29:45new name for the object, you could go as
  26982. 16:29:48well and rename all the columns inside
  26983. 16:29:50the view. Then the German users going to
  26984. 16:29:52access the German view and it's going to
  26985. 16:29:55be for them easier to understand the
  26986. 16:29:57content of your database. The same thing
  26987. 16:29:59for the Indian team. And for the Indian
  26988. 16:30:01users, you can go and provide a view in
  26989. 16:30:04Hindi. I'm not sure whether I'm
  26990. 16:30:05pronouncing the word correct, but this
  26991. 16:30:08is the first word that I said in Hindi.
  26992. 16:30:10I don't promise that I'm going to learn
  26993. 16:30:12the Hindi language because it's enough
  26994. 16:30:14to learn Germany. So I'm trying as well
  26995. 16:30:16to write this word Adish. I hope it is
  26996. 16:30:20correct. And to be honest, it is really
  26997. 16:30:22interesting how you write this word in
  26998. 16:30:24Hindi. So now back to the topic. As you
  26999. 16:30:26can see now we are using like the views
  27000. 16:30:29in order to provide a translation for
  27001. 16:30:31our database by just giving a new name
  27002. 16:30:34for the views and as well for the
  27003. 16:30:35columns. So this is another nice use
  27004. 16:30:37case that I usually use as well in my
  27005. 16:30:39projects in order to provide multi-
  27006. 16:30:41languages for the data model that I have
  27007. 16:30:43and I can do that with the power of
  27008. 16:30:49views. Now we come to my favorite use
  27009. 16:30:52case for the views and that I personally
  27010. 16:30:54recommend in each project that we can
  27011. 16:30:56use views as a virtual data ms in a data
  27012. 16:31:00warehouse. So now why this is my
  27013. 16:31:02favorite? Because I'm specialist in data
  27014. 16:31:03warehouses and data leaks and this topic
  27015. 16:31:06is very important decision in each
  27016. 16:31:08project like this. So let's understand
  27017. 16:31:10what this means. So now a classical data
  27018. 16:31:12warehouse architecture based on the
  27019. 16:31:14approach of enmon is going to look like
  27020. 16:31:16this. We have multiple source systems
  27021. 16:31:18where our data are spreaded and now we
  27022. 16:31:20would like to go and extract all our
  27023. 16:31:22data from these multiple sources and put
  27024. 16:31:25it in one big database called data
  27025. 16:31:28warehouse. And there will be a lot of
  27026. 16:31:29operations on this central database like
  27027. 16:31:32the data going to be first cleaned and
  27028. 16:31:34then maybe integrated together and maybe
  27029. 16:31:36we are building there some historical
  27030. 16:31:38data. So we're going to be doing
  27031. 16:31:40multiple steps in order to prepare the
  27032. 16:31:42data for complex reporting and analyzes.
  27033. 16:31:44And what we usually do in the data
  27034. 16:31:46warehouse, we're going to store all
  27035. 16:31:48those informations as a physical table.
  27036. 16:31:50Now once we have built the data
  27037. 16:31:52warehouse, what's going to happen? We're
  27038. 16:31:53going to have multiple use cases that
  27039. 16:31:56would like to access the data warehouse
  27040. 16:31:58in order maybe to do some different
  27041. 16:32:00reporting. Now, it's going to be very
  27042. 16:32:02complex if we connect immediately like a
  27043. 16:32:04reporting engine like PowerBI directly
  27044. 16:32:06to the data warehouse. But instead of
  27045. 16:32:08this, we try to split the data warehouse
  27046. 16:32:11into multiple subsets like we can split
  27047. 16:32:13it after topic or domain or departments
  27048. 16:32:16and we call those subsets as data marts.
  27049. 16:32:19So a data mart is always specific for a
  27050. 16:32:22use case that's focus on one topic like
  27051. 16:32:25for example we could have a dedicated
  27052. 16:32:26mart for the sales and another data m
  27053. 16:32:29which is dedicated only for finance
  27054. 16:32:31topics but both of them comes from our
  27055. 16:32:34data warehouse. Then the last layer
  27056. 16:32:36going to be like for example the
  27057. 16:32:37reporting and dashboarding maybe you
  27058. 16:32:39have something like powerbi where you
  27059. 16:32:40are creating a dashboard one data m like
  27060. 16:32:43the sales or and as well maybe few stuff
  27061. 16:32:45from other marts. But now the big
  27062. 16:32:47question here in the data mart is how
  27063. 16:32:49should I store the data? Should I store
  27064. 16:32:51the data using tables or should I use
  27065. 16:32:54views? And now the best practice says if
  27066. 16:32:56you are building data marts then use
  27067. 16:32:58views. And we call this virtual data
  27068. 16:33:01marts. And there are many reasons why
  27069. 16:33:03using views at a data mart it's way
  27070. 16:33:05better than using tables. Like for
  27071. 16:33:07example, it is more dynamic and quicker
  27072. 16:33:10to change them cuz usually at the data
  27073. 16:33:12mart you are building a lot of business
  27074. 16:33:13logics and you want to have some
  27075. 16:33:15flexibility and speed and the
  27076. 16:33:17maintenance efforts is very simplified.
  27077. 16:33:19No need to build any ETLs or data loads
  27078. 16:33:22from the data warehouse to the data
  27079. 16:33:24parts and this makes the data warehouse
  27080. 16:33:26as a real single point of truth for your
  27081. 16:33:29data. And once you start copying data
  27082. 16:33:31from one layer to another layer, it's
  27083. 16:33:33going to be really hard to maintain and
  27084. 16:33:35chaotic and you have to have really
  27085. 16:33:37restrict monitoring and data quality. So
  27086. 16:33:39that's why using views you're going to
  27087. 16:33:41always reflect the status of the data
  27088. 16:33:43warehouse and this can help you of
  27089. 16:33:45course with the data consistency which
  27090. 16:33:47is a critical point in each data
  27091. 16:33:49warehouse project. So there are many
  27092. 16:33:51reasons why we build virtual data mart
  27093. 16:33:54and we go with the views in this layer.
  27094. 16:33:56So as you can see how the views are
  27095. 16:33:58playing a very important role in
  27096. 16:34:01building a data warehouse. So this is
  27097. 16:34:03another amazing and very important use
  27098. 16:34:05case of using views in your data
  27099. 16:34:11projects. All right friends, so now
  27100. 16:34:13let's have a quick recap about views. So
  27101. 16:34:15we have learned that views are a virtual
  27102. 16:34:17table that is based on the result of a
  27103. 16:34:20query without actually storing any data
  27104. 16:34:23in the database. So we use views in
  27105. 16:34:25order to presist a complex SQL logic and
  27106. 16:34:28query in the database. And we have
  27107. 16:34:30learned that in some scenarios views are
  27108. 16:34:33better than CTE because it improves the
  27109. 16:34:35reusability and reduce the complexity in
  27110. 16:34:39multiple queries which reduce the
  27111. 16:34:41complexity of the whole projects where
  27112. 16:34:43the CTE only improves the reusability in
  27113. 16:34:45one query. And we have learned that as
  27114. 16:34:47well the views in some scenarios are
  27115. 16:34:49better than tables. We have learned that
  27116. 16:34:51they are very flexible and easier to
  27117. 16:34:53maintain since they don't store any data
  27118. 16:34:56and it's really fast and easy to change
  27119. 16:34:58stuff in the view compared to the
  27120. 16:35:00tables. But as well we have learned that
  27121. 16:35:02the tables are faster than views. Now
  27122. 16:35:04there are like endless use cases for the
  27123. 16:35:06views. But from my experience in
  27124. 16:35:08projects I have choose for you the best
  27125. 16:35:10use cases for the views. The first use
  27126. 16:35:11case is if we find like a common
  27127. 16:35:14repeated logic in SQL queries, we can go
  27128. 16:35:18and store this logic in view in the
  27129. 16:35:20database so that the users don't have to
  27130. 16:35:22keep repeating the logic over and over.
  27131. 16:35:24So we use views in order to have a
  27132. 16:35:26central business logic. Another use case
  27133. 16:35:29is to hide the complexity of your
  27134. 16:35:31physical data model and to offer for the
  27135. 16:35:33users and high abstracted layer. So you
  27136. 16:35:36provide for the user something very
  27137. 16:35:37friendly and you hide all the complex
  27138. 16:35:40technical data model that you have in
  27139. 16:35:41the database because not everyone is
  27140. 16:35:43expert with your data model. One more
  27141. 16:35:45use case we can use views in order to
  27142. 16:35:48implement security and to protect our
  27143. 16:35:50sensitive data in the database. So we
  27144. 16:35:52can offer multiple views in order to
  27145. 16:35:54protect columns or rows in a table.
  27146. 16:35:56Another use case we have learned that we
  27147. 16:35:58can use views in order to have more
  27148. 16:36:00dynamic and flexibility for your
  27149. 16:36:03database where we offer the users a
  27150. 16:36:05table view and then you have the freedom
  27151. 16:36:07to change stuff at your physical data
  27152. 16:36:09model without affecting all users. And
  27153. 16:36:12another nice use case for the views we
  27154. 16:36:14can offer multiple languages from our
  27155. 16:36:16data model. And the last use case we
  27156. 16:36:18have learned how views play an important
  27157. 16:36:21role in a data warehouse system. So
  27158. 16:36:23views are amazing. All right my friends.
  27159. 16:36:25So with that we have learned everything
  27160. 16:36:26about this new objects the views in
  27161. 16:36:29databases. This is amazing for
  27162. 16:36:30flexibility and dynamic in your
  27163. 16:36:32projects. Now in the next one we're
  27164. 16:36:34going to learn how to create tables
  27165. 16:36:35based on query and we will learn about
  27166. 16:36:38the temporary tables. So let's
  27167. 16:36:43go. Okay. So now first let's have a look
  27168. 16:36:46again to the database structure. We have
  27169. 16:36:48learned that in each SQL server there
  27170. 16:36:50are multiple databases and in each
  27171. 16:36:52database there are multiple schemas. And
  27172. 16:36:54now inside each schema we can define
  27173. 16:36:57multiple objects like we can define
  27174. 16:36:59tables and views. And now we will be
  27175. 16:37:01focusing on the object table. And we
  27176. 16:37:03have learned as well we can use the
  27177. 16:37:05language DDL data definition language
  27178. 16:37:07which is a set of SQL commands in order
  27179. 16:37:10to define this database structure. So we
  27180. 16:37:12can use the SQL command create in order
  27181. 16:37:14to define a new table or alter in order
  27182. 16:37:17to update the structure or drop in order
  27183. 16:37:20to drop the whole table. So a table is
  27184. 16:37:23an object in the database structure and
  27185. 16:37:25we have learned as well there is three
  27186. 16:37:27levels of the database architecture and
  27187. 16:37:29we have understood that at the logical
  27188. 16:37:31level the middle one the conceptual
  27189. 16:37:33level we deal as application developer
  27190. 16:37:36or data engineer with the tables. So we
  27191. 16:37:39define tables and relationship between
  27192. 16:37:41them. So if you are an end user or a
  27193. 16:37:43business analyst it's going to be little
  27194. 16:37:45bit more hard to work with the tables.
  27195. 16:37:47You have to be a developer or a data
  27196. 16:37:49engineer. But working with tables is way
  27197. 16:37:52easier than working with the complexity
  27198. 16:37:54of the database at the physical level.
  27199. 16:37:57So you don't have to be a database
  27200. 16:37:58expert or administrator to work with
  27201. 16:38:01tables. So the difficulty here is like
  27202. 16:38:03in the middle. The abstraction is not
  27203. 16:38:05that low but as well not that high. So
  27204. 16:38:07now let's answer the question, what are
  27205. 16:38:09tables? A database table is a structured
  27206. 16:38:12collection of data. It's like a simple
  27207. 16:38:14grid or spreadsheet that you might find
  27208. 16:38:16in Excel. So it has different columns
  27209. 16:38:18like each column represent a field like
  27210. 16:38:20the ID, name, country and the table has
  27211. 16:38:23as well multiple rows and each row
  27212. 16:38:26represent a record or an entry of the
  27213. 16:38:28data. So for example if this table is
  27214. 16:38:30about the employees then each record
  27215. 16:38:33each row is one employee. Now the
  27216. 16:38:36intersect between the rows and columns
  27217. 16:38:38we call it a cell and a cell is a single
  27218. 16:38:41piece of data. Now the whole table going
  27219. 16:38:43to be stored physically in the database
  27220. 16:38:45as database files. So they are in the
  27221. 16:38:48database like multiple files that are
  27222. 16:38:51holding the informations about the table
  27223. 16:38:53and those files are stored physically in
  27224. 16:38:56that disk storage of the database. So
  27225. 16:38:58that means your data inside the tables
  27226. 16:39:00are not stored like a spreadsheet like
  27227. 16:39:02an Excel but they are stored in special
  27228. 16:39:05database files that usual developers and
  27229. 16:39:08end users don't have access to those
  27230. 16:39:10files. So tables again it's like an
  27231. 16:39:12abstraction and representation for the
  27232. 16:39:14actual data that are in the files. So
  27233. 16:39:16actually each time you are querying the
  27234. 16:39:18database table the database has to go to
  27235. 16:39:20those files and fetch the data for you.
  27236. 16:39:22All right. So this is what we mean with
  27237. 16:39:24database
  27238. 16:39:28tables. Okay. So now we have like
  27239. 16:39:31different types of tables in SQL. We
  27240. 16:39:33have tables that stays forever. We call
  27241. 16:39:35it permanent tables. So they stay as
  27242. 16:39:38long as you don't drop them. And you
  27243. 16:39:40have another type of tables they called
  27244. 16:39:42the temporary tables. And those tables
  27245. 16:39:45going to be deleted and dropped once the
  27246. 16:39:47session ends. So now we're going to
  27247. 16:39:48focus first on the first type, the
  27248. 16:39:50permanent tables. And there are two ways
  27249. 16:39:52on how to create them. The first way is
  27250. 16:39:55the classical way where you create table
  27251. 16:39:57from the scratch and then you go and
  27252. 16:39:59insert your data. So we call it create
  27253. 16:40:01insert and the other way called create
  27254. 16:40:05table as select. It's going to create as
  27255. 16:40:07well the table but based on SQL query.
  27256. 16:40:10So let's understand the differences
  27257. 16:40:12between
  27258. 16:40:15them. The create insert method is the
  27259. 16:40:18classical way on how we define and
  27260. 16:40:20create tables in SQL where first we have
  27261. 16:40:23to go and create the table and define
  27262. 16:40:25the structure and after that we insert
  27263. 16:40:27our data into the database table where
  27264. 16:40:29the other method the CTAs create table
  27265. 16:40:32as select. And this one going to create
  27266. 16:40:34a new table as well but this time based
  27267. 16:40:37on the result of SQL query. So let's
  27268. 16:40:40understand what this means. Okay. So now
  27269. 16:40:42to the first method create insert. So
  27270. 16:40:44here we have two steps. The first step
  27271. 16:40:46is we have a DDL statements where we use
  27272. 16:40:49the command create. So once we execute
  27273. 16:40:51the first step what's going to happen
  27274. 16:40:52the database engine going to go and
  27275. 16:40:54create for us an empty table. It is a
  27276. 16:40:57brand new table where we can hold our
  27277. 16:40:59data. So with that we have defined the
  27278. 16:41:01structure of our table but it's still an
  27279. 16:41:04empty table. So now in the next step we
  27280. 16:41:06have to go and insert our data inside
  27281. 16:41:08this new table. So our data can come
  27282. 16:41:10from multiple sources like a CSV file or
  27283. 16:41:13maybe completely from another database
  27284. 16:41:15where we are doing migration or maybe
  27285. 16:41:17you are inserting manually your data or
  27286. 16:41:19maybe it come from an application or you
  27287. 16:41:21are doing data migration from one
  27288. 16:41:24database to another. So at the end once
  27289. 16:41:26you execute insert what's going to
  27290. 16:41:27happen your data going to be inserted in
  27291. 16:41:30this new table. So in this method we
  27292. 16:41:32have like two steps. First we define the
  27293. 16:41:35structure of the table and the second
  27294. 16:41:37step we take care of inserting our data
  27295. 16:41:40inside the table. And now this new table
  27296. 16:41:42and your data going to be persisted
  27297. 16:41:44permanently. Now let's check the other
  27298. 16:41:46method the CTIS. Here it's only one step
  27299. 16:41:49where you define a query and once you
  27300. 16:41:51execute this query what going to happen
  27301. 16:41:53the database has to retrieve the data
  27302. 16:41:56from another table. So it might retrieve
  27303. 16:41:58data from our new table that we just
  27304. 16:42:00created using create insert. So once the
  27305. 16:42:02query is executed we will get a result.
  27306. 16:42:05So now what the database going to do
  27307. 16:42:07going to create a new brand table but
  27308. 16:42:10this time the definition and the data of
  27309. 16:42:12this new table it doesn't come from any
  27310. 16:42:15definition that we specify. it comes
  27311. 16:42:17from the result of the query. So
  27312. 16:42:20whatever structure that we have in the
  27313. 16:42:22results, it going to be reflected in our
  27314. 16:42:24new table. So again the definition and
  27315. 16:42:27the data that we see in this new table
  27316. 16:42:29comes one one to one from the result of
  27317. 16:42:32our query. So in this type we don't have
  27318. 16:42:34to define anything or to insert any
  27319. 16:42:37data. We are just writing a query and
  27320. 16:42:39the output of this query going to define
  27321. 16:42:41the table. But in this method as you can
  27322. 16:42:43see it always needs a database table in
  27323. 16:42:46order to execute the query. But the
  27324. 16:42:47create insert method we are creating
  27325. 16:42:50something from the scratch. So these are
  27326. 16:42:52the two different ways on how you create
  27327. 16:42:54tables in SQL and the differences
  27328. 16:42:56between
  27329. 16:43:00them. Okay. So now you might ask you
  27330. 16:43:02know what the CTAs are very similar to
  27331. 16:43:05the views. We have a query and the
  27332. 16:43:07output of this query going to be like an
  27333. 16:43:08object in the database. So what are the
  27334. 16:43:11differences between them? Let's check
  27335. 16:43:13this. Now let's say that in our database
  27336. 16:43:15we have a table that has three columns
  27337. 16:43:17A, B, C. And now what we can do, we can
  27338. 16:43:19go and create view based on a query. So
  27339. 16:43:21you create the DDL statement in order to
  27340. 16:43:23create the view in the database. And of
  27341. 16:43:25course the database going to go and
  27342. 16:43:26store the query in the database and it's
  27343. 16:43:29going to be empty. So there will be no
  27344. 16:43:31data because views does not store any
  27345. 16:43:33data and the query of the view will not
  27346. 16:43:35be yet executed. But now in the other
  27347. 16:43:37hand if you go and create a table using
  27348. 16:43:39CTIS. So here again we have a query
  27349. 16:43:42attached to the object to the table. So
  27350. 16:43:44here what happens the database has to
  27351. 16:43:46execute the query in order to understand
  27352. 16:43:49the structure and as well the data that
  27353. 16:43:52should be inserted inside the table. So
  27354. 16:43:54our SQL query going to be executed and
  27355. 16:43:57the result of the query going to be
  27356. 16:43:59inserted inside the table. So that means
  27357. 16:44:01this new table is storing already the
  27358. 16:44:04result of the query. So now this is the
  27359. 16:44:06first differences between the table and
  27360. 16:44:08view. As you create view the query will
  27361. 16:44:10not be executed and we don't have
  27362. 16:44:12anything about the result of the query
  27363. 16:44:15where in the CTIS we have already result
  27364. 16:44:18of the query stored inside the table and
  27365. 16:44:20everything is prepared. So now let's see
  27366. 16:44:22what's going to happen once the user
  27367. 16:44:24selects something from the view. So now
  27368. 16:44:26the database going to go for the first
  27369. 16:44:28time executing the query of the view in
  27370. 16:44:31order to fetch the data from the
  27371. 16:44:33original table and then presented as a
  27372. 16:44:36result for the user. But now in the
  27373. 16:44:37other hand if the user go and query the
  27374. 16:44:40table that is created from the CTIS. So
  27375. 16:44:42now what can happen? SQL will not
  27376. 16:44:44execute again the query of the CTIS
  27377. 16:44:47because the database already done that
  27378. 16:44:49and prepared everything. So that means
  27379. 16:44:51we are not querying anything from the
  27380. 16:44:53original table and the data can be
  27381. 16:44:55directly fetched from the new table. So
  27382. 16:44:58the user is going to get immediately the
  27383. 16:44:59result from our table that is created
  27384. 16:45:01from the CDIS. So here comes the second
  27385. 16:45:04difference between the tables and views.
  27386. 16:45:06The views are slower than CTIS and
  27387. 16:45:09that's because the database has here an
  27388. 16:45:11extra task. It must execute the query of
  27389. 16:45:14the view in order to get the data. But
  27390. 16:45:16in the CTIS the query going to be faster
  27391. 16:45:19than the view because we have already
  27392. 16:45:21executed everything and prepared it for
  27393. 16:45:23the user. So that's why tables from CTIS
  27394. 16:45:26are way faster than views. And now there
  27395. 16:45:28is another difference and perspective
  27396. 16:45:30about this which is from my point of
  27397. 16:45:32view is more important than the
  27398. 16:45:34performance. So now let's say that in
  27399. 16:45:36the next day we are doing data updates
  27400. 16:45:38on the original table like we are doing
  27401. 16:45:40updates on the column C and as well in
  27402. 16:45:43the column P. So now let's see what this
  27403. 16:45:44means for the user if they are using
  27404. 16:45:46views. So the user in the next day is
  27405. 16:45:48executing again the same query and again
  27406. 16:45:50here the database has to execute the
  27407. 16:45:52query of the view in order to fetch the
  27408. 16:45:55data from the original table. So that
  27409. 16:45:57means today in the views we are getting
  27410. 16:45:59different data than yesterday because we
  27411. 16:46:02have a new data and new updates and the
  27412. 16:46:04user in the result going to see as well
  27413. 16:46:06the new updates and the fresh data. So
  27414. 16:46:08the user is seeing exactly the status of
  27415. 16:46:12the data in the original tables. But now
  27416. 16:46:14let's see what going to happen if the
  27417. 16:46:15user go and query the table from the
  27418. 16:46:18CATS. So in the table of the CATS, we
  27419. 16:46:21are still having the data from
  27420. 16:46:23yesterday. All those new updates from
  27421. 16:46:25the original data will not be reflected
  27422. 16:46:27in this new table because once the user
  27423. 16:46:29selects something from this table, the
  27424. 16:46:31database will not go and query or fetch
  27425. 16:46:34the new changes from the original table
  27426. 16:46:36because we have already prepared the
  27427. 16:46:38data from yesterday. So that means our
  27428. 16:46:40user now is getting old data from the
  27429. 16:46:43CTAs table and the only way to get new
  27430. 16:46:46fresh data from the CTIS is to reexecute
  27431. 16:46:50the CTIS query. And of course this is
  27432. 16:46:52another step and it is harder to
  27433. 16:46:55maintain the table from the CTAs and
  27434. 16:46:58this is a big difference for the users
  27435. 16:47:00between the views and the tables from
  27436. 16:47:02the CTAs. Now think about views you are
  27437. 16:47:04ordering a pizza at restaurants. So
  27438. 16:47:07every time you are quering the view you
  27439. 16:47:09are placing an order the chef going to
  27440. 16:47:11go and make a pizza from the scratch
  27441. 16:47:13using the freshest ingredients. So that
  27442. 16:47:15means you are always getting a fresh hot
  27443. 16:47:18pizza. And think about the CTS as like a
  27444. 16:47:21frozen pizza from a grocery store. The
  27445. 16:47:23pizza was prepared earlier and stored in
  27446. 16:47:26the freezer. And if you want to eat it,
  27447. 16:47:27you have to go and heat it up in the
  27448. 16:47:29oven. But it's still not like a fresh
  27449. 16:47:31pizza that is made on the spot and from
  27450. 16:47:33the scratch. Now I made myself hungry
  27451. 16:47:35because I love pizza. So I think I'm
  27452. 16:47:37going to go for a quick break.
  27453. 16:47:40[Music]
  27454. 16:47:51Okay, so now let's check quickly the
  27455. 16:47:52syntax of those two methods. The first
  27456. 16:47:54one is create insert. So first step we
  27457. 16:47:56have to go and create a table using a
  27458. 16:47:58DDL statements. So we use the command
  27459. 16:48:00create and then we have to tell SQL are
  27460. 16:48:03we creating a table or view. In this
  27461. 16:48:05scenario we are creating a table and
  27462. 16:48:07then we specify the name of the table.
  27463. 16:48:09Then after that we have two parenthesis
  27464. 16:48:11and inside them we make a list of all
  27465. 16:48:13columns that we need inside this table.
  27466. 16:48:15So we have two columns the ID and the
  27467. 16:48:17name. And after that we are defining the
  27468. 16:48:19data type of those columns and maybe as
  27469. 16:48:21well the length. There are a lot of
  27470. 16:48:23options that we can add to this syntax
  27471. 16:48:25but now we are just checking the
  27472. 16:48:27simplest form of creating a table. Now
  27473. 16:48:29the next step is that we need an insert
  27474. 16:48:31statement. So we are saying insert into
  27475. 16:48:34our new table the following values. we
  27476. 16:48:36are inserting the id number one and the
  27477. 16:48:39value for the name going to be frank. So
  27478. 16:48:41this is a classical way on creating new
  27479. 16:48:43table and inserting data to it. Now
  27480. 16:48:45let's move to the second method the cas.
  27481. 16:48:47Now this time we have an SQL query like
  27482. 16:48:50select from where and some extra logic.
  27483. 16:48:53So this is our query and then we're
  27484. 16:48:55going to go and put our query inside a
  27485. 16:48:58DDL statement. It's like we have done it
  27486. 16:49:00in the views. It's exactly like we have
  27487. 16:49:02done it in the views but this time
  27488. 16:49:05instead of saying view we're going to
  27489. 16:49:06say table. So again we have the create
  27490. 16:49:08command and we are creating a table then
  27491. 16:49:11the name of the table and then we say as
  27492. 16:49:14and then we have two parenthesis and
  27493. 16:49:16inside them we have our query and this
  27494. 16:49:18is where the name come from create table
  27495. 16:49:22as select cas. So it is very simple in
  27496. 16:49:26one statement you have everything you
  27497. 16:49:28are creating a new table and as well you
  27498. 16:49:31are inserting the data that comes from
  27499. 16:49:33this query. Now this syntax is used in
  27500. 16:49:36databases like MySQL, Postgress and
  27501. 16:49:39Oracle. But in MySQL we have like a
  27502. 16:49:41shorter way on how to do it. Again we
  27503. 16:49:44have our query select from where. But
  27504. 16:49:47now in SQL server we can insert a
  27505. 16:49:49command between the select and from like
  27506. 16:49:52this. So we are saying select the
  27507. 16:49:55following columns into new table. So we
  27508. 16:49:59have this keyword into then the table
  27509. 16:50:01name and then you continue after that
  27510. 16:50:03with your query from where aggregations
  27511. 16:50:05and so on. So here it's like the DDL is
  27512. 16:50:08inside your query itself but in the
  27513. 16:50:10other databases you can have like the
  27514. 16:50:12query is separated from the DDL
  27515. 16:50:14statements. Personally, I prefer this
  27516. 16:50:16syntax than having this into because if
  27517. 16:50:19you have like big complex query, this
  27518. 16:50:21can be really hard to see and to miss
  27519. 16:50:23the column selection. So, this is the
  27520. 16:50:25syntax of creating a new table from a
  27521. 16:50:28query the CTAs in different
  27522. 16:50:30[Music]
  27523. 16:50:33databases. Okay. So, now we're going to
  27524. 16:50:35check the scenarios and use cases where
  27525. 16:50:37it makes sense to use. So, let's start
  27526. 16:50:40with the first one. Now we have learned
  27527. 16:50:42before it makes sense to have a complex
  27528. 16:50:44logic stored inside the database so that
  27529. 16:50:47our end users don't have to keep
  27530. 16:50:49repeating the same logic over and over
  27531. 16:50:51and it's as well maybe complicated for
  27532. 16:50:53some users. So that's why we have used
  27533. 16:50:55views and the result of the view going
  27534. 16:50:57to be used from our users. So everything
  27535. 16:50:59can stay easy and friendly to consume
  27536. 16:51:01for our users. But now what might happen
  27537. 16:51:04is that the logic of the view could be
  27538. 16:51:06very complicated and needs a lot of time
  27539. 16:51:09to be executed from the database. So it
  27540. 16:51:12takes really long time until we get the
  27541. 16:51:14intermediate result from the database.
  27542. 16:51:16So that means if it's going to takes 30
  27543. 16:51:18minutes then each users has to wait 30
  27544. 16:51:21minutes until the query is executed and
  27545. 16:51:23none of your users going to be happy
  27546. 16:51:25with this situation. In this scenario,
  27547. 16:51:27if this happens, you have to try maybe
  27548. 16:51:29to optimize the query. But if you cannot
  27549. 16:51:32do anything about that, you have to
  27550. 16:51:34switch the view to CTAs table. So now
  27551. 16:51:37what you have to do, you have to take
  27552. 16:51:38the same logic and then put it
  27553. 16:51:41in so that the intermediate results are
  27554. 16:51:44stored in a table. And of course at the
  27555. 16:51:46moment of creating the table, it will
  27556. 16:51:48take 30 minutes. It will take long time
  27557. 16:51:50because it is the same query and the
  27558. 16:51:52database going to need the time until
  27559. 16:51:54creating the intermittent results. But
  27560. 16:51:56the big advantage is that once
  27561. 16:51:58everything is prepared maybe at the
  27562. 16:52:00night at the morning once your users are
  27563. 16:52:03like online and start querying the data
  27564. 16:52:06they have everything prepared. So the
  27565. 16:52:08user is going to go and start selecting
  27566. 16:52:10and analyzing the intermediate result
  27567. 16:52:12but this time using the table that you
  27568. 16:52:15have created from the CTAs and the
  27569. 16:52:17response time going to be for all users
  27570. 16:52:19again normal and fast. So if you have a
  27571. 16:52:21scenario where your views are very slow
  27572. 16:52:24you have to go and prepare the data at
  27573. 16:52:25the night using the CTIS and prepare the
  27574. 16:52:28tables to be analyzed from the end
  27575. 16:52:30users. So this is the most common use
  27576. 16:52:32case for the CTIS and this scenario
  27577. 16:52:35happens a lot in projects where you
  27578. 16:52:37decide to go instead of views to go with
  27579. 16:52:40the CTIS in order to have persistence
  27580. 16:52:42data and you gain performance. Okay, so
  27581. 16:52:44finally back to SQL let's go and create
  27582. 16:52:47a table using now we're going to go and
  27583. 16:52:49create a table that shows the total
  27584. 16:52:51number of orders for each month. Let's
  27585. 16:52:53go and do it. So first what do we need?
  27586. 16:52:55We need a query. So let's write it.
  27587. 16:52:58select. I'm going to go with the date
  27588. 16:53:00name in order to get the name of the
  27589. 16:53:02month from our order dates and we're
  27590. 16:53:06going to call it order month. And then
  27591. 16:53:09we're going to go and aggregate the data
  27592. 16:53:11by counting the order ID for total
  27593. 16:53:16orders from our table sales orders. Uh
  27594. 16:53:20don't forget to group by our month. So
  27595. 16:53:24something like this. Let's go and
  27596. 16:53:27execute it. So the result is very
  27597. 16:53:28simple. We have the order month and the
  27598. 16:53:30total orders. So we have two columns and
  27599. 16:53:33three rows. So we have our query and of
  27600. 16:53:35course we didn't create anything yet.
  27601. 16:53:37Now in SQL server in order to create a
  27602. 16:53:39table from the query what we're going to
  27603. 16:53:42do exactly before the from we're going
  27604. 16:53:45to write into and now we have to specify
  27605. 16:53:47the schema and the table name. I'm going
  27606. 16:53:49to stay with the schema sales and I'm
  27607. 16:53:51going to call it monthly
  27608. 16:53:54orders like this. So that means we have
  27609. 16:53:57our query and the DDL is exactly between
  27610. 16:54:00the from and select. So now if I go and
  27611. 16:54:02execute this what going to happen we
  27612. 16:54:05will not see here the result of the
  27613. 16:54:06query. We're going to get here like
  27614. 16:54:08three rows affected because this is a
  27615. 16:54:10DDL statement. It is not anymore a query
  27616. 16:54:13and the database is telling us I have
  27617. 16:54:14created now a table with three rows. So
  27618. 16:54:17now if you check our tables we don't see
  27619. 16:54:18it yet. Let's go and refresh and check
  27620. 16:54:20again the tables. Now we can see our
  27621. 16:54:22table here sales monthly orders. Now of
  27622. 16:54:25course we have to go and check whether
  27623. 16:54:27everything is fine. So let's go and
  27624. 16:54:29select the rows from our new table sales
  27625. 16:54:33monthly
  27626. 16:54:35orders. So let's go select it first and
  27627. 16:54:39execute. And now we can see again the
  27628. 16:54:42result of our query. But we are not
  27629. 16:54:44writing here the query. We are just
  27630. 16:54:45selecting it from the table. So our data
  27631. 16:54:47is stored in our table. And we can go
  27632. 16:54:50and check the structure of this table.
  27633. 16:54:52So if you go to the columns you can see
  27634. 16:54:54we have here the order month and the
  27635. 16:54:56total orders and those informations
  27636. 16:54:58comes from our query. So SQL is saying
  27637. 16:55:00here the order month is a var which is
  27638. 16:55:02correct because here we have the names
  27639. 16:55:04of the month. So SQL is able to define
  27640. 16:55:07the data type of the table from our
  27641. 16:55:09query and the second column the total
  27642. 16:55:11orders it is an integer and that's
  27643. 16:55:13because we have here numbers. So as you
  27644. 16:55:15can see SQL is defining the structure of
  27645. 16:55:17the table based on the result of our
  27646. 16:55:20query over here. And of course the data
  27647. 16:55:22inside the table comes as well from the
  27648. 16:55:24query. And the result of this table
  27649. 16:55:26going to stay like this as long as you
  27650. 16:55:28don't change anything. So if you go and
  27651. 16:55:30close this and open it after one year
  27652. 16:55:32it's going to show exact same results.
  27653. 16:55:34So it's going to live in the database as
  27654. 16:55:36long as you don't drop this table. But
  27655. 16:55:38if things change in the table orders,
  27656. 16:55:41this table will not be updated
  27657. 16:55:42automatically like we have learned in
  27658. 16:55:44the views. So now if you want to say you
  27659. 16:55:46know what I would like to go and drop
  27660. 16:55:47this table well it is very simple just
  27661. 16:55:50go and say drop table and the table name
  27662. 16:55:53over here. So make sure you select it
  27663. 16:55:55and execute it. And now if you go over
  27664. 16:55:57here and refresh. So let's check the
  27665. 16:55:59tables. You can see here the table is
  27666. 16:56:05dropped. And now if you say you know
  27667. 16:56:07what let's go and refresh the table that
  27668. 16:56:10come from the CTAs every day so that we
  27669. 16:56:13always get refresh data inside this
  27670. 16:56:15table. So now let's go and execute again
  27671. 16:56:18our CIS. And with that if we go and
  27672. 16:56:20refresh we're going to find again our
  27673. 16:56:22table inside it. Now if you go and
  27674. 16:56:24execute it one more time in order to
  27675. 16:56:26refresh the data of the table what you
  27676. 16:56:28going to get? You're going to get an
  27677. 16:56:29error. The database going to tell you we
  27678. 16:56:31have already this table so we cannot
  27679. 16:56:32recreate it. So now the question is how
  27680. 16:56:35we can update the the content of this
  27681. 16:56:37table. Well, we have to go and drop it
  27682. 16:56:39first and then recreate it. And if you
  27683. 16:56:41want to put everything in one statement,
  27684. 16:56:43we have to go and use the TSQL. It is
  27685. 16:56:46transacts SQL. It's like extension where
  27686. 16:56:48you can do some programming inside SQL.
  27687. 16:56:51So in order to do that, what we're going
  27688. 16:56:53to do, we're going to go at the start
  27689. 16:56:54over here and we're going to make an if
  27690. 16:56:57logic. So we're going to go and search
  27691. 16:56:58for the objects. So we're going to say
  27692. 16:57:01if the object ID and now we have to go
  27693. 16:57:03and specify the name of this object
  27694. 16:57:06together with the schema. Make sure to
  27695. 16:57:07select everything sales monthly order
  27696. 16:57:10and put it inside here. And then we have
  27697. 16:57:12to define the type of this object. And
  27698. 16:57:15here we're going to go with you. It is
  27699. 16:57:17userdefined table. So we are saying if
  27700. 16:57:21the object sales monthly orders is not
  27701. 16:57:24null. So that means it exist. So what
  27702. 16:57:27you want to do? we have to go and drop
  27703. 16:57:29it. I'm going to take the statement from
  27704. 16:57:31here and then we're going to put it
  27705. 16:57:33after the if over here. So we are saying
  27706. 16:57:36if this table exist then drop the table
  27707. 16:57:39otherwise don't do anything because we
  27708. 16:57:41don't have any new table and the query
  27709. 16:57:43going to work and at the end of the TSQL
  27710. 16:57:46we have go in order to say the TSQL is
  27711. 16:57:49done and then our usual query after all
  27712. 16:57:51that. So let's go and execute the whole
  27713. 16:57:53thing and as you can see it is working.
  27714. 16:57:56So what happens? The database did find
  27715. 16:57:58this table and drop it and then executed
  27716. 16:58:01our query. So if you keep executing
  27717. 16:58:03this, you are just refreshing the
  27718. 16:58:05content of this table. So this is how we
  27719. 16:58:07work with the CTAs in
  27720. 16:58:13SQL. All right, moving on to another
  27721. 16:58:15common use case for the CTAs that I
  27722. 16:58:17usually use as well in my projects. We
  27723. 16:58:19use CDS in order to create a persistent
  27724. 16:58:22snapshot of the data at specific time in
  27725. 16:58:25order to analyze data quality issue. So
  27726. 16:58:28let's understand what this means. Now in
  27727. 16:58:29some scenarios you have like a table and
  27728. 16:58:31you are analyzing an issue. So there is
  27729. 16:58:33like a data quality issue at your data
  27730. 16:58:35and you are analyzing this scenario in
  27731. 16:58:37order to understand why it happens. But
  27732. 16:58:39the problem is that at the same time
  27733. 16:58:41there will be updates on the table and
  27734. 16:58:44your data is changing. So there will be
  27735. 16:58:46updates maybe on some fields or you are
  27736. 16:58:48getting new records and everything is
  27737. 16:58:50getting mixed up and you will not be
  27738. 16:58:52able to analyze the scenario where the
  27739. 16:58:54data quality issue happened. So now it's
  27740. 16:58:57almost impossible to find the ro cause
  27741. 16:58:59of your issue. But instead of that what
  27742. 16:59:02we do if we have like an issue of the
  27743. 16:59:03data we go and create a fixed persisted
  27744. 16:59:06snapshot of the data in a separate table
  27745. 16:59:09using CTS so that we make sure nothing
  27746. 16:59:11is changing and everything is fixed. And
  27747. 16:59:14with that I can keep doing my analysis
  27748. 16:59:16on the same data without the worry that
  27749. 16:59:19data are getting changed. So this is
  27750. 16:59:21another way why we use CTS in projects
  27751. 16:59:23to make sure that we have snapshot of
  27752. 16:59:25the data to ensure that our analyzes are
  27753. 16:59:28done on the same scenario that caused
  27754. 16:59:30the buck and going to be used as a
  27755. 16:59:32foundation for finding the problem and
  27756. 16:59:35fixing
  27757. 16:59:39it. All right, moving on to another use
  27758. 16:59:41case of the CTAs. We can use it in order
  27759. 16:59:44to create our data m to make it physical
  27760. 16:59:47data m instead of virtual data ms using
  27761. 16:59:50views. So let's understand what this
  27762. 16:59:52means now. As we learned before, if you
  27763. 16:59:53have a data warehouse system, our data
  27764. 16:59:56warehouse layer going to store the data
  27765. 16:59:57inside tables. But for the second layer,
  27766. 17:00:00the data m, we can go and use views in
  27767. 17:00:02order to have dynamic and flexibility in
  27768. 17:00:04order to generate multiple data ms. And
  27769. 17:00:07we called it the virtual layer. But now
  27770. 17:00:10in some scenarios if things get
  27771. 17:00:12complicated your data m and reports
  27772. 17:00:14going to be slow because there for each
  27773. 17:00:16action you are generating a query. So
  27774. 17:00:19the powerbi reports and dashboards are
  27775. 17:00:21creating queries in your data marts and
  27776. 17:00:23your data marts have always to go to the
  27777. 17:00:25data warehouse in order to retrieve the
  27778. 17:00:28data for the reports and the whole thing
  27779. 17:00:30could take minutes or maybe sometimes
  27780. 17:00:32hours. So in these scenarios we cannot
  27781. 17:00:34stay using views because they are
  27782. 17:00:36slowing everything down. But instead of
  27783. 17:00:38that we have to convert our data mart to
  27784. 17:00:41a physical layer. That means instead of
  27785. 17:00:43using views we have to go and use
  27786. 17:00:45tables. And one very common way in order
  27787. 17:00:47to generate the tables of the data marts
  27788. 17:00:49on daily basis is to use queries between
  27789. 17:00:53the data warehouse layer and the data
  27790. 17:00:55mart layer. It's still going to take
  27791. 17:00:56maybe 30 minutes. That's why you can go
  27792. 17:00:58and prepare the data at the night. But
  27793. 17:01:00at the reporting layer where things and
  27794. 17:01:02the performance really matters, the
  27795. 17:01:04performance going to be better because
  27796. 17:01:05the response time from the tables is way
  27797. 17:01:08faster than views and the reports don't
  27798. 17:01:10have always to waste time waiting for
  27799. 17:01:12the data marts to get data from the
  27800. 17:01:14warehouse. So this is another use case
  27801. 17:01:16where you use CTAs where the views at
  27802. 17:01:18the data marts are slow and we have to
  27803. 17:01:20go and replace them with stables using
  27804. 17:01:22CTAs to speed up things. But still my
  27805. 17:01:25recommendation here is that start first
  27806. 17:01:27with the views. So create a virtual data
  27807. 17:01:29mart using views because the
  27808. 17:01:31implementation going to be very dynamic
  27809. 17:01:33and fast and you are always getting
  27810. 17:01:35fresh data from the warehouse but maybe
  27811. 17:01:37later if you notice okay some data ms
  27812. 17:01:39and models are complex then maybe go and
  27813. 17:01:42replace few marts from views to tables
  27814. 17:01:45using cis. So this is another use case
  27815. 17:01:47for the and it is nice workaround for
  27816. 17:01:50your data warehouse system. All right
  27817. 17:01:52friends, so with that we have covered
  27818. 17:01:53now the first type of the tables that we
  27819. 17:01:55have in databases. The permanent tables
  27820. 17:01:58where you create a table and it's going
  27821. 17:01:59to live forever until you go and drop
  27822. 17:02:01it. Now we're going to talk about
  27823. 17:02:03another type of tables in databases. We
  27824. 17:02:05have the temporary tables. So let's
  27825. 17:02:07understand what are temporary
  27826. 17:02:12tables. So temporary tables or sometimes
  27827. 17:02:15you call them as a shortcut temp tables.
  27828. 17:02:18They store intermediate results in a
  27829. 17:02:20temporary storage in the database during
  27830. 17:02:22a session and the database automatically
  27831. 17:02:25drop these tables after the session
  27832. 17:02:28ends. So let's understand what this
  27833. 17:02:30means. Now we have learned in the CIS we
  27834. 17:02:32could use a query in order to retrieve
  27835. 17:02:35data from one table and then it puts the
  27836. 17:02:37intermediate results in brand new table
  27837. 17:02:40in the database. So with that we are
  27838. 17:02:42creating another table based on a query.
  27839. 17:02:44The same thing for the temporary tables.
  27840. 17:02:47We have as well a query that goes and
  27841. 17:02:49retrieves the data from a table and as
  27842. 17:02:51well the database going to go and create
  27843. 17:02:53new brand table in the database that has
  27844. 17:02:55the structure and the data from the
  27845. 17:02:58result of the query. So it is exactly at
  27846. 17:03:00the CTIS. What is the difference here?
  27847. 17:03:02Well, it is about the lifetime of the
  27848. 17:03:05table. Now the database tables that you
  27849. 17:03:07have created using create insert or CTIS
  27850. 17:03:10those tables going to stay permanent and
  27851. 17:03:12they're going to live in the database as
  27852. 17:03:14long as you don't drop them. So even if
  27853. 17:03:17the system is completely offline the
  27854. 17:03:19data going to stay at the database once
  27855. 17:03:21it is online again but the temporary
  27856. 17:03:23tables going to get deleted and dropped
  27857. 17:03:26from the database automatically once the
  27858. 17:03:29session ends. So what session means like
  27859. 17:03:32once you open the client and you connect
  27860. 17:03:34to the database and you are start doing
  27861. 17:03:36queries we call the time between
  27862. 17:03:38connecting ourself to the database and
  27863. 17:03:40disconnecting from the database we call
  27864. 17:03:43this a session. So that means once you
  27865. 17:03:45close the client and you disconnect from
  27866. 17:03:46the database and maybe shut down your PC
  27867. 17:03:48and do something else. What going to
  27868. 17:03:49happen? The database going to go and
  27869. 17:03:51destroy and delete all the temporary
  27870. 17:03:54tables that you have created during the
  27871. 17:03:56session. So that mean the table going to
  27872. 17:03:58live as long as you have a session and
  27873. 17:04:00you can access during this time the
  27874. 17:04:02table as you are accessing any other
  27875. 17:04:04permanent table. So this is what we mean
  27876. 17:04:06with temporary tables or sometimes we
  27877. 17:04:08call it as a shortcut temp
  27878. 17:04:10[Music]
  27879. 17:04:13tables. Okay. So now let's check the
  27880. 17:04:16easiest syntax ever. So for the
  27881. 17:04:18temporary table the syntax going to look
  27882. 17:04:19like this. you're going to have like a
  27883. 17:04:21query select from where and as we
  27884. 17:04:23learned in the CTIS if you go and say
  27885. 17:04:26into then the table name it's going to
  27886. 17:04:28go and create a physical new table but
  27887. 17:04:30now if you want it as a temporary table
  27888. 17:04:32what you going to do you're going to
  27889. 17:04:34just put hash before the name of the
  27890. 17:04:36table then SQL can understand okay now
  27891. 17:04:38we are talking about temporary table and
  27892. 17:04:40the database going to store it in that
  27893. 17:04:42temporary storage so it is very simple
  27894. 17:04:45this is the syntax of that temporary
  27895. 17:04:47tables so so far we have learned that we
  27896. 17:04:49have a database called sales DB and
  27897. 17:04:51inside it we can find the tables that we
  27898. 17:04:53have created the customers, employees,
  27899. 17:04:56orders and so on. Those are our tables
  27900. 17:04:58and they are always there like if you go
  27901. 17:05:00and close everything and then start it
  27902. 17:05:02or in the next day you're going to find
  27903. 17:05:03always those tables with the same data.
  27904. 17:05:06So they're going to exist as long as we
  27905. 17:05:07are not dropping them. Now the question
  27906. 17:05:10is where do we find the temporary
  27907. 17:05:12tables? Well, as we learned, if you go
  27908. 17:05:14over here at the system databases, you
  27909. 17:05:16will find multiple databases from the
  27910. 17:05:19SQL server and normally only the
  27911. 17:05:21database administrator has an access to
  27912. 17:05:23this and one of those databases called
  27913. 17:05:25temp DB, temporary database. So, let's
  27914. 17:05:28go inside it. Now, we can find multiple
  27915. 17:05:30objects and one of them we can find here
  27916. 17:05:32the temporary tables. And now, of
  27917. 17:05:34course, we don't have anything inside it
  27918. 17:05:36because we didn't create anything. So,
  27919. 17:05:38let's go and create one. We have already
  27920. 17:05:40an open session and active session with
  27921. 17:05:41the SQL server. As you can see here, we
  27922. 17:05:43are connected to the database and we can
  27923. 17:05:45start creating temporal tables. So now
  27924. 17:05:47what is the plan? I would like now to do
  27925. 17:05:49few modifications on the table orders.
  27926. 17:05:52But I will not do it directly at the
  27927. 17:05:54table orders. I would like to take a
  27928. 17:05:56copy from the sales DB and create from
  27929. 17:05:59it a temporary table. So let's go and do
  27930. 17:06:01that. What do we need first? We need a
  27931. 17:06:04query. So I would like to select
  27932. 17:06:06everything all the columns all the rows
  27933. 17:06:08from the table orders. So from sales
  27934. 17:06:12orders. So this is my query. Now so far
  27935. 17:06:16nothing is created. We have only select
  27936. 17:06:17statements. But now in order to create a
  27937. 17:06:20temporary table what we're going to do
  27938. 17:06:21we're going to put a statement between
  27939. 17:06:23the select and from. So exactly before
  27940. 17:06:26the from go over here and say into then
  27941. 17:06:29in order to make sure it is a temporary
  27942. 17:06:31table we use hash and then the table
  27943. 17:06:33name. So we're going to call it orders.
  27944. 17:06:35So that's it. We have our query and in
  27945. 17:06:38between we have the into and make sure
  27946. 17:06:40you are using hash in order to be a
  27947. 17:06:42temporary table. So let's go and execute
  27948. 17:06:44it. And now we can see that 10 rows are
  27949. 17:06:46affected and we don't have any error.
  27950. 17:06:48And now of course we cannot see it yet
  27951. 17:06:50because we have to go and refresh the
  27952. 17:06:52object explorer. So let's go and do
  27953. 17:06:53that. And now let's expand it. And now
  27954. 17:06:56we can see our temporary tables. As you
  27955. 17:06:58can see it is at the schema dbo because
  27956. 17:07:01we haven't defined any schema. And this
  27957. 17:07:03is the default one from the database. So
  27958. 17:07:05nice. Now we have the table and let's go
  27959. 17:07:07and check few stuff. So let's go and
  27960. 17:07:09select the table itself. So select star
  27961. 17:07:12from and make sure to say hash orders.
  27962. 17:07:16Let's go and select it. And now we are
  27963. 17:07:18getting the data from the temporary
  27964. 17:07:20table and not from the original table.
  27965. 17:07:22The orders in the database sales DB. So
  27966. 17:07:25all those informations comes from the
  27967. 17:07:27temporary table. Now, of course, you can
  27968. 17:07:29do whatever you want to this temporary
  27969. 17:07:30table because it's not that important
  27970. 17:07:32and it's anyway going to get deleted.
  27971. 17:07:34So, let's say that I would like to
  27972. 17:07:36delete all the orders where the order
  27973. 17:07:39status equal to delivered. So, let's go
  27974. 17:07:41and do that. What we're going to do
  27975. 17:07:43delete from our hash orders. So, make
  27976. 17:07:47sure we are selecting the temporary
  27977. 17:07:49table and then where we're going to say
  27978. 17:07:51the
  27979. 17:07:53order status equal to what I say
  27980. 17:07:57delivered. Yeah, delivered. So delivered
  27981. 17:08:00like this. Let's go and execute it.
  27982. 17:08:02Okay, with that it says five rows are
  27983. 17:08:04affected. Let's go and select it again.
  27984. 17:08:07So
  27985. 17:08:08select from
  27986. 17:08:11orders and let's check that. So as you
  27987. 17:08:14can see now we don't have all orders. We
  27988. 17:08:16have only the orders where the status
  27989. 17:08:18equal to shipped. So all delivered
  27990. 17:08:19orders are removed. And now we can do
  27991. 17:08:22whatever we want to this copy. We can
  27992. 17:08:23analyze it. We can modify it. We can go
  27993. 17:08:26and insert a new data. So we can do
  27994. 17:08:28whatever manipulation we want on this
  27995. 17:08:30copy. And now if you say, you know what,
  27996. 17:08:31I like this result and I would like to
  27997. 17:08:33have it not only during the session.
  27998. 17:08:36Maybe I'm going to need it for tomorrow
  27999. 17:08:37or something. So now what we're going to
  28000. 17:08:39do, we're going to do the exact
  28001. 17:08:40opposite. We're going to now store the
  28002. 17:08:42result of the temporary table back to
  28003. 17:08:44our database so that we don't lose this
  28004. 17:08:47intermediate result. So in order to do
  28005. 17:08:49that, we're going to say into and then
  28006. 17:08:52make sure to specify the sales dot
  28007. 17:08:54because we want to select the correct
  28008. 17:08:56schema and then let's say it is orders
  28009. 17:08:59and I'm going to call it test like this.
  28010. 17:09:02So let's go and execute it. So it says
  28011. 17:09:04five rows are affected. Now we have to
  28012. 17:09:07see those informations in the sales DB.
  28013. 17:09:09We still don't have this table over
  28014. 17:09:10here. So right click on the DB and then
  28015. 17:09:13refresh it. So let's go again to the
  28016. 17:09:15tables. And now you can see we have our
  28017. 17:09:17new table orders test. So it is amazing
  28018. 17:09:20right? What we have done is we have took
  28019. 17:09:22a copy from the original table orders to
  28020. 17:09:25a temporary space. We have done some
  28021. 17:09:28modifications and play with the data and
  28022. 17:09:30we have done some analyzes and then the
  28023. 17:09:32end result of our temporary table. We
  28024. 17:09:35have loaded back to another new table
  28025. 17:09:38called orders test in order maybe in the
  28026. 17:09:40next day to keep working on it. So it is
  28027. 17:09:43really nice way to do changes in place
  28028. 17:09:45where you say you know what it is
  28029. 17:09:47temporary and whatever mistakes you
  28030. 17:09:48makes it's okay it is like playground.
  28031. 17:09:51So now we still have an active session
  28032. 17:09:53with the database and our temporary
  28033. 17:09:55table going to be always here. Now let's
  28034. 17:09:57see what going to happen if we end our
  28035. 17:09:58session. So in order to do that let's go
  28036. 17:10:01and just close everything. So I will
  28037. 17:10:04just close and we'll not store anything.
  28038. 17:10:07So with that we have now ended the
  28039. 17:10:09session. Let's go and start it again and
  28040. 17:10:11see whether we still have the temporary
  28041. 17:10:13table. So we have now again to connect
  28042. 17:10:15to the SQL server and now we have
  28043. 17:10:18another session. So that means the old
  28044. 17:10:20session is already lost. Let's go to the
  28045. 17:10:22databases to the system databases to the
  28046. 17:10:25temp DB and let's go to the temporary
  28047. 17:10:27tables. As you can see the database
  28048. 17:10:30already cleaned up everything and this
  28049. 17:10:32space is again empty for any new
  28050. 17:10:34temporary table that I'm going to
  28051. 17:10:35create. So as you can see once you close
  28052. 17:10:38the session everything going to get
  28053. 17:10:39lost. Now let's go back to our sales DB
  28054. 17:10:41over here to the tables. We can see the
  28055. 17:10:44table that we have created orders test
  28056. 17:10:46it is still living here and still has
  28057. 17:10:48like the data that we have created. So
  28058. 17:10:50this is how things works with the
  28059. 17:10:52temporary tables in
  28060. 17:10:56SQL. Now let's see how the database
  28061. 17:10:59server executed that temporary SQL. So
  28062. 17:11:02now let's say that you are as a data
  28063. 17:11:04analyst. You have created a query and
  28064. 17:11:05then you say into in a temporary table.
  28065. 17:11:07Now the database engine going to
  28066. 17:11:09identify the query and first it's going
  28067. 17:11:11to go and execute the query and then
  28068. 17:11:13it's going to go and execute it and
  28069. 17:11:15maybe we're going to get the data from
  28070. 17:11:16the table orders and after the query is
  28071. 17:11:19executed the database engine now has the
  28072. 17:11:21results. Now two things can happen.
  28073. 17:11:23First the database engine going to go
  28074. 17:11:25and store the metadata informations in
  28075. 17:11:28the system catalog. And now the second
  28076. 17:11:30thing the database engine going to
  28077. 17:11:31create a table but this time not in the
  28078. 17:11:34users but in the temporary storage in
  28079. 17:11:37the disk. So the table going to live
  28080. 17:11:38there for a short time. And now what you
  28081. 17:11:40can do you can write multiple SQL
  28082. 17:11:42queries that are doing maybe multiple
  28083. 17:11:44analysis on top of this table. So each
  28084. 17:11:46time you select something the database
  28085. 17:11:48engine has to go to the temporary
  28086. 17:11:50storage and fetch the data from there.
  28087. 17:11:53And now once you are finished and let's
  28088. 17:11:54say you close your client the session
  28089. 17:11:57between you and the database going to
  28090. 17:11:58ends and now the database going to
  28091. 17:12:00understand okay there is no more
  28092. 17:12:02connection to this user and it going to
  28093. 17:12:04go and clean up now the temporary
  28094. 17:12:07storage with any tables that are created
  28095. 17:12:10from this session. So that means the
  28096. 17:12:12database is automatically cleaning up
  28097. 17:12:14the storage maybe for other sessions. So
  28098. 17:12:16this is how the database engine works
  28099. 17:12:18with the temporary tables.
  28100. 17:12:24So now the question is why do we need
  28101. 17:12:26temporary tables? Let's see the
  28102. 17:12:27following scenario. Now let's say that
  28103. 17:12:29in our source database we have a table
  28104. 17:12:31called orders and now we would like to
  28105. 17:12:33go and load the table in our data
  28106. 17:12:34warehouse. We have to do several
  28107. 17:12:36transformations in order to prepare the
  28108. 17:12:38data for the analyzes in the data
  28109. 17:12:40warehouse. So maybe you have one query
  28110. 17:12:41to remove the duplicates and another one
  28111. 17:12:43to handle the nulls and maybe you are
  28112. 17:12:45doing filtering and cleaning up and the
  28113. 17:12:48last step you would like to aggregate
  28114. 17:12:49the data. And now of course those
  28115. 17:12:51queries those transformations want to
  28116. 17:12:53change the content of the table orders
  28117. 17:12:56and there is no scenario where you can
  28118. 17:12:58do that directly on the source database
  28119. 17:13:00and of course this is not allowed.
  28120. 17:13:02That's why in data warehousing we have
  28121. 17:13:04to go and get our own copy of the data
  28122. 17:13:06and then on top of this data we can do
  28123. 17:13:08our transformations. Now one way to do
  28124. 17:13:10this using the temporary tables. So you
  28125. 17:13:13have one script in order to extract the
  28126. 17:13:15data from the table orders and put it in
  28127. 17:13:17temporary table as an intermediate
  28128. 17:13:19results and then you come with the
  28129. 17:13:21transformations and all those queries
  28130. 17:13:23and they start manipulating and changing
  28131. 17:13:25the data of this extra copy in the
  28132. 17:13:28temporary table and the last step you
  28133. 17:13:30have the load where you go and load the
  28134. 17:13:32final version of the intermediate
  28135. 17:13:34results in the database. This is if you
  28136. 17:13:36would like to do the whole ETL before
  28137. 17:13:39inserting the data to the database. So
  28138. 17:13:41now the orders table and the final table
  28139. 17:13:43in the data warehouse both of them are
  28140. 17:13:45tables. So they are permanent tables and
  28141. 17:13:48they will stay there as long as we don't
  28142. 17:13:50drop them. So they are very important
  28143. 17:13:52tables. But now for the intermediate
  28144. 17:13:54results it is not that important. It is
  28145. 17:13:56just an intermediate step that we have
  28146. 17:13:58done in order to have our extra copy of
  28147. 17:14:01the data to manipulate it and so on in
  28148. 17:14:03order to prepare it to be inserted in
  28149. 17:14:05the data warehouse. So after we loaded
  28150. 17:14:08it in the data warehouse, this copy of
  28151. 17:14:10the data is not anymore important. It
  28152. 17:14:12shouldn't stay like for a long time.
  28153. 17:14:14That's why in this scenario, maybe we
  28154. 17:14:16can go and use the temporary tables
  28155. 17:14:18instead of normal tables for the
  28156. 17:14:20intermediate results. And that's because
  28157. 17:14:22only of one advantage is that the
  28158. 17:14:24database going to go and do an automatic
  28159. 17:14:27clean up after the host session ends. So
  28160. 17:14:30it comes out of the box automatically
  28161. 17:14:31from the database. So that means I don't
  28162. 17:14:34have to deal with the dropping mechanism
  28163. 17:14:36of this table for the next load. If
  28164. 17:14:38there is like something wrong in the
  28165. 17:14:40data warehouse, you would like always to
  28166. 17:14:41check the copy where the transformations
  28167. 17:14:44are done in order to debug and find
  28168. 17:14:46issues. So I don't normally use
  28169. 17:14:47temporary tables in these scenarios, I
  28170. 17:14:49use just normal tables. But for other
  28171. 17:14:52small projects, maybe this makes sense.
  28172. 17:14:53So this is one use case on when to use
  28173. 17:14:56the temporary tables in your projects.
  28174. 17:14:58We use it in order to store intermediate
  28175. 17:15:00results temporary until we are done with
  28176. 17:15:03the session and then once we are done
  28177. 17:15:04the database can go and drop that
  28178. 17:15:07temporary
  28179. 17:15:11table. All right guys, now a quick talk
  28180. 17:15:13about the temporary tables. To be
  28181. 17:15:15honest, I never use this in my projects.
  28182. 17:15:17If I need an intermediate results in one
  28183. 17:15:20query, I can go and use the CTEs. And if
  28184. 17:15:23my intermediate results is very
  28185. 17:15:25important then I put it in either view
  28186. 17:15:27or CTIS but it is nice technique to
  28187. 17:15:30learn maybe you can utilize it in one of
  28188. 17:15:32your
  28189. 17:15:36projects. All right guys so now let's
  28190. 17:15:38have a quick summary about tables.
  28191. 17:15:39Tables in database are like spreadsheet
  28192. 17:15:42or grid that contains columns and rows
  28193. 17:15:44and your actual data are stored in these
  28194. 17:15:47tables. And we have learned there are
  28195. 17:15:48two types of tables. We have permanent
  28196. 17:15:50tables and temporary tables. Permanent
  28197. 17:15:53tables lives in the database forever as
  28198. 17:15:55long as you don't drop them. But in the
  28199. 17:15:57other hand that temporary tables they
  28200. 17:15:59have short lifetime. They will be
  28201. 17:16:01dropped from the database once you end
  28202. 17:16:03the session. Now we have learned as well
  28203. 17:16:05there are two methods on how to create
  28204. 17:16:07tables in databases. The first method is
  28205. 17:16:10create insert. This method involves two
  28206. 17:16:12steps. The first one is defining and
  28207. 17:16:15creating the table and the second step
  28208. 17:16:17is by inserting the data inside this new
  28209. 17:16:20table. So you are creating something
  28210. 17:16:21from the scratch. And the second method
  28211. 17:16:23we call it CTAs. It create as well brand
  28212. 17:16:27new table but based on the result of a
  28213. 17:16:30query. So this type is done with only
  28214. 17:16:32one step but it always needs another
  28215. 17:16:35existing table. And we have learned as
  28216. 17:16:36well the difference between tables and
  28217. 17:16:38views where the main advantage of using
  28218. 17:16:40tables created from CTIS is that to
  28219. 17:16:43ensure the performance is fast enough at
  28220. 17:16:46the end of the users or your reporting
  28221. 17:16:48system. So we use CIS instead of views
  28222. 17:16:52if the logic of the view is very complex
  28223. 17:16:54and takes a lot of time to be executed
  28224. 17:16:56in the database. And one more nice use
  28225. 17:16:58case for the CIS is that we can go and
  28226. 17:17:01persist a snapshot of the data in order
  28227. 17:17:03to analyze a bug and data quality issue
  28228. 17:17:06and to ensure that we have the exact
  28229. 17:17:08data in order to find a solution for the
  28230. 17:17:10bug and the issue. Now we have learned
  28231. 17:17:12as well that we can use temporary tables
  28232. 17:17:14in order to store intermediate results
  28233. 17:17:16in a temporary storage and the main
  28234. 17:17:18advantage of the temporary table is the
  28235. 17:17:21database automatically drops all that
  28236. 17:17:23temporary tables when the session ends
  28237. 17:17:26and that's because for you the
  28238. 17:17:28intermediate results are not that
  28239. 17:17:29important to live long
  28240. 17:17:34time. Hey my friends. So we have learned
  28241. 17:17:37that in real data projects if you have a
  28242. 17:17:40database there will be a lot of
  28243. 17:17:42analytical use cases that want to access
  28244. 17:17:44your data and do analytics. And what
  28245. 17:17:46going to happen? They're going to write
  28246. 17:17:48complex queries because in many
  28247. 17:17:50scenarios they are doing complex
  28248. 17:17:52analyzes. And if you don't do anything
  28249. 17:17:54about it in your projects, you're going
  28250. 17:17:55to face a lot of challenges like
  28251. 17:17:57complexity and a lot of redundancy of
  28252. 17:18:00the same complex logic but from multiple
  28253. 17:18:02users and maybe performance and security
  28254. 17:18:05issues. And we have learned we have five
  28255. 17:18:07amazing techniques in order to solve
  28256. 17:18:10those problems. We have learned the
  28257. 17:18:11subqueries and cities and as well how to
  28258. 17:18:14create objects like views, CTAs and
  28259. 17:18:17temporary tables. So now what we're
  28260. 17:18:19going to do, we're going to go and
  28261. 17:18:20compare them side by side in order to
  28262. 17:18:22have a big picture about the advantages
  28263. 17:18:24and the disadvantages of each method. So
  28264. 17:18:27let's go and compare them. Okay. So now
  28265. 17:18:29we have our five methods and the first
  28266. 17:18:31criteria that I would like to compare
  28267. 17:18:32them is the storage type. We have
  28268. 17:18:35learned that if you are using subqueries
  28269. 17:18:37and CTE, what can happen? and the
  28270. 17:18:39database going to put the result of
  28271. 17:18:41those two techniques in the memory in
  28272. 17:18:43the cache so that later the main query
  28273. 17:18:46has a fast access to those intermediate
  28274. 17:18:48results. But in the other hand if you
  28275. 17:18:50are using temporary tables or tables
  28276. 17:18:52from CDS the new created table can be
  28277. 17:18:55stored inside the disk storage. And now
  28278. 17:18:57for the views as we understood there
  28279. 17:18:59will be no data storage and that means
  28280. 17:19:02we are not using any storage from the
  28281. 17:19:04database. Now if you are talking about
  28282. 17:19:06the lifetime so that means how long the
  28283. 17:19:08object going to live or persist in the
  28284. 17:19:10database. Now our three techniques sub
  28285. 17:19:12queries CTE and temporary tables all of
  28286. 17:19:15them going to live a short time in the
  28287. 17:19:17database. So all of them are temporary.
  28288. 17:19:20But now if you are talking about
  28289. 17:19:21creating objects using CIS and views
  28290. 17:19:24those two going to be permanent. So that
  28291. 17:19:26means they're going to live in the
  28292. 17:19:27database as long as you don't drop them.
  28293. 17:19:30Now we're going to compare them with
  28294. 17:19:31something similar is when the database
  28295. 17:19:34going to go and drop or delete those
  28296. 17:19:36objects. Now we have learned that the
  28297. 17:19:38subqueries and the cities have a short
  28298. 17:19:40time. They going to live only during the
  28299. 17:19:43execution of the query. So once the
  28300. 17:19:45query ends the database going to go to
  28301. 17:19:47the cache and delete everything. But for
  28302. 17:19:50the temporary tables they live little
  28303. 17:19:52bit longer as long as you are in the
  28304. 17:19:54session. But once you end the session,
  28305. 17:19:56the database as well going to go and
  28306. 17:19:58drop and delete your table. Now for the
  28307. 17:20:00objects that comes from the CIS and
  28308. 17:20:03views as we learned they are persistent
  28309. 17:20:05and permanent and the database can only
  28310. 17:20:07delete them if you ask the database to
  28311. 17:20:09do that by using the DDL command drop.
  28312. 17:20:12So the database will not delete anything
  28313. 17:20:14for these two. So now the next one is
  28314. 17:20:16the query scope like how we can access
  28315. 17:20:19those objects. Now for the subquery and
  28316. 17:20:21the CTE the scope is here very small. It
  28317. 17:20:24is accessed only from one single query.
  28318. 17:20:26The query itself where you write the
  28319. 17:20:28city and subquery. So you cannot access
  28320. 17:20:31it from external queries. But we have
  28321. 17:20:33learned that the temporary tables cis
  28322. 17:20:35and views you can access all those
  28323. 17:20:38objects from multiple queries. So that
  28324. 17:20:40means you can access those objects from
  28325. 17:20:43multiple external queries. Now the next
  28326. 17:20:45one if you are thinking about the
  28327. 17:20:47reusability if you look to the
  28328. 17:20:49subqueries they are very limited. the
  28329. 17:20:51subquery going to be used only in one
  28330. 17:20:53query and only in one place. So if you
  28331. 17:20:56need it in multiple places, you have to
  28332. 17:20:58go and repeat the same logic. So
  28333. 17:21:00subqueries are the worst with their
  28334. 17:21:02reusability. But now if you are talking
  28335. 17:21:04about the CTE, it is little bit better.
  28336. 17:21:06You still can access it only from one
  28337. 17:21:08single query but you can access it in
  28338. 17:21:10the same query from multiple places. So
  28339. 17:21:13you can access it multiple times from
  28340. 17:21:15different joins and you don't have to
  28341. 17:21:17repeat the same logics over and over.
  28342. 17:21:19But still it is limited because you have
  28343. 17:21:21only one query that is using the logic.
  28344. 17:21:24Now if you think about the temporary
  28345. 17:21:25tables I could say the reusability here
  28346. 17:21:28is medium and that's because you can
  28347. 17:21:30access the data by multiple queries but
  28348. 17:21:33only during this session. So once the
  28349. 17:21:35session is ended you cannot access it
  28350. 17:21:38anymore which means you have to recreate
  28351. 17:21:40it in order to reuse it again. So it is
  28352. 17:21:42more reusable than the city and the
  28353. 17:21:44subqueries but not that good like the
  28354. 17:21:46CTAs and views. Those techniques can
  28355. 17:21:49offer the highest reusability for you.
  28356. 17:21:52So they are always there for multiple
  28357. 17:21:54users from multiple queries. So it can
  28358. 17:21:57eliminate a lot of redundancies and you
  28359. 17:21:59have to do the job only once. Now moving
  28360. 17:22:01into the next one. If you are thinking
  28361. 17:22:03about the intermediate result of those
  28362. 17:22:04techniques, the question is how fresh is
  28363. 17:22:07the data? Is the data from these objects
  28364. 17:22:10always up to date? Now for the
  28365. 17:22:11subqueries and the cities they are
  28366. 17:22:14always up to date because the SQL is
  28367. 17:22:16executing the logic on the fly and
  28368. 17:22:18storing the data in the memory and
  28369. 17:22:20immediately after that going to come the
  28370. 17:22:22main query and get the data. So always
  28371. 17:22:24the intermediate results in the memory
  28372. 17:22:26are up to date. But now if you think
  28373. 17:22:28about that temporary tables and the CTIS
  28374. 17:22:30the query is only executed once and if
  28375. 17:22:33there is like any update and changes on
  28376. 17:22:35the original table you will not find
  28377. 17:22:38those changes in those objects and
  28378. 17:22:40that's because SQL executed once and
  28379. 17:22:42that's all. So if you query those tables
  28380. 17:22:44there is no guarantee that the data are
  28381. 17:22:46up to date. So if you want fresh data
  28382. 17:22:49you have always to drop the table and
  28383. 17:22:51create it again from the query. Now if
  28384. 17:22:53you are talking about the views they are
  28385. 17:22:55amazing they are always up to date
  28386. 17:22:57because views does not store any data.
  28387. 17:22:59So each time you ask the views for data
  28388. 17:23:02what's going to happen the database
  28389. 17:23:03going to go to the original table and
  28390. 17:23:05fetch the data to the view. So your data
  28391. 17:23:07are always fresh and up to date. So this
  28392. 17:23:09is a big picture about the behavior of
  28393. 17:23:11those advanced techniques that you can
  28394. 17:23:13use in SQL projects. And if you ask my
  28395. 17:23:16opinion my favorite is going to be the
  28396. 17:23:17views in the first place. Then in the
  28397. 17:23:20second in my list is the city. They are
  28398. 17:23:22amazing, but don't use more than five
  28399. 17:23:24CTEs in one query. Otherwise, it's going
  28400. 17:23:26to be really annoying and hard to read.
  28401. 17:23:28And then I'm going to say in the third
  28402. 17:23:29place, the sub queries. And then the
  28403. 17:23:32CDIS. I use CIS if the views are slow.
  28404. 17:23:35If that's a scenario, I'm jump to the
  28405. 17:23:37CDIS and create a permanent physical
  28406. 17:23:39tables from my query. And the last one
  28407. 17:23:41that I rarely use is the temporary
  28408. 17:23:43tables. So, this is how I rank those
  28409. 17:23:46techniques in my skill projects.
  28410. 17:23:52Now I would like to show you as well a
  28411. 17:23:53big picture on how things works in my
  28412. 17:23:55projects in order to see all those
  28413. 17:23:57different techniques and possibilities
  28414. 17:23:59that you can use. It's like a big
  28415. 17:24:01picture and recap. So story time. So you
  28416. 17:24:04have a database and things starts where
  28417. 17:24:06you have a database administrator or
  28418. 17:24:08let's say a data engineer that is
  28419. 17:24:10creating a new table from the scratch.
  28420. 17:24:12So he going to write a DDL statement in
  28421. 17:24:14order to create one physical table at
  28422. 17:24:16our database. And now our database table
  28423. 17:24:18is empty. That's why in the second step
  28424. 17:24:21he going to go and write an insert
  28425. 17:24:23statement in order to fill our new table
  28426. 17:24:25with data. Now once we have a table
  28427. 17:24:27we're going to give the access maybe to
  28428. 17:24:29a data scientist or data analyst in
  28429. 17:24:31order to start writing SQL queries. So
  28430. 17:24:33now the first thing that could happen
  28431. 17:24:35that the logic is complex and she has to
  28432. 17:24:37do that in two steps. So the first step
  28433. 17:24:40is a query that prepares the data in
  28434. 17:24:42order to execute the second step. So
  28435. 17:24:45that's why she going to go and use the
  28436. 17:24:46subquery and the main query going to go
  28437. 17:24:48and retrieve the data from the
  28438. 17:24:50intermediate results in order to prepare
  28439. 17:24:52the final results for the analyst. Now
  28440. 17:24:54what could happen is that there will be
  28441. 17:24:56an SQL logic in the query where it keep
  28442. 17:24:59repeating the scripts. So now instead of
  28443. 17:25:01writing another subquery for that she
  28444. 17:25:03going to go and put this logic in CTE
  28445. 17:25:05and now she going to go to the main
  28446. 17:25:07query and use the result of the CTE in
  28447. 17:25:10multiple places in the same query. So
  28448. 17:25:12all those stuff the sub queries and the
  28449. 17:25:14city queries the main queries all those
  28450. 17:25:16stuff happens in one single query and
  28451. 17:25:19now what could happen is that she is
  28452. 17:25:21writing an amazing code. So instead of
  28453. 17:25:23using it only in her query what's going
  28454. 17:25:26to happen she going to go and persist
  28455. 17:25:28this logic in the database. So she going
  28456. 17:25:30to put it as a view in the database so
  28457. 17:25:32that all other users and analysts can
  28458. 17:25:35benefit from this logic and they don't
  28459. 17:25:37have to write it again. So instead
  28460. 17:25:39they're going to go and query the view
  28461. 17:25:41and this going to makes the life easier.
  28462. 17:25:43And of course our data analyst can as
  28463. 17:25:45well use this view in the main query.
  28464. 17:25:47And now one more thing she has as well
  28465. 17:25:49another logic that is really complex and
  28466. 17:25:52as well everyone can benefit from it.
  28467. 17:25:54But the issue this query is very slow.
  28468. 17:25:56So now she has to decide do I put it in
  28469. 17:25:59view or do I create a new table based on
  28470. 17:26:01the query using CTAs. Now of course
  28471. 17:26:03because of the performance and the view
  28472. 17:26:05takes around 30 minutes to be executed.
  28473. 17:26:07She decided to execute the query using
  28474. 17:26:09the CTIS where she generate a physical
  28475. 17:26:12table so that all other analysts as well
  28476. 17:26:14can access this new table in order to
  28477. 17:26:17reuse the results and of course she can
  28478. 17:26:19use it in her main query and with that
  28479. 17:26:22now you have experience how things works
  28480. 17:26:24in real projects. It is not simple
  28481. 17:26:26select query from table it is like this
  28482. 17:26:29people are creating subquery CTE views
  28483. 17:26:32temporary tables CTAs for different
  28484. 17:26:35purposes. All right my friends. So
  28485. 17:26:37that's all about the CTIS and the
  28486. 17:26:39temporary tables. And with that we have
  28487. 17:26:40learned all the techniques on how to
  28488. 17:26:42organize our complex projects. Now next
  28489. 17:26:44we're going to start talking about
  28490. 17:26:45something completely different. We're
  28491. 17:26:47going to talk about the stored
  28492. 17:26:49procedures on how to put our code inside
  28493. 17:26:51the database. This is all about that
  28494. 17:26:53programmability and how to add stuff
  28495. 17:26:55like parameters, variables, error
  28496. 17:26:58handling. So it's like programming. So
  28497. 17:27:00let's go. So let's uncover this word of
  28498. 17:27:02the s procedures and let's go.
  28499. 17:27:08Now think about store procedures like
  28500. 17:27:10this. Every time you go to a coffee
  28501. 17:27:12shop, you say, "I would like a large
  28502. 17:27:14coffee with a coconut milk, no sugar,
  28503. 17:27:17and extra whipped cream." And you repeat
  28504. 17:27:19this over and over each time you go to
  28505. 17:27:22this coffee shop. And now, if you are
  28506. 17:27:24working with stored procedures, it's
  28507. 17:27:25going to be like this. Whenever you go
  28508. 17:27:27to the coffee shop, you just say, "Give
  28509. 17:27:29me my usual." and the barista know
  28510. 17:27:31exactly what you mean behind that and
  28511. 17:27:33you will get exactly your order without
  28512. 17:27:35specifying and repeating everything word
  28513. 17:27:37by word and this is exactly what's going
  28514. 17:27:39to happen if you work with stored
  28515. 17:27:40procedures so let's have some coffee
  28516. 17:27:44right all right so now we can continue
  28517. 17:27:47all right so now let's start again from
  28518. 17:27:48the scratch we have always these two
  28519. 17:27:50sides we have the client side and the
  28520. 17:27:52server side of the database and what we
  28521. 17:27:54have learned we have like a database and
  28522. 17:27:55you as a user you can go and create like
  28523. 17:27:58different SQL statements Like for
  28524. 17:28:00example, you can create like an SQL
  28525. 17:28:02select statements in order to retrieve
  28526. 17:28:04data from the database or another SQL
  28527. 17:28:07statements where you are inserting data
  28528. 17:28:09to the database and another one let's
  28529. 17:28:11say that you are updating the content of
  28530. 17:28:13your tables and so on. So you have like
  28531. 17:28:16different statements in order to
  28532. 17:28:17interact with the database. Now let's
  28533. 17:28:19say that what you are doing is not only
  28534. 17:28:21one time job you are keep repeating
  28535. 17:28:23those steps over and over. So you are
  28536. 17:28:26always like doing an insert then an
  28537. 17:28:28update and then a select and you keep
  28538. 17:28:30repeating that day after day. So now
  28539. 17:28:33imagine that you are doing something
  28540. 17:28:34crazy where you go in vacation but the
  28541. 17:28:37job should be done. So what you do you
  28542. 17:28:38hand over all those select statements to
  28543. 17:28:41your colleagues and they have to do it
  28544. 17:28:43every day as well as you are gone. So
  28545. 17:28:45you go and give them all those SQL
  28546. 17:28:47scripts and you tell them okay you have
  28547. 17:28:49to execute the first query then the
  28548. 17:28:51second query and then the third query.
  28549. 17:28:53This is of course not a good way on how
  28550. 17:28:55to do things because of course there
  28551. 17:28:57will be some human errors where like the
  28552. 17:29:00execution of the script is not correct
  28553. 17:29:02like first updating then inserting and
  28554. 17:29:04things can go wrong and that's exactly
  28555. 17:29:07why we have stored procedures in SQL. So
  28556. 17:29:10what we can do we can put all those SQL
  28557. 17:29:13statements together in one frame in one
  28558. 17:29:16program and we call it start procedure.
  28559. 17:29:19And now once you do that all your SQL
  28560. 17:29:21statements will not stay at the client
  28561. 17:29:23side they will be stored now in the
  28562. 17:29:26server side of the database. So that
  28563. 17:29:28means in store procedures we are storing
  28564. 17:29:30our SQL statements inside the database.
  28565. 17:29:33So you don't have to go and hand over
  28566. 17:29:35your SQL statements to your colleagues.
  28567. 17:29:37And now all what you have to do in order
  28568. 17:29:39to interact with your SQL statements is
  28569. 17:29:42to go and execute the store procedure.
  28570. 17:29:44So you write very simple command called
  28571. 17:29:47execute SP for example. So with that you
  28572. 17:29:50are calling your stored procedure that
  28573. 17:29:52is stored inside the server. And once
  28574. 17:29:54you execute this what can happen the
  28575. 17:29:56database going to go to the stored
  28576. 17:29:57procedure and start executing all the
  28577. 17:30:00SQL statements that you have inside the
  28578. 17:30:03store procedure and it's going to do it
  28579. 17:30:05exactly in the order that you have
  28580. 17:30:06defined. So from top to bottom. So now
  28581. 17:30:09once the database went through all your
  28582. 17:30:11SQL statements, it's going to return
  28583. 17:30:13back to the user the data that we have
  28584. 17:30:15from the selects. And with that things
  28585. 17:30:17are really easy and you can tell your
  28586. 17:30:19colleagues okay just execute this third
  28587. 17:30:21procedure and the rest can be done from
  28588. 17:30:24the database. So with that you minimize
  28589. 17:30:26the human errors and you make sure that
  28590. 17:30:28everything can be executed as you wish
  28591. 17:30:30and as well as you are back from your
  28592. 17:30:32vacation things are easier. You have to
  28593. 17:30:34just go and execute the third procedure.
  28594. 17:30:36So this is what we mean with start
  28595. 17:30:38procedure. You can store inside it
  28596. 17:30:40multiple SQL statements in specific
  28597. 17:30:42order and you can save it inside the
  28598. 17:30:44database and each time you need your SQL
  28599. 17:30:46statements you can go and simply execute
  28600. 17:30:52them. So now let's have a quick
  28601. 17:30:54comparison between a normal query normal
  28602. 17:30:56SQL statements compared to a stored
  28603. 17:30:58procedure. So a normal SQL query you
  28604. 17:31:01have like select from where and so on.
  28605. 17:31:04This is like one-time transaction. You
  28606. 17:31:06are asking the database for one thing
  28607. 17:31:08and the database is answering. So it is
  28608. 17:31:11like one-time request. But now in the
  28609. 17:31:13other hand in the stored procedures you
  28610. 17:31:15have multiple SQL statements and once
  28611. 17:31:17you execute the stored procedure there
  28612. 17:31:19will be many interactions with the
  28613. 17:31:21database in one go. So that means you
  28614. 17:31:23will have multiple transactions that is
  28615. 17:31:25happening in your store procedure. So an
  28616. 17:31:28SQL query it is like a simple request.
  28617. 17:31:30You need one thing and you are getting
  28618. 17:31:32it. But on the other hand in the start
  28619. 17:31:34procedure it is like a program. As you
  28620. 17:31:37are writing a code in any programming
  28621. 17:31:39languages it is more than one request it
  28622. 17:31:41has a lot of stuff like for example you
  28623. 17:31:44can go and build looping logic where we
  28624. 17:31:46go and iterate through something or you
  28625. 17:31:49can go and build a control flow where
  28626. 17:31:51you have a logic like the FL statements.
  28627. 17:31:54So there are like different paths in
  28628. 17:31:56your code and as well in programming we
  28629. 17:31:58have like parameters and variables in
  28630. 17:32:01order to make our code dynamic and
  28631. 17:32:03flexible and as well we can build error
  28632. 17:32:05handling on our code in order to
  28633. 17:32:08customize what can happen if there is
  28634. 17:32:09like an issue. So the store procedure it
  28635. 17:32:12is like having a code like for example
  28636. 17:32:14in Python. So that means you can do more
  28637. 17:32:16complicated stuff compared to a simple
  28638. 17:32:19query where you have only like one
  28639. 17:32:21request. So in the stored procedures you
  28640. 17:32:23are doing like programming and coding
  28641. 17:32:25and it is more advanced than only just
  28642. 17:32:28having a query. So that means if you are
  28643. 17:32:30working with stored procedures things
  28644. 17:32:32going to get more complicated and
  28645. 17:32:33advanced but of course you will get a
  28646. 17:32:35lot of flexibility and reusability
  28647. 17:32:38compared to a simple
  28648. 17:32:39[Music]
  28649. 17:32:42query. So now there is like another
  28650. 17:32:45alternative to stored procedures. Well,
  28651. 17:32:47you can go and put all your SQL
  28652. 17:32:49statements in a Python code and things
  28653. 17:32:52can work as well. So, either you put
  28654. 17:32:53your SQL statements inside the stored
  28655. 17:32:56procedure or in a Python code. But now
  28656. 17:32:58the big question is what are the
  28657. 17:33:00differences between them? Well, there is
  28658. 17:33:01like a disadvantage if you having Python
  28659. 17:33:03in different server because you have to
  28660. 17:33:05go and build a connection between your
  28661. 17:33:08server and the database server and
  28662. 17:33:10connection means always networking and
  28663. 17:33:12you might get slightly worse
  28664. 17:33:14performance. So this is one advantage
  28665. 17:33:16for the start procedure. Another
  28666. 17:33:18advantage for the search procedure that
  28667. 17:33:20all the scripts that you're going to
  28668. 17:33:21store inside the store procedure in the
  28669. 17:33:23database going to be pre-ompiled. So
  28670. 17:33:26pre-ompiled means the SQL database
  28671. 17:33:28servers knows already about your SQL
  28672. 17:33:31statements and there was already a check
  28673. 17:33:33whether all the syntaxes are correct and
  28674. 17:33:35the database as well going to be
  28675. 17:33:37preparing everything to execute the
  28676. 17:33:39stored procedure like maybe preparing
  28677. 17:33:41the execution plans and a lot of stuff.
  28678. 17:33:43So if you store your skill statements
  28679. 17:33:45inside store procedure in the database,
  28680. 17:33:47it is very close to the database and the
  28681. 17:33:49database knows everything about your
  28682. 17:33:51scripts and it is ready to execute it.
  28683. 17:33:53But if you put all your SQL statements
  28684. 17:33:55outside of the database, of course, the
  28685. 17:33:57database has no chance to understand
  28686. 17:34:00what is coming. So it cannot go and
  28687. 17:34:02compile anything until Python sends the
  28688. 17:34:05code to database. So this is another
  28689. 17:34:07advantage for the stored procedure. But
  28690. 17:34:09now if you build your SQL statements in
  28691. 17:34:12Python, you will get a lot of
  28692. 17:34:13advantages. Like for example, you can go
  28693. 17:34:15and build very flexible Python codes
  28694. 17:34:18where you can use Python features
  28695. 17:34:20together with the SQL and with that you
  28696. 17:34:22open the door of many possibilities and
  28697. 17:34:24flexibility. Another thing with Python,
  28698. 17:34:26you can make great version control. So
  28699. 17:34:29everything is integrated in Python
  28700. 17:34:31tools. And one more advantage is that if
  28701. 17:34:33you have a complex requirement in your
  28702. 17:34:35projects, it's going to be really hard
  28703. 17:34:36to implement it in stored procedures.
  28704. 17:34:38it's going to cost you a lot of lines of
  28705. 17:34:40code and things going to be not
  28706. 17:34:42comfortable. But if you are implementing
  28707. 17:34:44a complex logic in Python, things going
  28708. 17:34:47to be way easier. So with Python, you
  28709. 17:34:49can implement complex logics very easily
  28710. 17:34:52compared to the stored procedure. So
  28711. 17:34:54those are the big differences between
  28712. 17:34:55the stored procedure and Python. Now I
  28713. 17:34:57have to be honest with you about having
  28714. 17:34:59your code in store procedure or in
  28715. 17:35:01Python. Well, if you are working
  28716. 17:35:03together in a data project, I will never
  28717. 17:35:05recommend you to use stored procedure if
  28718. 17:35:07you have the possibility to have your
  28719. 17:35:09code in Python. And that's because I saw
  28720. 17:35:11a lot of projects using stored procedure
  28721. 17:35:13and most of them ends in chaos. It is
  28722. 17:35:16really hard to debug. It is really hard
  28723. 17:35:18to test. It's like catastrophic. So
  28724. 17:35:20really don't use in your projects any
  28725. 17:35:23store procedures. Especially if you have
  28726. 17:35:25like a big project and you have a lot of
  28727. 17:35:27data and tables and so on. You can
  28728. 17:35:29manage everything perfectly using
  28729. 17:35:31Python. Especially if you have platform
  28730. 17:35:33like data bricks or snowflakes then of
  28731. 17:35:36course the best way to control your data
  28732. 17:35:38projects is using Python. But of course
  28733. 17:35:40if you don't have this possibility and
  28734. 17:35:42you have only a database server and you
  28735. 17:35:44can only work with this then you don't
  28736. 17:35:46have any other option. You have to work
  28737. 17:35:47with the store procedures. But if you
  28738. 17:35:49have this possibility to put your
  28739. 17:35:51project inside Python and to run your
  28740. 17:35:53scripts from there, then it is way
  28741. 17:35:55better than having stored procedure.
  28742. 17:35:56Well, this is my opinion. I'm just
  28743. 17:35:58talking about working in projects in big
  28744. 17:36:00projects. But if you have like small
  28745. 17:36:02projects, few tables and so on, then
  28746. 17:36:04it's fine to stay with the store
  28747. 17:36:05procedure. But never build a big project
  28748. 17:36:07using stored procedures because I tell
  28749. 17:36:10you it will never work. So try to always
  28750. 17:36:13to think about to have the right
  28751. 17:36:14platform in order to run your projects.
  28752. 17:36:17And now I'm thinking about it. Maybe I
  28753. 17:36:19should have put this tip at the end of
  28754. 17:36:20the video, not in the middle. So
  28755. 17:36:22whatever. If you still want to learn
  28756. 17:36:24store procedures, we're going to
  28757. 17:36:25continue on that. And I'm going to have
  28758. 17:36:27like a really nice example about how to
  28759. 17:36:29build store procedures step by step like
  28760. 17:36:31having a mini projects. So why not
  28761. 17:36:33learning both of them. So let's
  28762. 17:36:38go. Okay. So now let's have a quick look
  28763. 17:36:40to the syntax of the store procedure. It
  28764. 17:36:42is very simple. So it has always two
  28765. 17:36:44parts. First we have to define the start
  28766. 17:36:46procedure. So we can do it like this.
  28767. 17:36:48Create procedure. Then we have to define
  28768. 17:36:50the procedure name and then we say as
  28769. 17:36:52and then we have begin and end. It's
  28770. 17:36:54very important for SQL to understand
  28771. 17:36:56when that definition starts and when it
  28772. 17:36:58ends. And then between the begin and end
  28773. 17:37:00we're going to have a set of SQL
  28774. 17:37:02statements. So here you can insert
  28775. 17:37:04whatever you want. Insert update queries
  28776. 17:37:06anything. And once you have defined the
  28777. 17:37:08sort procedure the next step is that
  28778. 17:37:10we're going to go and execute it. So the
  28779. 17:37:12syntax is very simple. We're going to
  28780. 17:37:13say execute and then the procedure name.
  28781. 17:37:15So that's it with that SSQL going to go
  28782. 17:37:17to the S procedure and start executing
  28783. 17:37:19all the SQL statements that you have in
  28784. 17:37:21the definition. So this is the syntax of
  28785. 17:37:23the S procedure. As I said it is very
  28786. 17:37:25simple. All right guys. So now let's do
  28787. 17:37:27it step by step. The first step is that
  28788. 17:37:29we're going to go and write a query. So
  28789. 17:37:31let's say that we have a very simple
  28790. 17:37:32task and it says for US customers find
  28791. 17:37:35the total number of customers and the
  28792. 17:37:38average score. So let's go and do it.
  28793. 17:37:40It's very simple. So select count star
  28794. 17:37:44total customers and then the average of
  28795. 17:37:47scores as average score from our table
  28796. 17:37:52sales customers and then since it says
  28797. 17:37:55US customers we have to go and filter
  28798. 17:37:57the data based on the column country is
  28799. 17:38:00equal to USA. So that's it. This is our
  28800. 17:38:03query. Let's go and execute it. So we
  28801. 17:38:05have a very quick nice report about the
  28802. 17:38:07total number of customers and the
  28803. 17:38:08average score. So now let's say that I
  28804. 17:38:10have a weekly meeting and I have to
  28805. 17:38:12represent this reports over and over. So
  28806. 17:38:15that means I have to go and execute this
  28807. 17:38:17query like frequently in weekly basis in
  28808. 17:38:20order to get the data for the reports.
  28809. 17:38:22So now what this means I have to go and
  28810. 17:38:24save this query in order to use it later
  28811. 17:38:27that each time I have to rewrite it. So
  28812. 17:38:29that means I have to store this text
  28813. 17:38:30somewhere that I don't go and rewrite
  28814. 17:38:33the query over and over. So what I
  28815. 17:38:35usually do, let's go and we copy the
  28816. 17:38:37whole query and then we create a new
  28817. 17:38:40text and let's say it's going to be my
  28818. 17:38:41weekly query and it's going to be SQL.
  28819. 17:38:45So I'm going to go and edit it and here
  28820. 17:38:48I'm going to save my query and each time
  28821. 17:38:50I need this query I have to go and copy
  28822. 17:38:52it, go back to my SQL and then I'm going
  28823. 17:38:55to go and paste it in order to execute
  28824. 17:38:58it. So either going to write it each
  28825. 17:38:59time or copy and paste it. Well, we
  28826. 17:39:02don't have to do that. we have start
  28827. 17:39:04procedures. So that means we're going to
  28828. 17:39:06go to the step two where we're going to
  28829. 17:39:07turn this query into a store procedure.
  28830. 17:39:10So let's do that. It's very simple. So
  28831. 17:39:12we're going to say create procedure. And
  28832. 17:39:15now we have to go and give it a name. So
  28833. 17:39:16it's going to be get customer summary.
  28834. 17:39:19And then after that we're going to say
  28835. 17:39:21as and then we need the begin and end.
  28836. 17:39:23And in between we're going to put our
  28837. 17:39:25query. So let's go and copy our query
  28838. 17:39:28and just put it in between. So that's
  28839. 17:39:31it. Let's go and execute it. And with
  28840. 17:39:33that we have created our store
  28841. 17:39:35procedure. And now in order to see our
  28842. 17:39:37store procedure we can go to the object
  28843. 17:39:39explorer to our database sales DB. And
  28844. 17:39:41then here we have a folder called
  28845. 17:39:43programmability. So let's go inside it.
  28846. 17:39:45And here we have a lot of stuff like
  28847. 17:39:47functions, triggers and we have stored
  28848. 17:39:49procedures. So let's go inside it. And
  28849. 17:39:51we can see over here this is our new
  28850. 17:39:53created stored procedure. So we are
  28851. 17:39:56almost there. The next step is that
  28852. 17:39:58we're going to go and call our store
  28853. 17:39:59procedure. And this is the easiest part.
  28854. 17:40:02So it's going to be execute the stored
  28855. 17:40:04procedure. And the syntax is very
  28856. 17:40:05simple. So execute and then the name of
  28857. 17:40:08the stored procedure. So get customer
  28858. 17:40:11summary. So let's go and execute it. And
  28859. 17:40:14with that as you can see we get the
  28860. 17:40:16result of our query. So as you can see
  28861. 17:40:18it is very simple. In just few steps we
  28862. 17:40:21created a store procedure. And then in
  28863. 17:40:23the future you don't need the whole
  28864. 17:40:24thing. You just go and execute the store
  28865. 17:40:27procedure. I don't have to store the
  28866. 17:40:29query locally at my PC or to copy and
  28867. 17:40:32paste anything. If I want this report
  28868. 17:40:35now, I just have to execute the store
  28869. 17:40:37procedure like this and I will get the
  28870. 17:40:43results. Okay. So now let's keep moving.
  28871. 17:40:45Now we're going to talk about the
  28872. 17:40:47parameters inside stored procedures. So
  28873. 17:40:49what is a parameter? It is like a
  28874. 17:40:52placeholder where you can pass in
  28875. 17:40:53information from you into the store
  28876. 17:40:56procedure while running it and using
  28877. 17:40:58parameters in store procedure it's going
  28878. 17:41:00to make it flexible reusable and
  28879. 17:41:03dynamic. So let's understand what this
  28880. 17:41:05means. Let's say that you got a new
  28881. 17:41:07task. So it says for German customers
  28882. 17:41:10find the total number of customers and
  28883. 17:41:12the average score. So that means now we
  28884. 17:41:14have like to generate two reports one
  28885. 17:41:16for USA and one for Germany. And in both
  28886. 17:41:18of them you are doing the same
  28887. 17:41:19aggregation. And again we have to go and
  28888. 17:41:21start writing the query. It's going to
  28889. 17:41:23be very similar to the one that we have
  28890. 17:41:24in the previous example. So we are doing
  28891. 17:41:26the same stuff same aggregations but the
  28892. 17:41:29only change here is that we're going to
  28893. 17:41:31use another value to filter the data. So
  28894. 17:41:33instead of USA we're going to go and say
  28895. 17:41:35here Germany. So let's go and execute
  28896. 17:41:38this one over here. And with that we can
  28897. 17:41:39see we have total number of customers
  28898. 17:41:41too. So this is the report that we have
  28899. 17:41:43to provide like in weekly basis. And
  28900. 17:41:45again in order not to go and copy paste
  28901. 17:41:47stuff we're going to go and create a
  28902. 17:41:49store procedure for that. At the end
  28903. 17:41:51we're going to have an end. But now of
  28904. 17:41:53course we cannot have like the same
  28905. 17:41:54names we're going to go and say here
  28906. 17:41:56Germany. So let's go and execute it. And
  28907. 17:42:00the next step we have to go and execute
  28908. 17:42:02the store procedure. So like this. Let's
  28909. 17:42:06go and execute it. And the whole logic
  28910. 17:42:08now stored inside the database. Let's go
  28911. 17:42:10and refresh on the explorer over here.
  28912. 17:42:12And you can see now we have two stored
  28913. 17:42:14procedures. But now you have to feel
  28914. 17:42:16there is something wrong. Always in
  28915. 17:42:18programming and coding. If you find
  28916. 17:42:20yourself repeating the same task over
  28917. 17:42:22and over then there is always a smarter
  28918. 17:42:25way on how to optimize that. Repeating
  28919. 17:42:28stuff in coding is always bad thing. So
  28920. 17:42:30now clearly we are repeating the same
  28921. 17:42:32query in two different store procedure.
  28922. 17:42:34And now if you compare them you see it's
  28923. 17:42:36because of the value. So we have here
  28924. 17:42:38the value for the filter once Germany
  28925. 17:42:40and one USA. And those values are static
  28926. 17:42:43values. So it's always going to stay
  28927. 17:42:45inside the store procedure as USA. But
  28928. 17:42:47instead of that we can replace those
  28929. 17:42:49static values with a parameter. And then
  28930. 17:42:52you decide as you are executing the
  28931. 17:42:54stored procedure for which country you
  28932. 17:42:57want to execute the store procedure. So
  28933. 17:42:59let's go and do that. I'm just going to
  28934. 17:43:01remove everything from here and focus
  28935. 17:43:03only on the first store procedure. Now
  28936. 17:43:05what we're going to do after giving the
  28937. 17:43:07name of our store procedure we have to
  28938. 17:43:10define our parameter. So it start with
  28939. 17:43:13at and with that SQL understandhuh now
  28940. 17:43:15we are talking about parameters and we
  28941. 17:43:17need now the name of the parameter. So
  28942. 17:43:19it's going to be country. It could be
  28943. 17:43:21any name that you want and after that we
  28944. 17:43:23have to define for SQL the data type.
  28945. 17:43:25It's like when you are creating a table
  28946. 17:43:27and you define columns you assign a data
  28947. 17:43:29type for each column. The same thing
  28948. 17:43:31here you have to assign as well a data
  28949. 17:43:33type for each parameter. So we're going
  28950. 17:43:35to use the data type in var and for the
  28951. 17:43:38countries it's enough to have the length
  28952. 17:43:39of 50. So with that we are telling SQL
  28953. 17:43:42for this third procedure we can pass an
  28954. 17:43:45information to the store procedure and
  28955. 17:43:47this information and value going to be
  28956. 17:43:49used inside this parameter. So now after
  28957. 17:43:51we defined this parameter over here we
  28958. 17:43:54can go and use it anywhere inside our
  28959. 17:43:56query. And of course we want to go and
  28960. 17:43:58use it instead of this static value. So
  28961. 17:44:00now we're going to remove this static
  28962. 17:44:02value and instead we're going to have
  28963. 17:44:04the parameter. So now we are saying
  28964. 17:44:06you're going to filter the table based
  28965. 17:44:08on the value that comes from the user
  28966. 17:44:10and not anymore static with a USA. And
  28967. 17:44:12as I said you can use this parameter
  28968. 17:44:15everywhere like even here in the select
  28969. 17:44:16statements. So it is a value that could
  28970. 17:44:18be used everywhere in your query. So
  28971. 17:44:20that's it. We have defined our new
  28972. 17:44:22parameter and we have used this
  28973. 17:44:25parameter in our query. So now we have
  28974. 17:44:26to go and update the store procedure. We
  28975. 17:44:29cannot leave it as create. Instead of
  28976. 17:44:31that, we're going to say alter. So we
  28977. 17:44:32are saying alter procedure and with the
  28978. 17:44:35new informations. Let's go and execute
  28979. 17:44:37it. And now we have to go and execute
  28980. 17:44:40it. So now what we're going to do, we're
  28981. 17:44:41going to say execute get customer
  28982. 17:44:43summary. But now our store procedure is
  28983. 17:44:45expecting a value from you from the
  28984. 17:44:47input. So we're going to do it exactly
  28985. 17:44:48like we done in the name over here. So
  28986. 17:44:51we're going to say the parameter country
  28987. 17:44:53is equal
  28988. 17:44:54to Germany. So that means the value of
  28989. 17:44:58this parameter come from me come from
  28990. 17:45:00the input and this information going to
  28991. 17:45:02be passed to my query to the store
  28992. 17:45:04procedure. So let's go and execute it.
  28993. 17:45:06And with that as you can see we are
  28994. 17:45:08getting the report of customers for
  28995. 17:45:10Germany. And now if you say okay let's
  28996. 17:45:12go and generate the report for USA. All
  28997. 17:45:14what you have to do is replace the
  28998. 17:45:17parameter. So in the value instead of
  28999. 17:45:19Germany we're going to say USA. So let's
  29000. 17:45:22go and execute it. Great. Now we are
  29001. 17:45:24getting as well the report for us
  29002. 17:45:26customers. So that seems my friends for
  29003. 17:45:29those two reports I just need one store
  29004. 17:45:31procedure and with the help of the
  29005. 17:45:32parameter I made my store procedure now
  29006. 17:45:35more flexible and professional. So this
  29007. 17:45:37is exactly the power of the parameters
  29008. 17:45:40it makes everything reusable and
  29009. 17:45:43dynamic. And now of course we don't need
  29010. 17:45:45the store procedure for Germany. So what
  29011. 17:45:47we can do we can go and drop it. So
  29012. 17:45:49we're going to say drop procedure and it
  29013. 17:45:53was like this Germany. So we don't need
  29014. 17:45:56this store procedure and we're going to
  29015. 17:45:58stay with only one dynamic store
  29016. 17:46:00procedure. So this is how to use
  29017. 17:46:02parameters in store procedure and why
  29018. 17:46:04it's important. Okay. So now to the next
  29019. 17:46:06step is that we can go and add default
  29020. 17:46:08values for the parameters. So let's say
  29021. 17:46:11that I execute very frequently this
  29022. 17:46:13report where I say the country equal to
  29023. 17:46:14USA and I don't want each time to define
  29024. 17:46:17the parameter value equal to USA. So if
  29025. 17:46:20you are using a value very frequently
  29026. 17:46:22you can add it as a default inside the
  29027. 17:46:24definition of the store procedure and it
  29028. 17:46:26is very simple. So if you go to the
  29029. 17:46:28definition again over here after the
  29030. 17:46:30parameter and you say equal to USA. So
  29031. 17:46:34now it's very important to understand
  29032. 17:46:35that the country will not be always
  29033. 17:46:38equal to USA. It is just you are saying
  29034. 17:46:40if I don't get from the user any value
  29035. 17:46:43then as a default I'm going to go and
  29036. 17:46:45use the USA. So let's go and again
  29037. 17:46:48change the definition of our stored
  29038. 17:46:50procedure using alter. So execute and
  29039. 17:46:52now we can go to our store procedure and
  29040. 17:46:55I can skip the whole thing over here and
  29041. 17:46:57execute it. So now as a default I'm
  29042. 17:46:59getting the report of USA without
  29043. 17:47:02passing an information to the store
  29044. 17:47:03procedure because I know it is as a
  29045. 17:47:05default USA. But if you need it as a
  29046. 17:47:08Germany of course you have to go and
  29047. 17:47:10define it. So you say execute the store
  29048. 17:47:12procedure where the country equal to
  29049. 17:47:14Germany. So if you execute it like this
  29050. 17:47:16SQL still going to use your value. So
  29051. 17:47:18the value that comes as an input from
  29052. 17:47:20the user has more priority of course as
  29053. 17:47:22the defaults. And with that we are
  29054. 17:47:24getting the Germany reports. So as you
  29055. 17:47:26can see it's really nice right using
  29056. 17:47:27parameters in store
  29057. 17:47:32procedure. All right moving on to the
  29058. 17:47:34next step. Now we can work with multiple
  29059. 17:47:36queries inside one stored procedure. And
  29060. 17:47:39this is what we have learned at the
  29061. 17:47:40start. We can have multiple SQL
  29062. 17:47:42statements in one stored procedure. And
  29063. 17:47:44now we have a new report and query to
  29064. 17:47:46generate. It says find the total number
  29065. 17:47:49of orders and the total sales. So let's
  29066. 17:47:51do it quickly. We can write it like
  29067. 17:47:53this.
  29068. 17:47:54Select counts order ID. This is the
  29069. 17:47:58total orders and then the sum of sales.
  29070. 17:48:03Total sales from our table sales orders.
  29071. 17:48:07And of course we are always creating a
  29072. 17:48:09report based on specific country. So
  29073. 17:48:11that means we have to go and join it
  29074. 17:48:12with the customers table in order to
  29075. 17:48:15filter the data. So on customer ID equal
  29076. 17:48:19to the customer id. And now we're going
  29077. 17:48:22to go and filter the data. So country
  29078. 17:48:25equal to USA. So something like this.
  29079. 17:48:28Let's go and execute it. And with that
  29080. 17:48:31for the US customers, we have six orders
  29081. 17:48:33and the total sales 180. And of course,
  29082. 17:48:36the same thing we're going to do for
  29083. 17:48:37Germany. So now, of course, we will not
  29084. 17:48:39go and create an extra store procedure.
  29085. 17:48:41For this, we're going to go and put
  29086. 17:48:42everything in one store procedure. So
  29087. 17:48:44let's go and copy the whole thing and
  29088. 17:48:47put it here inside. So after the first
  29089. 17:48:50report we're going to have the second
  29090. 17:48:51report and now the best practice here if
  29091. 17:48:53you have multiple queries in store
  29092. 17:48:55procedure go and add at the end of each
  29093. 17:48:58query a semicolon. It is just easier to
  29094. 17:49:00understand how now this is the end of
  29095. 17:49:02this query especially if you have like a
  29096. 17:49:04big complex queries where you have CTE
  29097. 17:49:07union and so on. It's going to be really
  29098. 17:49:09hard to understand that we are talking
  29099. 17:49:11now about completely new query but it is
  29100. 17:49:13not like something the database requires
  29101. 17:49:15it but it's just easier to read. So just
  29102. 17:49:18add semicolons at the end of each query.
  29103. 17:49:21So now let's go and execute the whole
  29104. 17:49:23thing in order to change the definition
  29105. 17:49:25of our query. And one more thing of
  29106. 17:49:27course don't forget we don't need static
  29107. 17:49:29values over here. We're going to go and
  29108. 17:49:30add our nice
  29109. 17:49:32parameters. So add country. So I think
  29110. 17:49:36with that we have everything is ready to
  29111. 17:49:38be executed. So let's go and change the
  29112. 17:49:40definition of our store procedure. And
  29113. 17:49:42now let's go and start with the defaults
  29114. 17:49:44where the country equal to USA. So let's
  29115. 17:49:47go and execute it. And now in the output
  29116. 17:49:49as you can see we have two results. And
  29117. 17:49:51that's because we have two queries. So
  29118. 17:49:53the first report is for the first query
  29119. 17:49:55and the second one for the new one that
  29120. 17:49:57we just created. And the same thing if
  29121. 17:49:59you go and execute the store procedure
  29122. 17:50:01for Germany we will get as well two
  29123. 17:50:03results. And here we can see we have
  29124. 17:50:04four orders and 200 of total sales for
  29125. 17:50:07Germany. So as you can see it's very
  29126. 17:50:09simple. You can go now and add multiple
  29127. 17:50:11SQL statements not only queries you can
  29128. 17:50:14go and update you can do an insert
  29129. 17:50:16delete any kind of SQL statements you
  29130. 17:50:19can just go and add it inside your
  29131. 17:50:21program. And as usual SQL going to
  29132. 17:50:23execute it from the top to the bottom.
  29133. 17:50:25So since this is the first SQL statement
  29134. 17:50:27it's going to execute it first and then
  29135. 17:50:29after that it's going to go to the next
  29136. 17:50:31one. So this is how you can add multiple
  29137. 17:50:33SQL statements to your store
  29138. 17:50:39procedure. All right everyone. So now
  29139. 17:50:40we're going to talk about the variables.
  29140. 17:50:42So what is a variable? It is like a
  29141. 17:50:44placeholder where you store inside it a
  29142. 17:50:46value in order to use it later inside
  29143. 17:50:49your stored procedure. So that means
  29144. 17:50:51variable holds like a value inside the
  29145. 17:50:53memory and you can reuse it everywhere
  29146. 17:50:55you want inside your stored procedure
  29147. 17:50:57but it's not like the parameters.
  29148. 17:50:59Parameters are something like outside
  29149. 17:51:01the store procedure. It's an input from
  29150. 17:51:03the one that is executing the store
  29151. 17:51:05procedure and the store procedure has to
  29152. 17:51:07adapt with the parameter. But a variable
  29153. 17:51:10it's something that lives inside the
  29154. 17:51:12store procedure and we use it as a
  29155. 17:51:14developers in order to make our code
  29156. 17:51:15dynamic and to move a value from one
  29157. 17:51:17place to another. So let's have a very
  29158. 17:51:19simple example now. Let's say that we
  29159. 17:51:21don't want our report here about the
  29160. 17:51:23total customers as a query. So I don't
  29161. 17:51:25want it as a result in the output. Let's
  29162. 17:51:27say I'm generating a report always like
  29163. 17:51:29this. We are saying the total customers
  29164. 17:51:31from Germany equal to two and the
  29165. 17:51:33average score from Germany is equal to
  29166. 17:51:35425. So I need it as a text not as a
  29167. 17:51:38table like here. So in order to do that
  29168. 17:51:40we can use the TSQL print in order to
  29169. 17:51:43give a message after executing the store
  29170. 17:51:45procedure. So the syntax of print is
  29171. 17:51:47very simple. So we can go over here and
  29172. 17:51:50say print and then we have single quotes
  29173. 17:51:53and let's go and get the whole message
  29174. 17:51:54from here without the comments and then
  29175. 17:51:57the semicolon and we can repeat that for
  29176. 17:52:01the second message. So for the average
  29177. 17:52:04score and we put it over here as well a
  29178. 17:52:07semicolon. Now if you do it like this
  29179. 17:52:10this message going to be always static.
  29180. 17:52:12So we will have always like two for the
  29181. 17:52:14total customers and the average score
  29182. 17:52:16going to always be like this even though
  29183. 17:52:18that the data is changing. So we cannot
  29184. 17:52:20have it static like this. We have to
  29185. 17:52:22make it dynamic and especially if we are
  29186. 17:52:24calling this function for USA. So we
  29187. 17:52:26cannot have it here as a Germany. So
  29188. 17:52:28let's see how we can make this dynamic.
  29189. 17:52:30Now let's start with the easy stuff.
  29190. 17:52:32Instead of the Germany over here we can
  29191. 17:52:34go and put our parameter right. So
  29192. 17:52:36instead of this so we're going to say at
  29193. 17:52:39country but now the problem is it is
  29194. 17:52:41part of the whole string we cannot do
  29195. 17:52:43that so we're going to stop the text and
  29196. 17:52:46you can see the coloring is changing and
  29197. 17:52:47then have a plus in order to have
  29198. 17:52:49concatenations. So this text comes first
  29199. 17:52:52then the value from the country and then
  29200. 17:52:55we're going to have as well the double
  29201. 17:52:56point as a static text and again a
  29202. 17:52:59concatenation and then we have the two
  29203. 17:53:00we can talk about later. So let's do the
  29204. 17:53:02same stuff over here. So we're going to
  29205. 17:53:04say plus add country caring is not
  29206. 17:53:07changing because of this code. So let me
  29207. 17:53:09just remove it and then afterward plus
  29208. 17:53:12make it static again plus and remove the
  29209. 17:53:15final quotes. So with that in the
  29210. 17:53:17message we have now dynamic where we get
  29211. 17:53:19the value of the country from the
  29212. 17:53:21parameter. And now we come to the
  29213. 17:53:23interesting part. We have here an issue
  29214. 17:53:25those two values they come from this
  29215. 17:53:27query. And of course we cannot use a
  29216. 17:53:29parameter for that. We have to use now
  29217. 17:53:31the variables. Now in order to make a
  29218. 17:53:33variables we have three steps. The first
  29219. 17:53:35step is that we have to tell SQL about
  29220. 17:53:38our new variable. So SQL can prepare and
  29221. 17:53:40make like placeholder for it in the
  29222. 17:53:42memory. So we have to tell and prepare
  29223. 17:53:44it with our new variables. Now usually
  29224. 17:53:47we do all the declarations of our
  29225. 17:53:49variables at the start of the store
  29226. 17:53:51procedure immediately after begin. So
  29227. 17:53:53that means we're going to go over here
  29228. 17:53:54and say declare and now after that it's
  29229. 17:53:58like the parameters. It's very simple.
  29230. 17:53:59So at total customers. So this is the
  29231. 17:54:03name of the variable. And after that we
  29232. 17:54:04have to define the data type. Of course
  29233. 17:54:06you have to understand the data type
  29234. 17:54:08from the query. Since we are saying
  29235. 17:54:10count star then the output going to be
  29236. 17:54:12an integer. That's why we're going to
  29237. 17:54:13write it like this. So integer. And now
  29238. 17:54:15we need another one for the average. So
  29239. 17:54:18what we're going to do we're going to
  29240. 17:54:19make a comma. Now we are declaring
  29241. 17:54:21another variable. So at average score
  29242. 17:54:24and the data type of this one going to
  29243. 17:54:26be float because we have an average. So
  29244. 17:54:29that's it for the first step. We are
  29245. 17:54:30telling SQL we have two variables and
  29246. 17:54:32SQL going to go and create an empty
  29247. 17:54:34placeholder. So now in the second step
  29248. 17:54:36we have to give our variables a value.
  29249. 17:54:39So where we going to get the values?
  29250. 17:54:40We're going to get it from the query. So
  29251. 17:54:42let's do that. Now let's start with the
  29252. 17:54:44first column. As you can see we have
  29253. 17:54:45here the count star. And as we learned
  29254. 17:54:47anything that we write on the right
  29255. 17:54:49side, it going to be like an alias for
  29256. 17:54:51the column. But in SQL if you go and
  29257. 17:54:53write something before it, it going to
  29258. 17:54:55be the variable. So we can do it like
  29259. 17:54:58this. at total customers and then equal.
  29260. 17:55:02So now we are saying whatever value this
  29261. 17:55:04query returns it should be stored inside
  29262. 17:55:06my new variable so that I'm assigning
  29263. 17:55:09values to my variable. But here there is
  29264. 17:55:12one thing that we cannot have any more
  29265. 17:55:13aliases because our query will not
  29266. 17:55:16return any results. Our query have now
  29267. 17:55:19only one task to assign values to my
  29268. 17:55:21variables. So that's why we cannot have
  29269. 17:55:23it like this. We have to remove the
  29270. 17:55:24alias. And the same thing we're going to
  29271. 17:55:25do it for the average. So at average
  29272. 17:55:29score equal to the average score and we
  29273. 17:55:32have to remove the alias. So that's it.
  29274. 17:55:34Now our query having different purpose.
  29275. 17:55:36It is not for returning result. It is to
  29276. 17:55:39assign values to our variables. So now
  29277. 17:55:42we have values in the next step we have
  29278. 17:55:43to go and use it. And we can use our
  29279. 17:55:45variables everywhere inside our store
  29280. 17:55:47procedure. So it could be in the print,
  29281. 17:55:49it could be in the next query. So in any
  29282. 17:55:51select statements in any place.
  29283. 17:55:53Sometimes we use variables in order to
  29284. 17:55:55pass an information from one query to
  29285. 17:55:58another one. But in this example, we
  29286. 17:55:59want to use our variables inside the
  29287. 17:56:02prints. So it is very simple. We now
  29288. 17:56:03we're going to go and replace the static
  29289. 17:56:06number and it's like the parameter.
  29290. 17:56:07We're going to say at total customers
  29291. 17:56:11and the same thing for the average at
  29292. 17:56:14average score. So that's it. It's very
  29293. 17:56:17simple. So again the step one we have to
  29294. 17:56:19declare them to define it for SQL and
  29295. 17:56:21with that we're going to get an empty
  29296. 17:56:22variable. The second step we have to add
  29297. 17:56:25values to those variables and the last
  29298. 17:56:27step we have to go and use those
  29299. 17:56:28variables. So it makes sense right now
  29300. 17:56:31if you check our message over here you
  29301. 17:56:33can see that everything is dynamic and
  29302. 17:56:35we don't have any static values but
  29303. 17:56:37there is one more thing that's in the
  29304. 17:56:39print everything should be as a string.
  29305. 17:56:41So we cannot have dates numbers floats
  29306. 17:56:43and so on. So that's why you have to
  29307. 17:56:45make check if you're adding any
  29308. 17:56:46parameter and variables all of them
  29309. 17:56:48should be string. So the country it is
  29310. 17:56:51okay because we have the data type of
  29311. 17:56:53varchar but the total number and the
  29312. 17:56:55average score this is not really good
  29313. 17:56:58because they have different data type
  29314. 17:56:59and we have to go and now cast those
  29315. 17:57:01data types to another one. So we're
  29316. 17:57:04going to say cast and we're going to say
  29317. 17:57:05here as invar so that we don't get any
  29318. 17:57:09errors from SQL. So cast as well here as
  29319. 17:57:12in
  29320. 17:57:14vchar like this. All right. So I think
  29321. 17:57:17we are ready. Let's go and change the
  29322. 17:57:20definition of our store procedure in
  29323. 17:57:21order to test. So let's go and execute.
  29324. 17:57:23Perfect. And now let's go and test. So
  29325. 17:57:26let's start with the defaults where we
  29326. 17:57:27have the parameter as USA. So now as you
  29327. 17:57:30can see we are getting one result and
  29328. 17:57:32this is from the second query. So the
  29329. 17:57:34first query is not returning anything
  29330. 17:57:36anymore in the output. But if you go to
  29331. 17:57:38the messages over here, you can see we
  29332. 17:57:40have a new message. It says total
  29333. 17:57:42customers from USA is equal to three and
  29334. 17:57:45the average score from USA is equal to
  29335. 17:57:48825. And this is exactly what we wanted
  29336. 17:57:51for our reports. Now let's go and
  29337. 17:57:53execute the parameter equal to Germany.
  29338. 17:57:56Again, we have only one result. And in
  29339. 17:57:58the messages, we're going to get total
  29340. 17:57:59customers from Germany is equal to two
  29341. 17:58:01and the average score from Germany is
  29342. 17:58:03equal to 425. So this is exactly how we
  29343. 17:58:06work with the variables. We use it in
  29344. 17:58:08order to hold one information in one
  29345. 17:58:10place in order to reuse it later in
  29346. 17:58:13different place. So that's it for
  29347. 17:58:15[Music]
  29348. 17:58:18variables. All right everyone. Now we're
  29349. 17:58:20going to talk about how to control the
  29350. 17:58:21flow in your store procedure and we're
  29351. 17:58:24going to learn how to do that using the
  29352. 17:58:25if else statements. So now let's have
  29353. 17:58:27the following scenario. Now if you check
  29354. 17:58:29our query over here we are doing the
  29355. 17:58:31average of score and if you check the
  29356. 17:58:33data you can see that in the scores we
  29357. 17:58:36have nulls and nulls are really bad for
  29358. 17:58:38aggregations. So we usually have to
  29359. 17:58:40clean up our data before doing any
  29360. 17:58:42aggregations. And in this scenario we
  29361. 17:58:45can understand null as a zero. And how
  29362. 17:58:47we going to clean up and handle the
  29363. 17:58:48data? We're going to go and make an
  29364. 17:58:50update on our table where we say if
  29365. 17:58:52there is like a null then make it as a
  29366. 17:58:55zero. And we will do this as a pre-step
  29367. 17:58:57inside our store procedure. So that
  29368. 17:58:59means first we have to clean up the data
  29369. 17:59:02and then afterward we're going to
  29370. 17:59:03generate the reports. And this is what
  29371. 17:59:05we usually do inside SQL projects. So
  29372. 17:59:08the logic going to be very simple. We
  29373. 17:59:10have to check first do we have nulls
  29374. 17:59:11inside the score. If the answer is yes
  29375. 17:59:14then we have to go and update the null
  29376. 17:59:16values to zero. But if the answer is no,
  29377. 17:59:18we don't have any values then we can
  29378. 17:59:20skip everything. So now we're going to
  29379. 17:59:22go and build this logic inside our store
  29380. 17:59:24procedure in order to clean up and
  29381. 17:59:26prepare the data. So let's go. Okay. So
  29382. 17:59:28now this part we're going to call it
  29383. 17:59:31generating
  29384. 17:59:33reports and we're going to have another
  29385. 17:59:35part called prepare and clean up data.
  29386. 17:59:40So now let's prepare first the structure
  29387. 17:59:42of the if statements. So the syntax
  29388. 17:59:44going to look like this. So if and then
  29389. 17:59:46begin and end. So this is the block of
  29390. 17:59:50the if and we're going to do the same
  29391. 17:59:51thing for the else. So we have else and
  29392. 17:59:54we have begin and end. Let me just
  29393. 17:59:56separate them. So now how this works? We
  29394. 17:59:58have to create a condition. If the
  29395. 18:00:00condition is met then the if statement
  29396. 18:00:03going to be executed. But if the
  29397. 18:00:04condition is not fulfilled and we have
  29398. 18:00:06false then the else statement going to
  29399. 18:00:08be executed. So what is the condition?
  29400. 18:00:10We have to check whether there is null
  29401. 18:00:12inside the scores. So let's write a very
  29402. 18:00:15simple query. It's going to say select
  29403. 18:00:17one from sales
  29404. 18:00:21customers where score is null and always
  29405. 18:00:25we have to check the country equal to
  29406. 18:00:28let's say USA. So let's go and execute
  29407. 18:00:31this one over here. So now we are
  29408. 18:00:32getting in the output a results. If we
  29409. 18:00:34are getting a results that means
  29410. 18:00:36somewhere there are nulls. But if you go
  29411. 18:00:39for example and say here Germany and
  29412. 18:00:41execute the same query in the output you
  29413. 18:00:44see that we don't have any results. That
  29414. 18:00:46means for the German customers we don't
  29415. 18:00:48have any nulls in their scores. So if
  29416. 18:00:51this query returns something we have
  29417. 18:00:53nulls. If it didn't return anything then
  29418. 18:00:55there is no nulls. And we're going to
  29419. 18:00:57use exactly this query as a condition.
  29420. 18:01:00So we're going to take our check and say
  29421. 18:01:02if exists and then two parenthesis and
  29422. 18:01:05then we put our query. So what we are
  29423. 18:01:07saying if exist if this query return
  29424. 18:01:10anything then go and execute the next
  29425. 18:01:12block and if it is not exist that means
  29426. 18:01:15it is not returning anything then go and
  29427. 18:01:17execute the second block. So it's a
  29428. 18:01:19logic right it's very simple now of
  29429. 18:01:20course instead of having a static value
  29430. 18:01:22over here we can use our parameter so at
  29431. 18:01:25country and now we have to tell SQL what
  29432. 18:01:27to do if it exists. So in between we can
  29433. 18:01:31have like an update statement. So update
  29434. 18:01:33sales customers and we're going to set
  29435. 18:01:36the score equal to zero. But very
  29436. 18:01:39important we have to go and use where
  29437. 18:01:41condition otherwise it going to go and
  29438. 18:01:43update everything. The score is
  29439. 18:01:47null and the country equal to our
  29440. 18:01:50parameter country. So with that we are
  29441. 18:01:53updating exactly the nulls for specific
  29442. 18:01:55country. And let's have a semicolon at
  29443. 18:01:57the end. And at the start maybe I'm
  29444. 18:02:00going to say just to have a nice message
  29445. 18:02:01in the output print and we can have a
  29446. 18:02:04message updating null scores to zero and
  29447. 18:02:09as well a semicolon at the end. So if
  29448. 18:02:11there is any nulls then execute the
  29449. 18:02:13whole thing print the message and update
  29450. 18:02:15the table. So now the next step is that
  29451. 18:02:17we're going to go and tell SQL what can
  29452. 18:02:19happen if the condition is not
  29453. 18:02:20fulfilled. That means we don't have any
  29454. 18:02:22nulls. Well we don't have to update the
  29455. 18:02:24table at all because we don't have to
  29456. 18:02:26clean up anything. But I'm going to go
  29457. 18:02:28and make print over here. So print and
  29458. 18:02:31we're going to give the message no null
  29459. 18:02:34scores found. And at the last end I'm
  29460. 18:02:38going to go and put a semicolon. So
  29461. 18:02:40that's it. This is our logic. We are
  29462. 18:02:42checking our condition and then we
  29463. 18:02:44execute if the condition is met where we
  29464. 18:02:46update the table with zero instead of
  29465. 18:02:48null and if the condition is not met
  29466. 18:02:50then don't do anything. Just print a
  29467. 18:02:52message. Now you might say you know what
  29468. 18:02:54why you are doing this? we just can use
  29469. 18:02:56this update statements and we don't need
  29470. 18:02:57the whole if else statements. So why we
  29471. 18:02:59are checking in the first place? I can
  29472. 18:03:01like each time I run this store
  29473. 18:03:02procedure I go and update all the nulls
  29474. 18:03:05if they exist to a zero. Well, this is
  29475. 18:03:07not really professional because you are
  29476. 18:03:09wasting resources. So each time you run
  29477. 18:03:11an update statement like this. So
  29478. 18:03:14imagine that you have a big table and
  29479. 18:03:15each time you run your store procedure,
  29480. 18:03:17SQL have to go and check whether there
  29481. 18:03:19is any nulls and so on. And this is of
  29482. 18:03:22course consume resources. It's way
  29483. 18:03:24better if you go and check first whether
  29484. 18:03:26it's really needed. So that's why we are
  29485. 18:03:28doing this logic. Now as you can see our
  29486. 18:03:30store procedure is getting bigger and
  29487. 18:03:32bigger. So we have like two parts. The
  29488. 18:03:34first part is preparing and cleaning up
  29489. 18:03:37the data. And the second part we are
  29490. 18:03:39generating reports. Let's go and update
  29491. 18:03:41the whole thing and execute it. And now
  29492. 18:03:44we have to do it step by step. So let's
  29493. 18:03:46check our query over here. And you can
  29494. 18:03:47see we have here null for USA customers.
  29495. 18:03:50So let's go first execute it for the USA
  29496. 18:03:53as a defaults. And now let's go and
  29497. 18:03:55check the messages. It's saying updating
  29498. 18:03:57null scores to zero. That means the
  29499. 18:04:00first block is executed because SQL did
  29500. 18:04:03find a customer with a null. And with
  29501. 18:04:06that the average of scores going to be
  29502. 18:04:08different than previously. So we have
  29503. 18:04:10now more accurate average in our
  29504. 18:04:13reports. So if you go and check our
  29505. 18:04:15query again, you can see now we have a
  29506. 18:04:16zero instead of null. Let's go and
  29507. 18:04:19execute it for Germany like this. And
  29508. 18:04:21let's go and check the messages. It says
  29509. 18:04:23no null scores found. And that is
  29510. 18:04:25correct because for Germany we don't
  29511. 18:04:28have any nulls. So with that we have
  29512. 18:04:30created a control flow using the FL
  29513. 18:04:33statements. And as you can see we are
  29514. 18:04:34not doing any more like simple queries.
  29515. 18:04:36We are creating like a mini program. And
  29516. 18:04:39now it's like an ETL where first we
  29517. 18:04:41prepare the data and second we generate
  29518. 18:04:43reports. And you can imagine a real
  29519. 18:04:45project how big those stored procedures
  29520. 18:04:47going to get where you have a lot of
  29521. 18:04:49tables and a lot of things to
  29522. 18:04:54do. Okay. So now we're going to talk
  29523. 18:04:56about the error handling in store
  29524. 18:04:58procedure. Error handling it is like
  29525. 18:05:00essential things to do while programming
  29526. 18:05:02because it gives you the control on what
  29527. 18:05:04can happen once you have an error. And
  29528. 18:05:07there's a lot of things that you can do
  29529. 18:05:08like maybe deleting data, printing a
  29530. 18:05:11very structured like message or maybe
  29531. 18:05:13doing some logging and so on. So you
  29532. 18:05:15have a full control on what to do if
  29533. 18:05:18there is an error and of course we can
  29534. 18:05:19do that in the store procedure. So now
  29535. 18:05:21let's check the quickly the syntax. It
  29536. 18:05:23is usually has two parts. The first part
  29537. 18:05:26is the try part. So the syntax is like
  29538. 18:05:28this begin try end try. So you are
  29539. 18:05:31defining the boundaries of the try and
  29540. 18:05:33in between you going to have all your
  29541. 18:05:35SQL statements and your code and the
  29542. 18:05:37second part going to be the catch parts.
  29543. 18:05:39So you say begin catch and end catch. So
  29544. 18:05:42you are defining the boundaries and then
  29545. 18:05:44in between you can tell SQL what to do
  29546. 18:05:46if there is like an error. So what is
  29547. 18:05:48try and catch? Like the word it says try
  29548. 18:05:51it's like you are attempt to do
  29549. 18:05:52something that might fail. So you are
  29550. 18:05:54telling SQL try to execute this code. So
  29551. 18:05:57the SQL going to go and try to execute
  29552. 18:06:00your codes. And if any error happens
  29553. 18:06:02while executing your codes, the SQL
  29554. 18:06:04going to jump to the second block and
  29555. 18:06:06start doing whatever you have defined in
  29556. 18:06:08the catch. But if there is no errors at
  29557. 18:06:11all, this part will not be executed. So
  29558. 18:06:14the catch is like your backup plan. If
  29559. 18:06:16something goes wrong here, then go to
  29560. 18:06:18the plan B and do something. So let's
  29561. 18:06:20see the workflow of the try catch. So
  29562. 18:06:22first the SQL going to go and execute
  29563. 18:06:24the try and then it going to check is
  29564. 18:06:26there any error. If we don't have any
  29565. 18:06:28error then everything ends and that's
  29566. 18:06:30it. But while execution if the SQL face
  29567. 18:06:33any error what going to happen it going
  29568. 18:06:35to go and execute the catch. So as you
  29569. 18:06:37can see the workflow is very simple and
  29570. 18:06:39this is what we mean with try and catch.
  29571. 18:06:41So let's go back to SQL to have some
  29572. 18:06:43example. All right. So now back to our
  29573. 18:06:45store procedure. Let's go and introduce
  29574. 18:06:47an error inside our code. So let's go
  29575. 18:06:49over here and maybe in our query we're
  29576. 18:06:52going to go and divide by zero which is
  29577. 18:06:55of course a problem. So we have this
  29578. 18:06:57error over here and let's go and update
  29579. 18:07:00the logic of our store procedure. And
  29580. 18:07:03now if you go and execute it. So let's
  29581. 18:07:05go and do that. We will get an error
  29582. 18:07:07saying yeah you cannot divide by zero.
  29583. 18:07:10But now what I would like to do I would
  29584. 18:07:11like to have something else where we
  29585. 18:07:12have customized message when error
  29586. 18:07:14happens. So I would like to have the
  29587. 18:07:16control on which information should be
  29588. 18:07:18displayed if there is an issue. And in
  29589. 18:07:20order to do that we have to use the try
  29590. 18:07:22and catch. So it's going to be very
  29591. 18:07:23simple. Now this is my whole code. So
  29592. 18:07:26the whole thing from preparing to
  29593. 18:07:28generate the report the whole thing is
  29594. 18:07:30my code and we have to put the whole
  29595. 18:07:32thing in a try. So how to do that?
  29596. 18:07:34Exactly after the first begin we're
  29597. 18:07:37going to have another begin but for the
  29598. 18:07:39try. And now what we're going to do,
  29599. 18:07:40we're going to go to the last end over
  29600. 18:07:42here and have an end try. So with that
  29601. 18:07:46we put now the whole code inside the
  29602. 18:07:48try. And after that we're going to
  29603. 18:07:50introduce the catch. So begin catch and
  29604. 18:07:54end catch. And now in between we have to
  29605. 18:07:56tell SQL what can happen if we encounter
  29606. 18:07:59an error. And here we can do many stuff
  29607. 18:08:01but I would like now to focus on
  29608. 18:08:03customizing the error message. Let's
  29609. 18:08:05start with the first one. So I'm going
  29610. 18:08:06to say print let's say an error
  29611. 18:08:11accord. This is the first thing. Then on
  29612. 18:08:14the next line I'm going to print more
  29613. 18:08:16informations. And now we're going to say
  29614. 18:08:17the error message. So error message
  29615. 18:08:21double point space. And now we can go
  29616. 18:08:24and use some predefined functions from
  29617. 18:08:26SQL like for example the error
  29618. 18:08:29message. This function going to return
  29619. 18:08:31the description of the error like the
  29620. 18:08:33one we have here divide by zero error
  29621. 18:08:35encountered and we can go and keep
  29622. 18:08:37adding stuff the way that we need like
  29623. 18:08:41maybe the error
  29624. 18:08:43number. So we can have it like this and
  29625. 18:08:45for that we have as well a function
  29626. 18:08:46called error number and I think we have
  29627. 18:08:49to cast this one because it is a number
  29628. 18:08:51and in the messages we have to have only
  29629. 18:08:54vchar. So this going to be as int var
  29630. 18:08:58like this and we can keep adding stuff
  29631. 18:09:00to our message like for example let's
  29632. 18:09:03take the error line and for that we have
  29633. 18:09:05as well a function so it's going to be
  29634. 18:09:07the error
  29635. 18:09:09line like this and we have to cast
  29636. 18:09:12it because it is as well a number and as
  29637. 18:09:16well what is really important is the
  29638. 18:09:19name of the stored procedure. So error
  29639. 18:09:23procedure and we have a function for
  29640. 18:09:25that error procedure like this. It's
  29641. 18:09:29going to be a string. So that's why I
  29642. 18:09:31don't have to cast it. So now with that
  29643. 18:09:32we have defined for SQL what to do if
  29644. 18:09:35there is like an error in our code. So
  29645. 18:09:37let's go and execute the whole thing.
  29646. 18:09:40And now let's go and execute our stored
  29647. 18:09:42procedure. So let's go and do that. So
  29648. 18:09:44now as you can see in the output we are
  29649. 18:09:46not getting any results and it is not
  29650. 18:09:48giving an error. But if you go to the
  29651. 18:09:50messages, you will see a very nice
  29652. 18:09:52message. So it says an error is
  29653. 18:09:54occurred. The error message is divided
  29654. 18:09:56by zero and we have the error number in
  29655. 18:09:59which line and as well the stored
  29656. 18:10:01procedure name. So as you can see it's
  29657. 18:10:02amazing. This is how we use the try and
  29658. 18:10:05catch in order to have more options on
  29659. 18:10:07to control what can happen if there is
  29660. 18:10:09an
  29661. 18:10:13error. Now the next step what I'm going
  29662. 18:10:15to do, we have to go and organize our
  29663. 18:10:17store procedure. As you can see,
  29664. 18:10:18everything is getting bigger. So now
  29665. 18:10:19what we usually do, we use tab in order
  29666. 18:10:21to make spaces between each section. So
  29667. 18:10:24now the first section is between the
  29668. 18:10:26first begin and the last end. So we have
  29669. 18:10:29to go and mark everything and hit once a
  29670. 18:10:32tab. So now it is easier to read. Now
  29671. 18:10:35the whole thing is our codes. So now the
  29672. 18:10:37next level is the block of the try. So
  29673. 18:10:39the whole thing over here is the try. So
  29674. 18:10:43let's go and do that. I'm just going to
  29675. 18:10:45mark everything until here and then hit
  29676. 18:10:48tab. So now we can see it better, right?
  29677. 18:10:50And the same thing for the catch. I
  29678. 18:10:52think I have already done that. So it's
  29679. 18:10:54already pushed. Now we go to the next
  29680. 18:10:55level. So between this begin and end,
  29681. 18:10:58everything is pushed. So this looks
  29682. 18:11:00nice. The same thing over here. It's
  29683. 18:11:02pushed as well. And then we don't have
  29684. 18:11:03here any begin and end. So it looks
  29685. 18:11:06okay. And the same thing over here. So
  29686. 18:11:08all our begin and end is now sorted
  29687. 18:11:11correctly. Now the next step is that we
  29688. 18:11:12can go and improve the comments a little
  29689. 18:11:14bit. So we can split our code into
  29690. 18:11:16multiple sections. So what we're going
  29691. 18:11:18to do, we're going to go over here and
  29692. 18:11:19say this is step one. And what I like to
  29693. 18:11:22do is to go and add separation using the
  29694. 18:11:25equals or any special character that you
  29695. 18:11:27like and as well here. So with that we
  29696. 18:11:31have the first step. We are preparing
  29697. 18:11:32the data. And then let's go and copy the
  29698. 18:11:34whole thing and go over here and say
  29699. 18:11:37this is the step two. And we're going to
  29700. 18:11:39say this is
  29701. 18:11:41generating summary reports and something
  29702. 18:11:45like this. And of course below that we
  29703. 18:11:47can say what is this report about. So
  29704. 18:11:51calculate total
  29705. 18:11:53customers and average score for
  29706. 18:11:58specific country. And as well we can go
  29707. 18:12:01over here and add as well a comment.
  29708. 18:12:04calculate total number of orders and
  29709. 18:12:09total sales for specific country. And of
  29710. 18:12:14course we have to go and remove this
  29711. 18:12:16error over here otherwise we'll get an
  29712. 18:12:18error and we can go and add something
  29713. 18:12:20about the catch where we can say like
  29714. 18:12:21this again few
  29715. 18:12:23comments we're going to say error
  29716. 18:12:28handling. So let's go and execute it
  29717. 18:12:31again in order to make sure we have the
  29718. 18:12:33newest version. And with that we are
  29719. 18:12:35done. We have a really nice stored
  29720. 18:12:36procedure with multiple steps and we
  29721. 18:12:38have it professional where we have error
  29722. 18:12:40handling inside it and everything looks
  29723. 18:12:42well organized and easy to read. So this
  29724. 18:12:45is how we build stored procedures. All
  29725. 18:12:47right my friends. So that's all about
  29726. 18:12:48the store procedures. That was an
  29727. 18:12:50amazing feature in SQL to add
  29728. 18:12:52programmability in SQL. Now in the next
  29729. 18:12:54step we're going to cover quickly the
  29730. 18:12:56topic of the triggers. So let's
  29731. 18:13:02go. All right. So previously we have
  29732. 18:13:04understood that we can put all our SQL
  29733. 18:13:07statements in one stored procedure and
  29734. 18:13:09you have to go and manually execute the
  29735. 18:13:12store procedure. So that means in order
  29736. 18:13:14to trigger the start procedure, you have
  29737. 18:13:16manually to execute it and this is of
  29738. 18:13:19course a problem. How about to do that
  29739. 18:13:21automatically? So triggers in SQL they
  29740. 18:13:24are special stored procedure that
  29741. 18:13:26automatically runs or let's say fired in
  29742. 18:13:29response to a specific event that
  29743. 18:13:31happens on a table. So what this exactly
  29744. 18:13:34means? So now let's say that we have a
  29745. 18:13:36table in our database and now something
  29746. 18:13:38could happen to this table like
  29747. 18:13:40inserting data, deleting, updating data,
  29748. 18:13:43all those stuff that is happening we
  29749. 18:13:45call them events. And now what we can do
  29750. 18:13:47we can go and attach like a trigger on
  29751. 18:13:50top of this table and each time an event
  29752. 18:13:52happened like insert update delete
  29753. 18:13:54something else going to be triggered
  29754. 18:13:56like maybe going and inserting data
  29755. 18:13:58somewhere else in another table or doing
  29756. 18:14:01a check whether we are allowed to delete
  29757. 18:14:03the data in the first place or maybe
  29758. 18:14:05sending a warning message or something.
  29759. 18:14:07So based on any changes to the table we
  29760. 18:14:10can trigger another events and we can do
  29761. 18:14:12that using the SQL triggers and for the
  29762. 18:14:15SQL triggers we have like multiple types
  29763. 18:14:17like the DML triggers and this type of
  29764. 18:14:20trigger going to respond once we have
  29765. 18:14:22like insert update delete statements.
  29766. 18:14:25Another type of triggers we have the DDL
  29767. 18:14:27triggers like you can make a trigger to
  29768. 18:14:29respond to any schema changes like
  29769. 18:14:32creating altering or dropping a table or
  29770. 18:14:35even view by the way not only tables.
  29771. 18:14:37And the third type of triggers we have
  29772. 18:14:38the login trigger. So the trigger can
  29773. 18:14:40respond to login events. Now in this
  29774. 18:14:43tutorial we're going to focus on the DML
  29775. 18:14:45triggers the insert update delete. And
  29776. 18:14:47for the DML triggers we have two types.
  29777. 18:14:50We have after triggers and as well we
  29778. 18:14:52have instead of triggers. So as the name
  29779. 18:14:55suggest if you use after so it can be
  29780. 18:14:58executed after the event and the other
  29781. 18:15:00type that instead of it's something that
  29782. 18:15:02cannot wait until everything happens. So
  29783. 18:15:05this time the trigger going to be
  29784. 18:15:06executed during the event not after it.
  29785. 18:15:10So now in order to understand all of
  29786. 18:15:11this we're going to have really nice use
  29787. 18:15:17case. And now the use case is about
  29788. 18:15:19maintaining an audit logs. So what we
  29789. 18:15:22mean with that? Let's have for example
  29790. 18:15:23the table employees. The employee data
  29791. 18:15:26are usually very sensitive informations
  29792. 18:15:28because there we can see which employees
  29793. 18:15:31are added, the salary updates, the
  29794. 18:15:33employee terminations and this makes the
  29795. 18:15:35table very important because we would
  29796. 18:15:38like to track all those changes that is
  29797. 18:15:40happening to this table. So each time we
  29798. 18:15:42are inserting, updating, deleting, we
  29799. 18:15:44would like to maintain a log about all
  29800. 18:15:46those changes in order to analyze it
  29801. 18:15:48later. It is of course very important
  29802. 18:15:50such a logs for the compliance and the
  29803. 18:15:53auditors and in case there is like a
  29804. 18:15:55problem we can go to the logs to
  29805. 18:15:57understand when this happened who made
  29806. 18:15:59the changes and what exactly changed and
  29807. 18:16:02now in order to maintain logs we're
  29808. 18:16:04going to use the power of triggers. So
  29809. 18:16:06what we're going to do we're going to go
  29810. 18:16:07and attach like a trigger on the table
  29811. 18:16:10employees and each time we insert new
  29812. 18:16:13data to the employees we are triggering
  29813. 18:16:16another events. So what can happen this
  29814. 18:16:18new employee going to be inserted in the
  29815. 18:16:21audit logs in order to have a record
  29816. 18:16:23about this activity in the logs. So that
  29817. 18:16:26means each time you are inserting data
  29818. 18:16:28to the table employees you are
  29819. 18:16:30automatically inserting data inside the
  29820. 18:16:32logs and this is really amazing use case
  29821. 18:16:34for the triggers. So let's go and
  29822. 18:16:36implement it. Okay. So now let's check
  29823. 18:16:38quickly the syntax of the triggers. So
  29824. 18:16:40we start with the usuals create trigger
  29825. 18:16:42then the trigger name and then we have
  29826. 18:16:43to specify on which table this trigger
  29827. 18:16:46going to be built in. So now we are
  29828. 18:16:48attaching like a trigger on top of one
  29829. 18:16:50table and after that we have to define
  29830. 18:16:52for SQL when this trigger going to
  29831. 18:16:55happen. So what is actually triggering
  29832. 18:16:57the trigger and here you can define
  29833. 18:16:59after or instead then you have to define
  29834. 18:17:02the operator. So first you have to
  29835. 18:17:04define like after or instead of and then
  29836. 18:17:06we have to define the operation. So
  29837. 18:17:09insert, update, delete or one of them.
  29838. 18:17:11And with that you are telling SQL when
  29839. 18:17:13exactly this should happen. And now
  29840. 18:17:14after that we have to tell SQL what
  29841. 18:17:17going to happen if the trigger is
  29842. 18:17:19triggered. So here we have like begin
  29843. 18:17:21and end. And then we have like several
  29844. 18:17:23skill statements that's going to
  29845. 18:17:24describe what's going to happen once we
  29846. 18:17:26have the trigger. So that's it. As you
  29847. 18:17:28can see the syntax is very simple. Okay.
  29848. 18:17:30So now let's do it step by step. First I
  29849. 18:17:32would like to create a table where we're
  29850. 18:17:34going to store the logs information. So
  29851. 18:17:36it's going to be very simple table.
  29852. 18:17:38We're going to say create table. Then
  29853. 18:17:40we're going to call it sales employee
  29854. 18:17:43logs and we're going to have the
  29855. 18:17:44following columns inside it. So let's
  29856. 18:17:47start with the primary key. It's going
  29857. 18:17:48to be the log ID and the data type int
  29858. 18:17:50and then we're going to have like a
  29859. 18:17:51sequence. So we're going to have
  29860. 18:17:53identity and this is the primary key.
  29861. 18:17:56Let's go to the next one. It's going to
  29862. 18:17:57be the employee ID and the data type
  29863. 18:18:00going to be ins. The next one is going
  29864. 18:18:01to be the log message. So let's have it
  29865. 18:18:04as a vchar and I'm going to have it like
  29866. 18:18:07255 and then to the next one we're going
  29867. 18:18:09to have the lock dates and then we're
  29868. 18:18:11going to have like let's say a date or a
  29869. 18:18:13date time. So that's it. Let's go and
  29870. 18:18:15execute it and with that we have a new
  29871. 18:18:17table inside our database. Now the next
  29872. 18:18:19step is that we're going to go and
  29873. 18:18:21create our trigger. So we're going to
  29874. 18:18:23say create trigger and I'm going to call
  29875. 18:18:26it like this trg. This is just a prefix
  29876. 18:18:28to indicate this is a trigger. And I'm
  29877. 18:18:30just going to call it after insert
  29878. 18:18:33employee. And now we have to define the
  29879. 18:18:36table. So it's going to be on sales
  29880. 18:18:39employee. So now with that we are saying
  29881. 18:18:41we have now a trigger on the table
  29882. 18:18:43employees. And now we have to define the
  29883. 18:18:45logic. So we're going to use after
  29884. 18:18:47insert. So that means after we insert
  29885. 18:18:50any record to the table employees the
  29886. 18:18:52following things should happen. So we're
  29887. 18:18:54going to say as and then begin and end
  29888. 18:18:58and in between we can have our logic. So
  29889. 18:19:00what can happen after a new record is
  29890. 18:19:02inserted to the employees. We're going
  29891. 18:19:04to go and insert a new record to the
  29892. 18:19:06employee logs. So we're going to have
  29893. 18:19:08insert into sales employee
  29894. 18:19:12logs and we're going to have here the
  29895. 18:19:14three columns employee
  29896. 18:19:16ID the log
  29897. 18:19:18message and the log dates. So now which
  29898. 18:19:22value is going to be inserted? it going
  29899. 18:19:23to be like from a query. So we're going
  29900. 18:19:25to say select and we're going to say as
  29901. 18:19:27well employee ID and for the log message
  29902. 18:19:30we can have customized one like let's
  29903. 18:19:32say new employee added and it's going to
  29904. 18:19:37be equal to the employee ID. So in order
  29905. 18:19:40to have the employee ID it's going to be
  29906. 18:19:41like
  29907. 18:19:42this. So that's it. Now to the next one
  29908. 18:19:46we need the log date. It's going to be
  29909. 18:19:48get date. And now you might say okay but
  29910. 18:19:51where this employee ID is coming from?
  29911. 18:19:54Well, it going to come from the table
  29912. 18:19:56from inserted. So what is actually
  29913. 18:19:58inserted? It is like special virtual
  29914. 18:20:00table that holds all the new inserted
  29915. 18:20:03data to our table employees. So anything
  29916. 18:20:06we are inserting inside the employees
  29917. 18:20:08will be available inside this table. And
  29918. 18:20:11of course this is only available during
  29919. 18:20:14the execution of this trigger. So you
  29920. 18:20:16cannot go now outside of this query and
  29921. 18:20:18start querying the table inserted
  29922. 18:20:20because you will not find anything. This
  29923. 18:20:21is only like a virtual table that
  29924. 18:20:23contains anything that you are doing to
  29925. 18:20:26the table employees and you find a lot
  29926. 18:20:28of informations like the salary, the age
  29927. 18:20:30and so on. So that's it for the
  29928. 18:20:32inserted. Now we have to make sure that
  29929. 18:20:35in our message we have everything as a
  29930. 18:20:37string because the employee ID is an
  29931. 18:20:39integer. So we have to cast it. So cast
  29932. 18:20:42and then we're going to say as far char
  29933. 18:20:46like this otherwise we'll get an error.
  29934. 18:20:48So I think we have our trigger ready. We
  29935. 18:20:50have a new trigger on the table
  29936. 18:20:52employees. And now the first question is
  29937. 18:20:55when this trigger going to happen? Well
  29938. 18:20:57it can happen after inserting data to
  29939. 18:21:00the employees. And then the second
  29940. 18:21:01question what's going to happen? Well,
  29941. 18:21:04once we have this event, the whole thing
  29942. 18:21:06here going to be executed where we are
  29943. 18:21:08saying insert to the logs, the employee
  29944. 18:21:11ID, the message and as well the date
  29945. 18:21:13when this happens. And we can get all
  29946. 18:21:15those informations from the table, the
  29947. 18:21:17virtual table inserted. So I think we
  29948. 18:21:20are ready. Let's go and execute it. And
  29949. 18:21:22now if you go to the object explorer to
  29950. 18:21:24our database, let's go to our table
  29951. 18:21:26employees and then to the triggers. So
  29952. 18:21:29if you refresh over here you can see our
  29953. 18:21:31new trigger that we just created. So
  29954. 18:21:34with that we have to find our trigger
  29955. 18:21:35and we are ready. Now the next step is
  29956. 18:21:37that we're going to go and trigger our
  29957. 18:21:39trigger. So let's go and do that. Let's
  29958. 18:21:41have a new query. But first I'm going to
  29959. 18:21:43have a look to our
  29960. 18:21:45logs. So sales employee logs. So let's
  29961. 18:21:50query this one. And as you can see our
  29962. 18:21:52logs is empty because we didn't insert
  29963. 18:21:54anything to the table employees. Let's
  29964. 18:21:57go and do that. Let's trigger our
  29965. 18:21:58trigger. So what we're going to do,
  29966. 18:21:59we're going to say insert into sales
  29967. 18:22:02employees and we're going to have the
  29968. 18:22:04following values. So we are at the
  29969. 18:22:06counter, I think six. Let's have the
  29970. 18:22:09first name
  29971. 18:22:10Maria. The last name an then we're going
  29972. 18:22:14to have the position. It's going to be
  29973. 18:22:15the HR for example. The birth date,
  29974. 18:22:18let's pick something. I don't know. We
  29975. 18:22:21have a female
  29976. 18:22:23here. And the salary. Let's go and get
  29977. 18:22:26this salary and the hierarchy it can be
  29978. 18:22:29for example three. So let's go and
  29979. 18:22:31execute it. And with that as you can see
  29980. 18:22:33we have inserted a new data to the
  29981. 18:22:34employees. Let's check now the logs. So
  29982. 18:22:38let's query it. So we have here nice log
  29983. 18:22:40about the employee number six. And we
  29984. 18:22:42have here nice message and when this did
  29985. 18:22:45happen. Of course you can go and insert
  29986. 18:22:47another employee let's say seven with
  29987. 18:22:50the same data. So let's do that and
  29988. 18:22:52check the logs. And with that we have
  29989. 18:22:55another log for the new employee. So
  29990. 18:22:57this is really amazing use case in order
  29991. 18:22:58to maintain a log to your data and you
  29992. 18:23:01can go and make like some analyzes on
  29993. 18:23:03how many inserted happens and of course
  29994. 18:23:06not only on the insert you can have it
  29995. 18:23:08on the update delete. So as you can see
  29996. 18:23:10it is very simple. This is how we create
  29997. 18:23:12the triggers in SQL. All right my
  29998. 18:23:13friends. So that's all about the
  29999. 18:23:14triggers with that with with that we
  30000. 18:23:17have covered now with that we have
  30001. 18:23:19covered now all the concepts and topics
  30002. 18:23:21that you have to learn about SQL. Now in
  30003. 18:23:23the next chapter it's going to be about
  30004. 18:23:25the performance. So as you start writing
  30005. 18:23:27queries and so on you will start
  30006. 18:23:29noticing some queries are really slow.
  30007. 18:23:31Now what we're going to do in this
  30008. 18:23:32chapter we're going to learn different
  30009. 18:23:34techniques on how to optimize the
  30010. 18:23:35performance. And the first and the very
  30011. 18:23:37famous one is to go and build indexes in
  30012. 18:23:40databases. So let's understand what this
  30013. 18:23:46means. So what is an index? An index is
  30014. 18:23:49a data structure that provides a quick
  30015. 18:23:52access to the rows to improve the speed
  30016. 18:23:55of your queries. So an index is like a
  30017. 18:23:58guide for your database in order to
  30018. 18:24:00speed up the process of searching for
  30019. 18:24:02data especially if you have like big
  30020. 18:24:04tables. So now in order to understand
  30021. 18:24:06what are indexes, imagine you have huge
  30022. 18:24:08book and you want to find a specific
  30023. 18:24:10topic or a chapter. Instead of flipping
  30024. 18:24:13each single page in order to find the
  30025. 18:24:15topic that you are searching for, you
  30026. 18:24:16would use the index at the back of the
  30027. 18:24:18book in order to jump straight to the
  30028. 18:24:21right page. And that's exactly what
  30029. 18:24:23index does but for your data. Another
  30030. 18:24:26analogy that I use in order to
  30031. 18:24:27understand indexes is think about the
  30032. 18:24:30indexes as a big hotel. Now let's say
  30033. 18:24:33that in the hotel we don't have any
  30034. 18:24:34guide and you would like to find the
  30035. 18:24:36room number let's say 5001. Now what you
  30036. 18:24:40going to do? You're going to go and
  30037. 18:24:41search for your room floor by floor and
  30038. 18:24:44checking each room until you find your
  30039. 18:24:46room. But instead of that, thankfully
  30040. 18:24:48hotels have a numbering system. And you
  30041. 18:24:51can ask for a map from the reception in
  30042. 18:24:53order to understand in which building in
  30043. 18:24:55which floor you can find your room. So
  30044. 18:24:58by just following the map and maybe some
  30045. 18:25:00signs, it's going to be very quickly to
  30046. 18:25:02locate and find your room in such a big
  30047. 18:25:04hotel. And that's exactly what each
  30048. 18:25:06database needs. It needs an index in
  30049. 18:25:08order to help the database finding and
  30050. 18:25:11locating the right data without having
  30051. 18:25:13to scan
  30052. 18:25:18everything. And now let's say that you
  30053. 18:25:20ask me, you know what, I have this big
  30054. 18:25:22table and I would like to speed up the
  30055. 18:25:24queries using indexes. And my first
  30056. 18:25:27question going to be, what are you
  30057. 18:25:28exactly doing with this table? Are you
  30058. 18:25:30using this table to search for text or
  30059. 18:25:33are you doing like complex analyszis
  30060. 18:25:35with this table? And the reason why I'm
  30061. 18:25:37asking this is that we have different
  30062. 18:25:40indexes in databases for different
  30063. 18:25:42purposes. So now let's have a quick look
  30064. 18:25:43to the different types of indexes that
  30065. 18:25:46we have in database. I divide the
  30066. 18:25:48indexes in databases into three
  30067. 18:25:50categories. The first one is by the
  30068. 18:25:52structure how the database is organizing
  30069. 18:25:55and referencing the data. And here we
  30070. 18:25:57have two types. The clustered index and
  30071. 18:26:00the non-clustered index. Those are very
  30072. 18:26:02important to understand. Now we have
  30073. 18:26:04another category for the indexes. We can
  30074. 18:26:07divide them by the storage. And in this
  30075. 18:26:09category we are talking about how the
  30076. 18:26:11data is stored physically in the
  30077. 18:26:14database. So we have two types. We have
  30078. 18:26:16the row store index and the column store
  30079. 18:26:19index. And the third type is the
  30080. 18:26:21functions and here we have two types. We
  30081. 18:26:24have the unique index and the filtered
  30082. 18:26:26index. Now each index type has its own
  30083. 18:26:29strings but as well there is always a
  30084. 18:26:32tradeoff. Some might improve their read
  30085. 18:26:34performance. The other one might improve
  30086. 18:26:36the insert and update operations. So
  30087. 18:26:39it's all about choosing the right type
  30088. 18:26:41of index for the job. So now what we're
  30089. 18:26:43going to do, we're going to go and deep
  30090. 18:26:44dive into each of those types in order
  30091. 18:26:46to understand how they work and how we
  30092. 18:26:49can create them. And we will start with
  30093. 18:26:50the first category, the structure. We
  30094. 18:26:53have the clustered index and the
  30095. 18:26:54nclustered index.
  30096. 18:27:00Now before we dive into how the indexes
  30097. 18:27:02works in databases, let's understand
  30098. 18:27:04first what happens to the database
  30099. 18:27:07tables if you don't use any index. When
  30100. 18:27:10you create a new table in your database
  30101. 18:27:12like for example the customers table
  30102. 18:27:14where you have let's say 20 customers
  30103. 18:27:16inside this table. What you're going to
  30104. 18:27:18see at the client side is like
  30105. 18:27:20spreadsheets like a table with rows and
  30106. 18:27:23columns but behind the scenes the
  30107. 18:27:24database store it a bit differently.
  30108. 18:27:27It's going to store the data in a data
  30109. 18:27:29file on the disk and inside this file
  30110. 18:27:32the data can be stored inside blocks
  30111. 18:27:34called pages. So it's not like rows and
  30112. 18:27:37columns that are stored inside data
  30113. 18:27:39files and inside the data files we have
  30114. 18:27:42pages. So what is a page? A page is the
  30115. 18:27:46unit of data storage in a database and
  30116. 18:27:49it is a fixed size of 8 kilobyt where
  30117. 18:27:52the SQL database can store anything
  30118. 18:27:55inside it. It can store inside it the
  30119. 18:27:57rows of your tables or columns metadata
  30120. 18:28:00indexes and every time you are
  30121. 18:28:02interacting with your data the SQL is
  30122. 18:28:05reading and writing to those pages. So
  30123. 18:28:08as you can see the SQL is not storing
  30124. 18:28:10the data inside like rows and columns.
  30125. 18:28:13So if you are running a query the SQL is
  30126. 18:28:15not like selecting a specific column it
  30127. 18:28:18always fetch a data page in order to
  30128. 18:28:21read the rows inside this page. And the
  30129. 18:28:24main two types that we're going to learn
  30130. 18:28:25is the data page and the index page. So
  30131. 18:28:28how the data page looks like it is
  30132. 18:28:30divided into multiple sections. The
  30133. 18:28:32first section is the page header where
  30134. 18:28:34the database can store key informations
  30135. 18:28:36about the metadata like the page ID and
  30136. 18:28:39it has the following format. It start
  30137. 18:28:41with the file ID like one and then we
  30138. 18:28:44have a unique number for each page. So
  30139. 18:28:46for example 150. So the page header is a
  30140. 18:28:49fixed size of 96 bytes. Now to the next
  30141. 18:28:51section, we're going to have a variable
  30142. 18:28:53size. This is where your data row is
  30143. 18:28:56going to be stored. So your actual data
  30144. 18:28:58and row is going to be stored in this
  30145. 18:28:59section. And the SQL going to try and
  30146. 18:29:01fits as many rows as it can in one
  30147. 18:29:04single page. And this of course depends
  30148. 18:29:06on the size of each row. So if you have
  30149. 18:29:09like a large table where the rows are
  30150. 18:29:11really big, so SQL can fit only few rows
  30151. 18:29:14in one single page. And now moving on to
  30152. 18:29:16the last section in the data page, we
  30153. 18:29:19have the offset array. This is like a
  30154. 18:29:21quick index for the rows stored inside
  30155. 18:29:24this page. It keeps track of where each
  30156. 18:29:27rows begins so that the SQL can easily
  30157. 18:29:30locate a specific row without having SQL
  30158. 18:29:33like scanning the entire page in order
  30159. 18:29:35to find a row. So this is the structure
  30160. 18:29:37of the data page and this is exactly how
  30161. 18:29:40the SQL stores data inside the
  30162. 18:29:43databases. So now back to our example
  30163. 18:29:44where we have the customers table and 20
  30164. 18:29:47rows. So let's see how SQL going to be
  30165. 18:29:49creating those pages. Now if you are not
  30166. 18:29:51using any index in this table. So now
  30167. 18:29:53what going to happen? SQL going to
  30168. 18:29:55insert the data inside those pages as
  30169. 18:29:57you are inserting the data inside the
  30170. 18:30:00customers. So maybe first you are
  30171. 18:30:01inserting the customers like 12 5 6 7
  30172. 18:30:05and SQL going to insert it to the data
  30173. 18:30:07pages exactly like that. So that means
  30174. 18:30:10SQL is just inserting the data as you
  30175. 18:30:12insert it to the table. So let's say
  30176. 18:30:14each data page is like fitting only five
  30177. 18:30:17rows. So after we insert five customers,
  30178. 18:30:19SQL going to go and create another data
  30179. 18:30:21page for the next rows. So in the next
  30180. 18:30:24page, the SQL going to insert the next
  30181. 18:30:26five customers. And once it's full, it's
  30182. 18:30:29going to create another data page in
  30183. 18:30:30order to start adding the next customer
  30184. 18:30:33until we have like for example four
  30185. 18:30:35pages for that 20 customers. So now if
  30186. 18:30:38you check the customers inside those
  30187. 18:30:39four pages you see that they are not
  30188. 18:30:42sorted at all and that's because in this
  30189. 18:30:44scenario we are not using any index. So
  30190. 18:30:47we call this structure as a heap
  30191. 18:30:49structure. So a heap table is a table
  30192. 18:30:52without a clustered index. That means
  30193. 18:30:54the rows are stored randomly without any
  30194. 18:30:57particular order. This is not a really
  30195. 18:31:00bad because it's going to be very quick
  30196. 18:31:02to insert data inside this table. But of
  30197. 18:31:05course finding something from this table
  30198. 18:31:07going to be very slow. So this is the
  30199. 18:31:09first tradeoff. You have a very fast
  30200. 18:31:12writes but a very bad reads. Think about
  30201. 18:31:15it like you are throwing all your papers
  30202. 18:31:17in a drawer without organizing them. So
  30203. 18:31:20you can toss things very quickly in this
  30204. 18:31:22drawer. But if you want to search for
  30205. 18:31:24specific paper later, it's going to be
  30206. 18:31:26very long process until you find it
  30207. 18:31:28because nothing's in order. So now let's
  30208. 18:31:31see how the SQL going to handle if you
  30209. 18:31:33read something from this table. Let's
  30210. 18:31:35say that you are searching for the
  30211. 18:31:36customer with the ID 14. So now SQL has
  30212. 18:31:39totally no idea where to find this
  30213. 18:31:41customer. So SQL going to start fetching
  30214. 18:31:43each data page and start scanning each
  30215. 18:31:46row. So it's going to start with the
  30216. 18:31:47first data page and start scanning.
  30217. 18:31:49Well, SQL will not find 14 here. So SQL
  30218. 18:31:52going to go to the next page and start
  30219. 18:31:54scanning as well. Searching for the ID
  30220. 18:31:5714 and nothing going to be found. The
  30221. 18:31:59same thing for the third page as well.
  30222. 18:32:00SQL will not find 14. So SQL going to go
  30223. 18:32:03to the last data page and there after
  30224. 18:32:05scanning four rows in this data page
  30225. 18:32:08finally SQL going to find the customer
  30226. 18:32:10number 14 and it's going to return it
  30227. 18:32:12for the clients. So as you can see in
  30228. 18:32:14order to find one customer SQL did read
  30229. 18:32:18four different pages and scanned like 19
  30230. 18:32:21rows in order to find the customer and
  30231. 18:32:23this process we call it full table scan.
  30232. 18:32:27So the full table scans means SQL is
  30233. 18:32:29scanning the entire table page by page
  30234. 18:32:32and row by row in order to find specific
  30235. 18:32:35row. And of course for this table maybe
  30236. 18:32:37it's not a big deal. But if you have
  30237. 18:32:39like a big table where you have like
  30238. 18:32:41hundred of thousands or maybe millions
  30239. 18:32:43of rows searching through the heap
  30240. 18:32:45structure going to be very painful and
  30241. 18:32:47slow in order to locate one row. And
  30242. 18:32:49here exactly why we need indexes in SQL
  30243. 18:32:52databases. So let's understand the first
  30244. 18:32:54type of indexes the clustered
  30245. 18:33:00index. All right. So now let's
  30246. 18:33:02understand what can happen if you create
  30247. 18:33:04clustered index in your table. So say
  30248. 18:33:06you create a clustered index on the ID
  30249. 18:33:09column of the customers. So the first
  30250. 18:33:11thing that's going to happen SQL going
  30251. 18:33:12to physically sort all the data based on
  30252. 18:33:16the column ID. So the rows going to
  30253. 18:33:18rearranged in each data page from the
  30254. 18:33:21lowest to the highest. So in the first
  30255. 18:33:23page we're going to have the first
  30256. 18:33:25customer ID number one then 2 3 4 5
  30257. 18:33:28until we reach in the last page the last
  30258. 18:33:31customer number 20. So as you can see
  30259. 18:33:33the first page has the lowest value and
  30260. 18:33:36the last page has the highest value. So
  30261. 18:33:39that's not all. The next step is that
  30262. 18:33:41SQL going to go and start structuring
  30263. 18:33:44and building the B tree. So what is a B
  30264. 18:33:48tree? A B tree short for balance tree.
  30265. 18:33:50It is hierarchal structure that store
  30266. 18:33:53the data as a tree upside
  30267. 18:33:56[Music]
  30268. 18:34:02down. It start with the root the root
  30269. 18:34:05node and then it keep branching out
  30270. 18:34:07until we reach eventually the leaves.
  30271. 18:34:10Between the leaf nodes and the root
  30272. 18:34:12nodes we call this section the
  30273. 18:34:14intermediate nodes. So it could be like
  30274. 18:34:16one level or multiple levels between the
  30275. 18:34:18root and the leaves. And once SQL
  30276. 18:34:21construct the B tree, it's going to be
  30277. 18:34:23very easy for SQL to navigate through
  30278. 18:34:25the B tree in order to find specific
  30279. 18:34:27information. So let's see how SQL is
  30280. 18:34:30building the B tree for the clustered
  30281. 18:34:32index. Now very important to understand
  30282. 18:34:34that the leaves the leaf nodes and the B
  30283. 18:34:37tree for the clustered index contain the
  30284. 18:34:40actual data the data pages. So all your
  30285. 18:34:43nice sorted data pages and your data is
  30286. 18:34:46stored at the leaf level. Then after
  30287. 18:34:48that SQL going to start building the
  30288. 18:34:50intermediate nodes and here the database
  30289. 18:34:52going to use different type of pages. We
  30290. 18:34:56have the index page. So in the index
  30291. 18:34:58page we cannot find the actual data the
  30292. 18:35:01entire rows but instead the index page
  30293. 18:35:03stores a key value that contain a
  30294. 18:35:06pointer to another index page or to a
  30295. 18:35:09data page. So for example we have here
  30296. 18:35:11the value one the key and then the value
  30297. 18:35:14going to be the ID of the data page. So
  30298. 18:35:16here we don't have like the whole row
  30299. 18:35:18about the data we have here only a
  30300. 18:35:21pointer to another data page. So here we
  30301. 18:35:23are telling the scale if you are
  30302. 18:35:25searching for ids between 1 and five you
  30303. 18:35:28can locate it at the data page ID
  30304. 18:35:321.100 and then we can store in this
  30305. 18:35:34index page another pointer where we can
  30306. 18:35:36tell SQL if you are searching between 6
  30307. 18:35:38and 10 then you can locate it at the
  30308. 18:35:41second data page. So this is the
  30309. 18:35:44structure of the index page it contains
  30310. 18:35:45only pointers to another page and the
  30311. 18:35:48same thing for the second two pages. The
  30312. 18:35:51SQL going to create another index page
  30313. 18:35:53where it's going to says if you are
  30314. 18:35:54searching for IDs between 11 and 15, you
  30315. 18:35:57can find it at the third page 1 double
  30316. 18:36:00point 10002. And for the last group
  30317. 18:36:02between 16 and 20, we have another
  30318. 18:36:04pointer to the last page to the page
  30319. 18:36:06number
  30320. 18:36:08one3. So as you can see inside those
  30321. 18:36:10index pages, we have like a pointer for
  30322. 18:36:13each group of ids for each cluster. So
  30323. 18:36:16for the group of customers between 1 and
  30324. 18:36:18five we have one pointer and for the
  30325. 18:36:21second group between six and 10 we have
  30326. 18:36:22another pointer. So that means we don't
  30327. 18:36:25have here a pointer for each row. We
  30328. 18:36:28have a pointer for each group for each
  30329. 18:36:30cluster. That's why we call it clustered
  30330. 18:36:33index. And now once SQL is done building
  30331. 18:36:35the intermediate nodes, SQL going to go
  30332. 18:36:37and build the last node, the root node
  30333. 18:36:40where it says if you are searching for
  30334. 18:36:42customers between 1 and 10, then go to
  30335. 18:36:46the index page with the ID
  30336. 18:36:481.200. So that means the route node here
  30337. 18:36:51is pointing to another index page, not
  30338. 18:36:54directly to the data page. And the same
  30339. 18:36:56thing, we need another pointer for the
  30340. 18:36:59second index page. So the customers
  30341. 18:37:01between 11 and 20 go to the index page
  30342. 18:37:04with the ID
  30343. 18:37:061.201 and this is exactly what going to
  30344. 18:37:08happen if you create a clustered index
  30345. 18:37:11in SQL. First it going to go and
  30346. 18:37:14physically sort all your data in the
  30347. 18:37:16databases. So if it's from the first
  30348. 18:37:18time sorted randomly SQL has to arrange
  30349. 18:37:22everything and sort the data from the
  30350. 18:37:24scratch. And then it's going to go and
  30351. 18:37:25build this structure where you have in
  30352. 18:37:27the root node and index page in the
  30353. 18:37:30intermediate nodes the index pages but
  30354. 18:37:32at the leaf level at the leaves we have
  30355. 18:37:36the actual data the data pages. So now
  30356. 18:37:38let's see what going to happen if you
  30357. 18:37:40query the table where you search for the
  30358. 18:37:42ID number 14. So it's going to check
  30359. 18:37:44which pointer to use since 14 is in the
  30360. 18:37:47group between 11 and 20. It's going to
  30361. 18:37:49go and use the second pointer to the
  30362. 18:37:52index page with the ID one double point
  30363. 18:37:542011. And here the SQL going to open
  30364. 18:37:56this index page and check the pointers.
  30365. 18:37:59So since 14 is between 11 and 15 it
  30366. 18:38:03going to go and use the pointer to the
  30367. 18:38:04data page one point 102 and with that
  30368. 18:38:08SQL located the correct data page the
  30369. 18:38:11third page and now SQL going to open
  30370. 18:38:13this data page and find the customer ID
  30371. 18:38:17number 14. So as you can see it was very
  30372. 18:38:19fast for SQL to locate the correct data
  30373. 18:38:21page with only three jumps from the root
  30374. 18:38:24node to the intermediate node. The SQL
  30375. 18:38:26were able to find fast the correct data
  30376. 18:38:28page. And here SQL needs only to read
  30377. 18:38:31one data page instead of reading as we
  30378. 18:38:33saw in the heap structure four different
  30379. 18:38:36data pages. And of course you might say
  30380. 18:38:37but still here we are reading like three
  30381. 18:38:39pages. Well, reading an index page is
  30382. 18:38:42very fast compared to the data page
  30383. 18:38:44because reading a data page is always
  30384. 18:38:46slower than reading an index page. So,
  30385. 18:38:49as you can see, this P3 structure, the
  30386. 18:38:51clustered index structure did help the
  30387. 18:38:53SQL and the database to locate the right
  30388. 18:38:56data in the right
  30389. 18:38:59[Music]
  30390. 18:39:02databases. And this is exactly how that
  30391. 18:39:05clustered index works in the SQL
  30392. 18:39:07database.
  30393. 18:39:12All right. So now we're going to move to
  30394. 18:39:13the second type and we're going to
  30395. 18:39:14understand how exactly SQL build and
  30396. 18:39:17create the nonclustered index. So let's
  30397. 18:39:20go. So now we are back to the heap
  30398. 18:39:22structure where our table don't have any
  30399. 18:39:24index and our data are stored randomly
  30400. 18:39:26inside the data pages. And now if you go
  30401. 18:39:28and create a non-clustered index on the
  30402. 18:39:31customer ID, what can happen? And here's
  30403. 18:39:33the big difference that SQL will not
  30404. 18:39:36touch or change anything on the physical
  30405. 18:39:40actual data on the databases. So the
  30406. 18:39:42database is going to stay as it is and
  30407. 18:39:45nothing going to be changed and the SQL
  30408. 18:39:47start immediately building the B
  30409. 18:39:50structure. So it's going to start
  30410. 18:39:51immediately building an index page and
  30411. 18:39:53this index page is a little bit
  30412. 18:39:55different than the one that we have
  30413. 18:39:56learned previously. So since it's index
  30414. 18:39:58page, it's going to store pointers. But
  30415. 18:40:00this time SQL going to store in the key
  30416. 18:40:02the customer ID. So one is the customer
  30417. 18:40:05ID and now the value the pointer it will
  30418. 18:40:08not be the data page ID. We will be more
  30419. 18:40:11specific. So we're going to have like an
  30420. 18:40:12address where exactly the row is stored.
  30421. 18:40:16So it's going to start with the file ID,
  30422. 18:40:18the page number because the customer ID
  30423. 18:40:21one is stored in the page
  30424. 18:40:24one2. But SQL gonna go add as well the
  30425. 18:40:28offset number of the row where exactly
  30426. 18:40:30in the page we can find this ID and the
  30427. 18:40:33whole thing we can call it an air ID the
  30428. 18:40:36row identifier. So now let's see quickly
  30429. 18:40:38how the index page is pointing exactly
  30430. 18:40:41to the row inside the data page. So the
  30431. 18:40:43first part of the row identifier is
  30432. 18:40:46mapping to the data page ID and then
  30433. 18:40:49from the 96 it's going to take us to the
  30434. 18:40:51offset and that's exactly the location
  30435. 18:40:54of the row number one. So 96 is the part
  30436. 18:40:57where we're going to start finding the
  30437. 18:40:59row number one and that's going to takes
  30438. 18:41:01us exactly to the place where we can
  30439. 18:41:04read the information about the row ID
  30440. 18:41:07number one. So this is how the index
  30441. 18:41:09page is locating the exact place of the
  30442. 18:41:13rows. So SQL going to go and continue
  30443. 18:41:15and assign for each customer ID a
  30444. 18:41:18pointer to the exact location. So as you
  30445. 18:41:21can see now in the index page we don't
  30446. 18:41:22have like a pointer for each group of
  30447. 18:41:25customers like we have learned in the
  30448. 18:41:27clusters index. We have now a pointer
  30449. 18:41:30for each ID and this type of index page
  30450. 18:41:33we call it roator page. So now SQL going
  30451. 18:41:36to go and continue and map a pointer for
  30452. 18:41:39each customer ID that we have inside our
  30453. 18:41:41table. So we will have multiple index
  30454. 18:41:43pages pointing to our data page. So as
  30455. 18:41:46you can see we have a lot of pointers
  30456. 18:41:48and the data inside the index page is of
  30457. 18:41:51course sorted but inside the data pages
  30458. 18:41:54it left as it is. And now those index
  30459. 18:41:57pages that has the row identifier going
  30460. 18:42:00to be stored at the leaf level of the B
  30461. 18:42:03tree. So at the leaf level we don't have
  30462. 18:42:05the actual data the data pages we have
  30463. 18:42:08index pages where we have pointers then
  30464. 18:42:11to the actual data and then it's going
  30465. 18:42:13to go and start building the
  30466. 18:42:14intermediate nodes. It's exactly like
  30467. 18:42:16the clustered index where it's going to
  30468. 18:42:18point to another index page. So between
  30469. 18:42:21one and five customers it's going to be
  30470. 18:42:23in the index page number 200. So the
  30471. 18:42:26next step is going to go and build the
  30472. 18:42:27intermediate nodes. It's going to be
  30473. 18:42:29exactly like the clustered index.
  30474. 18:42:31Nothing going to be changed. is like the
  30475. 18:42:33same structure. So it is an index page
  30476. 18:42:35pointing to another index page but this
  30477. 18:42:38time for a group of customers and then
  30478. 18:42:40we're going to have as well the root
  30479. 18:42:41node. So again we call this structure as
  30480. 18:42:44a B tree structure where they point to
  30481. 18:42:47another databases but the databases are
  30482. 18:42:49not part of the B tree. So now let's say
  30483. 18:42:52if we are searching for the customer ID
  30484. 18:42:55number 14, what's going to happen? It's
  30485. 18:42:57going to start again from the root node
  30486. 18:42:59and then it's going to find the pointer
  30487. 18:43:01to the intermediate node and then jump
  30488. 18:43:02to the next step to the intermediate
  30489. 18:43:04node and then it's going to find the
  30490. 18:43:05pointer to the index page between 11 and
  30491. 18:43:0815 and then it's going to go and scan
  30492. 18:43:11this index page and find okay for the
  30493. 18:43:13customer ID number 14 we have the
  30494. 18:43:15following address. So it's going to go
  30495. 18:43:17and locate the exact database and as
  30496. 18:43:20well the exact place of the row. So it
  30497. 18:43:23can go and jump immediately to the row
  30498. 18:43:25without scanning anything else. So here
  30499. 18:43:27this time with the nclustered index the
  30500. 18:43:30SQL did read three different index
  30501. 18:43:32pages. And finally the one data page in
  30502. 18:43:34order to find the data. So if you
  30503. 18:43:37compare to the clustered index you can
  30504. 18:43:38see that we have here one extra layer
  30505. 18:43:41one extra index page to be scanned in
  30506. 18:43:44order to find the right place of the
  30507. 18:43:46row. And this is how SQL creates the B
  30508. 18:43:48tree for the nonclustered index and how
  30509. 18:43:51it scans it in order to find the
  30510. 18:43:57information. All right. So now when I
  30511. 18:43:59think about the clustered index and the
  30512. 18:44:00non-clustered index, I think about a
  30513. 18:44:03book. You can think of the clustered
  30514. 18:44:05index like the table of contents at the
  30515. 18:44:08front of the table. So the table of
  30516. 18:44:10contents kind of tells you where to find
  30517. 18:44:12each chapter and the chapters are
  30518. 18:44:15exactly sorted like the table of
  30519. 18:44:17contents and this is exactly what the
  30520. 18:44:19clustered index does. But now in the
  30521. 18:44:21other hand think about the nclustered
  30522. 18:44:23index as the index that you can find at
  30523. 18:44:26the end of the book. The index of the
  30524. 18:44:28book is a very detailed list of topics,
  30525. 18:44:32terms and keywords where it points
  30526. 18:44:35exactly to the location where you can
  30527. 18:44:37find it in the book. And the content and
  30528. 18:44:39the topic of the book is not sorted like
  30529. 18:44:42the index of the book. And this is
  30530. 18:44:44exactly what the noncluster index does.
  30531. 18:44:46It is coexisting with the data. It is an
  30532. 18:44:49extra list where it can point exactly
  30533. 18:44:51where we can find the data inside our
  30534. 18:44:54table. All right. Right. So now let's
  30535. 18:44:55put those two indexes side by side to
  30536. 18:44:57understand the differences between them.
  30537. 18:44:59So the structure of the cluster the
  30538. 18:45:00index is a B tree where it start with
  30539. 18:45:03the root node where we have an index
  30540. 18:45:05page. This index page is pointing to the
  30541. 18:45:08intermediate nodes where we have as well
  30542. 18:45:10index pages and those index pages are
  30543. 18:45:13pointing to the actual data to the data
  30544. 18:45:15pages. So at the leave level of the
  30545. 18:45:18clustered index we have the data pages
  30546. 18:45:20the actual data. What's special about
  30547. 18:45:22the clustered index is that it
  30548. 18:45:24physically sort the data inside those
  30549. 18:45:27pages. So everything here is physically
  30550. 18:45:29rearranged and sorted. Now if you are
  30551. 18:45:32talking about the nclustlustered index
  30552. 18:45:34we have as well a bit tree. So the same
  30553. 18:45:36thing at the root node we have an index
  30554. 18:45:38page pointing to an intermediate index
  30555. 18:45:41page but this time the intermediate
  30556. 18:45:43nodes are pointing to another index
  30557. 18:45:46page. They are not pointing like the
  30558. 18:45:48clustered index to a data page. they are
  30559. 18:45:50pointing to index page. So now if you
  30560. 18:45:53check this structure you can see that at
  30561. 18:45:54the leaf level for the clustered index
  30562. 18:45:57we have the actual data the data pages
  30563. 18:45:59but on the other side at the leaf level
  30564. 18:46:01for the nclustered index we don't have
  30565. 18:46:03the actual data we have index pages but
  30566. 18:46:06those index pages are pointing to the
  30567. 18:46:09actual data to the data pages but the
  30568. 18:46:12big difference of that the data pages
  30569. 18:46:14are not part of the B3 the B3 of the
  30570. 18:46:17nclustlustered index is just a separate
  30571. 18:46:19structure that does not involve any
  30572. 18:46:22data. So we have only index pages and it
  30573. 18:46:25just points to the data pages without
  30574. 18:46:27changing anything physically with your
  30575. 18:46:30data. But in reality what happen is that
  30576. 18:46:33you can have those two types of indexes
  30577. 18:46:35the clustered and the nclustered indexes
  30578. 18:46:38in one table. So one can happen the leaf
  30579. 18:46:41level of the nclustered index going to
  30580. 18:46:44be pointing to the data pages of the
  30581. 18:46:46clustered index because those index
  30582. 18:46:48pages don't care whether those pages are
  30583. 18:46:51sorted or not. It's just going to go and
  30584. 18:46:54point to the correct page and to the
  30585. 18:46:56correct row. So that means we have now
  30586. 18:46:58like two different B3 structures that
  30587. 18:47:01are pointing to the data. And here there
  30588. 18:47:03is like one thing that you have to
  30589. 18:47:04understand that that you can create only
  30590. 18:47:08one clustered index on a table. And this
  30591. 18:47:11rule really makes sense because you can
  30592. 18:47:12sort the data only in one way in SQL.
  30593. 18:47:15And that's of course makes sense because
  30594. 18:47:17you can sort the data physically only
  30595. 18:47:19once. And that's why in SQL databases
  30596. 18:47:21you are allowed to create only one
  30597. 18:47:24clustered index because physically the
  30598. 18:47:26data can be sorted only in one way. But
  30599. 18:47:29in the other hand in the non-clustered
  30600. 18:47:30index you can create as many
  30601. 18:47:33nonclustered index you need. So you can
  30602. 18:47:35create three four and all of them are
  30603. 18:47:37pointing to the same data pages because
  30604. 18:47:40in the B tree of the non-clustered index
  30605. 18:47:42you don't store any data pages. We store
  30606. 18:47:44only pointers to the data and you could
  30607. 18:47:46have like multiple pointers. So this is
  30608. 18:47:48the most important and the main
  30609. 18:47:50difference between those two indexes.
  30610. 18:47:52Now if you put it side by side, we have
  30611. 18:47:54learned that the clustered index going
  30612. 18:47:56to go and physically sorts and stores
  30613. 18:47:59the rows at the B tree. But the
  30614. 18:48:01nclustered index is going to go and
  30615. 18:48:03create a separate p structure with
  30616. 18:48:06pointers to the actual data. And by the
  30617. 18:48:08way, the clustered index we call it the
  30618. 18:48:11main index that we could use in each
  30619. 18:48:14table. So the clustered index is the
  30620. 18:48:16main one, the most important one that
  30621. 18:48:18you can go and use in each table in your
  30622. 18:48:21database. Now as we learned if you are
  30623. 18:48:22talking about the number of indexes you
  30624. 18:48:25can create maximum one index for each
  30625. 18:48:27table but for the nclustered index there
  30626. 18:48:30is no limitations you can go and create
  30627. 18:48:32multiple indexes for each table. And now
  30628. 18:48:35if you go and compare them about the
  30629. 18:48:37read performance how fast we can get
  30630. 18:48:39data using clustered index. Well it is
  30631. 18:48:42faster than the nclustlustered index.
  30632. 18:48:44And that's because in the nonclass and
  30633. 18:48:46index we have this extra layer at the
  30634. 18:48:49leaf node from the B tree and because of
  30635. 18:48:52this having extra layer that means SQL
  30636. 18:48:54has to do extra job in order to find the
  30637. 18:48:56data that's why clustered index is
  30638. 18:48:59faster than the nonclustered index but
  30639. 18:49:01now in the other hand if we are talking
  30640. 18:49:03about the right performance how fast we
  30641. 18:49:06can insert data to the tables well
  30642. 18:49:09writing data to a table with a clustered
  30643. 18:49:11index is slower than the nclustered
  30644. 18:49:14index. And that's because as you are
  30645. 18:49:16inserting data to the table, SQL has
  30646. 18:49:18always to check the databases is
  30647. 18:49:21everything sorted correctly and if not
  30648. 18:49:23SQL has to go and start physically
  30649. 18:49:26sorting the data again in order to have
  30650. 18:49:28the correct order. So there is a lot of
  30651. 18:49:30stress in order to sort the data with
  30652. 18:49:32the clustered index. But in the other
  30653. 18:49:34hand in the non-clustered index we don't
  30654. 18:49:36have this. So the physical data going to
  30655. 18:49:38stay as it is. We are just creating nice
  30656. 18:49:41new pointers. So if you are writing to a
  30657. 18:49:43table where you have a clustered index,
  30658. 18:49:45it's going to be slower than writing to
  30659. 18:49:47a table where you have nclustered index.
  30660. 18:49:49And of course the fastest way to write
  30661. 18:49:52data to a table is to not have indexes
  30662. 18:49:55at all. So a heap structure. So SQL just
  30663. 18:49:58go and start inserting data inside those
  30664. 18:50:01databases without creating any extra
  30665. 18:50:03structures. So as you can see it's like
  30666. 18:50:05always a tradeoff. You can read fast but
  30667. 18:50:08you're going to write slower. So you
  30668. 18:50:10cannot have like everything. Now we are
  30669. 18:50:12talking about the storage efficiency.
  30670. 18:50:14The clustered index going to be better
  30671. 18:50:16with the storage than the nonclustered
  30672. 18:50:18index and that's because of the same
  30673. 18:50:20reason with the nonstructured index. We
  30674. 18:50:22have this extra layer of index pages and
  30675. 18:50:25index pages needs storage and that's why
  30676. 18:50:27they can waste more storage than the
  30677. 18:50:29clustered index. Now if you're talking
  30678. 18:50:31about the use cases when to use
  30679. 18:50:33clustered index. Well, if you have like
  30680. 18:50:35a column this column has to have few
  30681. 18:50:37criteria in order to be good candidate
  30682. 18:50:39for the clustered index. First, it's
  30683. 18:50:41going to be good if the values inside
  30684. 18:50:43the columns are unique. And second, and
  30685. 18:50:45it is way more important than that, the
  30686. 18:50:48values of this column should not change
  30687. 18:50:50a lot because if this column having a
  30688. 18:50:53lot of update operators and the data is
  30689. 18:50:55keep changing, that means each time SQL
  30690. 18:50:58going to go and start sorting the data
  30691. 18:51:00again left and right. So having a column
  30692. 18:51:02that is frequently changing, it's not
  30693. 18:51:05good for clustered index. And that's why
  30694. 18:51:08the primary keys of tables are a perfect
  30695. 18:51:11candidate because first they are unique
  30696. 18:51:13and second we will never go and update a
  30697. 18:51:15primary key value. We always append a
  30698. 18:51:18new primary key value and that's why
  30699. 18:51:20primary keys are perfect for clustered
  30700. 18:51:23index. And one more thing where I go and
  30701. 18:51:25use clustered index is that to optimize
  30702. 18:51:27the performance of a range query. If you
  30703. 18:51:30are quering the data between one value
  30704. 18:51:32and another one clusters index works
  30705. 18:51:34really well. Now in the other hand if we
  30706. 18:51:36are talking about the non-clustered
  30707. 18:51:37index we could use it on coms that are
  30708. 18:51:40used in the search conditions or if you
  30709. 18:51:42are joining tables without using the
  30710. 18:51:44primary keys then you can go and apply
  30711. 18:51:46the nclustered index in order to have
  30712. 18:51:48faster joins or you can go and use it to
  30713. 18:51:50optimize the performance if you are
  30714. 18:51:52searching for an exact value exact
  30715. 18:51:55match. So those are the main and
  30716. 18:51:57important differences between the
  30717. 18:51:59clustered and the nclustered indexes.
  30718. 18:52:05All right. So now before we go to SQL
  30719. 18:52:07and start practicing, I would like to
  30720. 18:52:09show you the syntax of the index. So
  30721. 18:52:12it's very very simple. It start with
  30722. 18:52:14create and then we can define whether it
  30723. 18:52:17is clustered or nonclustered and then
  30724. 18:52:19the keyword index. But this section is
  30725. 18:52:22optional. So if you don't define
  30726. 18:52:24anything, the default going to be the
  30727. 18:52:26nonclustered. So if you say create index
  30728. 18:52:29the SQL server going to go and create
  30729. 18:52:31nclustered index. Then after that we
  30730. 18:52:33have to go and define the name of the
  30731. 18:52:35index and then we have to tell SQL which
  30732. 18:52:38table we have to create the index in on
  30733. 18:52:40table name and then we can go and define
  30734. 18:52:44one column or multiple columns for the
  30735. 18:52:46index and we call an index with multiple
  30736. 18:52:49columns as composite index. So for
  30737. 18:52:51example we can go and create a clustered
  30738. 18:52:53index using this command create
  30739. 18:52:56clustered index the index name and then
  30740. 18:52:58we specify the table and the ID. So we
  30741. 18:53:01are saying create clustered index based
  30742. 18:53:04on this column the ID from the table
  30743. 18:53:06customers. And if you want to create a
  30744. 18:53:08nclustered index you say create
  30745. 18:53:10nclustered index and the same thing. So
  30746. 18:53:12so far we are using one column in the
  30747. 18:53:14index but we can go and create a
  30748. 18:53:16composite index with multiple columns
  30749. 18:53:18like the following example. So we can
  30750. 18:53:20say create an index and as you can see
  30751. 18:53:22we skipped here defining the type and
  30752. 18:53:25that's because the default going to be
  30753. 18:53:27nonclustered index. And now here we are
  30754. 18:53:29specifying two columns the last name and
  30755. 18:53:31the first name. And as you can see we
  30756. 18:53:33specifying as well for SQL how to sort
  30757. 18:53:36the data. So we are saying last name
  30758. 18:53:38should be sorted inside the data page
  30759. 18:53:41ascending lowest to the highest but the
  30760. 18:53:44first name should be the way around from
  30761. 18:53:46the highest to the lowest. So you can
  30762. 18:53:48control how the data going to be sorted
  30763. 18:53:50physically in the data page. So as you
  30764. 18:53:52can see it is very simple. This is the
  30765. 18:53:54syntax for creating index in SQL. All
  30766. 18:53:57right. So back to SQL and the first
  30767. 18:53:59question is where do we find indexes in
  30768. 18:54:01the database? Well you can go and
  30769. 18:54:03explore it. If you go to the object
  30770. 18:54:05explorer over here and check any tables
  30771. 18:54:06from our sales DB for example the
  30772. 18:54:08customers and here you have a folder
  30773. 18:54:10called indexes. So if you expand it you
  30774. 18:54:13will find here an index. I didn't create
  30775. 18:54:16any of those indexes in the database.
  30776. 18:54:18But in SQL server, if you define any of
  30777. 18:54:20the columns as a primary key, the SQL
  30778. 18:54:23server going to go by default creating a
  30779. 18:54:26clustered index for the primary key
  30780. 18:54:29because it makes always sense to create
  30781. 18:54:30a clustered index on the primary key. So
  30782. 18:54:33this one is created as a default and as
  30783. 18:54:35you can see at the start we have like a
  30784. 18:54:36key primary key customer and then it is
  30785. 18:54:39clustered. Now I would like to start
  30786. 18:54:40from the scratch. That's why I would
  30787. 18:54:42like to go and create a new table
  30788. 18:54:44without any indexes. So what we're going
  30789. 18:54:46to do, we're going to go and load the
  30790. 18:54:48table customers into a new table. So how
  30791. 18:54:50we going to do that? We're going to go
  30792. 18:54:51and say select star from sales
  30793. 18:54:56customers and before the from we're
  30794. 18:54:58going to say into a new table. So it's
  30795. 18:55:01going to be TB customers. So like this.
  30796. 18:55:05Let's go ahead and execute it. So now if
  30797. 18:55:07you go to the left side and refresh the
  30798. 18:55:09tables you can find we have now a new
  30799. 18:55:11table called DB customers. Now let's go
  30800. 18:55:14and check whether we have any indexes
  30801. 18:55:15inside it. So indexes it is empty. So we
  30802. 18:55:19don't have anything no clustered index
  30803. 18:55:21or anything else. And this table has the
  30804. 18:55:23structure of heap structure. So the data
  30805. 18:55:27are inserted there randomly. It is not
  30806. 18:55:29sorted. And if I go over here and for
  30807. 18:55:31example, let's say I'm going to select
  30808. 18:55:34from this new
  30809. 18:55:35table where customer ID equal one and I
  30810. 18:55:40execute it. The SQL server did a full
  30811. 18:55:43scan on the table in order to find this
  30812. 18:55:46customer ID. So our new table DB
  30813. 18:55:48customers is heap cluster. But let's go
  30814. 18:55:52and change that. What we're going to do,
  30815. 18:55:53we're going to go and create a new
  30816. 18:55:55clustered index. So we're going to say
  30817. 18:55:57create
  30818. 18:55:59clustered index and then we're going to
  30819. 18:56:01go and give it a name for the index. We
  30820. 18:56:04usually follow the following index. So
  30821. 18:56:06we have index as prefix and then after
  30822. 18:56:08that we specify the table name. So DB
  30823. 18:56:11customers and then the key for the
  30824. 18:56:14index. So the column that we are using
  30825. 18:56:16in order to index the table. This is
  30826. 18:56:18important to stick with the same naming
  30827. 18:56:20convention for the index name because
  30828. 18:56:22later as you are monitoring your
  30829. 18:56:24indexes, it's going to be really easy to
  30830. 18:56:25understand. Okay, this index is for the
  30831. 18:56:28table DB customers and we are using the
  30832. 18:56:30customer ID to index. So now after that
  30833. 18:56:33we're going to go specify on which table
  30834. 18:56:35we are doing the index. So on sales DB
  30835. 18:56:40customers and then we're going to
  30836. 18:56:42specify the column name. So we are
  30837. 18:56:44saying build for me a clustered index
  30838. 18:56:46based on the customer ID. So now let's
  30839. 18:56:49go and execute it. So as you can see
  30840. 18:56:51it's very fast because we have only five
  30841. 18:56:53rows. So the database just switched all
  30842. 18:56:55the data pages very fast. Now let's go
  30843. 18:56:58and check our new index. So let's go and
  30844. 18:57:00refresh and let's go inside it. And now
  30845. 18:57:02we can see that we have our new index
  30846. 18:57:04clustered index based on the customer
  30847. 18:57:06ID. Now as we learned we cannot create
  30848. 18:57:08multiple clustered index. But let's go
  30849. 18:57:10and test that. So I will just take the
  30850. 18:57:13whole thing and let's say I would like
  30851. 18:57:15to create a class index based on the
  30852. 18:57:17first
  30853. 18:57:18name as well
  30854. 18:57:22here. So let's go and execute it. So as
  30855. 18:57:25you can see saying you cannot create
  30856. 18:57:28more than one clustered index on this
  30857. 18:57:30table. That means we can create only one
  30858. 18:57:32clustered index. And let's say that
  30859. 18:57:35after you created the index you chose
  30860. 18:57:37the wrong column and you would like to
  30861. 18:57:39change it to the first name. So what
  30862. 18:57:42we're going to do, we have to go and
  30863. 18:57:43drop the index. So we say drop index and
  30864. 18:57:48then you need the index name. It was
  30865. 18:57:50this one. And then you have to specify
  30866. 18:57:52which table. So it's going to be sales
  30867. 18:57:55DB
  30868. 18:57:57customers like this. So if I do it like
  30869. 18:58:01this and let's go and refresh again. You
  30870. 18:58:03can see that we don't have any indexes
  30871. 18:58:05anymore and the table is packed as a hip
  30872. 18:58:08structure. And now you can go and create
  30873. 18:58:10the correct clustered index for this
  30874. 18:58:12table. But to be honest, I'm going to
  30875. 18:58:14stick with the customer ID. So I will
  30876. 18:58:16not create a clustered index on the
  30877. 18:58:18first name because the first name of
  30878. 18:58:19course is not unique. You can have like
  30879. 18:58:21maybe multiple customers having the same
  30880. 18:58:23name. And as well updates could happen
  30881. 18:58:26on the first name and that's going to be
  30882. 18:58:27very expensive. So that means I'm going
  30883. 18:58:29to stick with my index on the customer
  30884. 18:58:32ID. Let's go and execute it. And now I
  30885. 18:58:34have again my index on my table. Now
  30886. 18:58:38let's say that that I have the following
  30887. 18:58:40select statements from our tables. So
  30888. 18:58:44customers and I'm searching for the last
  30889. 18:58:48name where let's say we are searching
  30890. 18:58:50for brown. So let's go and execute it.
  30891. 18:58:53So let's say that we are getting more
  30892. 18:58:54and more customers and our table is
  30893. 18:58:56getting bigger and I frequently use this
  30894. 18:58:59query. So I'm searching for specific
  30895. 18:59:01customers using the last name. So what
  30896. 18:59:04we can do, we can go and create a
  30897. 18:59:06nonclustered index for the last name in
  30898. 18:59:08order to improve the performance of this
  30899. 18:59:10query. So let's go and create that. So
  30900. 18:59:12we're going to say create
  30901. 18:59:14nonclustered index. And now we're going
  30902. 18:59:17to give it the name using the naming
  30903. 18:59:18convention. So DB customers and we're
  30904. 18:59:22going to use the last name for this
  30905. 18:59:23index. So on
  30906. 18:59:26sales DB customers and we will use the
  30907. 18:59:30column last name for the index. So let's
  30908. 18:59:33go and execute it. And now if you go to
  30909. 18:59:36our indexes and refresh, we will find
  30910. 18:59:39our new index over here. And as you can
  30911. 18:59:42see, it says it is nonclustered and as
  30912. 18:59:45well non-unique. We will talk about the
  30913. 18:59:47uniqueness later. So as you can see,
  30914. 18:59:48it's very easy. We have just created a
  30915. 18:59:50uncclustered index on the last name. And
  30916. 18:59:52now as we learned, we can go and create
  30917. 18:59:54multiple nonclustered index on the same
  30918. 18:59:57table. Let's say for example, now we our
  30919. 19:00:00query looks like this. We are searching
  30920. 19:00:01for the first name using for example the
  30921. 19:00:04value Anna. And now this query happens a
  30922. 19:00:07lot and maybe slow. So we can go and
  30923. 19:00:09create new nonclustered index. So let me
  30924. 19:00:12just have it like this. And for the
  30925. 19:00:14nonclustered index you don't have to
  30926. 19:00:16specify always like nonclustered index.
  30927. 19:00:19As default it's going to be
  30928. 19:00:20nonclustered. So we can skip that. And
  30929. 19:00:23here let's call it first name. And the
  30930. 19:00:26column that we are using is the first
  30931. 19:00:29name. So let's go and create this index.
  30932. 19:00:33And now let's go and refresh our
  30933. 19:00:35indexes. And as you can see, SQL did
  30934. 19:00:37create a nonclustered index for the
  30935. 19:00:40first name. So if you don't specify the
  30936. 19:00:42type of the index, it's going to be as a
  30937. 19:00:44default nonclustered
  30938. 19:00:49index. All right. So now let's talk
  30939. 19:00:51about the composite index. It is an
  30940. 19:00:53index that has multiple columns inside
  30941. 19:00:56the same index. So far we have used only
  30942. 19:00:59one column in the index but we can go
  30943. 19:01:02and specify multiple columns and that's
  30944. 19:01:04because sometimes our wear conditions
  30945. 19:01:07are complicated and based on multiple
  30946. 19:01:09columns. So for example let's say that
  30947. 19:01:11we are searching for country equal to
  30948. 19:01:15USA and at the same time we are saying
  30949. 19:01:18the score should be higher than 500. So
  30950. 19:01:21that means in this condition we are
  30951. 19:01:23using two columns and we would like to
  30952. 19:01:25speed up this query. So how we going to
  30953. 19:01:27do it? So we're going to go and create
  30954. 19:01:29let's say an index and give it a name DB
  30955. 19:01:33customers and let's say country score on
  30956. 19:01:39sales DB customers. And now it is very
  30957. 19:01:43important to do the following thing. Now
  30958. 19:01:45we have to go and define a list of
  30959. 19:01:48columns that we want to be included in
  30960. 19:01:50this index. And it is very crucial and
  30961. 19:01:53important that you get the same order as
  30962. 19:01:56your query. So your query start with the
  30963. 19:01:59country and then the score. You have to
  30964. 19:02:02do it the same thing in the index. So
  30965. 19:02:04the first column it's going to be the
  30966. 19:02:06country and then the score. So it must
  30967. 19:02:09be the same order as your query. So
  30968. 19:02:12let's go and create this index. And if
  30969. 19:02:15you go to the indexes over here, you can
  30970. 19:02:16see that we have created our new index.
  30971. 19:02:19So now once you create such a index and
  30972. 19:02:22your table going to be like always
  30973. 19:02:24updating this index you have to be
  30974. 19:02:25committed and responsible. So in your
  30975. 19:02:28queries if you want to filter the data
  30976. 19:02:29using country and score always start
  30977. 19:02:32with the country then the score in order
  30978. 19:02:34to be able to use the index optimizer.
  30979. 19:02:38So if you do it like this the index
  30980. 19:02:40going to be working but if you go and
  30981. 19:02:42query the way around. So you start with
  30982. 19:02:45the score and then the country the SQL
  30983. 19:02:48will not be using your index. So either
  30984. 19:02:51you adjust your queries or you have to
  30985. 19:02:54go and recreate the index based on this
  30986. 19:02:57switch. So be very careful with the
  30987. 19:02:59composite indexes. The order is very
  30988. 19:03:02crucial. So you're going to have it
  30989. 19:03:04exactly like the query. And now you
  30990. 19:03:07might say you know what now we have like
  30991. 19:03:08a nice index for those two columns. What
  30992. 19:03:11going to happen if I go and use in my
  30993. 19:03:14query only one of them like for example
  30994. 19:03:16the country. So now the question is if I
  30995. 19:03:18go and execute this query is the SQL is
  30996. 19:03:22using this index even though that I
  30997. 19:03:24don't have the score. Well yes because
  30998. 19:03:27it follows the leftmost prefix rule. So
  30999. 19:03:30this means SQL can use the index if you
  31000. 19:03:33are using always the lift columns. So
  31001. 19:03:36here in our index country is on the left
  31002. 19:03:39that's why it is working over here. But
  31003. 19:03:42if you go and skip the lift column it
  31004. 19:03:44will not work. So if you go over here
  31005. 19:03:46for example and say let's go and select
  31006. 19:03:49only the
  31007. 19:03:51score and it is like higher than 500.
  31008. 19:03:55What we have done, we have skipped the
  31009. 19:03:57country in this query and that's why it
  31010. 19:04:00will not be working. So as long as you
  31011. 19:04:02are including the left columns, it will
  31012. 19:04:05work even though it is only one column.
  31013. 19:04:07So in this scenario, the first query
  31014. 19:04:09going to use the index, the second one
  31015. 19:04:12will not be using it. So now let me give
  31016. 19:04:13you a very simple example in order to
  31017. 19:04:15understand how this works. So let's say
  31018. 19:04:17that we have an index using four columns
  31019. 19:04:20A, B, C, D. Now in your query if you go
  31020. 19:04:22and target the column A the index going
  31021. 19:04:24to be used. Now the same thing going to
  31022. 19:04:26happen if you go and use A and P. So if
  31023. 19:04:29you're using those two columns you will
  31024. 19:04:31be using the index. So those are where
  31025. 19:04:34the index will be used. So now let's
  31026. 19:04:38have the scenarios where the index wants
  31027. 19:04:42be used. So for example if you go and
  31028. 19:04:44just jump immediately to the column B.
  31029. 19:04:47So you are not using the left column the
  31030. 19:04:49A that's why you will not be using the
  31031. 19:04:52index and as well in your query if you
  31032. 19:04:54are using A and you are skipping the P.
  31033. 19:04:56So you have A and then C you will not be
  31034. 19:05:00using the index. So you have always to
  31035. 19:05:02use always the lift columns. So here if
  31036. 19:05:05you are using A B C you will be using
  31037. 19:05:08the index. And let's see here you are
  31038. 19:05:09using A B and then you jump and skip to
  31039. 19:05:12the D you will not be using the index.
  31040. 19:05:14So this is what we mean with the
  31041. 19:05:15leftmost prefix rule by using the
  31042. 19:05:18composite index. So if you're using
  31043. 19:05:20multiple columns inside one index, be
  31044. 19:05:22careful with the order of the columns
  31045. 19:05:24that you are defining. All right. So
  31046. 19:05:26that's all for this category, clustered
  31047. 19:05:28and uncclustered index. Now we're going
  31048. 19:05:30to move to the second category where we
  31049. 19:05:32talk about the indexes by the storage,
  31050. 19:05:35the row store and the column store.
  31051. 19:05:41So now let's say that we have a table we
  31052. 19:05:43have multiple rows and multiple columns.
  31053. 19:05:45Now if we use a row store index this is
  31054. 19:05:48the classical one. What going to happen?
  31055. 19:05:50Our table going to be splitted into
  31056. 19:05:52multiple rows. And as we learned each
  31057. 19:05:54group of rows going to be stored inside
  31058. 19:05:56a data page. So that means we are
  31059. 19:05:58organizing the data row by row which
  31060. 19:06:01means all the columns for each row going
  31061. 19:06:04to be stored together. This is the
  31062. 19:06:06traditional way on how the databases
  31063. 19:06:09organize their data where the
  31064. 19:06:11informations are stored row by row. But
  31065. 19:06:13now in the other side if you use column
  31066. 19:06:15store index the SQL going to go and
  31067. 19:06:17split your table into multiple separate
  31068. 19:06:19columns and then SQL going to go and
  31069. 19:06:21store the values of one column together
  31070. 19:06:24in data page. So that means if you go
  31071. 19:06:26and open a data page you will find only
  31072. 19:06:29the values of one column. You will not
  31073. 19:06:31find the entire row. So if it's like the
  31074. 19:06:34first name you will see only the first
  31075. 19:06:36name informations you will not see the
  31076. 19:06:37last name information in this data page.
  31077. 19:06:39So if you compare them the row store
  31078. 19:06:41index stores the data row by row the
  31079. 19:06:44column store index stores the data
  31080. 19:06:46column by column. So this is a very high
  31081. 19:06:48level representation on how the column
  31082. 19:06:50store index is stored. As you know me we
  31083. 19:06:53go in details in order to understand
  31084. 19:06:55exactly how SQL works with the column
  31085. 19:06:58store index. So let's go.
  31086. 19:07:03All right. So now let's say that we have
  31087. 19:07:05a table for the customers. We have three
  31088. 19:07:07columns ID, name and status. And as well
  31089. 19:07:10we have around 2 million rows, 2 million
  31090. 19:07:12customers. And as we learned as a
  31091. 19:07:14default, the table going to be built as
  31092. 19:07:16a heap structure where the rows are
  31093. 19:07:18stored row by row inside data pages. But
  31094. 19:07:20now we go and create a column store
  31095. 19:07:23index on top of this table. So now once
  31096. 19:07:25you do that SQL going to go through a
  31097. 19:07:28process in order to build the column
  31098. 19:07:30store. So the first step is SQL going to
  31099. 19:07:32go and divide the data the rows into row
  31100. 19:07:35groups. Now in SQL server each row group
  31101. 19:07:38can contain around like 1 million row.
  31102. 19:07:40So in this example our table going to be
  31103. 19:07:42splitted into two row groups. The first
  31104. 19:07:45one million row in one group and the
  31105. 19:07:47second one in another row group. Now you
  31106. 19:07:49might ask me we are talking about
  31107. 19:07:50columns. Why we are splitting the rows?
  31108. 19:07:53Well, this is just a pre-step in order
  31109. 19:07:55just to optimize the performance and to
  31110. 19:07:57do parallel processing. And of course,
  31111. 19:07:59the data will not be stored like this
  31112. 19:08:01because we have the second step. Now, in
  31113. 19:08:03the next step, SQL going to go and
  31114. 19:08:05segment the columns. So now, SQL will go
  31115. 19:08:08for each row group and start splitting
  31116. 19:08:10the data by the columns. And that's why
  31117. 19:08:13we call it a column store because we are
  31118. 19:08:15separating the columns from each others.
  31119. 19:08:17So that means we have one segment for
  31120. 19:08:19the ID, another one for the name and a
  31121. 19:08:22third one for the status. And this can
  31122. 19:08:24happen for each row group. And now it's
  31123. 19:08:26going to move to the third step in this
  31124. 19:08:28process. We have the data compression.
  31125. 19:08:31And this is the most important step in
  31126. 19:08:33this process because it is the reason
  31127. 19:08:36why column store is very fast compared
  31128. 19:08:38to the ro store. So in this process
  31129. 19:08:41there are like different techniques on
  31130. 19:08:42how to do data compression and the most
  31131. 19:08:45famous one is that it's going to go and
  31132. 19:08:47create like a dictionary. Let's take for
  31133. 19:08:49example the column status the status of
  31134. 19:08:52the customer whether it is active or
  31135. 19:08:54inactive. So the word active and
  31136. 19:08:56inactive going to be repeated like 2
  31137. 19:08:59million times because we have 2 million
  31138. 19:09:01customers and since it is like string it
  31139. 19:09:03is like taking a lot of space and
  31140. 19:09:05storage. But now instead of that we're
  31141. 19:09:07going to go and compress the data. So
  31142. 19:09:09first it's going to go and create a
  31143. 19:09:10dictionary by replacing the value active
  31144. 19:09:14and inactive into smaller values like
  31145. 19:09:16one and two. So we have like a mapping
  31146. 19:09:19between the long value to a small value.
  31147. 19:09:22And after that SQL going to store like a
  31148. 19:09:25data stream where we have like only two
  31149. 19:09:27values one two one two. So we're going
  31150. 19:09:29to have like a big stream of 2 million
  31151. 19:09:31rows. So it's going to go and do this
  31152. 19:09:33for each column and with that the size
  31153. 19:09:35of each column going to be changed
  31154. 19:09:37depends of course on how much different
  31155. 19:09:39values you have in each column. So this
  31156. 19:09:41step is very important in order to
  31157. 19:09:43reduce the size of the data and as well
  31158. 19:09:45to increase the performance. So now once
  31159. 19:09:48everything is organized and compressed,
  31160. 19:09:50SQL going to go and start storing the
  31161. 19:09:53results in databases. But TSQL will not
  31162. 19:09:56use the standard databases that we have
  31163. 19:09:58learned previously. But instead going to
  31164. 19:10:00use a special database called LOB large
  31165. 19:10:04object page. So now let's quickly
  31166. 19:10:06compare the structure of the normal
  31167. 19:10:07database that we have learned in the row
  31168. 19:10:09store with the new one, the column
  31169. 19:10:11store, the LOB data page. So as usual
  31170. 19:10:14each page has a header. This is same as
  31171. 19:10:16any data page. But the next section is
  31172. 19:10:18going to be the segment header. It has
  31173. 19:10:20like metadata informations about the
  31174. 19:10:23column segment that is stored in this
  31175. 19:10:25page. Like we have the segment ID, the
  31176. 19:10:28row group ID, the column ID and it has
  31177. 19:10:31as well very important information the
  31178. 19:10:33ID to the dictionary page. So the
  31179. 19:10:35dictionary page is as well a type of
  31180. 19:10:38pages in SQL. It has as well a header
  31181. 19:10:41but inside it we have like a mapping. So
  31182. 19:10:43it maps the original value, the long
  31183. 19:10:45one, the inactive to the smaller version
  31184. 19:10:48of this value, for example, one. And
  31185. 19:10:50that's all for the dictionary page. It
  31186. 19:10:52has the mapping between the original
  31187. 19:10:54values and the smaller values. And
  31188. 19:10:56beneath the segment header, we can have
  31189. 19:10:58now the important place where our data
  31190. 19:11:00can be stored. We have the data stream.
  31191. 19:11:03So it is like sequence of ids from the
  31192. 19:11:05dictionary that represents the values of
  31193. 19:11:08the columns side by side. And of course,
  31194. 19:11:11we cannot fit the whole 1 million rows
  31195. 19:11:13inside this data stream. We're going to
  31196. 19:11:15have like multiple LOP databases. So
  31197. 19:11:18this is how exactly the SQL stores your
  31198. 19:11:21data. If you decided to go with the
  31199. 19:11:23column store, so let's go back to the
  31200. 19:11:25process. So back to the process. As you
  31201. 19:11:27can see, SQL is storing the data as LO
  31202. 19:11:30data storage. So this is the last step
  31203. 19:11:32and with that SQL did convert your table
  31204. 19:11:35into a column store. So now we cannot
  31205. 19:11:37just create a column store without
  31206. 19:11:39defining whether it is clustered index
  31207. 19:11:42or non-clustered index. So let's start
  31208. 19:11:44with the first one the clustered column
  31209. 19:11:46store index. So if you create such a
  31210. 19:11:48index SQL of course will not be building
  31211. 19:11:51a B3 structure. SQL going to use exactly
  31212. 19:11:54this structure the column store
  31213. 19:11:56structure. So as we learned the cluster
  31214. 19:11:58index is a complete makeover of your
  31215. 19:12:00table. when you apply it then SQL going
  31216. 19:12:02to format everything column-wise and it
  31217. 19:12:05is fully replacing the old row based
  31218. 19:12:08table structure that we have at the
  31219. 19:12:09start. So once you apply the clustered
  31220. 19:12:12column store index it will not leave
  31221. 19:12:14anything behind and your table going to
  31222. 19:12:16be completely structured as a column
  31223. 19:12:18store and one more thing which is makes
  31224. 19:12:20sense of course all the columns from the
  31225. 19:12:23original table going to be converted to
  31226. 19:12:24a column store. So it is not leaving
  31227. 19:12:27anything behind it. But in the other
  31228. 19:12:29hand, if you are using non-clustered
  31229. 19:12:31column store index, as we learned, it is
  31230. 19:12:34like a companion to your existing table.
  31231. 19:12:37So it coexist with the table and it will
  31232. 19:12:39not replace anything. So the column
  31233. 19:12:42store index can be an additional thing
  31234. 19:12:44that is stored beside your table. So
  31235. 19:12:47that means the original table will not
  31236. 19:12:49be deleted at all like the clustered
  31237. 19:12:51column store index. The first one is in
  31238. 19:12:54the old row based storage. the regular
  31239. 19:12:56table, the first one, and your data
  31240. 19:12:58going to be as well stored in a separate
  31241. 19:13:01structure in the column store index. And
  31242. 19:13:03of course, in the non-clustered column
  31243. 19:13:05store index, since we are creating an
  31244. 19:13:08extra index outside of your original
  31245. 19:13:10table, you can go and define which
  31246. 19:13:12column should be included in this
  31247. 19:13:13process. It must not be all the columns.
  31248. 19:13:16You can go for example with only the
  31249. 19:13:17status. So that means you build a column
  31250. 19:13:20store index only for one column for the
  31251. 19:13:22status of the customers. So this is what
  31252. 19:13:24we mean with the clustered column store
  31253. 19:13:26index and the nclustered column store
  31254. 19:13:32index. All right friends, so now you
  31255. 19:13:35might ask me why we are doing all those
  31256. 19:13:36stuff. Why I would split my data by the
  31257. 19:13:39columns? Well, it's all because of
  31258. 19:13:42analytics. Because in analytics we have
  31259. 19:13:44like big complex query where we have a
  31260. 19:13:46lot of data aggregations and stuff on
  31261. 19:13:48big tables. And the roster index is
  31262. 19:13:51perfectly designed in order to improve
  31263. 19:13:54the performance of such big queries. And
  31264. 19:13:56that's why SQL databases like SQL server
  31265. 19:13:59and as well BI tools like Tableau and
  31266. 19:14:01PowerBI did adopt this methods in order
  31267. 19:14:05to offer fast platform for data
  31268. 19:14:07analyzes. So now let's understand
  31269. 19:14:09exactly why the column store index is
  31270. 19:14:12way faster for data analyzes than the
  31271. 19:14:14row store index. So let's go. So again
  31272. 19:14:16we have the customers tables and let's
  31273. 19:14:18say we have like five customers where we
  31274. 19:14:20have ID, name and status and as we
  31275. 19:14:22learned before if we are using roster
  31276. 19:14:24index the data can be stored in multiple
  31277. 19:14:26databases and in each database we're
  31278. 19:14:28going to have the whole record the whole
  31279. 19:14:30information about one customer. So for
  31280. 19:14:33this example we're going to have like
  31281. 19:14:34three databases but if you are using the
  31282. 19:14:36column store index it's going to be
  31283. 19:14:38stored little bit differently. So the
  31284. 19:14:40first column the id going to be stored
  31285. 19:14:41in one data page and here the SQL will
  31286. 19:14:43not go and build a dictionary because
  31287. 19:14:45the ids are already short. So we're
  31288. 19:14:47going to have like one data stream with
  31289. 19:14:49all ids and now for the next column name
  31290. 19:14:51is going to be stored in separate data
  31291. 19:14:53page where we're going to have an extra
  31292. 19:14:55dictionary page where each name going to
  31293. 19:14:57be mapped to one small value. So the
  31294. 19:14:59data going to be compressed and we're
  31295. 19:15:00going to save storage. Now the database
  31296. 19:15:02going to create for the third column the
  31297. 19:15:04status one more data page and the
  31298. 19:15:06dictionary here going to be very small.
  31299. 19:15:08So for active we're going to have one
  31300. 19:15:09and for the inactive we're going to have
  31301. 19:15:11two and in the data stream we will be
  31302. 19:15:13storing only the ids of the dictionary.
  31303. 19:15:15So now let's understand why the column
  31304. 19:15:17store is faster. Let's have the
  31305. 19:15:19following query. We want to find the
  31306. 19:15:21total number of customers that are
  31307. 19:15:23active. So we have the query select
  31308. 19:15:26count star from customers and we're
  31309. 19:15:28going to filter the data by the status
  31310. 19:15:30where it is equal to active. So now if
  31311. 19:15:32we query the table with the row store
  31312. 19:15:34what can happen? SQL have first to go
  31313. 19:15:36and collect the data. So it's going to
  31314. 19:15:38go to the first data page and collect
  31315. 19:15:39the first two customer then to the
  31316. 19:15:41second to the third and so on. And as
  31317. 19:15:43you can see SQL here is reading
  31318. 19:15:45everything the whole row the ID the name
  31319. 19:15:48the status even though that for the
  31320. 19:15:50query we actually we don't need all
  31321. 19:15:52those informations we just need to count
  31322. 19:15:54how many customers we need with the
  31323. 19:15:56status active but still cannot go and
  31324. 19:15:59selectively only reading the status has
  31325. 19:16:03to read the whole record. So after SQL
  31326. 19:16:05has all the data it's going to go and
  31327. 19:16:07filter the data. So it's going to go and
  31328. 19:16:08remove the inactive rows and then SQL
  31329. 19:16:11going to do the aggregate operation and
  31330. 19:16:13with that we're going to get three rows.
  31331. 19:16:16So that's why the total count of active
  31332. 19:16:18customers going to be three. But now
  31333. 19:16:19let's see how SQL going to query the
  31334. 19:16:22column store. So SQL first have to
  31335. 19:16:23analyze okay which columns do I need
  31336. 19:16:26actually for this query. Well, we need
  31337. 19:16:28only the status. So SQL will not go and
  31338. 19:16:31open all three data pages and read it.
  31339. 19:16:33SQL will target only one data page the
  31340. 19:16:36database where we have the column
  31341. 19:16:37status. So it's going to take this very
  31342. 19:16:39simple data stream and then it's going
  31343. 19:16:41to go and understand the dictionary and
  31344. 19:16:43it going to go and remove all the values
  31345. 19:16:45where it is equal to two. So without in
  31346. 19:16:47the output we have only three values and
  31347. 19:16:49SQL going to go and do a very quick
  31348. 19:16:51count for those values. So in the output
  31349. 19:16:53we will get as well three total number
  31350. 19:16:55of active customers. So now if you
  31351. 19:16:57compare this intermediate result sets
  31352. 19:17:00from the row store and the column store
  31353. 19:17:02you can see that in the row store we
  31354. 19:17:04have fetched and retrieved a lot of
  31355. 19:17:06unnecessary informations for this query
  31356. 19:17:08and this of course going to make the
  31357. 19:17:10speed of the query very slow but in the
  31358. 19:17:13column store reads exactly what it needs
  31359. 19:17:15for this aggregation and we didn't read
  31360. 19:17:18any extra informations about the names
  31361. 19:17:20of the customers the ids it didn't like
  31362. 19:17:23open any extra data pages it exactly
  31363. 19:17:25gets the data that it needs for the
  31364. 19:17:28aggregation and that's exactly why the
  31365. 19:17:30performance of queries where we have
  31366. 19:17:32aggregations and data analyzes is going
  31367. 19:17:35to be very fast if you are using column
  31368. 19:17:37store compared to the row store. So
  31369. 19:17:40that's why we use column store for big
  31370. 19:17:42data and data analytics. All right. So
  31371. 19:17:44now let's summarize the differences
  31372. 19:17:46between the row store and the column
  31373. 19:17:47store indexes side by side. So let's
  31374. 19:17:50start by the definition. The row store
  31375. 19:17:52going to go and organize and store the
  31376. 19:17:53data row by row. It is really nice
  31377. 19:17:55method if you need a lot of columns in
  31378. 19:17:57one row. But in the other hand, the
  31379. 19:17:59column store index going to go and store
  31380. 19:18:01the data and organize it column by
  31381. 19:18:03column which is really great if you're
  31382. 19:18:05focusing on specific column. Now if you
  31383. 19:18:07are talking about the storage
  31384. 19:18:08efficiency, the row store index going to
  31385. 19:18:10take more space compared to the column
  31386. 19:18:13store index and that's because as we
  31387. 19:18:14learned the column store going to go and
  31388. 19:18:16compress the data which going to save a
  31389. 19:18:18lot of storage if you have large tables.
  31390. 19:18:20Now to the next point which is more
  31391. 19:18:22important about the performance. The
  31392. 19:18:24read and write optimizations we can say
  31393. 19:18:27for the row store things are more
  31394. 19:18:28balanced. So you will get a decent speed
  31395. 19:18:31for both write and read operations but
  31396. 19:18:33things in the column store is different.
  31397. 19:18:36It is fast for reading especially if you
  31398. 19:18:38are doing data analytics but writing
  31399. 19:18:40data like inserting and updating it is
  31400. 19:18:43slower because as we learned there are
  31401. 19:18:45like multiple steps until the data is
  31402. 19:18:48written in the pages. So in one hand you
  31403. 19:18:50are optimizing the speed of your
  31404. 19:18:52analytical queries but in the other hand
  31405. 19:18:55changing data it is slower than the
  31406. 19:18:57roster index. Now let's talk about the
  31407. 19:18:59next point input and output efficiency.
  31408. 19:19:01Well the roster index it's not really
  31409. 19:19:03good because you are retrieving a lot of
  31410. 19:19:05columns. So a lot of data should be read
  31411. 19:19:08from the disk storage in order to answer
  31412. 19:19:10your queries. But in the other hand for
  31413. 19:19:12the column store it is lower and that's
  31414. 19:19:15because it targets exactly the data and
  31415. 19:19:18columns that is needed for the query. So
  31416. 19:19:20there will be generally less data that
  31417. 19:19:22is read from the disk storage and of
  31418. 19:19:24course that's why we are getting fast
  31419. 19:19:26read performance. So now if you are
  31420. 19:19:28thinking which systems are best for ro
  31421. 19:19:30store index well the roster index is
  31422. 19:19:32very suitable for the OLTB systems
  31423. 19:19:35online transactional systems like
  31424. 19:19:37banking and commerce systems where the
  31425. 19:19:40full records are accessed very
  31426. 19:19:42frequently but in the other hand the
  31427. 19:19:44column store index is great for OLAP.
  31428. 19:19:46All app systems are online analytical
  31429. 19:19:49processing where you have like data
  31430. 19:19:51warehouses, data league, business
  31431. 19:19:52intelligence. You are building reports
  31432. 19:19:54and analyzes. You have large data sets
  31433. 19:19:57and very complicated aggregated queries.
  31434. 19:20:00So if you have such a project then the
  31435. 19:20:01column store index is the way to go. So
  31436. 19:20:04that means the use case for the row
  31437. 19:20:06store index if you have high frequency
  31438. 19:20:08transactions where the system has to
  31439. 19:20:10quickly access records and the use case
  31440. 19:20:13for the column store is big data
  31441. 19:20:15analytics where the SQL has to scan
  31442. 19:20:17large data sets. So those are the main
  31443. 19:20:19differences between the row store index
  31444. 19:20:22and the column store
  31445. 19:20:27index. All right. So now let's check the
  31446. 19:20:29syntax of the column store index. Well,
  31447. 19:20:31it is really easy what we're going to
  31448. 19:20:32do. we can just put a column store
  31449. 19:20:34keyword between the clustered or
  31450. 19:20:37nonclustered and the index. So once you
  31451. 19:20:40specify that then you are telling SQL
  31452. 19:20:42you want to create a column store index
  31453. 19:20:44and the rest is going to stay as it is.
  31454. 19:20:46Now if you want to create row column
  31455. 19:20:48store then you don't have to specify
  31456. 19:20:50anything. There is no keyword for the
  31457. 19:20:52row store. So as we learned before we
  31458. 19:20:54can go and create a nonclustered index
  31459. 19:20:56and cluster on the index and both of
  31460. 19:20:57those syntax is going to tell SQL we are
  31461. 19:21:00creating row store index but if you go
  31462. 19:21:03and use the column store keyword then
  31463. 19:21:06you are telling SQL that you want to
  31464. 19:21:07create either clustered or nclustered
  31465. 19:21:10column store index and here there is
  31466. 19:21:11like a syntax rule if you are creating a
  31467. 19:21:14clustered column index then you must not
  31468. 19:21:17specify anything for the columns. So you
  31469. 19:21:19cannot go and specify anything like an
  31470. 19:21:21ID or country or any columns over here
  31471. 19:21:24because it makes no sense once you say
  31472. 19:21:26cluster column store then all the
  31473. 19:21:28columns going to be included in the new
  31474. 19:21:31structure. So this is the syntax of the
  31475. 19:21:34column store index. All right. So back
  31476. 19:21:36to scale let's check how we can create
  31477. 19:21:37column store index. Now if you check our
  31478. 19:21:39table here DB customers that we have
  31479. 19:21:41created previously and we go to the
  31480. 19:21:43indexes you can see that we have created
  31481. 19:21:46few indexes and one of them is the
  31482. 19:21:48clustered index. This one is a row store
  31483. 19:21:52index. So our table is splitted by the
  31484. 19:21:55rows. Now let's go and change that.
  31485. 19:21:57Let's make our table splitted by the
  31486. 19:21:59columns using the column store. So we're
  31487. 19:22:01going to say
  31488. 19:22:02create
  31489. 19:22:04clustered column store index and we're
  31490. 19:22:08going to give it the name index DB
  31491. 19:22:11customers and it's going to be on the
  31492. 19:22:13table sales DB customers and here if you
  31493. 19:22:18go and specify a column it's going to be
  31494. 19:22:20a mistake. So let's go and check that.
  31495. 19:22:23So if you go and execute it says it
  31496. 19:22:25fails because key lists or the columns
  31497. 19:22:28is not allowed. So we cannot have this.
  31498. 19:22:30So let's remove it. And now we have the
  31499. 19:22:32correct syntax. Let's execute it again.
  31500. 19:22:35We will get another error because it
  31501. 19:22:37says in one table you cannot have more
  31502. 19:22:40than one clustered index. We have
  31503. 19:22:42already one. You have to decide do you
  31504. 19:22:44want to split your table by columns or
  31505. 19:22:46by rows. That's why we have to go and
  31506. 19:22:48drop the previous index. So we're going
  31507. 19:22:50to do it like this. Drop index. And I
  31508. 19:22:54need the name of the index like this.
  31509. 19:22:56And then we have to specify the table
  31510. 19:23:01name. So that's it. Let's drop the
  31511. 19:23:04index. Now if you refresh, we cannot see
  31512. 19:23:07anymore our clustered index and our
  31513. 19:23:09query should be working. So let's do
  31514. 19:23:11that. Now let's check the indexes again.
  31515. 19:23:14And now as you can see, we got a new
  31516. 19:23:17clustered index, but this time it is
  31517. 19:23:19column store. Now you can see at the
  31518. 19:23:21start we have like an icon. This looks
  31519. 19:23:23like a bar chart or like analytics and
  31520. 19:23:26reports and that's because the main
  31521. 19:23:27purpose of creating com store is to have
  31522. 19:23:30a bar chart. So now of course we cannot
  31523. 19:23:32go and create multiple clustered column
  31524. 19:23:34index. We can have maximum only one. So
  31525. 19:23:37now if you say you know what let's go
  31526. 19:23:38and create for the first name another
  31527. 19:23:41index but this time it's going to be a
  31528. 19:23:42column store. So if I go and copy the
  31529. 19:23:45whole thing over here and let's say it
  31530. 19:23:47is none clustered column index and let's
  31531. 19:23:51call it for example first
  31532. 19:23:53name and we define over here the first
  31533. 19:23:58name. So that's it. Let's go and execute
  31534. 19:24:01it. You will see that we will get an
  31535. 19:24:03error where SQL tells us you cannot
  31536. 19:24:06create multiple column store indexes.
  31537. 19:24:09That means you can create only one
  31538. 19:24:11column store index for each table and
  31539. 19:24:14you have to decide whether it is a
  31540. 19:24:16clustered or non-clustered and you
  31541. 19:24:18cannot create like the row store
  31542. 19:24:20multiple non-clustered index. So you are
  31543. 19:24:23allowed only with one column store index
  31544. 19:24:26but this limitation is only here in the
  31545. 19:24:28SQL server. In other databases I know
  31546. 19:24:30that is allowed to use multiple column
  31547. 19:24:32store indexes like in the Azure SQL
  31548. 19:24:36server you can do that. So now in order
  31549. 19:24:37to practice and you would like to create
  31550. 19:24:39a nonclustered column store index, you
  31551. 19:24:42can drop the first one and you can go
  31552. 19:24:43and create the one that you need as a
  31553. 19:24:46nclustered index. So actually let's go
  31554. 19:24:48and do that. Let's drop the first one.
  31555. 19:24:50So drop index and this is our index on
  31556. 19:24:55this table. Let's do that. And once you
  31557. 19:24:58execute the nonclustered column store
  31558. 19:25:00index is going to work. And if you
  31559. 19:25:02refresh over here, you will see that we
  31560. 19:25:04have a non-clustered column store index
  31561. 19:25:07for the first name. Okay. So now as we
  31562. 19:25:09learned that the column store going to
  31563. 19:25:11go and compress the data and the storage
  31564. 19:25:13that is needed for the entire table
  31565. 19:25:15going to be less than the row store. So
  31566. 19:25:18let's see whether that is really true.
  31567. 19:25:20Now in order to check this I will not do
  31568. 19:25:22that in the database sales DB because
  31569. 19:25:24everything here is already small. We're
  31570. 19:25:26going to go and use another database. We
  31571. 19:25:28have the adventure works DW2022 and if
  31572. 19:25:32you have a newer version that's okay. So
  31573. 19:25:34now what is the plan? We're going to go
  31574. 19:25:36and create three identical copies of one
  31575. 19:25:38table and we're going to have different
  31576. 19:25:40structures. So the first one going to be
  31577. 19:25:41the heap structure. The second one going
  31578. 19:25:43to be row store structure and the third
  31579. 19:25:46one going to be column store structure
  31580. 19:25:48and then we're going to go and compare
  31581. 19:25:49the storage of those three. So now we
  31582. 19:25:52have to go and pick one of those tables.
  31583. 19:25:54We need one big table. So for example
  31584. 19:25:56the fact internet sales. So let's see
  31585. 19:25:58how we can do that. Let's start with the
  31586. 19:25:59heap structure. We're going to say
  31587. 19:26:01select star into a new table. So it's
  31588. 19:26:05going to be the
  31589. 19:26:06fact internet sales and underscore hp
  31590. 19:26:11for the heap. And we're going to get it
  31591. 19:26:13from the table fact internet sales. So
  31592. 19:26:18like this. And here it's very important
  31593. 19:26:19if you are switching databases you have
  31594. 19:26:21to go and use the database. So it's
  31595. 19:26:23going to be use adventure work DW 2022.
  31596. 19:26:27So execute this at the starts to make
  31597. 19:26:30sure that you are switching to the new
  31598. 19:26:32database. And now let's go and execute
  31599. 19:26:34our heap structure. So with that we have
  31600. 19:26:36created heap table as you can see 60,000
  31601. 19:26:39rows. And since we didn't define any
  31602. 19:26:41clustered index this table going to be
  31603. 19:26:44heap structure. Now let's go and create
  31604. 19:26:46another table where we use clustered row
  31605. 19:26:49store index. So what we're going to do,
  31606. 19:26:51we're going to copy the whole thing over
  31607. 19:26:53here and we're going to call this row
  31608. 19:26:55store and we're going to go of course
  31609. 19:26:57change the name to RS but still we are
  31610. 19:26:59targeting the same table. So let's go
  31611. 19:27:02and execute this at the start. But now
  31612. 19:27:04in order to make it as clustered row
  31613. 19:27:06store we have to go and create an index.
  31614. 19:27:08So it going to be like this create
  31615. 19:27:12clustered index. We don't have to
  31616. 19:27:14specify the row store because it is as a
  31617. 19:27:17default. It's going to be ro store. So
  31618. 19:27:18let's call it
  31619. 19:27:20index facts
  31620. 19:27:23internet sales RS and then the primary
  31621. 19:27:27key. So B key and now we need the
  31622. 19:27:31table fact internet sales RS and now we
  31623. 19:27:36need the columns the primary key well
  31624. 19:27:39actually I don't know what is the
  31625. 19:27:40primary key so let's go and check that
  31626. 19:27:42so it is a composite primary keys so
  31627. 19:27:45it's going to be the sales order number
  31628. 19:27:49and sales order line number like this.
  31629. 19:27:53So let's go and execute this. And with
  31630. 19:27:56that we have clustered row index. I'm
  31631. 19:27:58going to go and check what do we have
  31632. 19:28:00over here. So let's go and refresh
  31633. 19:28:01everything. So we have now two tables
  31634. 19:28:04the heap and the row store. So let's
  31635. 19:28:07extend it and check the indexes. And as
  31636. 19:28:09you can see we have the clustered index.
  31637. 19:28:12Now we need the third table. It's going
  31638. 19:28:14to be the column store index. I'm just
  31639. 19:28:16going to go and copy the whole thing
  31640. 19:28:17over here. So this is the column store
  31641. 19:28:22going to be here CS and CS and of course
  31642. 19:28:27we don't need any columns for the column
  31643. 19:28:29store and don't forget to add the column
  31644. 19:28:32store keyword. So create cluster column
  31645. 19:28:35store index and we have to rename as
  31646. 19:28:37well over here. So let's go and execute
  31647. 19:28:40our new stuff. So we create first the
  31648. 19:28:42table and then we convert it to a column
  31649. 19:28:45store index. So let's go and do that and
  31650. 19:28:48we have to go and refresh and check our
  31651. 19:28:50tables. So this is our third table and
  31652. 19:28:53let's go and check the indexes and we
  31653. 19:28:55have clustered column store. All right.
  31654. 19:28:57So now we are done. We have our three
  31655. 19:28:59different tables. Now let's go and check
  31656. 19:29:01the stoages of those three tables. So
  31657. 19:29:04now let's go and check our first table
  31658. 19:29:05the heap table. So right click on it and
  31659. 19:29:08go to the properties. And now we can see
  31660. 19:29:10here a lot of informations about our
  31661. 19:29:12table. But we are interested on the
  31662. 19:29:13storage. So click here on the page for
  31663. 19:29:16the storage. And now we can see here few
  31664. 19:29:18informations about the storage and one
  31665. 19:29:20of them is the data space. It is around
  31666. 19:29:229 MB and the index space is almost
  31667. 19:29:25nothing. So we don't have anything over
  31668. 19:29:27here. So this is the storage of the heap
  31669. 19:29:30structure. We don't have any indexes.
  31670. 19:29:31Let's go now to the row store. So we're
  31671. 19:29:34going to go to the RS and properties.
  31672. 19:29:37Then let's go to the storage. And now as
  31673. 19:29:39you can see the data space is exactly
  31674. 19:29:41the same. And that's because whether it
  31675. 19:29:43is heap or row store index, we're going
  31676. 19:29:45to store the data in data pages as rows.
  31677. 19:29:48So the size of the data itself will not
  31678. 19:29:50change. It will be sorted differently.
  31679. 19:29:52But what changed here is the size of the
  31680. 19:29:55index. Now we are consuming more storage
  31681. 19:29:58for the index. So that means the overall
  31682. 19:30:01storage of the table with a cluster draw
  31683. 19:30:03store index it is more than the heap
  31684. 19:30:06structure. Let's go and check now our
  31685. 19:30:08column store index. So to the CS and
  31686. 19:30:11let's go to the properties. And now it
  31687. 19:30:13is interesting to see whether our table
  31688. 19:30:15is getting smaller. So let's go to the
  31689. 19:30:17storage. And as you can see the data
  31690. 19:30:19space is around 1 mgabyte compared to
  31691. 19:30:22the 9 mgabyte. I know those are small
  31692. 19:30:25numbers but still it is massively
  31693. 19:30:28reduced space because everything is
  31694. 19:30:30compressed and of course we are not
  31695. 19:30:32using any index spaces because we don't
  31696. 19:30:35have this B3 structure in the column
  31697. 19:30:38store. So as you can see if you compare
  31698. 19:30:39to the others it is the winner. This
  31699. 19:30:42table that is using the column store is
  31700. 19:30:44consuming way less storage than the
  31701. 19:30:47others. So now if you want to rank it
  31702. 19:30:49based on the storage the best one is the
  31703. 19:30:52column store index table. Then the next
  31704. 19:30:55one is the table with the he structure
  31705. 19:30:57and the worst one is the table with the
  31706. 19:31:01row store clustered index. So that's
  31707. 19:31:03true. column store index is consuming
  31708. 19:31:06less space than the other type of
  31709. 19:31:12indexes. All right. So now what is
  31710. 19:31:14unique index? Unique index is a special
  31711. 19:31:16type of indexes that going to make sure
  31712. 19:31:19no duplicates in your data. And there
  31713. 19:31:22are a couple of reasons why is it
  31714. 19:31:23important to have a unique index. The
  31715. 19:31:25first one and the most obvious reason is
  31716. 19:31:28to have data integrity. So the unique
  31717. 19:31:30index going to go and enforce uniqueness
  31718. 19:31:32in your data and that is very helpful.
  31719. 19:31:35For example, if you have a column like
  31720. 19:31:37an email address or a product ID. Having
  31721. 19:31:41duplicate in such a columns can mess up
  31722. 19:31:43your data very badly. So having a unique
  31723. 19:31:46index on a column like an email going to
  31724. 19:31:48make sure there are no sneaky duplicates
  31725. 19:31:50inside your data. And the second
  31726. 19:31:52important reason why unique index is
  31727. 19:31:55important is to improve the performance.
  31728. 19:31:57So for example, if you are searching for
  31729. 19:31:59specific email, the SQL going to start
  31730. 19:32:01searching for the email value and once
  31731. 19:32:04the SQL find the value, the SQL will
  31732. 19:32:06stop searching because we are sure that
  31733. 19:32:08there is no duplicates in the data. So
  31734. 19:32:10with that you are improving the
  31735. 19:32:12performance of your queries. So if you
  31736. 19:32:14are creating an index and you know this
  31737. 19:32:16column is unique then make sure to make
  31738. 19:32:18the index as unique index. So now if you
  31739. 19:32:21have a look again to our clustered index
  31740. 19:32:23where we have the B structure if you
  31741. 19:32:25make this index as unique then you are
  31742. 19:32:28giving an extra task for the SQL that's
  31743. 19:32:31going to go and make sure that all those
  31744. 19:32:34ids of the customer going to be unique.
  31745. 19:32:37So SQL has to guarantee that there are
  31746. 19:32:40no duplicates at all inside your data in
  31747. 19:32:42the databases. So now since we are
  31748. 19:32:45giving SQL an extra task to prove the
  31749. 19:32:48uniqueness of the data building the
  31750. 19:32:50clustered index going to be little bit
  31751. 19:32:52slower. So that means inserting new data
  31752. 19:32:55writing data going to be slower as the
  31753. 19:32:58normal clustered index. But now if you
  31754. 19:33:00are talking about the read performance
  31755. 19:33:02the performance of our query it's going
  31756. 19:33:04to be optimized a little bit faster than
  31757. 19:33:06a normal clustered index. So again this
  31758. 19:33:09tradeoff we are making writing data
  31759. 19:33:12slower but we are gaining more speed on
  31760. 19:33:15the query performance. So this is what
  31761. 19:33:17we mean with unique index. Okay. So
  31762. 19:33:20let's keep extending the syntax of the
  31763. 19:33:22index. So now in order to tell whether
  31764. 19:33:23it is unique or not we can specify it
  31765. 19:33:26exactly at the start. So we say create
  31766. 19:33:29unique is just before the clustered or
  31767. 19:33:31nonclustered and then afterward the cl
  31768. 19:33:33store and nothing changed for the rest.
  31769. 19:33:35So we can specify this keyword to TSQL,
  31770. 19:33:38it should be unique. And if you don't
  31771. 19:33:40write anything before the clustered
  31772. 19:33:42index, it's going to be not unique. So
  31773. 19:33:45for example, this one says create an
  31774. 19:33:47index. So we didn't specify anything
  31775. 19:33:50here, duplicates are allowed in the
  31776. 19:33:52index. But if you go and specify a
  31777. 19:33:54unique index, then the duplicates are
  31778. 19:33:57not allowed. So it is very simple. Okay.
  31779. 19:33:59So now let's go and create unique
  31780. 19:34:01cluster. Now let's go and target the
  31781. 19:34:03table products. Let's go and first
  31782. 19:34:05select the data from the table. So sales
  31783. 19:34:10products and execute it. Now let's see
  31784. 19:34:12that I'm going to go and create a unique
  31785. 19:34:14index on the column category. Let's go
  31786. 19:34:17and try it. So create unique
  31787. 19:34:21nonclustered index and let's give it the
  31788. 19:34:24name index products
  31789. 19:34:29category on the table sales products and
  31790. 19:34:33we are targeting the column category. So
  31791. 19:34:37let's go and execute it. Now we will get
  31792. 19:34:40an error because the category has
  31793. 19:34:43duplicates. So if you go and query again
  31794. 19:34:45our table, you can see we have here
  31795. 19:34:47duplicate values and the SQL cannot go
  31796. 19:34:50and create unique index for this table.
  31797. 19:34:53It's too late. But you still can create
  31798. 19:34:55this index if the table is empty and SQL
  31799. 19:34:57will not allow you to insert any
  31800. 19:34:59duplicates about the categories. And of
  31801. 19:35:02course it makes no sense to have unique
  31802. 19:35:04index on the categories because of
  31803. 19:35:06course we're going to get duplicates
  31804. 19:35:07here. But maybe you say, you know what,
  31805. 19:35:09my products are unique. The product name
  31806. 19:35:12should be unique and we are not allowed
  31807. 19:35:14to have in this table two products with
  31808. 19:35:16the same name. So if you have such a
  31809. 19:35:18rule at your business, you can go and
  31810. 19:35:20define a unique index for the products.
  31811. 19:35:22So let's go and do that. Now we're going
  31812. 19:35:24to go and replace the category with the
  31813. 19:35:27products and the same thing over here.
  31814. 19:35:30So we are targeting the column products.
  31815. 19:35:32Let's go and execute it. As you can see
  31816. 19:35:35now it is working because we don't have
  31817. 19:35:37any duplicates inside the table
  31818. 19:35:39products. And if you go and check the
  31819. 19:35:41indexes over here, we can see our new
  31820. 19:35:44index. And as you can see at the start
  31821. 19:35:46here, it says it is unique non-clustered
  31822. 19:35:48index. Now let's go and try the data
  31823. 19:35:51integrity. Are we allowed not to add any
  31824. 19:35:54duplicate to this table? So let's go and
  31825. 19:35:56try that out. Let's have an insert
  31826. 19:35:57statement. Let's say insert into sales
  31827. 19:36:01products. And I would like only to
  31828. 19:36:03insert the product ID and the product
  31829. 19:36:08name. and we're going to insert two
  31830. 19:36:11values. Values, let's say we're going to
  31831. 19:36:14have a new ID 106, but we're going to go
  31832. 19:36:16and insert duplicate for the product
  31833. 19:36:19name. So, we're going to say caps. We
  31834. 19:36:22have already a product called caps over
  31835. 19:36:24here. So, we are now inserting
  31836. 19:36:26duplicates. Let's go and try it. Now,
  31837. 19:36:28you will get an error saying you cannot
  31838. 19:36:30insert duplicates to this table because
  31839. 19:36:33we have unique index. So as you can see
  31840. 19:36:35this index is now helping us and
  31841. 19:36:38improving the quality of my table. So
  31842. 19:36:40this is how we work with the unique
  31843. 19:36:42index in
  31844. 19:36:46SQL. Okay. So now what is a filtered
  31845. 19:36:49index? A filtered index is a regular
  31846. 19:36:51index but with a twist. It only includes
  31847. 19:36:55rows that meet specific condition. So
  31848. 19:36:58let's understand what this means. So
  31849. 19:36:59again we have our nonclustered index and
  31850. 19:37:02the B3 structure. So now at the leaf
  31851. 19:37:04nodes we will get only the ids the data
  31852. 19:37:08that fulfill a specific condition. So
  31853. 19:37:10for example if we are saying we want
  31854. 19:37:12only the active customers this is the
  31855. 19:37:14condition. So that means on the leaf
  31856. 19:37:16nodes we will have only the customer ids
  31857. 19:37:19that are active and any inactive
  31858. 19:37:22customer will not be included at all at
  31859. 19:37:25the data page and at the nodes. So that
  31860. 19:37:27means our B structure going to be little
  31861. 19:37:30bit smaller as usual because we have
  31862. 19:37:32less data included in the structure. So
  31863. 19:37:35our index going to be smaller than the
  31864. 19:37:37regular nclustered index. So now the
  31865. 19:37:40question is why is it important to have
  31866. 19:37:42a filtered index? Well the biggest
  31867. 19:37:44benefit is we going to have targeted
  31868. 19:37:47optimizations. So for example if our
  31869. 19:37:49analyzes always focuses on the active
  31870. 19:37:52users and the inactive users are totally
  31871. 19:37:54unrelevant. So that means having only
  31872. 19:37:57relevant subset of data in the index
  31873. 19:38:00going to make the whole index much
  31874. 19:38:02smaller which leads to faster
  31875. 19:38:05performance. So it's going to be faster
  31876. 19:38:07to query this filtered B3 structure. So
  31877. 19:38:11that means we are doing targeted
  31878. 19:38:13optimizations and we are improving the
  31879. 19:38:15query performance. Now the second
  31880. 19:38:18benefit if you think about the storage
  31881. 19:38:20since the size of the B structure going
  31882. 19:38:22to be smaller that means we're going to
  31883. 19:38:24need less storage space in order to
  31884. 19:38:26store the index which is great thing if
  31885. 19:38:29you have large tables in your database.
  31886. 19:38:32So the filter the index going to make
  31887. 19:38:34the structure of the index smaller which
  31888. 19:38:36going to improve the speed and the
  31889. 19:38:38performance and as well reduce the
  31890. 19:38:40storage that is needed for your index.
  31891. 19:38:43Okay. So now let's check the syntax of
  31892. 19:38:44the filtered index. It's very simple.
  31893. 19:38:46It's like any query you can go and add
  31894. 19:38:49at the end of creating the index the
  31895. 19:38:52wear clause and then the condition as
  31896. 19:38:54you are doing in any select statements.
  31897. 19:38:56But the SQL server is very restrictive
  31898. 19:38:59using this type of index. So you cannot
  31899. 19:39:01use filtered index on a clustered index.
  31900. 19:39:05So it is only allowed for the nclustered
  31901. 19:39:08index because it makes no sense. If you
  31902. 19:39:11create a clustered index, the entire
  31903. 19:39:13table should be reorganized and ordered.
  31904. 19:39:16So it will not work for only subset of
  31905. 19:39:19data and as well you cannot create a
  31906. 19:39:21filtered index on a column store. So it
  31907. 19:39:24is only allowed if you are using row
  31908. 19:39:27store but you can go and combine the
  31909. 19:39:29unique index together with the filtered
  31910. 19:39:31index. There's no restrictions. So it's
  31911. 19:39:33going to be like this. Create unique
  31912. 19:39:35nonclustered index on the table and then
  31913. 19:39:38you specify the wear condition. So this
  31914. 19:39:40is the syntax of the filtered index and
  31915. 19:39:42we have these restrictions. All right.
  31916. 19:39:44So now let's say that we have the
  31917. 19:39:45following query where we are selecting
  31918. 19:39:47data from customers but always in our
  31919. 19:39:49program or in our report we are
  31920. 19:39:52selecting only the customers from USA.
  31921. 19:39:55So we have the following condition. It
  31922. 19:39:57says where country equal to USA and
  31923. 19:40:01execute. So this is the basics of many
  31924. 19:40:04queries that we have in our project and
  31925. 19:40:06we are always filtering the customers
  31926. 19:40:08based on the country. So in one query we
  31927. 19:40:10are finding maybe the top customers and
  31928. 19:40:13another query we are finding the average
  31929. 19:40:15of scores and so on. But we are always
  31930. 19:40:17filtering the data like this where
  31931. 19:40:19country equal to USA. So now since we
  31932. 19:40:22are using this column a lot and our
  31933. 19:40:24table may be getting like million of
  31934. 19:40:26records we can go and create
  31935. 19:40:28nonclustered index on this column. So
  31936. 19:40:30the usual way we go over here and say
  31937. 19:40:32create
  31938. 19:40:34nonclustered index and we call it like
  31939. 19:40:37this index
  31940. 19:40:39customers country and then it's going to
  31941. 19:40:42be on the
  31942. 19:40:43table sales customers and we select the
  31943. 19:40:47column country like this. So if you do
  31944. 19:40:50it like this SQL going to go and create
  31945. 19:40:52a nclustered index for all customers not
  31946. 19:40:55only from USA but for everything. So
  31947. 19:40:58even if the customers come from Germany
  31948. 19:41:00which is not really necessary because in
  31949. 19:41:02our project we only focus on the
  31950. 19:41:05customers from USA. So instead of that
  31951. 19:41:08we can go and include the wear condition
  31952. 19:41:11inside our cluster. So it's very simple
  31953. 19:41:13we're going to go and say where country
  31954. 19:41:16equal to USA exactly like our query. So
  31955. 19:41:20now the index that's going to be built
  31956. 19:41:22it will be focused and targeted only for
  31957. 19:41:25subset of data only for the data that
  31958. 19:41:27fulfill this condition. So now let's go
  31959. 19:41:30and create our filtered index and it is
  31960. 19:41:33working. Let's go and check our indexes
  31961. 19:41:35on the customers. So let's go to the
  31962. 19:41:37indexes over here and refresh. Now we
  31963. 19:41:40can see our index over here. It says it
  31964. 19:41:42is not unique because we didn't define
  31965. 19:41:44anything at the start. So duplicates are
  31966. 19:41:46allowed of course which is what we
  31967. 19:41:48defined here. And as well it is
  31968. 19:41:50filtered. So it doesn't contain all the
  31969. 19:41:53rows from your table. It contains only
  31970. 19:41:55the rows that fulfill our condition. So
  31971. 19:41:58that means now if I go and execute this
  31972. 19:42:00query, the index going to be used
  31973. 19:42:03because the rows of this query is
  31974. 19:42:05included in the index. But if I go over
  31975. 19:42:07here and say Germany and execute the
  31976. 19:42:10query, it's going to be slower because
  31977. 19:42:12all those rows inside the query is not
  31978. 19:42:16part of our index. So this index will
  31979. 19:42:18not be used at all in order to improve
  31980. 19:42:21the query. So this is how we work with
  31981. 19:42:23the filtered index in
  31982. 19:42:28SQL. All right. So now we're going to
  31983. 19:42:30summarize and talk quickly about how to
  31984. 19:42:32use the right index. So when to use
  31985. 19:42:34which type? Let's start with the first
  31986. 19:42:36one. We have the heap structure. So as
  31987. 19:42:38we learned it is a table without any
  31988. 19:42:41index. So in which scenario we don't
  31989. 19:42:43have to use any indexes in case you want
  31990. 19:42:46to have fast inserts. So if you want to
  31991. 19:42:48have a fast write performance then don't
  31992. 19:42:51take any index. So you stay with the
  31993. 19:42:53default with the he structure of your
  31994. 19:42:55table and we usually use it in not very
  31995. 19:42:57important tables like the staging tables
  31996. 19:43:00or temporary tables where we want to
  31997. 19:43:02insert the data fast and then get rid of
  31998. 19:43:05the data later. So here there is no need
  31999. 19:43:07to utilize any index. Now if you are
  32000. 19:43:09talking about the clustered index, we
  32001. 19:43:12usually use the clustered index for
  32002. 19:43:14primary keys. It is even a default from
  32003. 19:43:16the database. If you create any primary
  32004. 19:43:18keys, then SQL going to go and create a
  32005. 19:43:20clustered index. So this is the main
  32006. 19:43:23usage of the clustered index, you use it
  32007. 19:43:25in the primary keys. And if there's like
  32008. 19:43:27no primary key in your table, then you
  32009. 19:43:29can go and pick another column where
  32010. 19:43:31sorting the data is important like for
  32011. 19:43:33example a date column. So it could be a
  32012. 19:43:35good candidate for your clustered index.
  32013. 19:43:37Now moving on to another type we have
  32014. 19:43:39the column store index. So when I said
  32015. 19:43:42here clustered index I mean clustered
  32016. 19:43:44row store index of course. But now the
  32017. 19:43:46question is when do we use the column
  32018. 19:43:48store index. If you have like big
  32019. 19:43:50complex analytical queries where you are
  32020. 19:43:52aggregating a lot of data doing data
  32021. 19:43:54aggregations then go for the column
  32022. 19:43:56store index because it going to give you
  32023. 19:43:58amazing performance. And as well if you
  32024. 19:44:00are struggling with the size of tables
  32025. 19:44:02so if you have a super large table you
  32026. 19:44:05can go and use the column store index
  32027. 19:44:07because it can go and compress the data
  32028. 19:44:09and reduce the size of the whole table.
  32029. 19:44:11So for those scenarios we use the column
  32030. 19:44:13store index. So again for the row store
  32031. 19:44:16clustered index we use it usually for
  32032. 19:44:18the old TB systems where you have a lot
  32033. 19:44:20of transactions and so on but for the
  32034. 19:44:23column store we use it usually for the
  32035. 19:44:25OLAP systems where you have a data
  32036. 19:44:26warehouse reporting system business
  32037. 19:44:28intelligence and so on. Now moving on to
  32038. 19:44:30another type we have the nonclustered
  32039. 19:44:32index. We usually use this index for non
  32040. 19:44:35primary key columns. So that means the
  32041. 19:44:37rest of the columns of your tables could
  32042. 19:44:39be candidate for the nonclustered index.
  32043. 19:44:41And there are a lot of reasons why you
  32044. 19:44:43would do that. For example, for the
  32045. 19:44:45foreign keys or using it on the columns
  32046. 19:44:47that are used in order to join two
  32047. 19:44:50tables and another place where you can
  32048. 19:44:52use the nonclustered index for the
  32049. 19:44:54columns that are used for the work
  32050. 19:44:56clause. So there are like many scenarios
  32051. 19:44:58where we can use the nonclustered index
  32052. 19:45:00but not for the primary keys. Now moving
  32053. 19:45:02on to another type, we have the filtered
  32054. 19:45:04index. We use it in order to target a
  32055. 19:45:07subset of data. So if in our query and
  32056. 19:45:09analyzes we are only focusing on a
  32057. 19:45:12subset of data all time, it makes no
  32058. 19:45:14sense to have one big index for all
  32059. 19:45:16data, we can use the filtered index to
  32060. 19:45:18have focused index. And of course if the
  32061. 19:45:21size of the index is a problem then you
  32062. 19:45:24can use a filtered index in order to
  32063. 19:45:26reduce the overall size of the storage
  32064. 19:45:28of the index. And then to the last type
  32065. 19:45:30we have the unique index. you can go and
  32066. 19:45:33use the unique index in order to ensure
  32067. 19:45:35data integrity of your table and as well
  32068. 19:45:37it might prove slightly the performance
  32069. 19:45:39of your query and that's because SQL has
  32070. 19:45:42less task to do if the index is unique
  32071. 19:45:44once SQL finds a match it going to skip
  32072. 19:45:46the search so this is a quick summary
  32073. 19:45:48and guide on when to use which index
  32074. 19:45:51type that usually help me finding the
  32075. 19:45:54right
  32076. 19:45:58index all right friends so now let's say
  32077. 19:46:00that you have created your index ES in
  32078. 19:46:02your database and your query is
  32079. 19:46:04optimized and you have fast performance
  32080. 19:46:07but the job is not done yet.
  32081. 19:46:10No
  32082. 19:46:11god no god please no no no no
  32083. 19:46:17because over the time the indexes get
  32084. 19:46:19fragmented outdated unused and this
  32085. 19:46:22going to lead to a poor performance in
  32086. 19:46:24your queries and as well going to
  32087. 19:46:26increase the storage costs and the
  32088. 19:46:29overall performance of your database
  32089. 19:46:31going to drop down. So indexes like
  32090. 19:46:33having a car it need maintenance. So you
  32091. 19:46:36need to change the oil and the tire of
  32092. 19:46:38the car. And the same thing goes for the
  32093. 19:46:40indexes. You have to maintain them. They
  32094. 19:46:42need attention to keep everything
  32095. 19:46:44running smoothly. So now I'm going to
  32096. 19:46:46show you how I manage, maintain, and
  32097. 19:46:49monitor the indexes of my SQL projects.
  32098. 19:46:51So let's
  32099. 19:46:55go. The first and the most important
  32100. 19:46:58task is to monitor the usage of your
  32101. 19:47:00indexes. So of course the first question
  32102. 19:47:02we have to ask ourself over the time are
  32103. 19:47:05we using really the indexes that we have
  32104. 19:47:07created are they really helping
  32105. 19:47:09improving the speed of my queries or was
  32106. 19:47:12it just a good idea at the start of the
  32107. 19:47:14project and later no one used those
  32108. 19:47:16indexes. This is very crucial because if
  32109. 19:47:19you are having an unused index you are
  32110. 19:47:21consuming unnecessary storage space and
  32111. 19:47:24as well the right performance in the
  32112. 19:47:26tables going to be slow which is
  32113. 19:47:28completely unnecessary if you are not
  32114. 19:47:30using the index. So now our task is to
  32115. 19:47:33find out the usage of each index that
  32116. 19:47:36you have in the projects. So let's see
  32117. 19:47:37how we can do that. So now previously we
  32118. 19:47:39have created like multiple indexes on
  32119. 19:47:41the table DB customers. So if you go to
  32120. 19:47:44the DB customers and to the indexes, you
  32121. 19:47:46can see that we have four indexes. Now
  32122. 19:47:48we can go and show those informations by
  32123. 19:47:50using a special stored procedures from
  32124. 19:47:52the SQL server called SP help index.
  32125. 19:47:55Let's go and do that. So SP help index.
  32126. 19:47:59So it is a system stored procedure that
  32127. 19:48:02comes with the database. So this stored
  32128. 19:48:04procedure needs only one value and that
  32129. 19:48:06is the table name. So we have it over
  32130. 19:48:09here sales DB customers. Let's go and
  32131. 19:48:12query it. So we have four indexes. Then
  32132. 19:48:14we have a nice description of the index.
  32133. 19:48:16So it says it is nonclustered index and
  32134. 19:48:19whether it is column store. And it say
  32135. 19:48:21where it is located. So it says it
  32136. 19:48:23located on primary. Primary is the name
  32137. 19:48:26of the file group where the data is
  32138. 19:48:28stored. And as a default it can be
  32139. 19:48:29stored as primary. And now the next
  32140. 19:48:31information we have the index keys. It
  32141. 19:48:33is nice information to understand which
  32142. 19:48:35keys are used or which columns are used
  32143. 19:48:37for the index. So the first one you can
  32144. 19:48:40see we have two columns that means it is
  32145. 19:48:41a composite index and of course for the
  32146. 19:48:44column store we don't have any columns
  32147. 19:48:46and then we have the first name last
  32148. 19:48:47name. So this is a really nice quick
  32149. 19:48:49store procedure in order to see
  32150. 19:48:50information about our index. Okay. So
  32151. 19:48:52now let's focus on our task on how to
  32152. 19:48:54monitor the usage of the indexes. Now in
  32153. 19:48:57databases we have a lot of schemas and
  32154. 19:48:59tables that protocol the metadata of our
  32155. 19:49:03database. And in SQL Server, we have a
  32156. 19:49:05special schema called CIS where you can
  32157. 19:49:07find a lot of metadata information about
  32158. 19:49:10the SQL server. Metadata like the
  32159. 19:49:12description of the tables, views,
  32160. 19:49:14columns and as well the indexes. So now
  32161. 19:49:17let's check what we can find inside the
  32162. 19:49:19table indexes. So let's going to do it.
  32163. 19:49:21Select star from CIS. This is the schema
  32164. 19:49:24name. And then as you can see we have a
  32165. 19:49:26list of many informations but we want to
  32166. 19:49:29focus on the indexes. Now let's go and
  32167. 19:49:32execute it. Now we get a huge list of
  32168. 19:49:34all indexes that we have and a lot of
  32169. 19:49:37informations for each index. We don't
  32170. 19:49:40have to go and understand now each
  32171. 19:49:41column. But I'm going to go and select
  32172. 19:49:43the main important informations from
  32173. 19:49:45this table. So what do we need? The
  32174. 19:49:47object ID. This is the table ID. So the
  32175. 19:49:50object
  32176. 19:49:51ID and we have the name. It is the index
  32177. 19:49:55name. And then here we have a nice
  32178. 19:49:58information whether it is clustered or
  32179. 19:50:00nonclustered. So let's go and select it
  32180. 19:50:03type disk as so let's call it index type
  32181. 19:50:06and we can go and check whether it is
  32182. 19:50:08primary key or not. So let's get this
  32183. 19:50:10information as well is primary key. I
  32184. 19:50:13will go and just rename it is primary
  32185. 19:50:16key and what else do we need whether it
  32186. 19:50:19is unique. So it is as well nice
  32187. 19:50:20information to have. So is
  32188. 19:50:23[Music]
  32189. 19:50:26unique. So of course you can go and grab
  32190. 19:50:28a lot of stuff. It depends really on
  32191. 19:50:30what you are monitoring. So for example,
  32192. 19:50:32I'm going to go and check whether it is
  32193. 19:50:33disabled or not. So is
  32194. 19:50:36disabled and I'll just rename
  32195. 19:50:40it. So with that I have like focus
  32196. 19:50:43monitoring. I don't have to have all
  32197. 19:50:44those informations. So let's go and
  32198. 19:50:46execute. But now I would like to go and
  32199. 19:50:47change few stuff like for example I
  32200. 19:50:49don't want the object ID. I would like
  32201. 19:50:51to have the full name of the table. And
  32202. 19:50:53as well there is a lot of indexes that
  32203. 19:50:56is unrelevant for my database. So now in
  32204. 19:50:58order to do that we have to go and get
  32205. 19:51:00the informations from another metadata
  32206. 19:51:02table. So let's go and call this index
  32207. 19:51:04and let's go and join it with another
  32208. 19:51:07metadata table. It's called tables. So
  32209. 19:51:11tbl and we're going to go and join it
  32210. 19:51:13using the so the index object
  32211. 19:51:17ID equal to the table object ID. And now
  32212. 19:51:22if you like to see the content of this
  32213. 19:51:24table we can go and create separately.
  32214. 19:51:26So select star from our new table. So
  32215. 19:51:30let's see the content of this table. So
  32216. 19:51:32you can see we have the name which is
  32217. 19:51:34the table name. And I think that's all
  32218. 19:51:35what we need. We have a lot of other
  32219. 19:51:37informations about the table. Well, I
  32220. 19:51:39just need the table name. So let's go
  32221. 19:51:41and do it at the start. tbl name as
  32222. 19:51:45table
  32223. 19:51:46name and I don't need anymore the object
  32224. 19:51:49ID. But of course we have to go and use
  32225. 19:51:51the alias for each of those informations
  32226. 19:51:53in order to understand those
  32227. 19:51:54informations comes from the index. So
  32228. 19:51:56let's go and do that. All right. So my
  32229. 19:51:59query is ready. Let's go and execute it
  32230. 19:52:01again. So now as you can see we are
  32231. 19:52:02getting the table name and the list is
  32232. 19:52:04very short because it is only focusing
  32233. 19:52:06on the tables that you have in the
  32234. 19:52:08database. And this filter happens
  32235. 19:52:10because of the inner join. But one more
  32236. 19:52:12thing I would like to go and sort the
  32237. 19:52:13data. So I'm going to say order by I
  32238. 19:52:15would like to sort it by the table name
  32239. 19:52:18and then the index name. All right. So
  32240. 19:52:21now let's go and check for example the
  32241. 19:52:23table customers. You can see that we
  32242. 19:52:25have two non-clustered index and one of
  32243. 19:52:27them is column store index. Those two we
  32244. 19:52:29have created from the previous tutorial
  32245. 19:52:31and we have an index on the primary key
  32246. 19:52:33as you can see here is primary key equal
  32247. 19:52:35to one and this is as well unique. So
  32248. 19:52:37with that we have a really nice list of
  32249. 19:52:39all indexes that we have in our
  32250. 19:52:41database. But we are not there yet
  32251. 19:52:43because our task is how to monitor the
  32252. 19:52:47usage of the index. Now in order to get
  32253. 19:52:49the usage for each of those indexes, we
  32254. 19:52:52have to go to a special view called
  32255. 19:52:54dynamic management view. And there the
  32256. 19:52:56SQL server going to provide a lot of
  32257. 19:52:58statistics about the usage for that
  32258. 19:53:00index. And we can find it as well in the
  32259. 19:53:01same schema. So let's go and query this
  32260. 19:53:04table. So it's going to be select star
  32261. 19:53:06from. So the same schema says
  32262. 19:53:09dodm
  32263. 19:53:11db_ind index usage stats. So let's go
  32264. 19:53:15and explore this table and execute it.
  32265. 19:53:18Now in those statistics we can find the
  32266. 19:53:20usage of two indexes the index number
  32267. 19:53:23three and one. And we can see there are
  32268. 19:53:25like three usage informations of the
  32269. 19:53:27index number one. And next we have like
  32270. 19:53:29user seeks user scans and user lookups.
  32271. 19:53:32So this is how many times the index is
  32272. 19:53:34used as seeks or scans or lookups. We
  32273. 19:53:37will understand those informations as we
  32274. 19:53:39learn about the execution plan. And here
  32275. 19:53:41we have a very nice information about
  32276. 19:53:43how many time our index got updated. So
  32277. 19:53:46as you can see here is zero because I
  32278. 19:53:48didn't add any new data after creating
  32279. 19:53:50the index. But of course all those
  32280. 19:53:52numbers might be different at your site
  32281. 19:53:54because it depends whether you are doing
  32282. 19:53:55more queries and practicing. And you can
  32283. 19:53:57find here more informations about when
  32284. 19:54:00was exactly the last usage of those
  32285. 19:54:02indexes and many many nice informations.
  32286. 19:54:05So now let's go and integrate this view
  32287. 19:54:08with our query. So now what I'm going to
  32288. 19:54:10do, I'm going to do a lift join because
  32289. 19:54:12if I do an inner join, I will only find
  32290. 19:54:15the used indexes. But I don't want that
  32291. 19:54:18because I want to see a full build of
  32292. 19:54:20all my indexes in the database. So left
  32293. 19:54:22join and we're going to go and get our
  32294. 19:54:26view and call it S. And then we have to
  32295. 19:54:28join it on the keys. So S on. So I would
  32296. 19:54:31say let's go and grab the object ID
  32297. 19:54:33equal to the index object ID. And of
  32298. 19:54:37course we have to join on the index ID.
  32299. 19:54:40So it's going to be the index ID equal
  32300. 19:54:42to the index ID like this. Now we have
  32301. 19:54:46to go and select few informations from
  32302. 19:54:48this view. So I'm going to go and select
  32303. 19:54:50like all those number of usage. So s
  32304. 19:54:54let's get the user
  32305. 19:54:57seeks as the user
  32306. 19:55:00scans and the
  32307. 19:55:02lookups and maybe as well the user
  32308. 19:55:05updates and it is really nice
  32309. 19:55:07information to understand when it was
  32310. 19:55:09the last time used. So last user
  32311. 19:55:12seek and the
  32312. 19:55:14last user scan. Let me just correct it
  32313. 19:55:17over here. And actually I can go and put
  32314. 19:55:19those two dates in one date because if
  32315. 19:55:23it's like the last seek it's going to be
  32316. 19:55:24null over here or the opposite. And now
  32317. 19:55:27what we can do we can go and put those
  32318. 19:55:28two together actually in one column
  32319. 19:55:30because when we have a value over here
  32320. 19:55:32it's going to be null and vice versa. So
  32321. 19:55:34we can do that using the null function
  32322. 19:55:37kowalis like this and we can get this
  32323. 19:55:40over here and we can call the whole
  32324. 19:55:42thing last
  32325. 19:55:44update. So like this and maybe I'm going
  32326. 19:55:46to go and rename all those
  32327. 19:55:48[Music]
  32328. 19:55:54stuff. All right. So now we are done.
  32329. 19:55:57Let's go and execute it. Okay. So let's
  32330. 19:55:59go and check our new report over here.
  32331. 19:56:01So this is our query and let's start
  32332. 19:56:04with the first table for example the
  32333. 19:56:05customers and go to the right side. And
  32334. 19:56:07now we can see that we have three
  32335. 19:56:09indexes and from these two indexes we
  32336. 19:56:11have only one index that is not used at
  32337. 19:56:14all. So we can see over here that the
  32338. 19:56:17nclustered index on the country is not
  32339. 19:56:20being used and that's because we have
  32340. 19:56:22another index about the country that
  32341. 19:56:24comes from the column store. So it could
  32342. 19:56:26be like this that you are quering the
  32343. 19:56:27table using the country but the SQL
  32344. 19:56:31saying I would like to go and use this
  32345. 19:56:32index instead of the first one. So we
  32346. 19:56:34can say okay this one is not really
  32347. 19:56:37useful maybe we can go and drop it right
  32348. 19:56:39and for the rest you can see okay this
  32349. 19:56:41column store index is used twice and the
  32350. 19:56:43next one is once again the numbers at
  32351. 19:56:45your side might be different and if we
  32352. 19:56:47have a look to all other tables we have
  32353. 19:56:49a lot of nulls so that means all those
  32354. 19:56:51indexes that you have created on the DB
  32355. 19:56:54customers let me check only one is used
  32356. 19:56:56but now you might say you know what I've
  32357. 19:56:58used the index but why I'm not seeing
  32358. 19:57:00here any numbers about it well that's
  32359. 19:57:02because those numbers will not live
  32360. 19:57:04forever and we are using now the express
  32361. 19:57:07edition locally at our PC. So each time
  32362. 19:57:09you shut down your PC and you close the
  32363. 19:57:11client the database going to shut down
  32364. 19:57:13as well and those statistics going to be
  32365. 19:57:15lost because they are in the memory. But
  32366. 19:57:17in real projects the numbers going to be
  32367. 19:57:19totally different than here and of
  32368. 19:57:20course you're going to get realistic
  32369. 19:57:22numbers. Now let's try to target one of
  32370. 19:57:24those not used indexes. So for example
  32371. 19:57:27let's go with this index. It is not
  32372. 19:57:29clustered index on the product. So let's
  32373. 19:57:31go and query that. Currently it is
  32374. 19:57:33completely not used. So if I go and
  32375. 19:57:35select it. So select star from sales
  32376. 19:57:40products where
  32377. 19:57:43product equal to caps. So with that we
  32378. 19:57:46have used the index I think. Let's go
  32379. 19:57:49back and query again and let's go to our
  32380. 19:57:52index and check whether it is used. Well
  32381. 19:57:54it is correct. So our query did use this
  32382. 19:57:57index and we can see here it is used
  32383. 19:57:59once. And now you can go and analyze in
  32384. 19:58:01your project all the indexes that you
  32385. 19:58:03have on your tables and you can see
  32386. 19:58:05whether you are really using it with
  32387. 19:58:07your queries or not. And if you are not
  32388. 19:58:09using the query of course you have to
  32389. 19:58:11make a decision about it. Maybe if you
  32390. 19:58:13are working a team to ask about it who
  32391. 19:58:15did create it and why. Maybe there is
  32392. 19:58:17like one task in the database that is
  32393. 19:58:20not frequently used. Maybe it's
  32394. 19:58:22something that is run like once a month
  32395. 19:58:24or something like that. So the index is
  32396. 19:58:25needed but not that frequently. But
  32397. 19:58:27still now we have like insights about
  32398. 19:58:29what is going on with those indexes and
  32399. 19:58:31whether we need them or not. And if you
  32400. 19:58:34don't need them, go and drop them. All
  32401. 19:58:36right, my friends. So here is the secret
  32402. 19:58:38that 90% of SQL developers don't do
  32403. 19:58:41that's going to make you in 1 minute the
  32404. 19:58:43hero of the projects. So once I join a
  32405. 19:58:46project and after saying hello to
  32406. 19:58:47everyone, I open the database of the
  32407. 19:58:50project and do one query. I checked the
  32408. 19:58:52usage of the indexes of the projects and
  32409. 19:58:55I can tell you after working 15 years
  32410. 19:58:57with SQL that 90% of indexes created in
  32411. 19:59:01projects are totally untouched and
  32412. 19:59:03unused. So I collect all unused indexes
  32413. 19:59:06and discuss it with the team. And if we
  32414. 19:59:09don't find real usage for those indexes,
  32415. 19:59:11we go and drop them. So after dropping
  32416. 19:59:14all those unused indexes, you have done
  32417. 19:59:16two great things for the projects.
  32418. 19:59:19First, you have saved a lot of storage
  32419. 19:59:21in the database. And second, which is
  32420. 19:59:23way more important, you have improved
  32421. 19:59:25and optimized the right performance on
  32422. 19:59:28the database. So in your first day with
  32423. 19:59:30one query, you have optimized the
  32424. 19:59:33performance of the database. You have
  32425. 19:59:34save storage and you're going to shine
  32426. 19:59:36like an expert in your project. So if
  32427. 19:59:38you haven't done that, do that
  32428. 19:59:43now. All right. And now moving on to the
  32429. 19:59:46next one. As we learned, identifying an
  32430. 19:59:48unused index is an important task. But
  32431. 19:59:51in the other hand, identifying a missing
  32432. 19:59:54index is as well very important to
  32433. 19:59:57improve the performance of your queries.
  32434. 19:59:59So in SQL server, you can get
  32435. 20:00:01recommendations from the database itself
  32436. 20:00:03about missing indexes for your query. So
  32437. 20:00:06let's see where we can find those
  32438. 20:00:08recommendations. All right. So now let's
  32439. 20:00:09say that you are doing multiple queries
  32440. 20:00:11and you are doing analyszis and so on.
  32441. 20:00:13For example, I have this query over
  32442. 20:00:15here. It is query on the database
  32443. 20:00:17adventure works DW and I'm joining just
  32444. 20:00:20two tables the fact with the dimension
  32445. 20:00:22and then filtering the data based on the
  32446. 20:00:25colors and as well on the date key where
  32447. 20:00:28I have like a range over here. So once I
  32448. 20:00:30executed I got the following
  32449. 20:00:32informations. It could be any query that
  32450. 20:00:34you are doing while practicing and
  32451. 20:00:35analyzing and so on. So now if you have
  32452. 20:00:37like slow query and so on you can go and
  32453. 20:00:39check the recommendations from the
  32454. 20:00:41database about missing indexes. So in
  32455. 20:00:43order to do that we can go and check
  32456. 20:00:45again the metadata from the database
  32457. 20:00:47system to see the recommendations about
  32458. 20:00:49the missing indexes. So let's go and do
  32459. 20:00:51that. So we're going to go and select
  32460. 20:00:53from and now we have to go and target
  32461. 20:00:55the dynamic management views and it is
  32462. 20:00:57like this dm
  32463. 20:01:00db
  32464. 20:01:02missing index details. So let's go and
  32465. 20:01:06explore the content over here. And don't
  32466. 20:01:08forget that those informations going to
  32467. 20:01:10be inside the cache of the server and if
  32468. 20:01:13there's like a restart or something in
  32469. 20:01:15the server you will lose all those
  32470. 20:01:16informations. So now from my query there
  32471. 20:01:19is few suggestions and recommendations
  32472. 20:01:21from the database. Let's go and check
  32473. 20:01:22it. So we can see here there are four
  32474. 20:01:24recommendations about missing indexes
  32475. 20:01:27from the database. So now let's go and
  32476. 20:01:29check the first recommendation over
  32477. 20:01:30here. You can go and check the table
  32478. 20:01:32name from the object ID or you can find
  32479. 20:01:34it here in the statements. So here the
  32480. 20:01:36database is suggesting an index for the
  32481. 20:01:38table dimension product and it is
  32482. 20:01:41recommending us to make an index for the
  32483. 20:01:43column color and that's because if you
  32484. 20:01:45check our query we have like here a
  32485. 20:01:47filter the wear condition where we are
  32486. 20:01:48seeing the color equal to black and
  32487. 20:01:50since we don't have an index on the
  32488. 20:01:52color SQL is just suggesting to use an
  32489. 20:01:54index for the color and of course in
  32490. 20:01:56this situation we can go and use an
  32491. 20:01:58uncclustered index. Now after that we
  32492. 20:02:00have three recommendations for the same
  32493. 20:02:02table fact internet sales. So for
  32494. 20:02:04example here it is suggesting to make an
  32495. 20:02:06index on the order date K because we are
  32496. 20:02:09using it in the filter over here and as
  32497. 20:02:11well suggesting to make an index for the
  32498. 20:02:14product key since we are using it for
  32499. 20:02:16the join. So this is really nice report
  32500. 20:02:19about missing indexes in the database
  32501. 20:02:21and it could assist you to find out
  32502. 20:02:23things that you didn't thought about.
  32503. 20:02:25But here my recommendation is evaluate
  32504. 20:02:27those informations very carefully. Don't
  32505. 20:02:30go and create like an index for each
  32506. 20:02:32suggestions from the database. You still
  32507. 20:02:34have to think about it. Is it really
  32508. 20:02:36necessary? Do we really use this query
  32509. 20:02:38very frequently and so on? So don't go
  32510. 20:02:41blindly creating indexes for each
  32511. 20:02:43recommendations from the database. So
  32512. 20:02:45this is really nice tool and assistant
  32513. 20:02:47for you in order to make a good strategy
  32514. 20:02:49for your indexing. So this is how you
  32515. 20:02:51find the recommendations of missing
  32516. 20:02:53indexes from SQL
  32517. 20:02:59database. Okay. Okay. So now to the next
  32518. 20:03:01step, we have to go and monitor the
  32519. 20:03:03duplicates in indexing. If you are
  32520. 20:03:06working in team with multiple developers
  32521. 20:03:08and you are working parallely in order
  32522. 20:03:10to optimize the performance of the
  32523. 20:03:12queries, what might happen is that
  32524. 20:03:14different developers creating different
  32525. 20:03:17indexes for the same column in the same
  32526. 20:03:20table. But of course, this must not
  32527. 20:03:21happen if you have a clean and solid
  32528. 20:03:23review process in the project. But we
  32529. 20:03:26are human and those things could happen.
  32530. 20:03:28So that's why you have to monitor
  32531. 20:03:30whether there are like duplicates. So
  32532. 20:03:32the mission is to find whether there is
  32533. 20:03:34a column that is involved in multiple
  32534. 20:03:36indexes. So let's see how we can monitor
  32535. 20:03:38that in SQL. Okay. So now it's very
  32536. 20:03:40simple in order to find the duplicates
  32537. 20:03:42of indexes inside your database. So we
  32538. 20:03:45have learned before that we can find the
  32539. 20:03:46list of all indexes in this table
  32540. 20:03:48indexes in the system schema and then we
  32541. 20:03:51join it with the tables in order to get
  32542. 20:03:53the table name and then we have another
  32543. 20:03:55table in order to find the columns that
  32544. 20:03:58are involved in the index. Those
  32545. 20:04:00informations we can find it inside the
  32546. 20:04:02index columns and now in order to get
  32547. 20:04:04the full name of the columns we're going
  32548. 20:04:06to go and join it with the columns
  32549. 20:04:08table. So it's very simple and makes
  32550. 20:04:10sense. Let's go and execute the whole
  32551. 20:04:12query. Now as you can see it is sorted
  32552. 20:04:14by the table name and the column name
  32553. 20:04:16and that's because we can find then
  32554. 20:04:18easier the duplicate. So let's go and
  32555. 20:04:20check the first table. So the country is
  32556. 20:04:22part of this index where we have the
  32557. 20:04:25column store nonclustered and again the
  32558. 20:04:27country is involved in another index
  32559. 20:04:29where we have the customer's country and
  32560. 20:04:32this is a row store nonclustered index.
  32561. 20:04:35So this is of course bad thing. We have
  32562. 20:04:36to go and decide now do we want it as a
  32563. 20:04:38column store or row store. And if we
  32564. 20:04:41check as well this table, we can find
  32565. 20:04:43the first name in two different clusters
  32566. 20:04:46the same story. And that's because we
  32567. 20:04:47were practicing and creating those
  32568. 20:04:49indexes. And that's it. But now if you
  32569. 20:04:51have like large schema and a lot of
  32570. 20:04:53indexes, I would go and make like a flag
  32571. 20:04:55in order to understand whether we have a
  32572. 20:04:57duplicate or not. And that's by
  32573. 20:04:58calculating the number of rows of unique
  32574. 20:05:01table name and index name. And we can do
  32575. 20:05:03that very easily using the window
  32576. 20:05:05functions. So let's have new row. And
  32577. 20:05:07we're going to go and use the function
  32578. 20:05:09count since we want to find the number
  32579. 20:05:11of rows over. Then we're going to go and
  32580. 20:05:14partition
  32581. 20:05:15by we need the table name and as well
  32582. 20:05:19the column name. Our expectation of this
  32583. 20:05:22column should be one. If we have more
  32584. 20:05:24than one then there is an issue and that
  32585. 20:05:27means the column is inside two different
  32586. 20:05:30indexes. And now let's go and sort it by
  32587. 20:05:32the column name and descending. So let's
  32588. 20:05:36go and execute it. And now we have here
  32589. 20:05:38a nice flag where we can see how many
  32590. 20:05:40rows we have for a specific column in a
  32591. 20:05:42table. So if it's one like those
  32592. 20:05:44columns, they are fine. Those columns
  32593. 20:05:47are involved only once in one index. But
  32594. 20:05:49for the first four rows, we have here an
  32595. 20:05:52issue because we count here two columns.
  32596. 20:05:54That means we have two indexes for the
  32597. 20:05:56same column. So as you can see the query
  32598. 20:05:58is very simple and with that we have a
  32599. 20:05:59nice report about the duplicates of
  32600. 20:06:02indexes inside our database.
  32601. 20:06:08Okay, one more thing in order to
  32602. 20:06:10maintain our indexes is by updating the
  32603. 20:06:12statistics. The database engines usually
  32604. 20:06:15use statistics in order to understand
  32605. 20:06:18which index should be used for our
  32606. 20:06:20query. And if these statistics are not
  32607. 20:06:22up to date, SQL going to make wrong
  32608. 20:06:24decisions. So let's understand what this
  32609. 20:06:26means. Now let's say that you have
  32610. 20:06:28created a table and you start inserting
  32611. 20:06:30data to this new table. Now the database
  32612. 20:06:33engine going to go and create your new
  32613. 20:06:34table and insert the data. Behind the
  32614. 20:06:36scenes the database engine going to go
  32615. 20:06:38and create for your new table
  32616. 20:06:40statistics. It's like metadata
  32617. 20:06:42informations about your data and that's
  32618. 20:06:45like a report or insights about your
  32619. 20:06:47table where you can find a lot of
  32620. 20:06:49informations like the number of rows
  32621. 20:06:52that distribution of values in a column
  32622. 20:06:55and as well we can find the number of
  32623. 20:06:57distinct values and histogram and
  32624. 20:07:00patterns and many other informations
  32625. 20:07:02about your table. So now of course the
  32626. 20:07:04question is why do we have those
  32627. 20:07:06informations in the database? Now
  32628. 20:07:08imagine that you are doing select from
  32629. 20:07:10where what going to happen the database
  32630. 20:07:12engine has to go and create an execution
  32631. 20:07:15plan. We're going to learn about this
  32632. 20:07:17later in details. It is just a road map
  32633. 20:07:19on how to execute this query. So here
  32634. 20:07:22for example in order to load the data
  32635. 20:07:24from the table there are like different
  32636. 20:07:26ways on how to do it. So there is like a
  32637. 20:07:28table scan, index scan, index seek. So
  32638. 20:07:31that means the database engine has here
  32639. 20:07:33three different ways on how to do it.
  32640. 20:07:36And now in order for the database to
  32641. 20:07:38decide which way to use, it's going to
  32642. 20:07:41go and read the statistics of the table.
  32643. 20:07:43So it's going to go and collect
  32644. 20:07:45informations. Okay, how many rows do we
  32645. 20:07:47have? Are the informations are unique?
  32646. 20:07:49How is the distribution of the data and
  32647. 20:07:51so on. And now based on those statistics
  32648. 20:07:53and numbers, the database can now make a
  32649. 20:07:56good decision about which methods to use
  32650. 20:07:59in order to load the data. So for
  32651. 20:08:01example, here the index scan is the best
  32652. 20:08:03way to load our table. So this is
  32653. 20:08:06exactly why the database needs the
  32654. 20:08:08statistics in order to make the correct
  32655. 20:08:11decision and to use the correct index.
  32656. 20:08:13So now you might ask okay this is
  32657. 20:08:15something internal for the database why
  32658. 20:08:17do we have to care about it? Well there
  32659. 20:08:19is an issue. Now for example in our
  32660. 20:08:21table we have 50 rows and let's say that
  32661. 20:08:23in the next day you went and inserted to
  32662. 20:08:26this table like around 1 million row.
  32663. 20:08:28Now the issue that could happen is that
  32664. 20:08:30the statistics will not get updated
  32665. 20:08:33about this table and the statistics can
  32666. 20:08:35still say that we have only 50 rows. So
  32667. 20:08:38that means the statistics of this table
  32668. 20:08:40is now outdated. And the big issue that
  32669. 20:08:43once you query this table, the SQL
  32670. 20:08:45engine don't know at all about the 1
  32671. 20:08:48million row that you have inserted in
  32672. 20:08:50the table because it's going to go and
  32673. 20:08:52ask the statistics and it's going to
  32674. 20:08:54answer with only 50 rows and the
  32675. 20:08:56database going to say okay this is very
  32676. 20:08:58small table and let's maybe skip an
  32677. 20:09:00index or something. So that means the
  32678. 20:09:02database going to make wrong decisions
  32679. 20:09:04because the statistics are outdated. And
  32680. 20:09:08now your task is to monitor those
  32681. 20:09:10statistics and to keep updating them. So
  32682. 20:09:13let's see how we can do that. Okay. So
  32683. 20:09:15now the first thing that we have to do
  32684. 20:09:16is to find out whether our statistics
  32685. 20:09:18are up to date or outdated. In order to
  32686. 20:09:21do that we have as well to access the
  32687. 20:09:23metadata about our database. And for
  32688. 20:09:25that as well we have tables and dynamic
  32689. 20:09:27management functions in the system
  32690. 20:09:30schema where we can find a lot of
  32691. 20:09:32details about the statistics. And in
  32692. 20:09:34order to monitor the statistics, I have
  32693. 20:09:36prepared a query like this. So here I'm
  32694. 20:09:38using a table called stats uh where here
  32695. 20:09:41you're going to get a list of all
  32696. 20:09:42statistics inside our database and the
  32697. 20:09:45name of the statistics and then I'm
  32698. 20:09:47joining it with the tables in order to
  32699. 20:09:48get the table name and what is very
  32700. 20:09:51important is the dynamic management
  32701. 20:09:53function. So here we're going to get
  32702. 20:09:54very important informations like the
  32703. 20:09:56last updates and the number of rows and
  32704. 20:09:59the number of modifications. So let's go
  32705. 20:10:02and query it. So here we can see
  32706. 20:10:04informations like the table name, the
  32707. 20:10:06statistics name and now it's very
  32708. 20:10:08important when the last time the
  32709. 20:10:10statistics get updated. So now let's go
  32710. 20:10:12and check our table DB customers. We can
  32711. 20:10:15see here the statistics name and what is
  32712. 20:10:18very important is the last update. So
  32713. 20:10:20this tells us how old is the statistics.
  32714. 20:10:23So for me it is like 4 days. And then we
  32715. 20:10:25can find the total number of rows in
  32716. 20:10:27this table. And now what is very
  32717. 20:10:29important is the number of modifications
  32718. 20:10:31that have been done on the table. So
  32719. 20:10:34after updating the statistics on the
  32720. 20:10:3619th of October, there were around 15
  32721. 20:10:39rows that got modificated. This could be
  32722. 20:10:41an insert, update, delete. So any
  32723. 20:10:44operation of the table considered to be
  32724. 20:10:46a modification. So that you can see
  32725. 20:10:48there were a lot of modifications. So
  32726. 20:10:50these statistics should be updated. So
  32727. 20:10:52now for the table customers, you can see
  32728. 20:10:54that the statistics are up to date. So
  32729. 20:10:57we have here zero as a modifications and
  32730. 20:10:59there will be no need to update the
  32731. 20:11:01statistics. So this is how you can go
  32732. 20:11:03and check the statistics informations
  32733. 20:11:05inside your database in order to make a
  32734. 20:11:07decision should I update the statistics
  32735. 20:11:09or not. So now let's say that I would
  32736. 20:11:11like to go and update the statistics of
  32737. 20:11:13our table DB customers. Now as you can
  32738. 20:11:16see we have here multiple statistics. So
  32739. 20:11:18over here we have this statistics on
  32740. 20:11:20this table and as well we have the
  32741. 20:11:22statistics on the index. So as you can
  32742. 20:11:24see we have here multiple statistics in
  32743. 20:11:26one table. One for the table itself and
  32744. 20:11:29one for each index that we have in this
  32745. 20:11:31table. So now let's say that I would
  32746. 20:11:33like to go and update the statistics
  32747. 20:11:35only for one. I don't want to update
  32748. 20:11:37everything in this table only for one
  32749. 20:11:39statistics. Let's go and do that. So
  32750. 20:11:42it's going to be very simple update
  32751. 20:11:44statistics. And then we have to go and
  32752. 20:11:46mention the name. So it's going to be
  32753. 20:11:47sales DB customers. And then we have to
  32754. 20:11:50specify the name of the statistics. So
  32755. 20:11:52let's go and get this over here and
  32756. 20:11:55let's go and execute it. So it was very
  32757. 20:11:58fast. Let's go and reexecute our query
  32758. 20:12:01and check the data. So now let's go and
  32759. 20:12:04find it. It was exactly this one. And as
  32760. 20:12:07you can see it just got updated and the
  32761. 20:12:09number of rows is five and the number of
  32762. 20:12:11notifications is zero. So we have now an
  32763. 20:12:14upto-date statistics for this table. But
  32764. 20:12:17let's say that I would like to go and
  32765. 20:12:19update the rest but I don't want to do
  32766. 20:12:20it one by one. So what we can do we can
  32767. 20:12:23just copy the same thing over here but
  32768. 20:12:26we don't specify any name of the
  32769. 20:12:28statistic. So we are saying update
  32770. 20:12:30statistics and then only the table name.
  32771. 20:12:33So let's go and execute it. So now what
  32772. 20:12:35going to happen is still going to go and
  32773. 20:12:36update all the statistics that belongs
  32774. 20:12:38to this table. So let's go and check our
  32775. 20:12:41query again. Now you can see everything
  32776. 20:12:43disappeared and the DB customer is
  32777. 20:12:46completely up to date with no
  32778. 20:12:48modifications problem. So this is how
  32779. 20:12:50you can go and update your table and you
  32780. 20:12:53can do then for the rest as well. But
  32781. 20:12:55now there is like one more thing where
  32782. 20:12:57you can go and update the statistics of
  32783. 20:12:59the whole database. But beware this
  32784. 20:13:03might take really long time and we're
  32785. 20:13:05going to do that by executing a special
  32786. 20:13:07store procedure. So execute SP update
  32787. 20:13:11stats. This one over here. Let's go and
  32788. 20:13:15do that. And now it is done. And we have
  32789. 20:13:17here a pretty long log. It was fast
  32790. 20:13:20because we don't have a big database. It
  32791. 20:13:22is very small database. So it's not
  32792. 20:13:23compared to any real databases. So now
  32793. 20:13:26we can see over here that SQL is going
  32794. 20:13:29through everything that you have in the
  32795. 20:13:31database and trying to update the
  32796. 20:13:32statistics. So in many situations it's
  32797. 20:13:35going to be not necessary because there
  32798. 20:13:36is nothing to update. There were no
  32799. 20:13:38modifications and so on. That's why the
  32800. 20:13:40database is smart enough to say no it is
  32801. 20:13:42not required and it go and skip it. So
  32802. 20:13:44now how I usually do it in my project is
  32803. 20:13:46that I have like a job on the weekend
  32804. 20:13:49where it's going to go and update the
  32805. 20:13:51whole database statistics. So with that
  32806. 20:13:54I make sure all my tables and indexes
  32807. 20:13:57having up to-date statistics. Of course
  32808. 20:14:00if you have small database you can run
  32809. 20:14:01this like every day but if this takes
  32810. 20:14:04long time then you can schedule it in
  32811. 20:14:06the weekend. And as well if I know in
  32812. 20:14:08the project that there will be in one
  32813. 20:14:10day a lot of new incoming data. So we
  32814. 20:14:13are doing some kind of data migrations.
  32815. 20:14:15So I go and update the statistics after
  32816. 20:14:17the data migration is done just to make
  32817. 20:14:19sure we have up-to-date statistics. So
  32818. 20:14:21this is how we monitor and update the
  32819. 20:14:23statistics of the
  32820. 20:14:24[Music]
  32821. 20:14:28database. Okay. Okay, so now moving on
  32822. 20:14:30to the final task that I usually do in
  32823. 20:14:32order to monitor and manage the indexes
  32824. 20:14:34is to monitor the index fragmentations.
  32825. 20:14:37Over the time as your data is inserted,
  32826. 20:14:40updated, deleted into your tables,
  32827. 20:14:42indexes can become fragmented. So what
  32828. 20:14:45is fragmentation? It means like there is
  32829. 20:14:48unused spaces in your databases and the
  32830. 20:14:50database is not filling them or your
  32831. 20:14:53data is not anymore sorted correctly in
  32832. 20:14:55the index and this of course leads to
  32833. 20:14:58inefficient use of the storage and as
  32834. 20:15:00well going to slow down your
  32835. 20:15:07queries and in SQL in order to get
  32836. 20:15:10everything organized again we have two
  32837. 20:15:12methods the first method is reorganize
  32838. 20:15:15so it's going to go and def fragment the
  32839. 20:15:17leaf level of the index in order to get
  32840. 20:15:20it organized and sorted again with the
  32841. 20:15:22logical order. So it is very light
  32842. 20:15:25operation and it will not block the user
  32843. 20:15:27from using your table. And the second
  32844. 20:15:29method called rebuild this is
  32845. 20:15:31heavyweight operation. It going to go
  32846. 20:15:34and drop the whole index and recreate it
  32847. 20:15:37from the scratch. And this means of
  32848. 20:15:39course not only the data going to get
  32849. 20:15:40sorted again but as well the
  32850. 20:15:43fragmentations inside your databases and
  32851. 20:15:45the index going to be eliminated. So
  32852. 20:15:47let's see how we can do that in SQL.
  32853. 20:15:49Okay. So now back to our database and
  32854. 20:15:51the first question that you have to ask
  32855. 20:15:53do we have an issue with the
  32856. 20:15:54fragmentations in our indexes. So we
  32857. 20:15:57have to check the health of our indexes
  32858. 20:15:59in the database. And in order to do
  32859. 20:16:01that, we have again to go to the system
  32860. 20:16:04metadata that we have and we're going to
  32861. 20:16:06check their dynamic management
  32862. 20:16:08functions. So there is like a special
  32863. 20:16:10functions in order to get an answer in
  32864. 20:16:12the SQL server. Let's go and do that. So
  32865. 20:16:14we're going to go and select star from
  32866. 20:16:16the function. So it is sis dot so it's
  32867. 20:16:19going to be sis dot dm db index physical
  32868. 20:16:24states this one. And this is a function
  32869. 20:16:26that we have to pass few parameters. We
  32870. 20:16:28will not go in details just follow me
  32871. 20:16:30with this. So we have to give it the DB
  32872. 20:16:32ID and a null another null and a third
  32873. 20:16:37null and the last one going to be
  32874. 20:16:39limited. So we have to do it like this.
  32875. 20:16:41So let's go and query it. Now what do we
  32876. 20:16:43find? We have the object ID. We have the
  32877. 20:16:45index ID and few other informations but
  32878. 20:16:48the most important one is the average
  32879. 20:16:50fragmentation in percent. So this
  32880. 20:16:52columns gives us the degree of the
  32881. 20:16:54fragmentations in a word index. If it is
  32882. 20:16:57zero then it is perfect. We have no
  32883. 20:16:59fragmentation in the index and our index
  32884. 20:17:02is very healthy. But if it is like 100
  32885. 20:17:05then that means it is completely out of
  32886. 20:17:07order and we have to do something about
  32887. 20:17:09it. And now you might say you know what
  32888. 20:17:11I don't know which object it does and
  32889. 20:17:13which index. Well you have to go and
  32890. 20:17:15join few tables like the cy.ts and
  32891. 20:17:18cis.index in order to get those
  32892. 20:17:20informations. So we have to go and do
  32893. 20:17:22that like we have done at the first
  32894. 20:17:23query. So okay so offline I have done
  32895. 20:17:25that. So I joined with the tables and
  32896. 20:17:27the indexes and I'm sorting the data by
  32897. 20:17:30the average fragmentations and
  32898. 20:17:32percentage descending in order to get
  32899. 20:17:34the problems at the start because we are
  32900. 20:17:36interested where we have high
  32901. 20:17:37percentage. So let's go and execute
  32902. 20:17:39this. And now since it is practicing
  32903. 20:17:41database I didn't insert any data and so
  32904. 20:17:44on. But in real projects you will get
  32905. 20:17:45here different numbers. And here is my
  32906. 20:17:48recommendations about the percentage. If
  32907. 20:17:50the fragmentation is between like zero
  32908. 20:17:52and 10 that means everything is like
  32909. 20:17:54okay and you don't have to do anything
  32910. 20:17:56about it. But if the percentage is
  32911. 20:17:58between like 10 and 30 then here we have
  32912. 20:18:01to do something about it. So here I
  32913. 20:18:03recommend to use the reorganize method
  32914. 20:18:05in order to sort the data again
  32915. 20:18:07correctly. But if you have more than 30%
  32916. 20:18:10then here my recommendation is to go and
  32917. 20:18:12rebuild the whole index because not only
  32918. 20:18:15the data is in wrong order but as well
  32919. 20:18:18there is a new spaces in your data page
  32920. 20:18:20in the index. So you have to do
  32921. 20:18:21something about it. So now let's go and
  32922. 20:18:23imagine one of those indexes for example
  32923. 20:18:25this one over here has fragmentation of
  32924. 20:18:2815%. So now what we have to do is to go
  32925. 20:18:30and reorganize this index. Let's see how
  32926. 20:18:32we can do that. So let's go over here
  32927. 20:18:35and say the following. alter index and
  32928. 20:18:38then we need the index name. So let's go
  32929. 20:18:40and get it from here and then you have
  32930. 20:18:42to mention the table name where the
  32931. 20:18:44index exists. So we have it from the
  32932. 20:18:46customers. So from sales customers so
  32933. 20:18:49now we are editing the index and we have
  32934. 20:18:51to tell SQL what to do now. So we just
  32935. 20:18:53want to reorganize the index. So you go
  32936. 20:18:55and use the keyword reorganize. So
  32937. 20:18:58reorganize and that's it. This is very
  32938. 20:19:01simple. So let's go and do that. And as
  32939. 20:19:03you can see it is completed and it was
  32940. 20:19:05very fast because we have small
  32941. 20:19:06database. But sometimes it take little
  32942. 20:19:08more time if you have a big index and
  32943. 20:19:10big table. So after reorganizing you can
  32944. 20:19:12go and again check the table over here
  32945. 20:19:14and see the results and it should be
  32946. 20:19:17like here is zero. Now let's see that we
  32947. 20:19:19have another index where the
  32948. 20:19:20fragmentation around like 50%. So let's
  32949. 20:19:23go and copy it and this time instead of
  32950. 20:19:26reorganize we're going to do rebuild. So
  32951. 20:19:29I'm going to take the whole thing and
  32952. 20:19:32this time we're going to go and rebuild
  32953. 20:19:34this index over here on the same table
  32954. 20:19:36and instead of reorganize we're going to
  32955. 20:19:38say rebuild. So let's go and execute
  32956. 20:19:41that. And with that SQL did drop the
  32957. 20:19:44whole index and create it from the
  32958. 20:19:46scratch. And this is usually takes more
  32959. 20:19:48time than reorganize of course. And the
  32960. 20:19:51next step of course is to go and check
  32961. 20:19:52again the fragmentations and so on. So
  32962. 20:19:55that's all about how to make your index
  32963. 20:19:57healthy and remove the fragmentations
  32964. 20:20:00from your index. All right, my friends.
  32965. 20:20:03So as you can see, improving the
  32966. 20:20:04performance of your queries doesn't end
  32967. 20:20:06by creating them. It's all about staying
  32968. 20:20:09proactive. So monitor the usage of the
  32969. 20:20:12indexes, check whether there are any
  32970. 20:20:14missing indexes, and always make sure
  32971. 20:20:16the statistics of the database are up to
  32972. 20:20:19date and keep your eyes on the
  32973. 20:20:20fragmentations and make sure you have
  32974. 20:20:22healthy indexes. So with that you have
  32975. 20:20:25learned how I manage and monitor the
  32976. 20:20:27indexes once I create them and I really
  32977. 20:20:29recommend you to follow those
  32978. 20:20:34steps. All right friends, so now let's
  32979. 20:20:36say that you have a large complex
  32980. 20:20:38analytical SQL query and it involves a
  32981. 20:20:42lot of joins and aggregations and so on
  32982. 20:20:44but it is slow and of course you want to
  32983. 20:20:47go and optimize the performance of your
  32984. 20:20:48query by maybe using indexes. And now
  32985. 20:20:51the big question is where exactly I'm
  32986. 20:20:54going to go build this index on which
  32987. 20:20:55table on which columns. So that means
  32988. 20:20:58you have to understand where exactly the
  32989. 20:20:59problem is. Is it by joining tables or
  32990. 20:21:02sorting data or by the aggregations? Now
  32991. 20:21:05in order to answer all those questions
  32992. 20:21:08we have something called execution plan.
  32993. 20:21:10So what is that? The execution plan
  32994. 20:21:13going to show you how the database
  32995. 20:21:15exactly process your query step by step.
  32996. 20:21:19And this is what we need. It's going to
  32997. 20:21:21show us where exactly we have a
  32998. 20:21:23performance issue. So in other words,
  32999. 20:21:25the execution plan it's like your window
  33000. 20:21:28on how the SQL database thinks and once
  33001. 20:21:31you understand that then you're going to
  33002. 20:21:33make a right decision on building an
  33003. 20:21:35index. So let's understand exactly what
  33004. 20:21:37this means. Okay. So now let's imagine
  33005. 20:21:39that you are doing a query like
  33006. 20:21:41selecting from table and then joining
  33007. 20:21:43the data with another table. So now once
  33008. 20:21:45you execute this query the database
  33009. 20:21:47engine will not go immediately and start
  33010. 20:21:49fetching data from the disk but instead
  33011. 20:21:51of that first the SQL has to make a
  33012. 20:21:54plan. So it's like you are planning a
  33013. 20:21:56trip where you check the Google map in
  33014. 20:21:58order to find the best route in order to
  33015. 20:22:01reach the destination and the execution
  33016. 20:22:03plan is exactly the same thing. The
  33017. 20:22:05database has first to plan how to
  33018. 20:22:08execute your query and it's going to
  33019. 20:22:09build this plan step by step based on
  33020. 20:22:12your query and as well the statistics.
  33021. 20:22:15So the first step for example how to get
  33022. 20:22:17the data from the tables and there are
  33023. 20:22:19like multiple ways like scan index or
  33024. 20:22:22full table scan and then after that it
  33025. 20:22:24need to decide which type of joins going
  33026. 20:22:26to be done like is it hash join or a
  33027. 20:22:28loop join and then at the end of this
  33028. 20:22:30plan it's going to be the select
  33029. 20:22:32statements. So once the execution plan
  33030. 20:22:34is ready the database engine going to
  33031. 20:22:36start implementing the steps. So it's
  33032. 20:22:38going to go and start reading your
  33033. 20:22:40tables for example from the disk and
  33034. 20:22:41then after that it's going to join the
  33035. 20:22:43tables and then select the columns and
  33036. 20:22:45send at the end the results to the end
  33037. 20:22:47user. And now once everything is done
  33038. 20:22:50the database engine going to do one more
  33039. 20:22:51thing where it's going to go and take
  33040. 20:22:53this execution plan and store it at the
  33041. 20:22:56cache. And that's because the database
  33042. 20:22:58engine can go and reuse this plan if we
  33043. 20:23:02have a similar query. So for example, if
  33044. 20:23:04you go and execute the same query again,
  33045. 20:23:06the database engine here going to
  33046. 20:23:08understand ah this is the same query. We
  33047. 20:23:10have already built an execution plan for
  33048. 20:23:13that. So it going to go and check the
  33049. 20:23:15cache and it is way faster to get it
  33050. 20:23:17immediately from the cache instead of
  33051. 20:23:19building it. So in this scenario, the
  33052. 20:23:20database engine doesn't have to make any
  33053. 20:23:22decisions or something like that. going
  33054. 20:23:24to go and get the plan from the cache
  33055. 20:23:26and start immediately by executing the
  33056. 20:23:29plan. And of course, the database engine
  33057. 20:23:31will not hide the execution plan from
  33058. 20:23:33the users. You can go and check it
  33059. 20:23:35because you can go and check how the
  33060. 20:23:37database loaded the data, how they are
  33061. 20:23:39joined and so on. And then you can make
  33062. 20:23:41a correct decision on how to optimize
  33063. 20:23:43your query maybe by adding indexes. So
  33064. 20:23:46let's go back to SQL and see how we can
  33065. 20:23:48do that.
  33066. 20:23:52Okay, so now we're going to work with
  33067. 20:23:54the database Adventure Works DW2022. And
  33068. 20:23:57now we're going to go to our tables and
  33069. 20:23:59we're going to focus on the fact fact
  33070. 20:24:02reseller sales. Now let's go and check
  33071. 20:24:04the type of this table. So if you go
  33072. 20:24:06inside it and go to the indexes, you can
  33073. 20:24:08see that we have an index on the primary
  33074. 20:24:11key. So we have a clustered roster
  33075. 20:24:14index. So that means the data is
  33076. 20:24:16structured in this P tree. So now what
  33077. 20:24:18we're going to do, we're going to go and
  33078. 20:24:18create a mirror of this table but
  33079. 20:24:20without any indexes. So it's going to be
  33080. 20:24:23very simple. Select star from our fact
  33081. 20:24:26reseller sales and we're going to insert
  33082. 20:24:29it in a new table. So
  33083. 20:24:32into fact
  33084. 20:24:34reseller sales and I'm going to call it
  33085. 20:24:37HP for heap. So let's go and execute it.
  33086. 20:24:40And now you can see we have inserted in
  33087. 20:24:41the new table around 60,000 rows. So now
  33088. 20:24:44we can go and refresh our tables in
  33089. 20:24:46order to find our new table. So it is
  33090. 20:24:48over here factory seller sales and if
  33091. 20:24:51you check the indexes you will not find
  33092. 20:24:53any. So that means it is a heap table.
  33093. 20:24:55Now let's go and do a very simple query
  33094. 20:24:57on top of our new table. So select star
  33095. 20:25:01from the factory seller HP like this. So
  33096. 20:25:04let's go and execute it and we got the
  33097. 20:25:07results. So now the question is I would
  33098. 20:25:09like to see the execution plan of this
  33099. 20:25:11query. Now in order to see the execution
  33100. 20:25:13plan we're going to go to the toolbar
  33101. 20:25:15over here and we have three things. The
  33102. 20:25:18first one is says display estimated
  33103. 20:25:21execution plan and we have another one
  33104. 20:25:24says include actual execution plan and a
  33105. 20:25:27third one says include live query
  33106. 20:25:30statistics. So now the question is what
  33107. 20:25:32are the differences between them? Let's
  33108. 20:25:33start with the first one displayed
  33109. 20:25:35estimated execution plan. So here what's
  33110. 20:25:37going to happen? SQL going to go and
  33111. 20:25:39guess the execution plan without
  33112. 20:25:42executing the query. So it's just an
  33113. 20:25:44estimation. So this is only a guess an
  33114. 20:25:46estimation. The second one is the actual
  33115. 20:25:49one. So this going to show you the
  33116. 20:25:51execution plan that is used in order to
  33117. 20:25:54process your query. So after executing
  33118. 20:25:57your query, SQL going to show for you
  33119. 20:25:59which plan is used. So that means the
  33120. 20:26:01estimated plan it is something before
  33121. 20:26:04executing your query and the actual plan
  33122. 20:26:07is something after executing your query.
  33123. 20:26:10And the third one is while executing the
  33124. 20:26:13query. So you're going to get a realtime
  33125. 20:26:15execution of your query and you can see
  33126. 20:26:17how your execution plan is working. So
  33127. 20:26:20now we can go and try that. Let's go and
  33128. 20:26:22activate the estimated execution plan.
  33129. 20:26:24Now we can see over here we have a new
  33130. 20:26:26output where you can see like few boxes.
  33131. 20:26:29So this is an estimated execution plan
  33132. 20:26:31without executing your query. But now if
  33133. 20:26:34you go over here and switch it to the
  33134. 20:26:36actual execution plan nothing going to
  33135. 20:26:38happen because first you have to execute
  33136. 20:26:40your query. So let's go and do that. So
  33137. 20:26:42once we have executed we got the result
  33138. 20:26:45the messages and here we have a new tab
  33139. 20:26:47called execution plan. So if you go over
  33140. 20:26:49here you will find the real execution
  33141. 20:26:52plan that is used to process your query.
  33142. 20:26:54And let's go and try the third one. And
  33143. 20:26:57let's go and
  33144. 20:26:58execute. It was pretty fast because the
  33145. 20:27:01query is very fast. But here we can see
  33146. 20:27:03how the data and the plan is working
  33147. 20:27:06during the execution. So this is the
  33148. 20:27:08live execution plan. And of course we
  33149. 20:27:10have the last one which is the current
  33150. 20:27:13execution plan. So those are the
  33151. 20:27:15differences between those stuff. Now you
  33152. 20:27:17might ask why do we have this estimated
  33153. 20:27:20and actual execution plans? Well, it is
  33154. 20:27:23really nice tool to understand whether
  33155. 20:27:25everything like is healthy at your
  33156. 20:27:27database because if the guessing is
  33157. 20:27:29something else at the actual execution
  33158. 20:27:32plan that means this is an indicator
  33159. 20:27:34that something is wrong at the
  33160. 20:27:36statistics or the index at your
  33161. 20:27:38database. So if they are matching the
  33162. 20:27:40estimated and the actual then everything
  33163. 20:27:42looks good. But now we're going to focus
  33164. 20:27:44only on one type of those execution
  33165. 20:27:46plans. We're going to stick with the
  33166. 20:27:48actual execution plan. So now what we're
  33167. 20:27:50going to do, we're going to go and open
  33168. 20:27:52two queries side by side and one going
  33169. 20:27:54to be from the clustered index and
  33170. 20:27:56another one is from the heap structure.
  33171. 20:27:59So it's going to be like one to one.
  33172. 20:28:00Let's go and query both of them. And now
  33173. 20:28:03let's go and try to read the execution
  33174. 20:28:05plan. But make sure that you are
  33175. 20:28:07activating the actual execution plan. So
  33176. 20:28:10we have here now two plans. So now we
  33177. 20:28:13are at the he table and we don't have
  33178. 20:28:15any indexes. So now the question is how
  33179. 20:28:17to read this execution plan? Well, now
  33180. 20:28:20the plan is very simple because we have
  33181. 20:28:21a very simple query but we read it from
  33182. 20:28:24the right to the left. So the first
  33183. 20:28:26operation is the table scan and then we
  33184. 20:28:29have here a very small arrow to the next
  33185. 20:28:31one where we have the select. So from
  33186. 20:28:33right to left. So now of course the
  33187. 20:28:35first operator is how to read your data
  33188. 20:28:37inside the table and here we have
  33189. 20:28:39different types of scans and one of them
  33190. 20:28:41is the table scan. So table scan
  33191. 20:28:43actually is scanning the entire table.
  33192. 20:28:46So it's going to go and scan all the
  33193. 20:28:48rows inside your tables in order to
  33194. 20:28:50execute this query. Now if you go and
  33195. 20:28:52mouse hover on the table scan, you will
  33196. 20:28:55find a lot of details about what is
  33197. 20:28:58happening during loading the data or
  33198. 20:29:00scanning the table. But it is little bit
  33199. 20:29:02annoying better than that. If you go
  33200. 20:29:04right click on it and then go to
  33201. 20:29:06properties, you will get in the right
  33202. 20:29:08side the same details but it is easier
  33203. 20:29:10to read. So the first thing that we have
  33204. 20:29:12to read is the number of rows that has
  33205. 20:29:15been read. So we can see that we have
  33206. 20:29:17read all the rows inside the table which
  33207. 20:29:19is not really good and we have another
  33208. 20:29:21important informations about the
  33209. 20:29:22resources and the cost. So we have the
  33210. 20:29:24CPU cost and the input output costs and
  33211. 20:29:27what is interesting is the logical
  33212. 20:29:29operator the table scan and we can see
  33213. 20:29:32some nice informations about the
  33214. 20:29:33storage. It says it is row store. Now
  33215. 20:29:35let's go and check the execution plan of
  33216. 20:29:38this other table where we have a
  33217. 20:29:40clustered index. So let's go to the
  33218. 20:29:42execution plan. And now you can see that
  33219. 20:29:44we have on the right side something
  33220. 20:29:46else. We don't have table scan. We have
  33221. 20:29:48something called clustered index scan.
  33222. 20:29:51It is either scanning the entire table
  33223. 20:29:53again or only a range or a part of the
  33224. 20:29:57index. And of course in the details we
  33225. 20:29:59can see whether it read all the
  33226. 20:30:00informations or not. Now if you go and
  33227. 20:30:03check the number of rows again the whole
  33228. 20:30:05index is read in order to get this
  33229. 20:30:07results. So again we have here the total
  33230. 20:30:09number of rows inside our table. And as
  33231. 20:30:11well you can see over here the logical
  33232. 20:30:13operation it is clustered index scan. So
  33233. 20:30:16it is not table scan. Now of course we
  33234. 20:30:18have to go and check the CPU and the
  33235. 20:30:20input output costs whether we are
  33236. 20:30:21consuming the same efforts or not. So we
  33237. 20:30:24can go and compare stuff. So here we
  33238. 20:30:26have like
  33239. 20:30:270.07. And if you go over here you can
  33240. 20:30:30see we didn't gain like a lot of
  33241. 20:30:32information having an index on this
  33242. 20:30:34table. And that's of course logical
  33243. 20:30:35because this query is not using any
  33244. 20:30:38indexes. It is just like selecting
  33245. 20:30:40everything from the whole
  33246. 20:30:44table. So now let's go and extend it
  33247. 20:30:47where we're going to sort the data by
  33248. 20:30:48the primary key sales order number. So
  33249. 20:30:53let's go and get this one and as well
  33250. 20:30:55for the heap structure. So let's go and
  33251. 20:30:58execute it and check the execution plan
  33252. 20:31:01and the same thing for our cluster
  33253. 20:31:04table. Now let's check first the heap
  33254. 20:31:07structure. As you can see here, we have
  33255. 20:31:08like two steps. First, it's going to go
  33256. 20:31:11and scan the whole table and then we
  33257. 20:31:14have sort operator in order to go and
  33258. 20:31:17sort all the data in order to present it
  33259. 20:31:19in the output. And at the end, we have
  33260. 20:31:21the select which is not really
  33261. 20:31:23important. So here we have like two
  33262. 20:31:24operators. But now if you go to our
  33263. 20:31:26clustered index, you can see that we
  33264. 20:31:29have only like two steps. There is no
  33265. 20:31:30sort step, right? And that's because the
  33266. 20:31:33clustered index is only sorted and SQL
  33267. 20:31:37don't have to go and sort the data
  33268. 20:31:39again. So it doesn't have to go and sort
  33269. 20:31:41anything. The data is already sorted. So
  33270. 20:31:43this is the first win that you have if
  33271. 20:31:46you have an index. So everything is
  33272. 20:31:48already sorted and if you have an order
  33273. 20:31:50by on this column then SQL don't have to
  33274. 20:31:53do it during the query. So now if you
  33275. 20:31:55want to go and compare the cost you can
  33276. 20:31:56see here we still have the same cost for
  33277. 20:31:58the CPU and the input output in the h
  33278. 20:32:01structure without any index we have here
  33279. 20:32:04like double cost. The first cost is for
  33280. 20:32:06the table scan. It is the exact same
  33281. 20:32:09amount of CPU and input output like the
  33282. 20:32:12clustered but as well on top of it we
  33283. 20:32:14have high cost for sorting the data. So
  33284. 20:32:17we are consuming more CPU and input
  33285. 20:32:19output. And if you summarize those cost
  33286. 20:32:21of course this query going to be slower
  33287. 20:32:24and bad compared to the clustered index.
  33288. 20:32:28So with that in the execution plan you
  33289. 20:32:30can understand exactly the benefit of
  33290. 20:32:32your index. And one more thing about
  33291. 20:32:34this plan if you go over here. So if you
  33292. 20:32:36go to the objects and let me just extend
  33293. 20:32:39it like this. You can see the name of
  33294. 20:32:42the index that has been used for your
  33295. 20:32:44query. So it says the index is B key for
  33296. 20:32:48primary key. And then we have the whole
  33297. 20:32:50thing. So now if you go to our table on
  33298. 20:32:52the left side, check the indexes, it
  33299. 20:32:54going to be exactly this index. So in
  33300. 20:32:57the execution plan you can find as well
  33301. 20:33:00which index has been used in your query.
  33302. 20:33:02And this is very important to check. If
  33303. 20:33:04you create a new index then run your
  33304. 20:33:07query and check whether the database is
  33305. 20:33:09using your new created index. And if not
  33306. 20:33:12then you are making the wrong decisions
  33307. 20:33:14about your index. So each time you
  33308. 20:33:15create a new index, make sure to check
  33309. 20:33:17whether in the execution plan the
  33310. 20:33:19database is using your new
  33311. 20:33:21[Music]
  33312. 20:33:24index. Okay, so now let's keep going.
  33313. 20:33:27Now instead of using the primary key,
  33314. 20:33:29I'm going to go and filter the data
  33315. 20:33:30based on one of those columns that we
  33316. 20:33:32have in this table. So let me check the
  33317. 20:33:34results and let's take for example the
  33318. 20:33:37carrier tracking number. So carrier
  33319. 20:33:40tracking number and let's go and pick a
  33320. 20:33:43value. the first one here like this and
  33321. 20:33:46let's do the same thing for the heap
  33322. 20:33:48table and execute it. And now in the
  33323. 20:33:51execution plan you see we still have a
  33324. 20:33:53table scan and on this table let's see
  33325. 20:33:56the execution plan with the clustered
  33326. 20:33:58index. Now let's say that I would like
  33327. 20:34:00to go and create a nclustered index for
  33328. 20:34:03this column. So let's go and do it. So
  33329. 20:34:05create
  33330. 20:34:07nonclustered index and I'm going to call
  33331. 20:34:09it index fact reseller and then the
  33332. 20:34:13column name. So on our table fact
  33333. 20:34:18reseller and the column going to be
  33334. 20:34:20carrier tracking number. So I'm going to
  33335. 20:34:22take it from here and let's go and
  33336. 20:34:25create it. Now let's see whether our
  33337. 20:34:27query going to use this index. So let's
  33338. 20:34:29go and execute it and let's go to the
  33339. 20:34:31execution plan. Now things looks
  33340. 20:34:34completely different than before. So
  33341. 20:34:36what is going on? We can see that we
  33342. 20:34:38have now something new. We don't have a
  33343. 20:34:40clustered index. We have something
  33344. 20:34:42called index seek. Index seek is an
  33345. 20:34:45amazing sign in your execution plan
  33346. 20:34:47because it tells us that SQL server did
  33347. 20:34:50find a way to use the index in order to
  33348. 20:34:53find the exact data that we need without
  33349. 20:34:55scanning a lot of stuff. So that means
  33350. 20:34:58now we have like three types of scans.
  33351. 20:35:00We have the table scan where the SQL
  33352. 20:35:02going to go and scan the whole table and
  33353. 20:35:04this can happen in the heap structure
  33354. 20:35:06and the second one we have the index
  33355. 20:35:09scan and here we don't know whether it
  33356. 20:35:11is scanning the whole index or a part of
  33357. 20:35:13the index and the last one we have the
  33358. 20:35:16index seek where the database is able to
  33359. 20:35:19find directly the data without scanning
  33360. 20:35:21a lot of stuff. So the worst type is the
  33361. 20:35:24table scan. Then we have the index scan
  33362. 20:35:27and the best one is the index seek. So
  33363. 20:35:30if you check here the details you can
  33364. 20:35:32see the number of rows that has been
  33365. 20:35:34read is only 12. This is amazing. Let's
  33366. 20:35:37go and check the heap scan over here. So
  33367. 20:35:40to the execution plan and if you go over
  33368. 20:35:42here you can see that we are reading
  33369. 20:35:45around 60,000 rows in order to get 12.
  33370. 20:35:49But with the index we are reading only
  33371. 20:35:5212 in order to get 12 and this is
  33372. 20:35:54amazing and very fast of course and of
  33373. 20:35:57course the cost of this is very very
  33374. 20:35:59small. So if you check the CPU and the
  33375. 20:36:01input output you can see those numbers
  33376. 20:36:03are nothing and of course if you go to
  33377. 20:36:05the object over here you can see which
  33378. 20:36:07index has been used and this is exactly
  33379. 20:36:09the index that we have just created. So
  33380. 20:36:12that means it was a really good decision
  33381. 20:36:15to create this index and the SQL was
  33382. 20:36:17very happy about it and used it in order
  33383. 20:36:19to fast find our data. So now let's go
  33384. 20:36:22and check the rest of the plan. And now
  33385. 20:36:24you can see over here we have key
  33386. 20:36:25lookup. The key lookup is an operation
  33387. 20:36:28that we need in order to get the rest of
  33388. 20:36:30the columns because from this index we
  33389. 20:36:33are getting the data of only one column
  33390. 20:36:35the carrier tracking number. But since
  33391. 20:36:37in our query we are saying select star
  33392. 20:36:40that means we have a lot of columns and
  33393. 20:36:42those columns are not part of the index.
  33394. 20:36:44So in this index is called don't know
  33395. 20:36:46anything about the rest. That's why has
  33396. 20:36:49to go and search for the other columns
  33397. 20:36:52and of course it is called a lookup not
  33398. 20:36:54a scan or something like that and that's
  33399. 20:36:56why we have here as well only 12 rows
  33400. 20:36:59but from this step we will get the rest
  33401. 20:37:02of the columns. So and now the next step
  33402. 20:37:05is that SQL going to go and join those
  33403. 20:37:07two informations. So we have from the
  33404. 20:37:10first one the carrier tracking number
  33405. 20:37:12and the second one we have the rest of
  33406. 20:37:14course SQL has to go and merge all those
  33407. 20:37:16stuff in one in order to have it as a
  33408. 20:37:18results. And now this operation called a
  33409. 20:37:20nested loops. Behind the scenes there
  33410. 20:37:23are different types of joins not the one
  33411. 20:37:25that we know the inner lift and so on
  33412. 20:37:27but there is another types of joints. We
  33413. 20:37:29have the nested loop. We have the merge
  33414. 20:37:32join and the hash join. The nested loop
  33415. 20:37:34is very good for small stuff. If you
  33416. 20:37:37have large tables, then the merge and
  33417. 20:37:39the hash joints are way better than the
  33418. 20:37:42nested loop. So that means if you are
  33419. 20:37:44getting here a lot of data from the
  33420. 20:37:46index and the lookups and you seek is
  33421. 20:37:49using a nested loop, this is not good.
  33422. 20:37:52But for now it is okay because we are
  33423. 20:37:54getting only 12 rows and the operation
  33424. 20:37:56going to be fast enough. And now one
  33425. 20:37:58more thing that we can see inside our
  33426. 20:37:59execution plan is the cost in
  33427. 20:38:01percentage. So from checking this plan
  33428. 20:38:03you can see the select is almost costing
  33429. 20:38:06nothing. The cost of the nested loop is
  33430. 20:38:09as well like 0%. And then we have like
  33431. 20:38:116% of the index seek. That's because it
  33432. 20:38:14is pretty fast and the most expensive
  33433. 20:38:17operation that done in our query is the
  33434. 20:38:20key lookups of course because it's going
  33435. 20:38:22to go and get all the columns. And now
  33436. 20:38:25if you go and compare to the heap
  33437. 20:38:27structure even though that the execution
  33438. 20:38:29plan of the heap structure looks very
  33439. 20:38:31small doesn't mean that is faster than
  33440. 20:38:34the indexes that we have. Still if you
  33441. 20:38:36go and add up all those numbers it is
  33442. 20:38:39way way faster than the heap structure.
  33443. 20:38:42Now I would like to show you one more
  33444. 20:38:43thing. If you want to get rid of this
  33445. 20:38:45key lookup and in your query you have
  33446. 20:38:48only selecting the carrier tracking
  33447. 20:38:50number. Let's go and execute it and go
  33448. 20:38:52to the execution plan. As you can see
  33449. 20:38:54there is no need for the lookup because
  33450. 20:38:57we have only one column and this data we
  33451. 20:38:59can get it completely from our index. So
  33452. 20:39:02as you can see it is interesting to
  33453. 20:39:04understand how SQL is working with your
  33454. 20:39:06table and with your index and this is
  33455. 20:39:08how to validate whether you are making
  33456. 20:39:11correct decisions about your
  33457. 20:39:16indexes. Okay. So now let's go and add
  33458. 20:39:18more stuff where we are doing
  33459. 20:39:20aggregations joins and so on. Let's
  33460. 20:39:22extend our query. So I'm going to go and
  33461. 20:39:24join it with another dimension like for
  33462. 20:39:26example the dim products and the join
  33463. 20:39:31going to be on the product key. So
  33464. 20:39:33product key and equal to as well product
  33465. 20:39:37key. Now after that we're going to go
  33466. 20:39:39and aggregate few stuff. So we're going
  33467. 20:39:40to aggregate by the product name. So I'm
  33468. 20:39:43going to take the product name. So it's
  33469. 20:39:45going to be the English product name and
  33470. 20:39:48let's go and call it product name. And
  33471. 20:39:51let's go and aggregate the sales. So sum
  33472. 20:39:55and we're going to get it from the fact
  33473. 20:39:56table. It's going to be sales amount. So
  33474. 20:40:00as
  33475. 20:40:01total sales and of course we have to go
  33476. 20:40:04and do group by and not French name.
  33477. 20:40:08It's going to be the English
  33478. 20:40:09name. So let's group up by the product
  33479. 20:40:13name. And that's it. Let's go and
  33480. 20:40:15execute it. Now we have a nice list of
  33481. 20:40:17products and total sales. But let's go
  33482. 20:40:19and check the execution plan. And oh my
  33483. 20:40:22god, we have a lot of stuff. So let's
  33484. 20:40:24start from the right side. So let's do
  33485. 20:40:27it quickly from the right to the left.
  33486. 20:40:28So the first thing is that it's going to
  33487. 20:40:30go and get the data from the fact. So it
  33488. 20:40:33is using the clustered index. And then
  33489. 20:40:35after that it's going to go and do a
  33490. 20:40:37hashmatch for the aggregation. And after
  33491. 20:40:40that it's going to go and sort the data
  33492. 20:40:42because it is doing later a merge join.
  33493. 20:40:45So all those steps are preparing the
  33494. 20:40:47fact table. And then we have another
  33495. 20:40:49cluster scan for the dimension. So it
  33496. 20:40:52going to go and as well select the
  33497. 20:40:54informations from the dimension. And we
  33498. 20:40:55have here like not a lot of rows. So it
  33499. 20:40:58is very small table 600 rows. And now of
  33500. 20:41:00course the result of the cluster scan is
  33501. 20:41:03as well sorted right and of course as we
  33502. 20:41:05learned the cluster the index going to
  33503. 20:41:06go and sort the data. So we have here a
  33504. 20:41:09sorted output together with another
  33505. 20:41:11sorted output. So we have like two data
  33506. 20:41:14sets that are sorted and SQL here
  33507. 20:41:16decided to go with the merge join which
  33508. 20:41:18is a good join in order to join two
  33509. 20:41:20sorted data sets. It is way faster than
  33510. 20:41:23joining using the nested loop. So
  33511. 20:41:25everything is fine and then the data
  33512. 20:41:27going to be sorted and presented at the
  33513. 20:41:29output. And now if you are checking this
  33514. 20:41:31plan you can see the most expensive
  33515. 20:41:33thing happened at the fact table. So
  33516. 20:41:3671% of the total cost happened in this
  33517. 20:41:39step. Now let's say that the query is
  33518. 20:41:41slow and I would like to go and optimize
  33519. 20:41:43it. We have learned that if you are
  33520. 20:41:45doing aggregations on big tables then
  33521. 20:41:48the column store index is a good idea.
  33522. 20:41:52So let's go and find whether that is
  33523. 20:41:54true. So I'm going to go to our other
  33524. 20:41:56table. So our sales table was with the
  33525. 20:41:59heap structure. And now you say you know
  33526. 20:42:01what let's go and convert this he
  33527. 20:42:04structure to a column store. So let's go
  33528. 20:42:06and do that. So we're going to say
  33529. 20:42:07create
  33530. 20:42:09clustered column store index and we're
  33531. 20:42:13going to call it index and then the
  33532. 20:42:14whole name fact
  33533. 20:42:17reseller sales HP and we don't have to
  33534. 20:42:20specify any columns. So it's going to be
  33535. 20:42:23our table on and that's it. Let's go and
  33536. 20:42:26execute it. So now our table is not
  33537. 20:42:29anymore heap structure. It should be a
  33538. 20:42:32column store. So if you go and check the
  33539. 20:42:34informations we can see we have like
  33540. 20:42:36clustered column stored index on it. So
  33541. 20:42:39now let's go and do the same query and
  33542. 20:42:41check whether we have a better
  33543. 20:42:42performance. Let's go and execute it.
  33544. 20:42:44And of course you have to go and
  33545. 20:42:45activate the execution plan. So I'm
  33546. 20:42:47going to and now let's go and check from
  33547. 20:42:50the right again. So this is our fact
  33548. 20:42:53table and as you can see already it is
  33549. 20:42:56costing only 6%. Interesting. So let's
  33550. 20:42:59go and compare what happened to our fact
  33551. 20:43:00table. First of all, we can see that the
  33552. 20:43:02physical operation is a column store
  33553. 20:43:05index scan. And if you go to the objects
  33554. 20:43:07over here, you can see that the SQL did
  33555. 20:43:10use the column store. And that is of
  33556. 20:43:12course going to happen because the whole
  33557. 20:43:13data is stored only in the index. So
  33558. 20:43:16there is no way around it. So it can go
  33559. 20:43:18and of course and use the index. But now
  33560. 20:43:19what is interesting maybe we have to go
  33561. 20:43:21and compare the CPU costs. So if we
  33562. 20:43:24check over here, it is like
  33563. 20:43:270,000.67 almost the same thing for the
  33564. 20:43:29input output. Let's go to the previous
  33565. 20:43:32plan where we don't have a column store
  33566. 20:43:34and check our facts. So as you can see
  33567. 20:43:36here it is way more expensive reading
  33568. 20:43:39the fact table than the column store and
  33569. 20:43:42as well we have reduced the input output
  33570. 20:43:44costs. So as you can see we went from
  33571. 20:43:4671% of total cost for the fact table to
  33572. 20:43:51only 6%. And the resources that is used
  33573. 20:43:54to execute the query it is way less than
  33574. 20:43:58a normal clustered res store. And this
  33575. 20:44:00is exactly the power of this index, the
  33576. 20:44:02column store index. You can use it in
  33577. 20:44:05big tables like the fact tables like we
  33578. 20:44:07are doing here in this query, you will
  33579. 20:44:09be getting amazing performance for this
  33580. 20:44:12scenario. So of course you can go and
  33581. 20:44:14compare the execution plan by moving
  33582. 20:44:16left and right. So as you can see if I
  33583. 20:44:18click over here and I just switch to the
  33584. 20:44:20other tab, I can like quickly compare
  33585. 20:44:22the numbers. But there is another way on
  33586. 20:44:24how to compare execution plans and that
  33587. 20:44:27is if you go to the execution plan and
  33588. 20:44:29right click on it then go to save
  33589. 20:44:31execution plan as and then you have to
  33590. 20:44:34go and give it a name for example query
  33591. 20:44:36pro store. So let's go and save it and
  33592. 20:44:40then you can go to the second query
  33593. 20:44:42where we have the row store and then
  33594. 20:44:43right click on the execution plan and
  33595. 20:44:46say compare show plan. So once you click
  33596. 20:44:49on that then you have to go and select
  33597. 20:44:51the one that you want to compare with.
  33598. 20:44:53So open and now on top you have your
  33599. 20:44:56query and at the bottom you have the
  33600. 20:44:58execution plan that you have saved and
  33601. 20:45:00then you have here a lot of informations
  33602. 20:45:03where they compare both of the execution
  33603. 20:45:06plan and with that you can go in more
  33604. 20:45:08details in order to understand which
  33605. 20:45:10plan is better. All right friends so as
  33606. 20:45:12you can see having the execution plan is
  33607. 20:45:14is amazing. We can see how the SQL is
  33608. 20:45:17working behind the scenes and we can
  33609. 20:45:19understand how SQL is processing my
  33610. 20:45:21query step by step. How much resources
  33611. 20:45:24it is consuming, whether my indexes are
  33612. 20:45:26useful or useless and I can go and
  33613. 20:45:29experiment stuff. I can go and add like
  33614. 20:45:31an index then test and check whether I
  33615. 20:45:33gained like few performance or not. And
  33616. 20:45:35we can go and compare like multiple
  33617. 20:45:37execution plans before and after until
  33618. 20:45:40you get the right index for the right
  33619. 20:45:42table and the right column. So the
  33620. 20:45:44execution plan are amazing in order to
  33621. 20:45:47help us understanding whether our
  33622. 20:45:50indexing strategy is correct or
  33623. 20:45:56not. All right friends, so so far we
  33624. 20:45:58have learned that the SQL server going
  33625. 20:46:00to make its own decisions on how to
  33626. 20:46:03execute your queries and the SQL make
  33627. 20:46:05those plans based on the statistics. But
  33628. 20:46:07sometimes the plan that you are getting
  33629. 20:46:09from the database might be not the best
  33630. 20:46:12one for your query and there could be
  33631. 20:46:14many reasons why this could happen.
  33632. 20:46:16Maybe the statistics are not up to date
  33633. 20:46:19or you have a lot of indexes and the
  33634. 20:46:21database engine get confused and here
  33635. 20:46:24exactly where we need the SQL hints. So
  33636. 20:46:27you can use the SQL hints in order to
  33637. 20:46:30command to force the SQL database on how
  33638. 20:46:34exactly your SQL query should be
  33639. 20:46:36executed. So you can intervene and
  33640. 20:46:38change the steps in the execution plan.
  33641. 20:46:41So let's see how we can do that. All
  33642. 20:46:43right. So now let's have a very simple
  33643. 20:46:45query. We are just joining the table
  33644. 20:46:46orders with the customers and we are
  33645. 20:46:48showing like few columns. Now if you go
  33646. 20:46:50and execute it and we go and check the
  33647. 20:46:53execution plan, we can see in this plan
  33648. 20:46:55that it is using the clustered index in
  33649. 20:46:57order to read the data from the orders
  33650. 20:46:59and the customers and then it is using
  33651. 20:47:01the nested loop in order to do the
  33652. 20:47:03joins. Now let's say that our tables are
  33653. 20:47:06really big but still the SQL is using
  33654. 20:47:08the nested loops and of course this is
  33655. 20:47:10not good for large tables and maybe the
  33656. 20:47:13SQL was confused with the indexes and
  33657. 20:47:15statistics and so on and it decided to
  33658. 20:47:18use the nested loops. So now in order to
  33659. 20:47:20force the SQL to use another type of
  33660. 20:47:23join, we can go and give a hint in our
  33661. 20:47:25query for the SQL to use different types
  33662. 20:47:28for the join. So let's go and do that.
  33663. 20:47:31We're going to go at the end of our
  33664. 20:47:32query and we're going to say option and
  33665. 20:47:36inside it we're going to say use the
  33666. 20:47:38hash join like this. So that's it. This
  33667. 20:47:42is our query and at the end we are
  33668. 20:47:44giving the database a hint for the
  33669. 20:47:46execution plan. So let's go and try that
  33670. 20:47:48out. So let's check the execution plan.
  33671. 20:47:50And now as you can see is using
  33672. 20:47:53different type of join. So with that we
  33673. 20:47:55are intervening in the execution plan
  33674. 20:47:58and we are making choices. So with that
  33675. 20:48:00we have changed the technicality on how
  33676. 20:48:03the SQL is joining those two tables. All
  33677. 20:48:05right. So now let's go and change
  33678. 20:48:07something else like for example instead
  33679. 20:48:08of having index scan I would like to
  33680. 20:48:12have an index seek. So if you have the
  33681. 20:48:14right index in your table, you can go
  33682. 20:48:16and tell SQL how to read your data in
  33683. 20:48:20the table. So let's go and do that.
  33684. 20:48:22Currently here we have an index scan on
  33685. 20:48:25the table customers. So we can go over
  33686. 20:48:27here near the table and we're going to
  33687. 20:48:29say with and inside it we're going to
  33688. 20:48:31say for SQL force seek. So we are
  33689. 20:48:34forcing SQL to use the seek index. So we
  33690. 20:48:37can use those keywords near the table in
  33691. 20:48:41order to specify for SQL how to load the
  33692. 20:48:43data. If you are not specifying anything
  33693. 20:48:45like here with the orders, we don't have
  33694. 20:48:47here any hints. That means we are
  33695. 20:48:49counting on the execution plan that is
  33696. 20:48:52generated from the SQL. But if you don't
  33697. 20:48:55want the recommendations, you can go and
  33698. 20:48:57specify which one should be used. So now
  33699. 20:49:00let's go and execute it. Now we got an
  33700. 20:49:02error because the SQL is not able to
  33701. 20:49:05process what we are asking for and I
  33702. 20:49:08think maybe we are using the force
  33703. 20:49:09command and as well the hash join. Let
  33704. 20:49:11me just uncomment this and let's go and
  33705. 20:49:13give it another try and now it is
  33706. 20:49:16working. So let's go to the execution
  33707. 20:49:17plan. So you can see we got again the
  33708. 20:49:19nested loop. And now if you go to the
  33709. 20:49:21customers table you can see now it is
  33710. 20:49:24using the index seek. So it is not using
  33711. 20:49:26anymore the index scan. So as you can
  33712. 20:49:29see again we are intervening and forcing
  33713. 20:49:31SQL to use the method that might be
  33714. 20:49:34better for our query. Now if you are
  33715. 20:49:36creating a lot of indexes in one table
  33716. 20:49:38and the SQL is still not targeting the
  33717. 20:49:41right index. So if you check the object
  33718. 20:49:43you can see it is targeting specific
  33719. 20:49:45index. But if you have a better index
  33720. 20:49:48than that you can give a hint for the
  33721. 20:49:50SQL to use a specific index. And we can
  33722. 20:49:53do that like this. If you go over here
  33723. 20:49:56and remove the force seek and you say
  33724. 20:49:58use index and then we have to go and
  33725. 20:50:01specify the index name. So let's go and
  33726. 20:50:04get again the primary key over here. Now
  33727. 20:50:06I'm telling SQL you have to go and use
  33728. 20:50:08this index in order to scan the table
  33729. 20:50:11customers. So let's go and try this out.
  33730. 20:50:13And if you go to the execution plan you
  33731. 20:50:16can see it is as well targeting this
  33732. 20:50:18index. So not only you can force SQL for
  33733. 20:50:21a specific type of loading or joining,
  33734. 20:50:25you can force SQL to use a specific
  33735. 20:50:27index that you created. All right
  33736. 20:50:29friends, so as you can see, SQL hands
  33737. 20:50:31are very powerful, but we have to be
  33738. 20:50:33very careful with them because I really
  33739. 20:50:35had a bad experience using them in my
  33740. 20:50:38projects. So here are my recommendations
  33741. 20:50:40and what happens. So what could happen
  33742. 20:50:41is that you are optimizing the
  33743. 20:50:43performance in the development database
  33744. 20:50:46and you start using the hints and the
  33745. 20:50:48speed was really good and once you roll
  33746. 20:50:50that out to another database the
  33747. 20:50:53production database this hint will not
  33748. 20:50:56be working correctly. The same hint that
  33749. 20:50:58you are using might not improve the
  33750. 20:51:00performance and one reason is that
  33751. 20:51:02sometimes the productive database has
  33752. 20:51:05like large data compared to the
  33753. 20:51:07development database. So you have really
  33754. 20:51:09to test the hint in each database that
  33755. 20:51:12you have. So if your hint is working in
  33756. 20:51:15one environment that doesn't mean it
  33757. 20:51:17going to work in the other one. So
  33758. 20:51:19always make sure to test. And the second
  33759. 20:51:21recommendation is that don't use the
  33760. 20:51:23hint as a permanent fix for your
  33761. 20:51:25queries. So what this means? Let's say
  33762. 20:51:27that you are working in the project and
  33763. 20:51:29one of your queries are very slow. Now,
  33764. 20:51:31if it's not clear why the execution plan
  33765. 20:51:33is really bad, you can go and use the
  33766. 20:51:36hints as a workaround in order to speed
  33767. 20:51:38up your query again, but it's still as a
  33768. 20:51:41workaround temporary. You still have to
  33769. 20:51:43invest and spend time in order to
  33770. 20:51:45analyze what was the road cause. So
  33771. 20:51:48maybe it is an old statistics or you
  33772. 20:51:50have wrong indexing and so on. So use
  33773. 20:51:52hints only to work around and speed up
  33774. 20:51:55your queries, but don't use it as a
  33775. 20:51:57permanent fix. So friends, SQL hints are
  33776. 20:52:00really amazing in order to control the
  33777. 20:52:02execution plan, but use it very
  33778. 20:52:04carefully and only if there is like an
  33779. 20:52:06emergency.
  33780. 20:52:11All right friends, so now for each SQL
  33781. 20:52:14data project, we have to make sure that
  33782. 20:52:16we create a clear guidance about the
  33783. 20:52:19index strategy and everyone in the team
  33784. 20:52:22has to commit and follow the strategy in
  33785. 20:52:24order to make sure that each index that
  33786. 20:52:27is created in the project to fulfill a
  33787. 20:52:29purpose and that's because without a
  33788. 20:52:31clear strategy about the indexing, I'm
  33789. 20:52:33going to promise you there will be a lot
  33790. 20:52:35of redundancy, unused indexes, uh waste
  33791. 20:52:38of storage and the whole system of your
  33792. 20:52:41project is going to be slow and bad. So
  33793. 20:52:43now what we're going to do, I'm going to
  33794. 20:52:44show you my indexing strategy that I
  33795. 20:52:46usually follow in my projects. But I'm
  33796. 20:52:48going to tell you from now there is like
  33797. 20:52:49not one strategy that can fit any
  33798. 20:52:52project and any scenario. That's why the
  33799. 20:52:54team of each project should brainstorm
  33800. 20:52:56in order to make their own strategy. So
  33801. 20:52:59now let's have a look to my indexing
  33802. 20:53:01strategy.
  33803. 20:53:05And now if I have to pick only one
  33804. 20:53:07recommendation from me to you in this
  33805. 20:53:10indexing tutorial, I'm going to have
  33806. 20:53:12this advice for you. Avoid overindexing.
  33807. 20:53:15Overindexing is the biggest mistake and
  33808. 20:53:18trap that a lot of developers do where
  33809. 20:53:21they think adding more indexes. That
  33810. 20:53:23sounds like we are speeding up things
  33811. 20:53:25and our queries can be fast. But I have
  33812. 20:53:28to tell you this exactly lead to the
  33813. 20:53:30opposite. And here's why. As we learned,
  33814. 20:53:33each time you add a new data to your
  33815. 20:53:35table, your index has to get updated,
  33816. 20:53:37sorted, rearranged. That means having
  33817. 20:53:40too many indexes, what's going to
  33818. 20:53:42happen? Your insert, update, delete
  33819. 20:53:44operations going to be slow. And this
  33820. 20:53:46means your database is slower and not
  33821. 20:53:49faster. And one more very important
  33822. 20:53:51reason why overindexing is bad is you
  33823. 20:53:54make the database confused while
  33824. 20:53:56creating the execution plan. As we
  33825. 20:53:58learned, the SQL database has to create
  33826. 20:54:01the best execution plan for your query.
  33827. 20:54:04And if you have a lot of indexes in your
  33828. 20:54:06database, it's going to make the process
  33829. 20:54:08of creating an execution plan
  33830. 20:54:10complicated for the database, which
  33831. 20:54:12makes it of course for database harder
  33832. 20:54:14to choose the best path and index. And
  33833. 20:54:17as well, you open the door for bad
  33834. 20:54:19execution plans. And this means it's
  33835. 20:54:21going to slow the query because first
  33836. 20:54:23the database has to create the execution
  33837. 20:54:25plan before executing your query. So
  33838. 20:54:27again it has a bad effect for the
  33839. 20:54:29performance and as well there is another
  33840. 20:54:31bad thing. It can make it harder for the
  33841. 20:54:33database to decide what is the best
  33842. 20:54:36execution plan for a query and having
  33843. 20:54:38too many indexes might make the SQL
  33844. 20:54:41database choosing a really bad execution
  33845. 20:54:44plan. So overindexing confuse the
  33846. 20:54:46execution plan and as well makes the
  33847. 20:54:49query slower. So that's why I call this
  33848. 20:54:51a golden rule and you have to commit to
  33849. 20:54:53it. Just avoid overindexing because it
  33850. 20:54:56is double-edged sword and exactly you
  33851. 20:54:58have to have the mindset of less is
  33852. 20:55:01more. So having a few effective indexes
  33853. 20:55:04is way better than having a lot of
  33854. 20:55:06indexes. So keep it in mind and write it
  33855. 20:55:09in your development guideline for the
  33856. 20:55:11team with big statement avoid
  33857. 20:55:13overindexing. So this is the first
  33858. 20:55:15statement in your indexing strategy. So
  33859. 20:55:17now let's check the
  33860. 20:55:18[Music]
  33861. 20:55:21rest. All right. So now we can split the
  33862. 20:55:24indexing strategy into four phases and
  33863. 20:55:27each phase has multiple steps. So now
  33864. 20:55:29the first step is we're going to go and
  33865. 20:55:30create an initial indexing strategy. So
  33866. 20:55:33now once you start a new SQL project you
  33867. 20:55:36have to define the objectives of the
  33868. 20:55:38projects very clearly. So that means we
  33869. 20:55:40have to make it clear what we are
  33870. 20:55:41focusing on what we want to achieve and
  33871. 20:55:43in order to define the goal of your
  33872. 20:55:46indexing strategy you have to understand
  33873. 20:55:48your system. We have mainly two types of
  33874. 20:55:51databases. In one hand we have OLAB
  33875. 20:55:54databases. It stands for online
  33876. 20:55:56analytical processing. The purpose of
  33877. 20:55:58this database is for data analytics and
  33878. 20:56:00an example for that is the data
  33879. 20:56:02warehouse. So in data warehousing we go
  33880. 20:56:05and extract the data from multiple
  33881. 20:56:07sources and then we prepare it and
  33882. 20:56:09transform it and put it in one big
  33883. 20:56:11storage and we call this process an ETL
  33884. 20:56:13process. And then the front end we have
  33885. 20:56:16like reports and dashboards where the
  33886. 20:56:18data is summarized and aggregated and
  33887. 20:56:20presented for the end user. And these
  33888. 20:56:22reports could be used from users in
  33889. 20:56:24order to analyze and have insights about
  33890. 20:56:26the data. And now in order to generate
  33891. 20:56:28those reports there will be like heavy
  33892. 20:56:31reading on the data warehouse database.
  33893. 20:56:34So that means there will be huge queries
  33894. 20:56:36that's going to access the database in
  33895. 20:56:38order to aggregate and prepare the data
  33896. 20:56:40for the visualization. But now in the
  33897. 20:56:42other hand we have the OLTP systems
  33898. 20:56:45online transactional processing. It is
  33899. 20:56:47like an e-commerce finance banking where
  33900. 20:56:50you have at the back end a database
  33901. 20:56:52where the data is stored and on the
  33902. 20:56:54front end we have like an applications
  33903. 20:56:56for the end users. So now as the users
  33904. 20:56:58are interacting with the app this can
  33905. 20:57:00cause write operations on the database.
  33906. 20:57:03So inserting new data or changing data
  33907. 20:57:05and as well there will be read
  33908. 20:57:07operations on the database in order to
  33909. 20:57:09show the data in the app. So we have
  33910. 20:57:11both write and read. So now of course we
  33911. 20:57:13have to ask ourself what is the goal
  33912. 20:57:15what do we want to achieve and here
  33913. 20:57:17mainly there is like two strategy either
  33914. 20:57:19you want to improve the read performance
  33915. 20:57:22or the right performance. Now if you are
  33916. 20:57:24looking to the OLAP system here it's
  33917. 20:57:26really you have to understand the
  33918. 20:57:27project where is the struggle sometimes
  33919. 20:57:29it could be like the ATL process itself
  33920. 20:57:32it's slow and mainly the ATL is writing
  33921. 20:57:34data from the sources in the data
  33922. 20:57:36warehouse and maybe you have scenario
  33923. 20:57:38where it takes like every day 10 hours
  33924. 20:57:40and 10 hours is of course a problem
  33925. 20:57:42because you cannot wait so long in order
  33926. 20:57:45to get a new data fresh data to the
  33927. 20:57:47report every day. So you can make the
  33928. 20:57:49goal of the project is to optimize the
  33929. 20:57:52right performance. You want to speed up
  33930. 20:57:54the ETL. But actually most of those
  33931. 20:57:56projects having another issue. Well, it
  33932. 20:57:59is the read operation on the database
  33933. 20:58:01because data warehouses normally have
  33934. 20:58:03really big data sets and at the front
  33935. 20:58:06end the reports generate large complex
  33936. 20:58:08queries on the database. So that means
  33937. 20:58:11the rate process going to be the pain
  33938. 20:58:13point in each OLAP system. So normally
  33939. 20:58:16the big goal in each OLAP system going
  33940. 20:58:18to be how to optimize the read
  33941. 20:58:21performance. But now in the right hand
  33942. 20:58:23with the OLTB we have different nature
  33943. 20:58:25of database and scenario. What going to
  33944. 20:58:28happen? You will not have like big
  33945. 20:58:29queries from the apps. You're going to
  33946. 20:58:31have like many query many transactions
  33947. 20:58:34happening between the application and
  33948. 20:58:36the database. So you're going to have
  33949. 20:58:38like massive amount of read and write
  33950. 20:58:41transactions. So the whole time we are
  33951. 20:58:43reading, writing, reading, writing and
  33952. 20:58:45so on. But with the OL app we have like
  33953. 20:58:47something bigger and slower because in
  33954. 20:58:49the ATL we usually run it only once.
  33955. 20:58:52That means we are writing only once new
  33956. 20:58:54data to the database and this happen
  33957. 20:58:56usually at the night but on the
  33958. 20:58:58transactional systems you have a lot of
  33959. 20:59:00readrs all time. Again depend on the
  33960. 20:59:02project but usually the main pain point
  33961. 20:59:05in the OLTP is the right operation. So
  33962. 20:59:08it could be like this. If you are
  33963. 20:59:10building OTP system, the main goal is to
  33964. 20:59:13optimize the right performance. Now of
  33965. 20:59:15course the question is how to do that?
  33966. 20:59:17How we going to optimize that? Well,
  33967. 20:59:19again we have to understand the nature
  33968. 20:59:20of the database. What do we have in the
  33969. 20:59:22OLAP systems is usually like a data
  33970. 20:59:25model where you have a very big fact
  33971. 20:59:28tables and around the fact we have like
  33972. 20:59:30multiple dimensions that are connected
  33973. 20:59:32to the facts. So those fact tables are
  33974. 20:59:34really big tables in the database and
  33975. 20:59:37each time they are used in order to
  33976. 20:59:39build a report and the report going to
  33977. 20:59:41be using all time those facts in order
  33978. 20:59:44to prepare the data for the
  33979. 20:59:45visualizations and a lot of aggregations
  33980. 20:59:48query going to be done on the facts and
  33981. 20:59:50now of course you have to answer now the
  33982. 20:59:52question which type of index should we
  33983. 20:59:54use in this scenario. Well we have a
  33984. 20:59:56perfect one called a column store index.
  33985. 20:59:59So the best practice here is and you can
  33986. 21:00:01make it as a strategy for the whole
  33987. 21:00:03project that we make all fact tables as
  33988. 21:00:06a column store index because this is
  33989. 21:00:08what we are doing in the OLAP. We are
  33990. 21:00:10aggregating large data sets but now the
  33991. 21:00:13data model and the scenario is
  33992. 21:00:15completely different at the right side
  33993. 21:00:16here. We're going to have like a lot of
  33994. 21:00:18tables and they have like different
  33995. 21:00:20sizes and so on and there are like a lot
  33996. 21:00:23of relationship between all those
  33997. 21:00:25tables. So it is completely connected.
  33998. 21:00:27So you have a lot of like primary keys
  33999. 21:00:29and foreign keys relationships between
  34000. 21:00:31them and normally those tables are
  34001. 21:00:33completely normalized table. So they are
  34002. 21:00:36like small pieces but on the left side
  34003. 21:00:38we have denormalized tables as a facts.
  34004. 21:00:41So here is like one strategy that we can
  34005. 21:00:43follow in the indexing of the ALTB is
  34006. 21:00:45that we create clustered index for each
  34007. 21:00:48primary key of our tables. This of
  34008. 21:00:51course can improve a lot of stuff like
  34009. 21:00:52searching, sorting and as well joining
  34010. 21:00:55tables together. But of course since we
  34011. 21:00:57are focusing on optimizing the right
  34012. 21:00:59performance on the OLTP you have to be
  34013. 21:01:01more sensitive by adding new indexes
  34014. 21:01:04compared to the OLAP because each index
  34015. 21:01:06you add it could be a reason why the
  34016. 21:01:09data is written very slowly. So in the
  34017. 21:01:12OLTB you have to be way more careful
  34018. 21:01:14adding indexes. So now as you can see
  34019. 21:01:16you have to understand the nature of
  34020. 21:01:18your project. You have to understand
  34021. 21:01:20what is the main issue. Once you
  34022. 21:01:22understand your project, you can go and
  34023. 21:01:24define like a goal for optimizing the
  34024. 21:01:27system. So either read or write or maybe
  34025. 21:01:30both of them and with that you are
  34026. 21:01:32making like the initial strategy of
  34027. 21:01:34indexing your
  34028. 21:01:35[Music]
  34029. 21:01:39system. All right. So with that we have
  34030. 21:01:41an initial strategy for our indexing and
  34031. 21:01:44we have a rough plan. Now in the next
  34032. 21:01:47phase we have usage patterns indexing.
  34033. 21:01:50So now we're going to do a deep dive
  34034. 21:01:51into our project. And the first thing
  34035. 21:01:53that we have to do is that we have to
  34036. 21:01:55identify the frequently used tables and
  34037. 21:01:57columns. So that means you have to go
  34038. 21:01:59and check the queries used in your
  34039. 21:02:01project in order to understand okay what
  34040. 21:02:03is the most important table that is used
  34041. 21:02:06in many queries. Like for example here
  34042. 21:02:08we have the fact internet sales. It is
  34043. 21:02:11used like in many many queries in our
  34044. 21:02:13scripts. So here you are like developing
  34045. 21:02:15a feeling about what are the most
  34046. 21:02:18important frequently used tables and not
  34047. 21:02:20only that you can go and check how we
  34048. 21:02:22are filtering the data on those queries.
  34049. 21:02:24So for example we have over here we are
  34050. 21:02:26filtering by the order date key is this
  34051. 21:02:29kind of filtering is used like in
  34052. 21:02:31multiple queries. So as you can see we
  34053. 21:02:32have like here a couple of queries where
  34054. 21:02:34we are doing always the same where we
  34055. 21:02:36are filtering the data by the dates. So
  34056. 21:02:39with that we understand there is like a
  34057. 21:02:40pattern inside our projects where this
  34058. 21:02:43column is used mainly on filtering and
  34059. 21:02:45as well for aggregating. So that means
  34060. 21:02:47you do a deep dive in order to
  34061. 21:02:49understand what are the most and
  34062. 21:02:51frequently used tables and columns
  34063. 21:02:53inside your scripts. And now of course
  34064. 21:02:55what I usually do I go and use the help
  34065. 21:02:57of the AI and IBT where I give it my
  34066. 21:02:59code and then ask questions about it.
  34067. 21:03:02For example, this prompt, it says, "Anal
  34068. 21:03:03analyze the following SQL queries and
  34069. 21:03:05generate a report on table and column
  34070. 21:03:07usage statistics. And for each table,
  34071. 21:03:09provide the total number of times the
  34072. 21:03:11table is used across all queries. A
  34073. 21:03:14breakdown for each column in the table
  34074. 21:03:16showing the number of times each column
  34075. 21:03:18appears. And I would like to see as well
  34076. 21:03:20the primary usage of each column,
  34077. 21:03:22filtering, joining, grouping, and so on.
  34078. 21:03:24And in the output, as you can see, we
  34079. 21:03:25got like nice statistics about my
  34080. 21:03:27scripts. So as you can see the most used
  34081. 21:03:30fact table is fact internet sales. It is
  34082. 21:03:33like 13 times used in the projects and
  34083. 21:03:35then we can see like statistics about
  34084. 21:03:37each column that is inside these facts.
  34085. 21:03:39So most of the time is the sales is used
  34086. 21:03:42for aggregating and as we saw the order
  34087. 21:03:45date key is used like five times for
  34088. 21:03:47filtering and the other keys is used for
  34089. 21:03:50joining tables. So as you can see it's
  34090. 21:03:52amazing right now we can identify which
  34091. 21:03:55tables are important which columns as
  34092. 21:03:57well are important and we can like based
  34093. 21:03:59on those informations maybe derive our
  34094. 21:04:02indexing for our database. So with that
  34095. 21:04:04we have identified our frequently used
  34096. 21:04:06tables and columns and now the next step
  34097. 21:04:09we have to go and choose the right index
  34098. 21:04:12type and as we learned before we have
  34099. 21:04:14multiple types of indexes and that's
  34100. 21:04:16really depend on the usage and the
  34101. 21:04:18scenario. So for examples, if your
  34102. 21:04:20columns are primary keys, then go with
  34103. 21:04:21the clustered index. And if you are
  34104. 21:04:23using columns that are not primary key
  34105. 21:04:25where you are doing joining filtering,
  34106. 21:04:27then think about the non-clustered
  34107. 21:04:29index. And of course, if the table is
  34108. 21:04:31very big, as we said, you can go and use
  34109. 21:04:32the column store index. And if you are
  34110. 21:04:34targeting always like a subset of data
  34111. 21:04:37only like one year informations, then
  34112. 21:04:39you can think about the filtered index.
  34113. 21:04:41And the last one, if you have like a
  34114. 21:04:43unique column where you don't have any
  34115. 21:04:44duplicates, then you can go and apply a
  34116. 21:04:46unique index. So it depends on the
  34117. 21:04:48scenario and the usages. You have to
  34118. 21:04:50choose the right index. And of course
  34119. 21:04:52the last step in this phase is that you
  34120. 21:04:54have to go and test your index whether
  34121. 21:04:56everything is working
  34122. 21:05:01fine. So that's all for the phase two.
  34123. 21:05:04Then we go to phase three scenario-based
  34124. 21:05:06indexing. So here we have to tackle and
  34125. 21:05:08focus on specific issues to specific
  34126. 21:05:12pain points. So that means we have first
  34127. 21:05:14to identify the slow queries. So it
  34128. 21:05:17could be reported from users or the team
  34129. 21:05:19is doing like analyzing on the logs and
  34130. 21:05:22to understand which queries are causing
  34131. 21:05:24like performance issues. And now once
  34132. 21:05:27you get a list of slow queries then you
  34133. 21:05:29have to analyze them one by one and it
  34134. 21:05:32is time to dig into the execution plans.
  34135. 21:05:35So as we learn we can check how SQL is
  34136. 21:05:37implementing our queries and start
  34137. 21:05:39looking for areas for example where the
  34138. 21:05:41SQL is doing a full scan of the tables
  34139. 21:05:44or maybe using expensive operations like
  34140. 21:05:47nested loop joins and so on. So once you
  34141. 21:05:49understood where is exactly the pain
  34142. 21:05:52point the next step is that you have to
  34143. 21:05:54go and choose the right index. So which
  34144. 21:05:56type of indexes we're going to use in
  34145. 21:05:58order to optimize the query. And once
  34146. 21:06:00you go and create the index, the last
  34147. 21:06:03step is that you have to go and test it.
  34148. 21:06:05So you're going to run again the
  34149. 21:06:06execution plan in order to make sure
  34150. 21:06:08that your query is using the index that
  34151. 21:06:11you have just created. So that means you
  34152. 21:06:13have to go and compare the execution
  34153. 21:06:15plans before and after. And if you see
  34154. 21:06:17that there is no benefit, then something
  34155. 21:06:20is wrong. That means you have to go and
  34156. 21:06:22investigate more and analyze the
  34157. 21:06:23execution query and maybe choose a
  34158. 21:06:26better index way. And you have to do
  34159. 21:06:28this process for each slow query until
  34160. 21:06:31you get all your queries fast. But of
  34161. 21:06:33course, don't forget indexing is not the
  34162. 21:06:35only methods on how to optimize the
  34163. 21:06:37speed of queries. So as you can see
  34164. 21:06:40through these three phases, we went from
  34165. 21:06:42a very generic methods on how to index
  34166. 21:06:45our system to something very specific
  34167. 21:06:48and scenario based. So as you can see as
  34168. 21:06:50we moving in the phases, we are doing
  34169. 21:06:52more deep dive into our projects.
  34170. 21:06:59All right. So now moving to the last
  34171. 21:07:00phase, we have the monitoring and
  34172. 21:07:02maintenance of our indexes. As we
  34173. 21:07:05learned, the job doesn't stop by just
  34174. 21:07:07creating and implementing indexes. We
  34175. 21:07:09have to be responsible by keeping eye on
  34176. 21:07:12the health of our indexes. And here the
  34177. 21:07:14databases offers a lot of statistics and
  34178. 21:07:17metadata about your data that you could
  34179. 21:07:19use in this phase. So the first step is
  34180. 21:07:22to monitor the usage of the indexes. And
  34181. 21:07:25as we learned, we can use the dynamic
  34182. 21:07:27management views or functions that we
  34183. 21:07:30can find in the system schema where we
  34184. 21:07:32can see the number of usage of each
  34185. 21:07:34index and when the last time our queries
  34186. 21:07:37did use the indexes. So with that we can
  34187. 21:07:40go and find out all those indexes that
  34188. 21:07:42we have created and never been used in
  34189. 21:07:45our projects. And now the next step is
  34190. 21:07:46that we can go and monitor the missing
  34191. 21:07:48indexes. So here we can go and check
  34192. 21:07:51what are the recommendations from the
  34193. 21:07:52database where the database is reporting
  34194. 21:07:56missing indexes from the execution plan
  34195. 21:07:58and again we can go and use those
  34196. 21:08:00dynamic management views or functions in
  34197. 21:08:02order to see more details and as well we
  34198. 21:08:05can go and monitor whether we have
  34199. 21:08:07duplicates in the indexing. It happens a
  34200. 21:08:09lot if you have like a lot of developers
  34201. 21:08:11in your team. So it could be that they
  34202. 21:08:13are working parallelly to optimize the
  34203. 21:08:15performance of slow queries and then go
  34204. 21:08:18and create multiple indexes for the same
  34205. 21:08:20column. So this is something that we can
  34206. 21:08:22go and check whether we have duplicates
  34207. 21:08:24in our indexes and if you have
  34208. 21:08:25duplicates then you have to go and find
  34209. 21:08:27how you can go and consolidate them.
  34210. 21:08:29Then the next step we have to go and
  34211. 21:08:31update the statistics. So as we learned
  34212. 21:08:34statistics are very important for the
  34213. 21:08:36execution plan because the database
  34214. 21:08:38engine use those informations to decide
  34215. 21:08:41the best execution plan for your query
  34216. 21:08:43and if the statistics are old then the
  34217. 21:08:45database going to make wrong decisions
  34218. 21:08:47about how to execute your query which
  34219. 21:08:50might lead to bad performance. So here
  34220. 21:08:52again we have like special functions in
  34221. 21:08:54order to monitor the statistics but here
  34222. 21:08:56my recommendation that each weekend have
  34223. 21:08:59a job that go and create all the
  34224. 21:09:01statistics of your database. And the
  34225. 21:09:03last step we don't have to forget about
  34226. 21:09:04monitoring the fragmentations as we
  34227. 21:09:06learned over the time as you are doing
  34228. 21:09:08modifications on the tables. What could
  34229. 21:09:10happen the order of the databases could
  34230. 21:09:12get wrong or there are like free spaces
  34231. 21:09:15on the database that are not used. So we
  34232. 21:09:17have like fragmentations in the index
  34233. 21:09:20and the same thing we have to monitor
  34234. 21:09:21the fragmentations of each tables and
  34235. 21:09:24here if the percentage is between 0 and
  34236. 21:09:2610 then there is no issue but if the
  34237. 21:09:28fragmentation is between 10 and 30 then
  34238. 21:09:30we have to go and reorganize the index
  34239. 21:09:33and if it's more than 30 then this is
  34240. 21:09:35alerting you have to go and rebuild the
  34241. 21:09:38whole index and usually for the
  34242. 21:09:40monitoring I go and build like automated
  34243. 21:09:43dashboard in PowerBI or Tableau where I
  34244. 21:09:45go and extract all those metad data and
  34245. 21:09:47create a nice dashboards in order to
  34246. 21:09:50monitor the health of the database or
  34247. 21:09:51you can go and buy some other tools that
  34248. 21:09:54are advanced in order to do those
  34249. 21:09:59stuff. All right. So this is my indexing
  34250. 21:10:02strategy that I usually follow in my
  34251. 21:10:03projects. And as you can see, each phase
  34252. 21:10:05builds upon the previous one. Moving
  34253. 21:10:08from a general strategy to more
  34254. 21:10:10targeted, refined, specific strategy
  34255. 21:10:13where we define first the goal of the
  34256. 21:10:15indexing strategy of the projects. And
  34257. 21:10:17as we move with the phases, we're going
  34258. 21:10:19to be targeting more specific scenarios.
  34259. 21:10:22And this cycle keep repeating. It's not
  34260. 21:10:24only one time. So you have to keep
  34261. 21:10:26discussing is the goal still suitable
  34262. 21:10:28for the projects. You have to keep
  34263. 21:10:30analyzing the frequently used tables and
  34264. 21:10:33columns and keep searching and finding
  34265. 21:10:35those slow queries and always keep an
  34266. 21:10:38eye monitoring the indexes and of course
  34267. 21:10:41I can only keep repeating this avoid
  34268. 21:10:44overindexing. All right my friends so
  34269. 21:10:46that's all about the indexes that was a
  34270. 21:10:48lot of informations and a lot of
  34271. 21:10:50technique. So now you know everything
  34272. 21:10:51about indexing in SQL. Now in the next
  34273. 21:10:53one there is another important
  34274. 21:10:55techniques on how to optimize the
  34275. 21:10:57performance. So we're going to talk
  34276. 21:10:58about the partitions. So how to divide
  34277. 21:11:00our data in order to optimize the
  34278. 21:11:02performance. So let's
  34279. 21:11:07go. All right. So what is SQL
  34280. 21:11:09partitioning? It's a technique in order
  34281. 21:11:11to divide a large table into small
  34282. 21:11:14pieces and each piece we call it a
  34283. 21:11:16partition. Well, this sounds like we are
  34284. 21:11:18dividing one big table into smaller
  34285. 21:11:20tables but it's not like that. We are
  34286. 21:11:22just dividing one table into smaller
  34287. 21:11:25partitions. So we going to see it in the
  34288. 21:11:27database still as one solid table but
  34289. 21:11:30behind the scenes it is splitted into
  34290. 21:11:32multiple partitions. So now let's go and
  34291. 21:11:34understand what this means. Okay. So now
  34292. 21:11:36let's say that you have a table at your
  34293. 21:11:38database and over the time this table is
  34294. 21:11:41getting bigger and bigger where you have
  34295. 21:11:43like hundreds of millions of rows. Now
  34296. 21:11:45once you have such a big table what's
  34297. 21:11:46going to happen everything going to be
  34298. 21:11:48slow. So for example, if you are reading
  34299. 21:11:50the table and the execution plan is
  34300. 21:11:52doing full scan of the table, this can
  34301. 21:11:55take SQL long time until all the rows
  34302. 21:11:57are fetched. And if you decide to make
  34303. 21:11:59like an index for this table, what's
  34304. 21:12:02going to happen? SQL going to go and
  34305. 21:12:03build a very big B tree index where
  34306. 21:12:06there are a lot of branches and files
  34307. 21:12:08and so on. And having a big index is not
  34308. 21:12:11always a good thing because if you do
  34309. 21:12:13operations like delete rows, update rows
  34310. 21:12:16or inserting rows, these operations
  34311. 21:12:19going to need long time to process. So
  34312. 21:12:21having a big index doesn't mean that you
  34313. 21:12:24can have a good performance for your big
  34314. 21:12:26table. So that means having a big table
  34315. 21:12:28is a problematic because everything
  34316. 21:12:30going to be slow. So now what we can do
  34317. 21:12:32in order to optimize the performance of
  34318. 21:12:35this big table? Well, we can use SQL
  34319. 21:12:38partitioning and in order to do that, we
  34320. 21:12:40have to understand the behavior and the
  34321. 21:12:43transactions that are happening on our
  34322. 21:12:45table and what usually happen with that
  34323. 21:12:47the table grows over the time. So, you
  34324. 21:12:50can have like subset of data that
  34325. 21:12:51belongs to 2023 and another one that is
  34326. 21:12:54created and updated in 2024 and then you
  34327. 21:12:57have something like more current in
  34328. 21:12:592025. So that means we have like in our
  34329. 21:13:02table old data and as well new data and
  34330. 21:13:05we usually interact with the new data
  34331. 21:13:07more often than the old data. So maybe
  34332. 21:13:10for example for 2023 there is like only
  34333. 21:13:12one read transaction and for the data in
  34334. 21:13:152024 we have done like two reads and one
  34335. 21:13:18rights. So it is little bit more than
  34336. 21:13:202023 but for the new data for the
  34337. 21:13:23current year there will be heavy
  34338. 21:13:25transactions. So we're going to have a
  34339. 21:13:27lot of reads a lot of rights. We are
  34340. 21:13:29updating, inserting, reading. So a lot
  34341. 21:13:31of things are going on for the new data.
  34342. 21:13:33So that means we are accessing
  34343. 21:13:35frequently the big table only to
  34344. 21:13:37interact with the new data and we rarely
  34345. 21:13:40need the old data. So what we can do, we
  34346. 21:13:42can go and divide this big table and we
  34347. 21:13:45usually divide it by like a date. So
  34348. 21:13:48that means we can go and split this
  34349. 21:13:49table by the year and we put each year
  34350. 21:13:52in one partition. So at the end we're
  34351. 21:13:54going to have like three partitions. And
  34352. 21:13:55now it's really important to understand
  34353. 21:13:57that that those are three partitions.
  34354. 21:13:59They are not three tables. So that means
  34355. 21:14:01at the client side the users can see
  34356. 21:14:04only one table but behind the scenes we
  34357. 21:14:07have like three partitions. Now let's
  34358. 21:14:08say that you have a query in order to
  34359. 21:14:10read the data from 2025. And now what
  34360. 21:14:13going to happen? SQL will not go and
  34361. 21:14:14scan all the data from the table. It's
  34362. 21:14:16going to go and only target one
  34363. 21:14:18partition the 2025. So that means SQL is
  34364. 21:14:22only scanning the relevant informations
  34365. 21:14:24the relevant partition and not the
  34366. 21:14:26entire table. And now we have another
  34367. 21:14:28benefits of having partitions. Let's say
  34368. 21:14:30that you're using a modern database and
  34369. 21:14:33normally they support parallel
  34370. 21:14:34processing. So if you have the
  34371. 21:14:36infrastructure for that what can happen
  34372. 21:14:37the database engine can process each
  34373. 21:14:40partition independently and parallelly.
  34374. 21:14:43So whether you are reading or writing
  34375. 21:14:45data. So what's going to happen? SQL
  34376. 21:14:47going to process your queries parallelly
  34377. 21:14:49which of course can reduce the overall
  34378. 21:14:52execution time. So that means if you
  34379. 21:14:54have a modern infrastructure like maybe
  34380. 21:14:56for example the Azure Synapse and so on
  34381. 21:14:58go with the partitions because the
  34382. 21:15:00partition then could be stored in
  34383. 21:15:02different servers and this helps of
  34384. 21:15:04course the SQL engine to use all the
  34385. 21:15:07resources at once. So that means
  34386. 21:15:09partitions allow scalability and as well
  34387. 21:15:12parallel processing. partitions going to
  34388. 21:15:14make the indexing more efficient. So
  34389. 21:15:17instead of having one very big index for
  34390. 21:15:20the whole table, if you put an index on
  34391. 21:15:22a partition table, what's going to
  34392. 21:15:23happen? Each partition going to get its
  34393. 21:15:26own index, which means the size of the
  34394. 21:15:28indexes going to be smaller. And of
  34395. 21:15:30course, this helps a lot with searching
  34396. 21:15:33for data or as well extending the index
  34397. 21:15:35itself. So for example, if you are
  34398. 21:15:37inserting data to the partition 2025,
  34399. 21:15:40the SQL will not go and change anything
  34400. 21:15:42on the other indexes, it's going to go
  34401. 21:15:44and only change the index of the
  34402. 21:15:46partition 2025. So that you can see the
  34403. 21:15:48power of the partitioning. It improves
  34404. 21:15:51significantly the performance of your
  34405. 21:15:53table whether you are reading or writing
  34406. 21:15:55data to this big table. So this is what
  34407. 21:15:58we mean with partitioning and why we
  34408. 21:15:59need
  34409. 21:16:03it. All right, friends. So now we're
  34410. 21:16:05going to go to the process of creating
  34411. 21:16:07partitions in SQL. At the start it might
  34412. 21:16:10sounds a little bit complicated but
  34413. 21:16:11we're going to do it step by step and I
  34414. 21:16:13have a sketch for that. So we have like
  34415. 21:16:15four steps because we have in the
  34416. 21:16:17database like multiple layers. So let's
  34417. 21:16:19see how we can do that. Let's go. So the
  34418. 21:16:22first step is that we're going to go and
  34419. 21:16:23define the partition function. So what
  34420. 21:16:25is that? We're going to go and define
  34421. 21:16:27here in the function the logic on how to
  34422. 21:16:30divide the table into partitions. And
  34423. 21:16:32this can be based on the partition key.
  34424. 21:16:35So that means we need a column in order
  34425. 21:16:37to define the logic. And we usually use
  34426. 21:16:39columns with the dates like for example
  34427. 21:16:41the order dates or in other scenarios we
  34428. 21:16:44can use the region or country and so on.
  34429. 21:16:46But the most famous one is the dates and
  34430. 21:16:48that's because our tables like get
  34431. 21:16:51bigger over the time and there are like
  34432. 21:16:53multiple types of functions. We're going
  34433. 21:16:55to focus on the range function. So how
  34434. 21:16:57it going to work? We're going to have
  34435. 21:16:58like a range of dates and then we have
  34436. 21:17:00to define like boundary values and let's
  34437. 21:17:03say that I would like to make a
  34438. 21:17:05partition for each year and in order to
  34439. 21:17:08do that we have to define the partition
  34440. 21:17:10boundary. So it is like a value the
  34441. 21:17:12boundary of the years could be like the
  34442. 21:17:14first day of the year or the last day of
  34443. 21:17:16the year. So here in this example we're
  34444. 21:17:18going to take for the boundary the last
  34445. 21:17:20day of the year. So the last day of
  34446. 21:17:222023, 2024 and 2025. So we call those
  34447. 21:17:26values the boundary of our function. Now
  34448. 21:17:30between the boundaries we going to have
  34449. 21:17:31our partitions. So for examples all the
  34450. 21:17:34rows for 2025 and earlier years is going
  34451. 21:17:38to be the partition one. So between the
  34452. 21:17:40boundary and everything before is one
  34453. 21:17:42partition and after that between the two
  34454. 21:17:44boundaries we have partition two. So
  34455. 21:17:46this partition going to be for all rows
  34456. 21:17:48of 2024. And then we have another
  34457. 21:17:51section the partition three where we
  34458. 21:17:53have all rows of 2025 and then between
  34459. 21:17:56the last boundary and everything onwards
  34460. 21:17:59is going to be partition 4 and here
  34461. 21:18:00we're going to have all the rows from
  34462. 21:18:022026 onward. So with that we have now a
  34463. 21:18:05logic we are telling SQL how to divide
  34464. 21:18:08our data into multiple partitions and
  34465. 21:18:10here there is like two methods the left
  34466. 21:18:12and the right. So what are those two
  34467. 21:18:15methods? So again we have our boundary
  34468. 21:18:17and now the big question to which
  34469. 21:18:19partition does this boundary belongs to
  34470. 21:18:22is it partition one or partition two and
  34471. 21:18:24that's why we have those two methods. If
  34472. 21:18:26you say it is left that mean the
  34473. 21:18:28boundary belongs to the partition number
  34474. 21:18:30one. But in the other hand if you say it
  34475. 21:18:32is right then the boundary going to be
  34476. 21:18:34part and belongs to the partition number
  34477. 21:18:37two. So you have to decide whether the
  34478. 21:18:39boundaries belongs to the left partition
  34479. 21:18:40or to the right partition. And with that
  34480. 21:18:42in the partition one, we're going to
  34481. 21:18:44have all the rows of 2023 including the
  34482. 21:18:47last day of 2023 because in the
  34483. 21:18:50partition 2 we only focus on 2024. So
  34484. 21:18:53it's just the boundary belongs to the
  34485. 21:18:56left partition. It's very simple. Now
  34486. 21:18:57let's go and implement that in SQL. So
  34487. 21:19:00let's do it. The syntax is very simple.
  34488. 21:19:02We're going to say create partition
  34489. 21:19:05function and then we have to give it a
  34490. 21:19:07name. So it's going to be
  34491. 21:19:09partition by year since we are dividing
  34492. 21:19:12the data by the year. And after that we
  34493. 21:19:14have to define the data type. So we are
  34494. 21:19:17splitting the data by a date. So it's
  34495. 21:19:19going to be date. And after that we have
  34496. 21:19:21to define the partition function type.
  34497. 21:19:24So in our example we are using the
  34498. 21:19:26range. And now we have to define whether
  34499. 21:19:28it is left or right. We're going to
  34500. 21:19:31stick with the left. And now comes the
  34501. 21:19:33very important step. We have to define
  34502. 21:19:35the boundaries. So we're going to say
  34503. 21:19:38for
  34504. 21:19:39values and we're going to enter here
  34505. 21:19:41three boundaries like in our example for
  34506. 21:19:43each year we're going to define a date.
  34507. 21:19:45So
  34508. 21:19:472023 and the last day of the year. Same
  34509. 21:19:50goes for
  34510. 21:19:522024 and for the last one
  34511. 21:19:562025. So with that we have defined the
  34512. 21:19:59logic the range we have defined the
  34513. 21:20:02boundaries and we tell SQL the
  34514. 21:20:04boundaries are a date. So let's go and
  34515. 21:20:06execute our function. Okay, so that's
  34516. 21:20:09it. As you can see, it's very simple. We
  34517. 21:20:11just created a function that split the
  34518. 21:20:14data by the date using the range lift.
  34519. 21:20:16And of course, this function is not yet
  34520. 21:20:18attached to any tables or anything. It
  34521. 21:20:21is just a logic that is stored in the
  34522. 21:20:23database. All right. So now since our
  34523. 21:20:24partition function is stored inside the
  34524. 21:20:26database, we will have metadata about
  34525. 21:20:29those functions stored in the system
  34526. 21:20:31schema. So we have there a dedicated
  34527. 21:20:33table called partition functions and
  34528. 21:20:35there we're going to find informations
  34529. 21:20:37about all functions that we have inside
  34530. 21:20:39our database. So let's go and execute
  34531. 21:20:41it. And as you can see we find now our
  34532. 21:20:43new created partition function. So
  34533. 21:20:46partition by year it is a range and it
  34534. 21:20:48has an ID and so on. And I really
  34535. 21:20:50recommend you to check it before
  34536. 21:20:52creating any new partition function.
  34537. 21:20:54Maybe you have already one in the
  34538. 21:20:59projects. Okay. Okay. So now let's check
  34539. 21:21:01the next step in our process. We're
  34540. 21:21:03going to go and build now the file
  34541. 21:21:05groups. So what is a file group? It is
  34542. 21:21:08like a logical container of one or more
  34543. 21:21:11data files. So it's very simple. It's
  34544. 21:21:13like folders. We're going to go and
  34545. 21:21:15create now like multiple folders. So
  34546. 21:21:17later we can insert inside them files.
  34547. 21:21:20And this is really nice because it gives
  34548. 21:21:22us like freedom and flexibility where we
  34549. 21:21:25can go and decide how the data files are
  34550. 21:21:27organized for each partition. So what we
  34551. 21:21:30usually do, we go and create for each
  34552. 21:21:32partition a file group. So we're going
  34553. 21:21:34to have like four folders or four file
  34554. 21:21:36groups for 2023, 2024 and so on. So now
  34555. 21:21:39let's go back to SQL in order to do
  34556. 21:21:41that. All right. So now let's go and
  34557. 21:21:43create those file groups. The syntax is
  34558. 21:21:45very simple. So it's going to say alter
  34559. 21:21:47database. And now we have to tell the
  34560. 21:21:49database where these file groups should
  34561. 21:21:51be stored in which database. So I'm
  34562. 21:21:53going to stay with the sales DB. And
  34563. 21:21:55then we have to tell okay add file group
  34564. 21:21:59and after that we have to define the
  34565. 21:22:01name of the file group. So the first one
  34566. 21:22:02going to be for
  34567. 21:22:032023. So the syntax is very simple.
  34568. 21:22:06Let's go and do it for the other years.
  34569. 21:22:09So we need
  34570. 21:22:112024 5 and six. Okay. So that's all. We
  34571. 21:22:14can just select everything and execute.
  34572. 21:22:17So as you can see it's very simple. We
  34573. 21:22:18have just created four file groups and
  34574. 21:22:21they are empty. So we don't have
  34575. 21:22:23anything inside those containers. Now
  34576. 21:22:25let's say that you have made mistake
  34577. 21:22:26with the namings and so on and you would
  34578. 21:22:28like to drop one of them. So the syntax
  34579. 21:22:30is as well very easy. So it's going to
  34580. 21:22:33say alter database sales DB and instead
  34581. 21:22:35of add you're going to say remove. So
  34582. 21:22:38once you execute this file group will be
  34583. 21:22:41dropped but we need it. So let's go and
  34584. 21:22:44recreate it. Now as usual after creating
  34585. 21:22:46stuff let's check whether everything is
  34586. 21:22:48created correctly and whether we have
  34587. 21:22:51any duplicate or anything wrong. So with
  34588. 21:22:53that we have as well a file group table
  34589. 21:22:56inside the system schema and let's go
  34590. 21:22:58and execute it. So I'm just filtering
  34591. 21:23:00with the type FG for file group. So
  34592. 21:23:03let's execute it. And now we can see in
  34593. 21:23:05our database we have four file groups.
  34594. 21:23:08Now four of those file groups we just
  34595. 21:23:10created it right. So we have the 2023 24
  34596. 21:23:13and so on. But we have something called
  34597. 21:23:16primary file group. This is the default
  34598. 21:23:18file group that is created for each
  34599. 21:23:21database. So it is a container for all
  34600. 21:23:23data files in your database. And as you
  34601. 21:23:25can see we have here a flag saying it is
  34602. 21:23:27a default. So it's default and we have
  34603. 21:23:29it one and for the rest they are not the
  34604. 21:23:31defaults. So this is really nice to see
  34605. 21:23:33all the file groups inside your database
  34606. 21:23:35to check that you don't have duplicate
  34607. 21:23:37and so
  34608. 21:23:41on. Okay. Now moving on to the third
  34609. 21:23:43step where things going to get more
  34610. 21:23:45physically. So so far we have like a
  34611. 21:23:47function the file group and all those
  34612. 21:23:48stuff are logical stuff. We don't have
  34613. 21:23:50data yet. In order to have data, we have
  34614. 21:23:53to go and create data files. So, as we
  34615. 21:23:55learned before, data files going to
  34616. 21:23:57contain our actual data and they're
  34617. 21:23:59going to be stored physically in the
  34618. 21:24:00database. So, you can go and assign for
  34619. 21:24:02each file group like one or multiple
  34620. 21:24:05data files. And the file format here is
  34621. 21:24:08MDF. It is secondary data files. We have
  34622. 21:24:11like primary and secondary. But in the
  34623. 21:24:13partitions, we usually go with this
  34624. 21:24:15format, the NDF. So again the file
  34625. 21:24:17groups are illogical containers and the
  34626. 21:24:19data files are physical files where our
  34627. 21:24:22actual data going to be stored inside
  34628. 21:24:23it. So now let's go back to SQL in order
  34629. 21:24:25to create some data files. Okay. So now
  34630. 21:24:27we're going to come to the little bit
  34631. 21:24:29annoying part where we're going to go
  34632. 21:24:30and create files. But the syntax is as
  34633. 21:24:32well very simple. So we're going to say
  34634. 21:24:34the same things alter database and our
  34635. 21:24:37database is sales DB. And then this time
  34636. 21:24:39we're going to say add file. And now we
  34637. 21:24:42have to give SQL not only the name but
  34638. 21:24:44the physical place of the files. So
  34639. 21:24:46let's do it step by step. We're going to
  34640. 21:24:48open new two parenthesis. So first we
  34641. 21:24:50have to define for SQL the logical name.
  34642. 21:24:53It is not the file name. It is the
  34643. 21:24:55logical name of the file. So let's give
  34644. 21:24:57it a name for example B 2023 and then
  34645. 21:25:00comma. So this is the logical name. And
  34646. 21:25:04now the next one is we're going to give
  34647. 21:25:05the physical name of the file together
  34648. 21:25:08with the path. So we're going to say
  34649. 21:25:09file name equal and now we have to
  34650. 21:25:12define for SQL the complete path of the
  34651. 21:25:15file in SQL server there is like a
  34652. 21:25:17default path where the data going to be
  34653. 21:25:19stored and I'm going to go and use the
  34654. 21:25:21same path and the path really depends on
  34655. 21:25:24the version and as well the type of the
  34656. 21:25:26SQL server that you are using. So for
  34657. 21:25:28the current version that I'm using for
  34658. 21:25:30this tutorial we can find it over here
  34659. 21:25:32in this path. So if you go to the C then
  34660. 21:25:34program files Microsoft SQL Server MSSQL
  34661. 21:25:38and the version for me is 16 SQL Express
  34662. 21:25:41and then inside MSSQL data and so on. So
  34663. 21:25:44we're going to go inside this folder and
  34664. 21:25:46now we can see over here all the
  34665. 21:25:48database files. So we can see for
  34666. 21:25:50example here the sales DB the sales DB
  34667. 21:25:53logs and we have here the adventure
  34668. 21:25:55works and so on. So you're going to see
  34669. 21:25:56all the files of your database. And what
  34670. 21:25:58we're going to do, we're going to put as
  34671. 21:25:59well our partitions files inside the
  34672. 21:26:02default folder. But for real project,
  34673. 21:26:04you have to ask the database
  34674. 21:26:05administrators about the exact location
  34675. 21:26:08where you can put your partitions. So
  34676. 21:26:10let's go back to SQL and I'm going to
  34677. 21:26:12put this path over here. And then we
  34678. 21:26:14have to specify the file name. So it's
  34679. 21:26:17going to be P 2023 dot. And now we have
  34680. 21:26:20to specify the file name. So, NDF and
  34681. 21:26:23with that we have now a complete path
  34682. 21:26:25with the file name. So, we are almost
  34683. 21:26:27there but we are not done yet. We have
  34684. 21:26:29to tell SQL where to put this file in
  34685. 21:26:31which container in which file group. So,
  34686. 21:26:34we're going to go over here and we're
  34687. 21:26:35going to say to file group and here make
  34688. 21:26:39sure to select the correct one. So, FG
  34689. 21:26:422023. All right. So, that's all. Let's
  34690. 21:26:45go and execute it. So, let's do it. And
  34691. 21:26:48with that we have created a file inside
  34692. 21:26:50a file group. I will not be creating
  34693. 21:26:52like multiple files inside one file
  34694. 21:26:54group. It's going to be like one to one.
  34695. 21:26:56So now what we're going to do we're
  34696. 21:26:57going to go and create the other files
  34697. 21:26:58for each file group for each year. So we
  34698. 21:27:01just have to copy and paste and just
  34699. 21:27:03change the names. So for
  34700. 21:27:062024 going to be like
  34701. 21:27:08this. So that's it. And the same thing
  34702. 21:27:11for 2025.
  34703. 21:27:17And for the last one 20
  34704. 21:27:2426 and we can go and select now
  34705. 21:27:27everything and execute it. So that's it
  34706. 21:27:30with that we have created now four
  34707. 21:27:32different files and we have mapped as
  34708. 21:27:34well each file to the correct file group
  34709. 21:27:37and I usually don't create like a lot of
  34710. 21:27:39files. I just create like one for each
  34711. 21:27:41year or maybe for bunch of years. So you
  34712. 21:27:44don't have to go and make for each day
  34713. 21:27:46like partition or something like that.
  34714. 21:27:48Okay. As usual after creating stuff we
  34715. 21:27:50have to go and check the metadata. Now I
  34716. 21:27:52have here prepared a query where we
  34717. 21:27:54query the file groups together with the
  34718. 21:27:56files. So all the data informations
  34719. 21:27:58could be found inside the table master
  34720. 21:28:00files and then we join those tables and
  34721. 21:28:02select our database. So let's go and
  34722. 21:28:05query this one. And now we're going to
  34723. 21:28:07get a list of all files inside your
  34724. 21:28:09database. So we see over here we have
  34725. 21:28:12the primary for the database itself and
  34726. 21:28:15you can see the path of the file and as
  34727. 21:28:17well the size of it and we can see over
  34728. 21:28:19here we have four files and the file
  34729. 21:28:21group that is assigned to and the
  34730. 21:28:23complete path of each file and you can
  34731. 21:28:26monitor over here of course how the size
  34732. 21:28:28of each file is growing over the time.
  34733. 21:28:31Maybe one of them is getting like really
  34734. 21:28:33big and then you can think about let's
  34735. 21:28:35go and split it to multiple files. So
  34736. 21:28:37that's it about how to create data
  34737. 21:28:39files.
  34738. 21:28:43All right. So now we're going to move to
  34739. 21:28:45the last step where we're going to go
  34740. 21:28:46and define the function scheme. Now if
  34741. 21:28:48you have a look to this picture, you see
  34742. 21:28:50that there is something missing. From
  34743. 21:28:52one side, we have defined how to divide
  34744. 21:28:54our data into multiple partitions. And
  34745. 21:28:57from the other side, we have repaired
  34746. 21:28:58all the files and the file groups and so
  34747. 21:29:01on. And now what is missing is the
  34748. 21:29:03connection. How to connect those
  34749. 21:29:05partitions to the file groups. And we
  34750. 21:29:08can do that by using the partition
  34751. 21:29:09scheme. So all what we are doing now is
  34752. 21:29:12just defining which partition belongs to
  34753. 21:29:14which file group. So for example, we're
  34754. 21:29:16going to go and map the partition one to
  34755. 21:29:18the file group 2023. And with that all
  34756. 21:29:21the data of 2023 and earlier going to go
  34757. 21:29:24to the file group 2023. And of course we
  34758. 21:29:28have to go and map each partition to a
  34759. 21:29:30file group. If you don't do that, you
  34760. 21:29:32will get error in SQL. And once we build
  34761. 21:29:34the partition scheme then we can have
  34762. 21:29:36all the component ready in order to have
  34763. 21:29:39partition table. So now let's have a
  34764. 21:29:41quick summarize. The partition function
  34765. 21:29:44going to decide on how to split your
  34766. 21:29:46data into multiple partitions. The
  34767. 21:29:48partition scheme going to go and map the
  34768. 21:29:50partitions to a file group. And the file
  34769. 21:29:53groups are like folders in order to
  34770. 21:29:55organize your files. And each file group
  34771. 21:29:57has one or more data files where your
  34772. 21:30:00actual data going to be stored
  34773. 21:30:01physically. add these files at the
  34774. 21:30:04start. It might be confusing, but now as
  34775. 21:30:06you understand each layer, then it's
  34776. 21:30:08going to make it easier for you to build
  34777. 21:30:09partitions. So now let's go back to SQL
  34778. 21:30:12in order to build the partition scheme.
  34779. 21:30:14Okay, so now we have the easiest part
  34780. 21:30:16where we're going to connect everything
  34781. 21:30:17together. So the syntax as well very
  34782. 21:30:19simple. It's going to say create
  34783. 21:30:21partition scheme and now we have to give
  34784. 21:30:24it a name. So let's go with like scheme
  34785. 21:30:28partition by year. And now we have to
  34786. 21:30:31map the partition function with the file
  34787. 21:30:33groups. So first we're going to say as
  34788. 21:30:35and then we define here the partition
  34789. 21:30:38function. So as partition and now we
  34790. 21:30:41need the partition function that we have
  34791. 21:30:43created. So as
  34792. 21:30:44partition by year and then after that
  34793. 21:30:48we're going to map it to the file
  34794. 21:30:49groups. And here it is very important to
  34795. 21:30:52map it in the correct order. So the
  34796. 21:30:54order is very important. So the first
  34797. 21:30:57one was file group 2023. The second one
  34798. 21:31:012024 and we have 2025 and the last one
  34799. 21:31:072026. So again the order is very
  34800. 21:31:10important and as well it's going to be a
  34801. 21:31:11little bit tricky. So sometimes as you
  34802. 21:31:13are creating like the functions maybe
  34803. 21:31:15you make mistake that you don't know how
  34804. 21:31:17much partitions are going to create like
  34805. 21:31:19in our example we have three boundaries
  34806. 21:31:21and SQL going to create four partitions.
  34807. 21:31:23So it happens sometimes that you think
  34808. 21:31:25okay I have three boundaries and then
  34809. 21:31:28I'm going to get three partitions which
  34810. 21:31:30is not really correct. So for example
  34811. 21:31:32let me just remove one of those and
  34812. 21:31:34let's say I have only three five groups
  34813. 21:31:37and let's go and execute this one over
  34814. 21:31:39here. Now we are getting error. It says
  34815. 21:31:41the partition function generates more
  34816. 21:31:44partitions than the five groups. And
  34817. 21:31:46that is really correct because our
  34818. 21:31:48definition of the logic can split the
  34819. 21:31:50data into four partitions. And now we
  34820. 21:31:52are giving SQL only three five groups
  34821. 21:31:55which is not correct. So we have to go
  34822. 21:31:56and add the plus one. And one more thing
  34823. 21:31:59SQL will not go and check whether you
  34824. 21:32:01are mapping things correctly to the five
  34825. 21:32:03groups because it doesn't really care
  34826. 21:32:05about the naming of those five groups.
  34827. 21:32:07So for example, if you go and put this
  34828. 21:32:09one at the end, what's going to happen?
  34829. 21:32:11It's going to be a big problem. So all
  34830. 21:32:13the years of 2023 going to be stored
  34831. 21:32:15inside 2024, 2024 going to be in 2025.
  34832. 21:32:19So everything going to be mixed and the
  34833. 21:32:21skill can do it like you tell it. So
  34834. 21:32:23that's why make sure you have the
  34835. 21:32:25correct sorts. So that's it. Let's go
  34836. 21:32:27and create our scheme. So it is working.
  34837. 21:32:30This is very simple. We just map now the
  34838. 21:32:33partitions to the five groups. And as
  34839. 21:32:35usual we check things after creating and
  34840. 21:32:38I have prepared here like really nice
  34841. 21:32:40query from the metadata in order to see
  34842. 21:32:42the whole thing the functions the file
  34843. 21:32:44groups the schemes you can of course add
  34844. 21:32:46to it the data files but I'm just going
  34845. 21:32:49to stick with this over here. So again
  34846. 21:32:51in SQL server we have a dedicated table
  34847. 21:32:53for the partition schemes. Then I'm just
  34848. 21:32:55joining it with the functions and then
  34849. 21:32:57with the destination data spaces in
  34850. 21:32:59order to get the partition number and
  34851. 21:33:01the file groups. So let's go and execute
  34852. 21:33:03it. And now we can see very nicely the
  34853. 21:33:05scheme that we have created and the
  34854. 21:33:07function name of the partition. And then
  34855. 21:33:09we can see the partition number and the
  34856. 21:33:12file group name. So we can see how
  34857. 21:33:14things are mapped together. So if you
  34858. 21:33:16get it like this then so far everything
  34859. 21:33:18is
  34860. 21:33:22good. All right. So so far what you have
  34861. 21:33:24done we have prepared all the layers. So
  34862. 21:33:27we have the setup is ready to be used in
  34863. 21:33:30any table. So we have the functions, the
  34864. 21:33:32files, the file groups and schema and
  34865. 21:33:34everything is ready. But still we are
  34866. 21:33:36not using it. The logic just exist and
  34867. 21:33:38the files are empty. So now what we're
  34868. 21:33:40going to do we're going to go and create
  34869. 21:33:41a table but not a normal one a partition
  34870. 21:33:44table. So let's go and do that. It's
  34871. 21:33:46very simple as well. So create table and
  34872. 21:33:48we have to give it a name. So let's get
  34873. 21:33:50it as well in the schema sales orders
  34874. 21:33:53and I'm just going to give it the name
  34875. 21:33:54partitions. So now we have just to
  34876. 21:33:56define like few columns inside this
  34877. 21:33:58table. So let's get an order ID and data
  34878. 21:34:03type int. And let's go and get an order
  34879. 21:34:05date. We call it dates with the data
  34880. 21:34:08type dates. And maybe just one more
  34881. 21:34:10called sales and a data type in. So this
  34882. 21:34:13is very normal table that we create in
  34883. 21:34:15databases. But it's still not yet
  34884. 21:34:17partitioned. Now in order to use
  34885. 21:34:19everything that we have defined, we're
  34886. 21:34:21going to go do the following. We're
  34887. 21:34:22going to say on and now we have to tell
  34888. 21:34:25SQL only the name of the partition
  34889. 21:34:28scheme. So everything else is like
  34890. 21:34:30connected and mapped together because
  34891. 21:34:32the scheme is mapping the function with
  34892. 21:34:34the file groups. The file groups are
  34893. 21:34:36mapped to the data files and everything
  34894. 21:34:38is like connected together. And here in
  34895. 21:34:40the table we have just to give the name
  34896. 21:34:42of the scheme. So the name of the
  34897. 21:34:43partition scheme is scheme
  34898. 21:34:46partition by year. And now it's very
  34899. 21:34:49important to give a column. And since
  34900. 21:34:52the whole logic and the function is
  34901. 21:34:54based on a date, we cannot go and
  34902. 21:34:56specify here for example the order ID or
  34903. 21:34:58sales because it makes no sense. We're
  34904. 21:35:00going to go and pick the order date and
  34905. 21:35:02put it over here. And with that, we have
  34906. 21:35:04created a partition table. So now what
  34907. 21:35:06we're going to do, we're going to go and
  34908. 21:35:07start inserting that out of our table.
  34909. 21:35:09So let's go and do that. We're going to
  34910. 21:35:10say insert into sales order
  34911. 21:35:15partitioned and we're going to pick
  34912. 21:35:17values like this. So one and then let's
  34913. 21:35:20get any dates like 2023 like for example
  34914. 21:35:24my the mid of the month and the sales
  34915. 21:35:26could be anything like let's say 100. So
  34916. 21:35:30let's go and execute this and let's go
  34917. 21:35:32query our
  34918. 21:35:34table. So it is this one over
  34919. 21:35:38here. All right. So now we have one
  34920. 21:35:40record inside our partition table. And
  34921. 21:35:42now the big question is in which
  34922. 21:35:44partition in which data file did SQL
  34923. 21:35:47store this record. So we have to test
  34924. 21:35:49whether everything is working fine. So
  34925. 21:35:51in order to do that I have prepared as
  34926. 21:35:53well a query. So we are again asking the
  34927. 21:35:55table partitions with the destination
  34928. 21:35:57data spaces where we're going to get the
  34929. 21:35:59number of rows in each partition and
  34930. 21:36:01then we have the file group and we are
  34931. 21:36:03focusing on our table orders partitions.
  34932. 21:36:06So let's go and execute this one. And
  34933. 21:36:07now we can see very easily we have the
  34934. 21:36:09four partitions. our new record is
  34935. 21:36:11inserted in the correct place in 2023
  34936. 21:36:15file group and in the correct partition.
  34937. 21:36:17So with that we make sure our function
  34938. 21:36:20and the whole logic that we have built
  34939. 21:36:22is working correctly. So now let's go
  34940. 21:36:24and add more records. I'm just going to
  34941. 21:36:26go and duplicate it. Record number two.
  34942. 21:36:28And I'm just going to pick a date in
  34943. 21:36:312024. And this one going to be like 20.
  34944. 21:36:35Let's just change the value. So 50.
  34945. 21:36:38Let's go and execute it.
  34946. 21:36:40And now we have a second row inside our
  34947. 21:36:42table. And again the big question is
  34948. 21:36:45whether it is working. So let's go and
  34949. 21:36:47execute this again. And now we can see
  34950. 21:36:49our record is inserted in the partition
  34951. 21:36:512 in the file group 2024 which is
  34952. 21:36:55correct. Now let's go and check the
  34953. 21:36:57boundaries whether it is working
  34954. 21:36:59correctly. So I'm going to go and here
  34955. 21:37:01in the third row I'm going to say the
  34956. 21:37:04last day of 2025. So it's going to be
  34957. 21:37:07month 12 and the last day. So 20. Let's
  34958. 21:37:12go and insert it and check our table. So
  34959. 21:37:15we have a new record. And now let's go
  34960. 21:37:18and check. My expectation here that this
  34961. 21:37:21row is going to be inserted in the file
  34962. 21:37:23group
  34963. 21:37:242025. So let's go and execute. And that
  34964. 21:37:27is correct. As you can see the record is
  34965. 21:37:30inserted in the correct partition. And
  34966. 21:37:32this is really important to test the
  34967. 21:37:33boundaries whether they are working
  34968. 21:37:35correctly because it's a little bit
  34969. 21:37:36tricky. You have this range left right
  34970. 21:37:39and boundaries and so on. So you can do
  34971. 21:37:41it like this to check whether the
  34972. 21:37:42expectation of your logic is working
  34973. 21:37:44correctly. And the last one I'm just
  34974. 21:37:46going to do it very fast. So let's do it
  34975. 21:37:492026. And I'm going to pick the first
  34976. 21:37:51day of this
  34977. 21:37:54year. So let's go and insert it. And now
  34978. 21:37:57what is the expectation? I think it is
  34979. 21:37:59pretty simple. So let's go and query.
  34980. 21:38:01And the first day of this year is
  34981. 21:38:02inserted in the partition number four.
  34982. 21:38:04So I can say everything is working
  34983. 21:38:06correctly. If you get it like this then
  34984. 21:38:08you have created successfully a
  34985. 21:38:10partition table and you have prepared
  34986. 21:38:12all the layers of this partition
  34987. 21:38:14correctly. I know this is a lot of work
  34988. 21:38:16but to be honest it is fun because for
  34989. 21:38:19the first time in database you feel like
  34990. 21:38:20you are controlling stuff. Usually in
  34991. 21:38:22database everything like behind the
  34992. 21:38:24scenes and you don't know exactly where
  34993. 21:38:26the files are stored of your tables and
  34994. 21:38:28so on. There is a lot of abstraction in
  34995. 21:38:30databases but here like we are getting
  34996. 21:38:33deep in databases and we are controlling
  34997. 21:38:35and managing all those files which is
  34998. 21:38:37sometimes it's nice to have this freedom
  34999. 21:38:39and flexibility. All right one quick
  35000. 21:38:41thing that I would like to show you that
  35001. 21:38:42if you go to the database in the
  35002. 21:38:44explorer then let's go to the storage
  35003. 21:38:46over here. So let's expand it and here
  35004. 21:38:48you can find easily informations about
  35005. 21:38:50the partitions. So over here we can find
  35006. 21:38:52our partition scheme and as well the
  35007. 21:38:54partition function that we have created.
  35008. 21:38:56it is just a quick access instead of
  35009. 21:38:58like querying the
  35010. 21:39:02metadata. So now let's have a quick
  35011. 21:39:04summarize how everything is connected
  35012. 21:39:06together. So we have a table and then we
  35013. 21:39:08specify for scale that is connected to a
  35014. 21:39:11partition scheme and in the partition
  35015. 21:39:13scheme we have everything connected. It
  35016. 21:39:15is linked to a specific partition
  35017. 21:39:17function and there we have the
  35018. 21:39:19partitions and at the same time it is
  35019. 21:39:21connected to file groups and the file
  35020. 21:39:24groups are connected to the data files.
  35021. 21:39:26So as you can see all those layers and
  35022. 21:39:28elements are connected together. Now
  35023. 21:39:30let's see how this works. So we have
  35024. 21:39:32inserted the last day of 2025 and now
  35025. 21:39:34the first thing that's going to happen
  35026. 21:39:36the partition function going to decide
  35027. 21:39:38to which partition it belongs. So as you
  35028. 21:39:40can see it is a boundary value and since
  35029. 21:39:42we have defined it as a lift it going to
  35030. 21:39:45target the left partition the partition
  35031. 21:39:47three and then the partition scheme
  35032. 21:39:49going to connect it to the right file
  35033. 21:39:51group and in this scenario it's going to
  35034. 21:39:52be the file group 2025 and we have here
  35035. 21:39:55only one file so it going to as well go
  35036. 21:39:57to the correct data file and in this
  35037. 21:39:59file the SQL going to store this row so
  35038. 21:40:02it is pretty
  35039. 21:40:06easy and now we come to very important
  35040. 21:40:08part where we can understand how the
  35041. 21:40:10partitions are really improving the
  35042. 21:40:12performance of my query and of course we
  35043. 21:40:14can do that by checking the execution
  35044. 21:40:16plan. So now in order to compare like
  35045. 21:40:18the behavior with and without the
  35046. 21:40:20partition what we have to do is to
  35047. 21:40:22create a mirror table without partition.
  35048. 21:40:24So we have our table here the
  35049. 21:40:25partitioned one what I'm just going to
  35050. 21:40:27do I will go over here and say into and
  35051. 21:40:29we're going to call it sales
  35052. 21:40:32orders no partition. So we are taking
  35053. 21:40:35the data and the structure from the
  35054. 21:40:38orders partitions and of course it will
  35055. 21:40:40not be partitioned. So let's go and
  35056. 21:40:42execute it. Now if you go over here we
  35057. 21:40:45can see that we have two tables. We have
  35058. 21:40:47the no partition and the partitioned
  35059. 21:40:49one. So now what we're going to do we're
  35060. 21:40:50going to write a query on both tables
  35061. 21:40:52and then compare the execution plan. So
  35062. 21:40:54first let's start with the no partition.
  35063. 21:40:56also from and and now in order to see
  35064. 21:40:59the effect of the partition what we're
  35065. 21:41:00going to do we're going to say where
  35066. 21:41:03order dates equal to and now we're just
  35067. 21:41:05going to pick a value like 2026 the 1st
  35068. 21:41:08of January so let's go and query it and
  35069. 21:41:11we're going to do the same thing a new
  35070. 21:41:13query but this time for the partitions
  35071. 21:41:17so now in order to see the execution
  35072. 21:41:20plan make sure to activate it so we go
  35073. 21:41:22to the action bar over here and we're
  35074. 21:41:24going to say include the actual
  35075. 21:41:25execution plan. So let's click on it and
  35076. 21:41:28execute. And with that we have here an
  35077. 21:41:30execution plan. And let's do the same
  35078. 21:41:32thing for the no partitions. So execute
  35079. 21:41:35and we have here execution plan. So now
  35080. 21:41:37let's check what we have in execution
  35081. 21:41:39plan. We're going to focus on this one
  35082. 21:41:40over here. So right click on it and then
  35083. 21:41:42go to properties. And now we can see a
  35084. 21:41:44lot of details about the execution plan.
  35085. 21:41:46But what is interesting is the number of
  35086. 21:41:48rows. So as you can see we are reading
  35087. 21:41:50four rows. That means the whole table.
  35088. 21:41:52And of course we have here the CPU and
  35089. 21:41:54the other costs. Now let's go and check
  35090. 21:41:56the partition. So let's click over here.
  35091. 21:41:59So now if you check over here, you can
  35092. 21:42:00see that the total number of rows is
  35093. 21:42:03one. So SQL didn't read all four rows.
  35094. 21:42:06It reads only row and that's because we
  35095. 21:42:08have in this partition only one row. And
  35096. 21:42:10as you can see the number of partitions
  35097. 21:42:12that is used is as well only one. So as
  35098. 21:42:14you can see using partition we have
  35099. 21:42:16reduced the number of rows that is
  35100. 21:42:18retrieved from the files. Now let's go
  35101. 21:42:20and retrieve like two data from two
  35102. 21:42:23different partitions and check the
  35103. 21:42:25execution plan. So let's target 2025 the
  35104. 21:42:28last day of the year like this. So let's
  35105. 21:42:32go and execute it. And the same thing
  35106. 21:42:34for the other
  35107. 21:42:37query. So let's check the without
  35108. 21:42:40partition. We still we are reading like
  35109. 21:42:42four rows. But now if you go to the
  35110. 21:42:44other one, if you check the execution
  35111. 21:42:46plan and check the table scan, you can
  35112. 21:42:49see we are reading only two rows and
  35113. 21:42:51this time the number of partitions that
  35114. 21:42:53are involved in this query is two and
  35115. 21:42:56that's because we have partition for
  35116. 21:42:572025 and 2026. So as you can see it's
  35117. 21:43:00worth the efforts. We have optimized our
  35118. 21:43:02queries and this has a great impact on
  35119. 21:43:05big tables. The number of resources and
  35120. 21:43:07the number of reads going to be reduced
  35121. 21:43:09massively. All right my friends. So
  35122. 21:43:11that's all about the partitions in SQL.
  35123. 21:43:13It is amazing and you can use it as well
  35124. 21:43:14not only in databases but as well in
  35125. 21:43:17many other data platforms and tools
  35126. 21:43:19where you always can divide your data in
  35127. 21:43:21order to optimize the performance. Now
  35128. 21:43:22in the next step what I have prepared
  35129. 21:43:24for you after 15 years working in real
  35130. 21:43:26projects using SQL. I have a lot of best
  35131. 21:43:29practices and tips for you. So I have
  35132. 21:43:31collected everything that I know and now
  35133. 21:43:33I'm going to show you the best practices
  35134. 21:43:34and tips and tricks that I can give you
  35135. 21:43:36in order to optimize the performance in
  35136. 21:43:38SQL. So let's go.
  35137. 21:43:44And now before we deep dive into the 30
  35138. 21:43:47best practices, I'm going to give you
  35139. 21:43:49the golden rule. The SQL optimizer
  35140. 21:43:51responds differently for different sizes
  35141. 21:43:53of tables. So that means if you have
  35142. 21:43:55small and medium tables like hundred of
  35143. 21:43:57thousands, you might not notice any
  35144. 21:43:59performance differences if you are
  35145. 21:44:00following the best practices. And that's
  35146. 21:44:02because the size of the data is small.
  35147. 21:44:04But if you have like million or hundred
  35148. 21:44:06of millions of records in tables, you
  35149. 21:44:08will immediately notice how things can
  35150. 21:44:10be faster if you follow the best
  35151. 21:44:12practices. And here is my golden rule.
  35152. 21:44:14If you get any best practice from me or
  35153. 21:44:17let's say you are reading something in
  35154. 21:44:18the internet, always you have to test
  35155. 21:44:20using the execution plan. So for
  35156. 21:44:22example, if you have like two queries
  35157. 21:44:24are returning the same result of the
  35158. 21:44:25data, I'm going to recommend you here to
  35159. 21:44:27check the execution plan. And if you
  35160. 21:44:29notice there is no differences between
  35161. 21:44:31them in the execution plan then pick the
  35162. 21:44:34one that you see it is easier to read
  35163. 21:44:36and to understand because sometimes if
  35164. 21:44:38you are following the best practices for
  35165. 21:44:40the performance your query might be like
  35166. 21:44:42little bit more complicated. So always
  35167. 21:44:44write the query to be understandable and
  35168. 21:44:47only optimize it if you notice it is
  35169. 21:44:49slow. So the golden rule here is always
  35170. 21:44:52test. If you find you are optimizing the
  35171. 21:44:54performance with the new query then pick
  35172. 21:44:56that and if there is no gain in the
  35173. 21:44:58performance then focus on making your
  35174. 21:45:00queries readable. So this is the golden
  35175. 21:45:03rule always test test test using
  35176. 21:45:05execution plan. So let's deep dive into
  35177. 21:45:07best practices and we're going to start
  35178. 21:45:09by optimizing the performance of our
  35179. 21:45:15queries. All right let's start with the
  35180. 21:45:17easy stuff. The first step is select
  35181. 21:45:19only what you need. What I usually see
  35182. 21:45:21in many queries is that the developers
  35183. 21:45:23just go and select all the columns from
  35184. 21:45:25one table and I can tell you I cannot
  35185. 21:45:27think of one scenario where you need all
  35186. 21:45:28the columns of one table in one query.
  35187. 21:45:31So for sure in the result we will get
  35188. 21:45:33like unnecessary columns and of course
  35189. 21:45:35reading unnecessary informations going
  35190. 21:45:37to make your query slower. So this is
  35191. 21:45:40usually a bad practice. Don't use select
  35192. 21:45:42star but instead of that go list all the
  35193. 21:45:44columns that you need for your query. So
  35194. 21:45:47make sure that you only select what you
  35195. 21:45:49need. Don't go and select all the
  35196. 21:45:50columns from one table and with that you
  35197. 21:45:52don't risk reading unnecessary
  35198. 21:45:54informations from the database. So
  35199. 21:45:56always make sure that you select exactly
  35200. 21:45:58what you need for a query don't go with
  35201. 21:46:00a star. Okay. Tip number two avoid
  35202. 21:46:03unnecessary distinct and order by. I
  35203. 21:46:05have noticed that many developers as
  35204. 21:46:07they are writing a lot of queries they
  35205. 21:46:09tend by default adding always distinct
  35206. 21:46:12and order by for each query. And as we
  35207. 21:46:15review the code and discuss it with the
  35208. 21:46:16developer, we see that we really don't
  35209. 21:46:19need to remove any duplicates in the
  35210. 21:46:21query because there are no duplicates
  35211. 21:46:22and it was only a habit to remove the
  35212. 21:46:25duplicates using distincts. And the same
  35213. 21:46:26thing for the order by in many
  35214. 21:46:28situations there is no need to sort the
  35215. 21:46:30data at all. And those operations, the
  35216. 21:46:32distinct removing the duplicate and
  35217. 21:46:34sorting the data, they are very
  35218. 21:46:36expensive operations in your execution
  35219. 21:46:38plan. So they're going to take a lot of
  35220. 21:46:39resources and slow down your query. So
  35221. 21:46:42this considered as a bad practice if you
  35222. 21:46:44always go and use distinct even though
  35223. 21:46:46it's not needed or you are using the
  35224. 21:46:48order by in order to sort the data when
  35225. 21:46:50it is not necessary. So the best
  35226. 21:46:52practice here is to avoid them. Don't
  35227. 21:46:54use distinct or order by only if it is
  35228. 21:46:56necessary. Okay. The next one for
  35229. 21:46:59exploration purposes limit the rows. So
  35230. 21:47:02sometimes especially if you are working
  35231. 21:47:03with a new database you would like to
  35232. 21:47:05explore the tables just to have a quick
  35233. 21:47:07peek in order to see the content of the
  35234. 21:47:09tables. And if your database has a lot
  35235. 21:47:11of big tables with millions of rows and
  35236. 21:47:13so on, you will be consuming a lot of
  35237. 21:47:15resources. If you just select the data
  35238. 21:47:17like this. So now imagine that the
  35239. 21:47:19orders has like 100 million. As you run
  35240. 21:47:21this query, the database has to fetch
  35241. 21:47:24all the 100 million for you. And usually
  35242. 21:47:26for exploration, it's enough to see like
  35243. 21:47:2810 rows and that's going to be enough.
  35244. 21:47:30That's why it is considered as a bad
  35245. 21:47:32practice if you are exploring the tables
  35246. 21:47:34to not have a limit or top. So a good
  35247. 21:47:37practice would be to say select top 10
  35248. 21:47:39and then have the same query. So if you
  35249. 21:47:41go over here you will get only 10 rows
  35250. 21:47:44and the database will not fetch 100
  35251. 21:47:46million. It can fetch only 10 rows. And
  35252. 21:47:48now if you are exploring a lot of tables
  35253. 21:47:51you will not consume a lot of resource
  35254. 21:47:53from the database. So if you are
  35255. 21:47:55exploring always limit the number of
  35256. 21:47:57rows that you are
  35257. 21:48:01retrieving. All right. Right. So now
  35258. 21:48:03we're going to talk about how to
  35259. 21:48:04optimize the filtering in SQL. So the
  35260. 21:48:07tip here is to create an uncclustered
  35261. 21:48:09index on frequently used columns in wear
  35262. 21:48:12clause. So now of course you have to
  35263. 21:48:13check your queries and so on. And if you
  35264. 21:48:15see that you are frequently filtering
  35265. 21:48:17the data using the order status then it
  35266. 21:48:20makes sense to create a non-clustered
  35267. 21:48:22index for this column in order to
  35268. 21:48:24improve the performance of your query.
  35269. 21:48:26So for this situation I'm going to go
  35270. 21:48:27and create then a nonclustered index for
  35271. 21:48:30the table sales order for the order
  35272. 21:48:32status. So once you create it then you
  35273. 21:48:36improving now the performance of your
  35274. 21:48:38query. Okay. The next one is avoid
  35275. 21:48:40applying functions to columns in the
  35276. 21:48:42works. So in many cases what we usually
  35277. 21:48:45do is that we go and transform the
  35278. 21:48:47columns before like filtering the data.
  35279. 21:48:49Like for example here I'm applying the
  35280. 21:48:51function lower on the order status
  35281. 21:48:53because I'm searching for the value
  35282. 21:48:55delivered and I'm not sure about the
  35283. 21:48:56values in the table whether they have
  35284. 21:48:58like a camel case or uppercase or
  35285. 21:49:01anything but in order to make sure that
  35286. 21:49:03I'm going to find the value I'm going to
  35287. 21:49:05go and say lower the order status and
  35288. 21:49:07then give here a lower value and of
  35289. 21:49:10course it's going to work. So if we go
  35290. 21:49:11and search for it and as you can see we
  35291. 21:49:13have here the status delivered and the
  35292. 21:49:15value is different than the one I used
  35293. 21:49:16because here we have like a capital
  35294. 21:49:18first character but here we have a
  35295. 21:49:20problem we have an index on the order
  35296. 21:49:22status and now if you use any functions
  35297. 21:49:24like for example here the lower the SQL
  35298. 21:49:27will not use the index so that means the
  35299. 21:49:30whole index is now useless and the SQL
  35300. 21:49:33is not using it and that's why we
  35301. 21:49:35consider it as a bad practice to use
  35302. 21:49:37functions for the wear clause and
  35303. 21:49:40Instead of that the good practice is
  35304. 21:49:42that to not use any function and to
  35305. 21:49:44write exactly the value that is used
  35306. 21:49:46inside your data and with that the SQL
  35307. 21:49:48going to be happy and use the index that
  35308. 21:49:51you have created. Okay, let's have
  35309. 21:49:52another example about this rule and here
  35310. 21:49:54we are selecting all the customers where
  35311. 21:49:56the first name start with the A. So with
  35312. 21:49:58that we can go and use the function
  35313. 21:50:00substring in order to get the first
  35314. 21:50:03character of the first name and once you
  35315. 21:50:05match it with a then you will get the
  35316. 21:50:07result and here we have Anna. And this
  35317. 21:50:08is again bad if you have an index on the
  35318. 21:50:10first name and that's because we are
  35319. 21:50:12applying a function on the column. So
  35320. 21:50:15this considered to be a bad practice and
  35321. 21:50:17instead of that we can go and use the
  35322. 21:50:18help of the like. So we can go and
  35323. 21:50:21search for this pattern where it start
  35324. 21:50:22with the A and then we have a white
  35325. 21:50:24card. We don't care about the rest. So
  35326. 21:50:26it must start with a. So if you go and
  35327. 21:50:28execute it you will get the same
  35328. 21:50:30results. So try as much as you can to
  35329. 21:50:32avoid the functions in the wear clouds
  35330. 21:50:34in order to hit and get the index
  35331. 21:50:37working. And in many scenarios, we have
  35332. 21:50:38a workaround in order to use the
  35333. 21:50:40function without transformations. So try
  35334. 21:50:43your best to avoid using functions if
  35335. 21:50:45your columns having an index. All right,
  35336. 21:50:47one more example that you see a lot on
  35337. 21:50:49queries that you filter by the year. So
  35338. 21:50:52we are searching for the orders that
  35339. 21:50:54happens in 2025 and we usually go and
  35340. 21:50:56use the year order dates. And now if you
  35341. 21:50:59have an index on the order dates, this
  35342. 21:51:01again will not be working because you
  35343. 21:51:03are using a function year. So this
  35344. 21:51:05considered to be a bad practice. Instead
  35345. 21:51:07of using the year function, you can go
  35346. 21:51:09and use between. So we don't apply a
  35347. 21:51:12function on the order date and we say
  35348. 21:51:13the order date is between the boundaries
  35349. 21:51:16of the year. Of course, now our query is
  35350. 21:51:18not looking really cool and easy like
  35351. 21:51:20the first one. But still with the second
  35352. 21:51:22one, we are hitting the index. So again
  35353. 21:51:25while you are filtering, try to not use
  35354. 21:51:27functions on the columns because it is
  35355. 21:51:29really waste if you have an index and
  35356. 21:51:31you are not using it. and most of the
  35357. 21:51:33cases you have like a workound for your
  35358. 21:51:35function. So those are the three
  35359. 21:51:36examples that I wanted to show you about
  35360. 21:51:38this tip. All right, moving on to a
  35361. 21:51:40similar one. It says avoid leading wild
  35362. 21:51:42cards as they prevent index usage. So
  35363. 21:51:45this is a similar one. Let's say for
  35364. 21:51:47example I'm searching for the word gold
  35365. 21:51:49inside the last name. And here we have
  35366. 21:51:51to be careful what we are searching for.
  35367. 21:51:53Should the gold exist somewhere in the
  35368. 21:51:56last name or only we are searching for
  35369. 21:51:58the last name that start with gold? If
  35370. 21:52:01it's like that we are searching only the
  35371. 21:52:03last name that starts with gold then we
  35372. 21:52:05are doing it here wrong. And in SQL if
  35373. 21:52:07you're using the leading wild card then
  35374. 21:52:10the SQL will not be using the index. But
  35375. 21:52:12if you are using the wild card at the
  35376. 21:52:14end and the trailing this one is fine
  35377. 21:52:16and will not avoid using the index. So
  35378. 21:52:19this considered as a bad practice
  35379. 21:52:21because you will not be hitting the
  35380. 21:52:23index. Better than that to not use the
  35381. 21:52:25white card as a leading and if that's
  35382. 21:52:27enough for your search then with that
  35383. 21:52:29you are hitting and using the index.
  35384. 21:52:32Okay, moving on to the next one. It says
  35385. 21:52:34use in instead of multiple or or
  35386. 21:52:37operator is very evil for performance
  35387. 21:52:40and try to avoid using it. It really
  35388. 21:52:42kills your performance whether it is in
  35389. 21:52:44the filters or joins and so on. So now
  35390. 21:52:46we want to show the orders where the
  35391. 21:52:47customers is equal to one or two or
  35392. 21:52:50three. And of course this is considered
  35393. 21:52:52to be bad practice and hard to read and
  35394. 21:52:54so on. Please don't do that. Instead we
  35395. 21:52:56have the in operator and we are saying
  35396. 21:52:58if the customer is one of those values
  35397. 21:53:01then show the orders. So if you go and
  35398. 21:53:03run it you will get the exact results
  35399. 21:53:06and it's not only looks nicer than the
  35400. 21:53:08first query but it has as well a better
  35401. 21:53:11performance. So if you find out writing
  35402. 21:53:13a lot of ors think about the inoperator.
  35403. 21:53:16So those are the best practices for
  35404. 21:53:17filtering data to improve the
  35405. 21:53:19performance.
  35406. 21:53:24Okay, so now we're going to focus on how
  35407. 21:53:26to optimize joining tables in SQL. So
  35408. 21:53:28the first tip here is to understand the
  35409. 21:53:31speed of joins and to use inner join
  35410. 21:53:34when it's possible. Well, as we learned
  35411. 21:53:35before, we have like different types of
  35412. 21:53:37joins. We have the inner, left, right,
  35413. 21:53:39and outer join. And if we talk about the
  35414. 21:53:41performance, the best performance you
  35415. 21:53:43will get from the inner join. And that's
  35416. 21:53:45because SQL going to work only on the
  35417. 21:53:47matching rows. That means the effort and
  35418. 21:53:49the processing time is better than the
  35419. 21:53:52other joins. Now in the next one in
  35420. 21:53:54ranking we have the left and right
  35421. 21:53:56joins. They are slightly slower than the
  35422. 21:53:58inner join because usually they process
  35423. 21:54:01more data and more rows than the inner
  35424. 21:54:03join because SQL will work not only with
  35425. 21:54:06the matching rows as well with the
  35426. 21:54:08unmatching rows. So for right and left
  35427. 21:54:10SQL has to do more stuff than the inner
  35428. 21:54:12join. And now the worst type of joins we
  35429. 21:54:15have the outer join. And that and that's
  35430. 21:54:17because this type works with the biggest
  35431. 21:54:20number of rows compared to the other
  35432. 21:54:21types. It's going to present unmatching
  35433. 21:54:23rows from the left and from the right
  35434. 21:54:25tables. So that means SQL has a lot of
  35435. 21:54:28to-do and that's why this join has the
  35436. 21:54:30worst performance. So here my advice is
  35437. 21:54:33always try to use the inner join if it's
  35438. 21:54:36enough to work with the matching rows
  35439. 21:54:38and if the matching rows is not enough
  35440. 21:54:40then go with the lift join maybe. But
  35441. 21:54:42try your best always to bring the inner
  35442. 21:54:44join instead of lift join. But don't
  35443. 21:54:46forget inner join filters the data.
  35444. 21:54:49Okay. The next one it says use explicit
  35445. 21:54:51join the unzi join instead of implicit
  35446. 21:54:55join. Well it is considered as a bad
  35447. 21:54:57practice if you join tables like this
  35448. 21:54:59the implicit join or the nonzi join.
  35449. 21:55:02It's better to use the normal modern
  35450. 21:55:04join where you use the inner join for
  35451. 21:55:06example. about the performance. There is
  35452. 21:55:08like no differences between them. And
  35453. 21:55:10for this scenario, it's very simple. But
  35454. 21:55:12if you have like a complex query, then
  35455. 21:55:14joining table like this might be very
  35456. 21:55:16confusing and really hard to read and as
  35457. 21:55:19well complex to optimize. That's why the
  35458. 21:55:21best practice says go with the normal
  35459. 21:55:23inner join. So go with the anzi join
  35460. 21:55:26instead of the nonzi join. Okay. To the
  35461. 21:55:29next tip. Make sure to index the columns
  35462. 21:55:31used in the on clause. So we have to go
  35463. 21:55:34and make sure that both of those columns
  35464. 21:55:36has an index because indexes speed up
  35465. 21:55:39the lookup process. Without an index,
  35466. 21:55:41the SQL might go and do a full table
  35467. 21:55:44scan. Without an index on those columns,
  35468. 21:55:46the database might go and scan the
  35469. 21:55:48entire tables in order to find a match.
  35470. 21:55:51And that is really slow if you have big
  35471. 21:55:53tables. So now if you go to the
  35472. 21:55:54customers over here and then to the
  35473. 21:55:56indexes, we can see that we have an
  35474. 21:55:59index, a clustered index for the
  35475. 21:56:01customer ID. But if you check the
  35476. 21:56:03customer ID in the orders, we don't have
  35477. 21:56:06an index for that. So this one doesn't
  35478. 21:56:08have an index. So in order to fix that,
  35479. 21:56:10we're going to go and create an
  35480. 21:56:11uncclustered index on the table orders
  35481. 21:56:14for the customer's ID since it is a
  35482. 21:56:16foreign key. So once we do that, we have
  35483. 21:56:19now an index for both of those columns
  35484. 21:56:21and with that our join going to be
  35485. 21:56:23faster. Okay. So now we come to a tip
  35486. 21:56:25where we say really it depends on there
  35487. 21:56:28is like not one clear way on how to do
  35488. 21:56:30it. But let's say if you have a big
  35489. 21:56:32tables, it is better to filter data
  35490. 21:56:34before joining. And here we have like
  35491. 21:56:36three different scenarios that going to
  35492. 21:56:38deliver the same results. But of course
  35493. 21:56:40the question is which one is the best
  35494. 21:56:41for performance. So now let's have a
  35495. 21:56:43look to them. What we are doing here we
  35496. 21:56:45are just joining two tables and then we
  35497. 21:56:47are filtering the result based on the
  35498. 21:56:49order status that comes from the orders.
  35499. 21:56:52So in the first query what we are doing
  35500. 21:56:53we are first joining tables and at the
  35501. 21:56:56ends we are using where clause in order
  35502. 21:56:58to filter the data. So by looking to
  35503. 21:57:00this we are just filtering the data
  35504. 21:57:01after joining the tables. But there is
  35505. 21:57:03another way on how to do it. You can go
  35506. 21:57:05and join the tables but on the join
  35507. 21:57:08condition you can go and add this order
  35508. 21:57:11status equals to delivered. So we are
  35509. 21:57:13matching the data by the customer ID and
  35510. 21:57:15at the same time we are filtering the
  35511. 21:57:17data by the order status since we are
  35512. 21:57:20using the inner join. So the filtering
  35513. 21:57:22is happening during the join or you can
  35514. 21:57:24do it like this where we have here more
  35515. 21:57:26stuff to be added where we don't join
  35516. 21:57:28the table directly with the orders. We
  35517. 21:57:30first prepare the table orders before
  35518. 21:57:33joining it with the customers. And here
  35519. 21:57:35our preparation is we are just selecting
  35520. 21:57:37the columns that we need and we are
  35521. 21:57:39already filtering the data before doing
  35522. 21:57:42the join using the subquery. But if you
  35523. 21:57:44run all those queries you will get the
  35524. 21:57:46exact same results. And of course there
  35525. 21:57:48is another way on how to do it. you can
  35526. 21:57:50go and prepare the data not in subquery
  35527. 21:57:53you can go and use a CTE and then join
  35528. 21:57:55the result of the CTE with the table
  35529. 21:57:57customers. So now about the performance
  35530. 21:57:59if your query is like small not that
  35531. 21:58:02complex and as well you don't have a big
  35532. 21:58:04data inside your tables all those three
  35533. 21:58:07queries going to deliver the same
  35534. 21:58:09performance. I know it might sounds
  35535. 21:58:11weird because here we are like filtering
  35536. 21:58:13after joining or here we are filtering
  35537. 21:58:15during the join. Normally in databases
  35538. 21:58:18the SQL optimizers are now very smart
  35539. 21:58:20can understand that there is a filter
  35540. 21:58:22here and decide on the best execution
  35541. 21:58:25plan for you. So actually wherever you
  35542. 21:58:27put your filter after, during or before
  35543. 21:58:30the SQL is smart enough to do it
  35544. 21:58:32correctly. So if you don't have complex
  35545. 21:58:34query and you don't have like big
  35546. 21:58:36tables, go with the one that suits you.
  35547. 21:58:38And I really recommend you to go with
  35548. 21:58:40the first one because it's logical and
  35549. 21:58:42easier to understand. But if you have
  35550. 21:58:44big tables and complex queries, the best
  35551. 21:58:46practices says try always to prepare the
  35552. 21:58:49data before joining it. So try to
  35553. 21:58:51isolate and abstract the pre-step in a
  35554. 21:58:54subquery or in a CTE before joining it
  35555. 21:58:57with any other tables. And in many
  35556. 21:58:59scenarios in my project where I have a
  35557. 21:59:01big table, this did help where the
  35558. 21:59:03execution plan was better if I isolate
  35559. 21:59:05and prepare the data before joining it.
  35560. 21:59:07So if you have small or medium tables,
  35561. 21:59:10go with the normal way, use the wear
  35562. 21:59:11clause. But if you have complex big
  35563. 21:59:13tables, prepare the data in subquery or
  35564. 21:59:16CTE and then join it with the tables.
  35565. 21:59:19Okay. And now moving on to tip number
  35566. 21:59:2112. It is similar to the previous one
  35567. 21:59:24but this time it says aggregate data
  35568. 21:59:26before joining tables and again it is
  35569. 21:59:28special case to improve the performance
  35570. 21:59:30of big tables. So now we have the
  35571. 21:59:32following scenario where we are joining
  35572. 21:59:34the orders and the customers and we are
  35573. 21:59:36aggregating the data by the customer ID
  35574. 21:59:39but we are just joining the table
  35575. 21:59:40customers because we need the first
  35576. 21:59:42name. So as a result we have the
  35577. 21:59:44customer ID, the first name and the
  35578. 21:59:46order count. So the standard way is to
  35579. 21:59:48join the tables and then do a group by
  35580. 21:59:51in order to summarize the data. Now if
  35581. 21:59:53you look to this query, we actually
  35582. 21:59:54don't need the join in order to do the
  35583. 21:59:56aggregations. We can do first the
  35584. 21:59:59aggregation like preparing the orders
  35585. 22:00:01with the aggregated data and then join
  35586. 22:00:04the result with the customers in order
  35587. 22:00:06to get the first name. So again we
  35588. 22:00:09prepare first and then we do the join
  35589. 22:00:11and we can do that using either the
  35590. 22:00:13subqueries or using the CTE. So in this
  35591. 22:00:16scenario first we are doing the group by
  35592. 22:00:18we are aggregating the data and the
  35593. 22:00:20result of this is joined with the
  35594. 22:00:22customers tables in order to get the
  35595. 22:00:23first name. Now of course there are like
  35596. 22:00:25many ways on how to do it like for
  35597. 22:00:26example as well using the correlated
  35598. 22:00:28queries where we can go and use the
  35599. 22:00:31subquery in the select statements and
  35600. 22:00:33then use the where condition over here
  35601. 22:00:35to make the correlated query. Now all
  35602. 22:00:37those three going to deliver the same
  35603. 22:00:39results but the question here again
  35604. 22:00:41which one has the best performance?
  35605. 22:00:43Well, I can go immediately and tell you
  35606. 22:00:45that correlated subqueries are the worst
  35607. 22:00:48one. Always avoid using correlated
  35608. 22:00:51subqueries. They has really bad
  35609. 22:00:52performance. And that's because SQL
  35610. 22:00:55going to go and do the aggregations for
  35611. 22:00:57each customer individually. So it's
  35612. 22:01:00going to go like for each row and doing
  35613. 22:01:01aggregation then to the next row and so
  35614. 22:01:03on. So it takes long time. So this is
  35615. 22:01:06bad practices. Don't use it. Now we are
  35616. 22:01:08left again with the first option and the
  35617. 22:01:11second option. And here my tip going to
  35618. 22:01:13be like the previous one. I'm going to
  35619. 22:01:14say if you have small to medium size of
  35620. 22:01:17tables then go with this one because it
  35621. 22:01:19is easier to read and to understand and
  35622. 22:01:22you will gain exactly the same
  35623. 22:01:23performance as this subquery. But if
  35624. 22:01:26your tables are big the best practices
  35625. 22:01:28is to prepare first the data to group up
  35626. 22:01:31the data to filter the data and to
  35627. 22:01:33isolate it in a subquery or a CTE before
  35628. 22:01:36joining it with the final table in the
  35629. 22:01:39final query. But again here only for big
  35630. 22:01:41tables and always test check the
  35631. 22:01:43execution plan whether you are really
  35632. 22:01:45getting any benefits from it. All right.
  35633. 22:01:47So if you have big tables try to prepare
  35634. 22:01:49the data first in city subquery and then
  35635. 22:01:51join. Okay moving on to the next tip. It
  35636. 22:01:54says use union instead of or operator in
  35637. 22:01:57joins. So what this means sometime let's
  35638. 22:02:00say that you are joining two tables the
  35639. 22:02:02customers and the orders. And now about
  35640. 22:02:04the join key, you can see over here it
  35641. 22:02:06says the customer ID should be equal to
  35642. 22:02:08the customer ID from the orders or the
  35643. 22:02:11customer ID should be equal to the
  35644. 22:02:12saleserson's ID. If one of these two
  35645. 22:02:15conditions is fulfilled, then we have a
  35646. 22:02:17match. And I can tell you the or
  35647. 22:02:19operator over here is a performance
  35648. 22:02:21killer. It has really bad performance.
  35649. 22:02:24So try to avoid it. Don't use ore in the
  35650. 22:02:26joins. It has a lot of problems like it
  35651. 22:02:29avoid indexes, it create like loop joins
  35652. 22:02:32and so on. That's why we consider it as
  35653. 22:02:35a bad practice. And now in order to get
  35654. 22:02:37the same results, we can go and split
  35655. 22:02:40the joins. So we can go and have two
  35656. 22:02:42queries. The first query is joining the
  35657. 22:02:44data based on the customer ID and the
  35658. 22:02:47second query based on the saleserson and
  35659. 22:02:50then we go and merge those two results
  35660. 22:02:52using the union. It sounds like bigger
  35661. 22:02:54and too much for the SQL but with this
  35662. 22:02:57you will get better performance than
  35663. 22:02:59using this simple or operator. So again
  35664. 22:03:02if you have big tables try to avoid
  35665. 22:03:04using or and instead of that go and use
  35666. 22:03:07union. Okay the next tip says check for
  35667. 22:03:10nested loops and use SQL hints. Now
  35668. 22:03:13imagine that we have like big tables and
  35669. 22:03:15we are joining tables. So now if you are
  35670. 22:03:17checking the execution plan you have to
  35671. 22:03:19check always the join type. So for
  35672. 22:03:21example here it is using the nested
  35673. 22:03:23loops which is of course is okay because
  35674. 22:03:26we have small tables but if you have big
  35675. 22:03:28tables and still SQL is using for some
  35676. 22:03:30reason the nested loops then this is
  35677. 22:03:33alerting. So in order to change this
  35678. 22:03:35what we can do we can go and use the SQL
  35679. 22:03:37hints in order to force SQL to use the
  35680. 22:03:40hash join. Hash join is really good if
  35681. 22:03:42you have a big table like for example
  35682. 22:03:44the orders that is joins with a small
  35683. 22:03:47table like the customers. So now what we
  35684. 22:03:49can do at the end we can write over here
  35685. 22:03:50option hash join. So let's go and
  35686. 22:03:53execute it and let's check the execution
  35687. 22:03:55plan and with that we have forced SQL to
  35688. 22:03:58use the hash join or hash match. Again
  35689. 22:04:01you have here really to evaluate your
  35690. 22:04:02tables. If you have like small tables
  35691. 22:04:05don't bother with that. But if you have
  35692. 22:04:07big tables and SQL still doing the
  35693. 22:04:09nested loops, nested loops are usually
  35694. 22:04:11very slow because you have a lot of
  35695. 22:04:13iterations and so on and with the hash
  35696. 22:04:15join that small table going to be stored
  35697. 22:04:17in the memory and then you have really a
  35698. 22:04:19quick matching between the two tables.
  35699. 22:04:22So those are all the best practices and
  35700. 22:04:24tips on how to optimize joining tables
  35701. 22:04:26in SQL. All right, so now we're going to
  35702. 22:04:28talk about union and here is the best
  35703. 22:04:29practices. It says use union all instead
  35704. 22:04:32of using union if duplicates are
  35705. 22:04:35acceptable. So it's very simple. If the
  35706. 22:04:37duplicates are acceptable or let's say
  35707. 22:04:39that there is no duplicates then don't
  35708. 22:04:42go with the union because it needs more
  35709. 22:04:44time to be executed. SQL has to go and
  35710. 22:04:46check row by row whether we have
  35711. 22:04:48duplicates or not and this usually takes
  35712. 22:04:51longer time than using the union all. So
  35713. 22:04:54if duplicates are acceptable or you
  35714. 22:04:55don't have any duplicates in your data
  35715. 22:04:57go with the union all just have to go
  35716. 22:05:00and merge all the data without checking
  35717. 22:05:02anything and the performance going to be
  35718. 22:05:04faster. All right, the next one is
  35719. 22:05:05little bit tricky. So it says use union
  35720. 22:05:08all together with the distinct instead
  35721. 22:05:10of using union if the duplicates are not
  35722. 22:05:13acceptable. So you want to remove the
  35723. 22:05:15duplicates. So we have learned that in
  35724. 22:05:17order to do that we're going to go and
  35725. 22:05:18use the union. It's going to go and
  35726. 22:05:20merge the data and as well remove the
  35727. 22:05:22duplicates which is really okay to use
  35728. 22:05:24it if you have like smaller data or
  35729. 22:05:26medium. But let's say that you have like
  35730. 22:05:28millions of row which is really okay if
  35731. 22:05:30you have like medium and small tables.
  35732. 22:05:32But again here if you have huge tables
  35733. 22:05:34big tables hundreds of millions the best
  35734. 22:05:37practice says go with the union all and
  35735. 22:05:40afterwards use a distincts. So in the
  35736. 22:05:43sub query we are using union all but in
  35737. 22:05:46order to remove the duplicates we use
  35738. 22:05:48the distincts. But again here you have
  35739. 22:05:50to test it to check the execution plan.
  35740. 22:05:52If you are getting benefit then go with
  35741. 22:05:54this version. But if your data is not
  35742. 22:05:56really big you have hundred of
  35743. 22:05:57thousands. So go just with the normal
  35744. 22:06:00union. the code is smaller and you will
  35745. 22:06:02get the same effects but only for large
  35746. 22:06:04tables you can go with this best
  35747. 22:06:06practice. So that's all what I have for
  35748. 22:06:08you for the
  35749. 22:06:09[Music]
  35750. 22:06:12union. Okay. So now let's talk about
  35751. 22:06:14aggregations and here the tip says use
  35752. 22:06:17column store index for aggregations on
  35753. 22:06:19large tables like for example fact
  35754. 22:06:21tables and that's because column store
  35755. 22:06:23index going to compress the data. So the
  35756. 22:06:25size of the data going to be smaller and
  35757. 22:06:27as well the aggregation is super fast
  35758. 22:06:30because we are selecting only the
  35759. 22:06:32relevant informations only the relevant
  35760. 22:06:34columns. So it makes it a perfect setup
  35761. 22:06:37for aggregating large tables. And now
  35762. 22:06:39let's say that we have hundreds of
  35763. 22:06:40millions of orders and we have this
  35764. 22:06:42query over here. So the best practice
  35765. 22:06:44says convert this table to a clustered
  35766. 22:06:47column store index. So if you go and
  35767. 22:06:49create this clustered index over here,
  35768. 22:06:52the whole table going to have amazing
  35769. 22:06:54performance for aggregations like this.
  35770. 22:06:56All right. So to the next one, it says
  35771. 22:06:59pre-agregate data and store it in a new
  35772. 22:07:02table for reporting. So let's say that
  35773. 22:07:04we have like a big query where we are
  35774. 22:07:06aggregating the data and so on. And this
  35775. 22:07:08query takes really long time. Let's say
  35776. 22:07:10like 5 minutes or something like that.
  35777. 22:07:12But now the problem with that I would
  35778. 22:07:14like to show the results as a report
  35779. 22:07:16maybe to my manager or let's say during
  35780. 22:07:18a meeting it's going to be really bad if
  35781. 22:07:20everyone have to wait until the query is
  35782. 22:07:23done. So the best practice here if you
  35783. 22:07:25have like a query that runs very slow
  35784. 22:07:28what you can do you can go and store the
  35785. 22:07:30results in a table. So if I go over here
  35786. 22:07:33and say into sales summary what going to
  35787. 22:07:36happen going to store the result inside
  35788. 22:07:39this table. So let's go and execute it.
  35789. 22:07:41And now with that we have a nice table
  35790. 22:07:43where everything is prepared. So all
  35791. 22:07:44that you have to do is to go and query
  35792. 22:07:47this table. And of course it's going to
  35793. 22:07:48be very fast because it's only select
  35794. 22:07:50statements. And with that you have like
  35795. 22:07:52prepared and pre-agregated the data to
  35796. 22:07:55have like fast reports. So don't forget
  35797. 22:07:58about this. If you have a big query you
  35798. 22:08:00can insert the result of this query in a
  35799. 22:08:02new table in order later to use it for
  35800. 22:08:04reporting. But one thing that you have
  35801. 22:08:06to make sure that you have always to
  35802. 22:08:08update this table. So if we have new
  35803. 22:08:10orders, it will not be presented inside
  35804. 22:08:12the sales summary. You have to go and
  35805. 22:08:15run this query again in order to get new
  35806. 22:08:17data inside the sales summary. So those
  35807. 22:08:19are the tips on how to improve the
  35808. 22:08:21performance of your aggregations in
  35809. 22:08:27SQL. So now what is happening here? I
  35810. 22:08:29would like to show the orders but only
  35811. 22:08:31from customers from USA. So if you check
  35812. 22:08:34this query over here, we are joining the
  35813. 22:08:36tables order and customers but mainly we
  35814. 22:08:39are showing only the orders information
  35815. 22:08:41and that means we are using the
  35816. 22:08:43customers only to filter the table
  35817. 22:08:45orders and there are like multiple ways
  35818. 22:08:47on how to do this task. So it's not only
  35819. 22:08:50the joins you can go and use the exist
  35820. 22:08:52as a subquery and as well you can go and
  35821. 22:08:55use the in operator in the subquery. And
  35822. 22:08:58now comes the old but gold question.
  35823. 22:09:02Which one is better? Should we join or
  35824. 22:09:04use exist or in? And oh my god, if you
  35825. 22:09:07go to the forums, you will see people
  35826. 22:09:09fighting about which one is the best.
  35827. 22:09:14Clean tech. Come on, do that again. Do
  35828. 22:09:16that again. I dare you.
  35829. 22:09:19Okay,
  35830. 22:09:21bring it. Oh, you can't say you can't
  35831. 22:09:24say one point. Two point. Now, about the
  35832. 22:09:27best practices, everyone agrees that's
  35833. 22:09:30don't go and use the in operator. So
  35834. 22:09:32this is the bad practice. So
  35835. 22:09:36bad practice avoid it. Don't use it. And
  35836. 22:09:39of course I'm always speaking about big
  35837. 22:09:41tables, okay? Not small tables. So we
  35838. 22:09:44don't go and use this in order to filter
  35839. 22:09:47one table based on the result of another
  35840. 22:09:49table. So don't use any operator in this
  35841. 22:09:52scenario. Now here comes the conflicts.
  35842. 22:09:54We have join and exist. Well, about the
  35843. 22:09:57performance of those two, they are very
  35844. 22:09:59similar for medium tables. like I'm
  35845. 22:10:01speaking about hundred or thousand and
  35846. 22:10:03so on. But still you have to test it.
  35847. 22:10:05You have to go and compare the execution
  35848. 22:10:07plans and if you are getting like
  35849. 22:10:09identical results and both of them are
  35850. 22:10:12having the same speed then I prefer to
  35851. 22:10:15go with the join and that's because to
  35852. 22:10:17be honest it is easier to write than
  35853. 22:10:19writing that exists. So I'm going to say
  35854. 22:10:21from my point of view this is best
  35855. 22:10:24practice if the
  35856. 22:10:27performance
  35857. 22:10:29equal to exist. But now what happens for
  35858. 22:10:32me is that sometimes I get better
  35859. 22:10:34performance using exists. So I'm going
  35860. 22:10:37to say from my point of view the best
  35861. 22:10:39practice
  35862. 22:10:40here. And now you might ask why we are
  35863. 22:10:43getting with the exist better
  35864. 22:10:44performance than in the inner join. And
  35865. 22:10:46that's because SSQL has only to check
  35866. 22:10:48the existence of data from the subquery.
  35867. 22:10:51But in the other hand with the inner
  35868. 22:10:52join SQL has to go and start doing
  35869. 22:10:55matching between two tables. So it can
  35870. 22:10:57go and evaluate all matching records and
  35871. 22:11:00so on. It is not evaluating whether it
  35872. 22:11:03exist or not. And as well sometimes SQL
  35873. 22:11:05has to deal with more rows because you
  35874. 22:11:08might introduce duplicates as you are
  35875. 22:11:10joining tables. And this will not happen
  35876. 22:11:12using exists. So for some scenarios if
  35877. 22:11:14you are using exist you might get better
  35878. 22:11:17performance than using join but everyone
  35879. 22:11:20agrees to not use the end operator. Okay
  35880. 22:11:22the next tip is to avoid redundant logic
  35881. 22:11:25in your query. This happens a lot if you
  35882. 22:11:28have a lot of sub queries and if you
  35883. 22:11:30analyze it you might find sometimes
  35884. 22:11:32there is like redundancy. So for example
  35885. 22:11:34this query I would like to have like a
  35886. 22:11:36tag for each employee whether the salary
  35887. 22:11:39is above the average or below the
  35888. 22:11:40average. So now we might do it like
  35889. 22:11:42this. we say okay let's get the data for
  35890. 22:11:44employees where the salary is higher
  35891. 22:11:46than the average and you go and
  35892. 22:11:48calculate the average in a subquery. So
  35893. 22:11:50if it's higher then you write here above
  35894. 22:11:53average and now we say okay let's go for
  35895. 22:11:55the below average. So we do a union all
  35896. 22:11:57and the condition going to be salary is
  35897. 22:11:59less than the average. And now by
  35898. 22:12:01checking this you see that there's a
  35899. 22:12:03problem. First of all we are querying
  35900. 22:12:06the employees like four times. We have 1
  35901. 22:12:082 3 4. So we are scanning the table
  35902. 22:12:12employees four times and as well we have
  35903. 22:12:14the same logic over here. So we are
  35904. 22:12:16calculating the average of salary at
  35905. 22:12:18twice. So this is of course I can say a
  35906. 22:12:21bad practice and there is like many ways
  35907. 22:12:23on how to do it better than that. For
  35908. 22:12:25example, you can go and put this
  35909. 22:12:26subquery in CTE and then use it multiple
  35910. 22:12:29times. But there is like better solution
  35911. 22:12:31using the window function. So if you
  35912. 22:12:33check this, it is very simple. Let's me
  35913. 22:12:34execute it. We are reading the table
  35914. 22:12:36employees only once and then we are
  35915. 22:12:39using the case statements. If the salary
  35916. 22:12:41is higher than the window function. So
  35917. 22:12:43we are calculating the average on top of
  35918. 22:12:45the whole table employees. If it's
  35919. 22:12:48higher then write above average. If it's
  35920. 22:12:50lower then below average. So as you can
  35921. 22:12:52see it is easier to read and it is
  35922. 22:12:54smaller and the performance here is way
  35923. 22:12:56better than reading four times the
  35924. 22:12:58employees and repeating the same logic.
  35925. 22:13:00So here you have always to look to your
  35926. 22:13:02queries and if you see that you are
  35927. 22:13:04repeating the same things over and over
  35928. 22:13:06then you are writing a bad query. Think
  35929. 22:13:08about alternatives like CTE window
  35930. 22:13:11functions and I'm sure you will find a
  35931. 22:13:12better way than reading the table
  35932. 22:13:15several times or repeating the same
  35933. 22:13:17logic several times. So as you can see
  35934. 22:13:18optimizing the queries is not always
  35935. 22:13:20about using indexes and partitions. It's
  35936. 22:13:23all about using best practices. All
  35937. 22:13:25right guys, so with that we have covered
  35938. 22:13:27a lot of best practices on how to
  35939. 22:13:29optimize the performance of your query.
  35940. 22:13:31And as you can see it's not always
  35941. 22:13:33creating indexes, right? In many
  35942. 22:13:34scenarios it's about how you write the
  35943. 22:13:40query. And now in the next section I'm
  35944. 22:13:42going to show you the best practices on
  35945. 22:13:45how to create tables. So the best
  35946. 22:13:47practices of DDL data definition
  35947. 22:13:50language. If you have a poor definition
  35948. 22:13:52of your tables, this has a great impact
  35949. 22:13:54on the performance of your queries. All
  35950. 22:13:56right. So now we have here like a DDL in
  35951. 22:13:58order to create a table customer info
  35952. 22:14:01and it is not really following best
  35953. 22:14:02practices. So let's go through it one by
  35954. 22:14:05one. The first tip is try to avoid the
  35955. 22:14:07data types varchar and text if it's
  35956. 22:14:10possible. The vchart and text they are
  35957. 22:14:13like one of the worst data types for
  35958. 22:14:15performance because they consume a lot
  35959. 22:14:17of resources whatever you do like for
  35960. 22:14:19example if you are sorting the data by a
  35961. 22:14:21column that is var or text it is very
  35962. 22:14:23expensive operation the same thing if
  35963. 22:14:25you go like and create an index on top
  35964. 22:14:27of such a column it's going to be as
  35965. 22:14:28well expensive and they cause a lot of
  35966. 22:14:30problems with the data fragmentations
  35967. 22:14:32and many issues. So try as much as you
  35968. 22:14:35can to skip those data type if it's
  35969. 22:14:37possible. So now let's go and review all
  35970. 22:14:39those columns in order to see whether we
  35971. 22:14:40can change something about it because it
  35972. 22:14:43has a lot of bar charts. So the first
  35973. 22:14:44one over here we have is var because it
  35974. 22:14:46is the first name. Well, it is okay. Now
  35975. 22:14:49moving on to the next one. We have the
  35976. 22:14:50last name as a text which is not really
  35977. 22:14:52good because text is worse than vchar.
  35978. 22:14:55So it's better to use var than a text.
  35979. 22:14:57So here we have to fix it. So var and
  35980. 22:15:00I'm going to go with the links 50. Now
  35981. 22:15:02moving on to the countries. So the
  35982. 22:15:04country is going to be vartar. We cannot
  35983. 22:15:06change that. that contain characters. So
  35984. 22:15:08the next one is the score of the
  35985. 22:15:10customer. H here we can do something
  35986. 22:15:12about it because scores are only
  35987. 22:15:14numbers. So that's why we can go and
  35988. 22:15:16skip this one. So let's remove it and
  35989. 22:15:19say you are integer and with that we
  35990. 22:15:21have avoided using the varchar. And the
  35991. 22:15:23same thing goes for the birthday. The
  35992. 22:15:25birthday is a date and here we have it
  35993. 22:15:27as a vchar. Well this is not really good
  35994. 22:15:29and we can skip that by having this
  35995. 22:15:31column as a date. So date is way better
  35996. 22:15:34than having a vchar. All right. And the
  35997. 22:15:36next one is integer. So with that we
  35998. 22:15:38have fixed few stuff. So we have fixed
  35999. 22:15:40the score and the birthday. And with
  36000. 22:15:42that we have saved some storage. If we
  36001. 22:15:44have an index on the score it's going to
  36002. 22:15:45be way better than having a var. And if
  36003. 22:15:48you are filtering the data based on the
  36004. 22:15:50birthday it's going to be faster. So
  36005. 22:15:51again try your best to avoid the vchar
  36006. 22:15:54and the text. I have seen in many
  36007. 22:15:55projects that a lot of developers tend
  36008. 22:15:57to use the vchar and I understand it is
  36009. 22:16:00easier to make everything as a vchar
  36010. 22:16:02than deciding whether it is an integer,
  36011. 22:16:04date, float and so on because you can
  36012. 22:16:06fit everything in the vchar and text but
  36013. 22:16:09this is lazy. Take time to understand
  36014. 22:16:11the content of this column and try to
  36015. 22:16:13assign it to the correct data type
  36016. 22:16:15because this has really impact on the
  36017. 22:16:17performance. Okay, to the next one it
  36018. 22:16:19says avoid using max or overly large
  36019. 22:16:22lengths. So now we have to keep our eyes
  36020. 22:16:24on the links of each data type
  36021. 22:16:26especially the bar charts. Not only it
  36022. 22:16:28going to waste like a lot of storage.
  36023. 22:16:30It's also going to like mislead the SQL
  36024. 22:16:33by creating large indexes which is
  36025. 22:16:36totally unnecessary because the data
  36026. 22:16:38itself is small but because you have
  36027. 22:16:40defined like a large length SQL going to
  36028. 22:16:43check those informations and make
  36029. 22:16:44decision to make a big index and large
  36030. 22:16:47indexes are always problematic because
  36031. 22:16:49they're going to slow everything down by
  36032. 22:16:50sorting the data by retrieving data by
  36033. 22:16:53updating the index. So it is really bad
  36034. 22:16:55practices if you go blindly and define
  36035. 22:16:58everywhere max or
  36036. 22:17:00255. Again give it a chance to think
  36037. 22:17:03about each column and predict a length
  36038. 22:17:05for it. So for example if you check over
  36039. 22:17:07here we are saying first name v chart
  36040. 22:17:09max. Well most of the first names are
  36041. 22:17:11short. So we don't need like the maximum
  36042. 22:17:14size of a v chart to fit a first name.
  36043. 22:17:17So here we can go easily instead of max
  36044. 22:17:19with the 50. And the same thing goes for
  36045. 22:17:22the column country. We don't need 255
  36046. 22:17:24characters for the country name. We can
  36047. 22:17:27go with something more realistic like
  36048. 22:17:29around 50. I think you can even go
  36049. 22:17:31smaller, but it's fine to have 50. So,
  36050. 22:17:33the best practice here is to analyze
  36051. 22:17:35your data and to predict the size of
  36052. 22:17:38each column. And don't be lazy by just
  36053. 22:17:40defining max everywhere. I know it's
  36054. 22:17:42faster, but it's bad for performance.
  36055. 22:17:44Okay. What do you have else? Use the
  36056. 22:17:47constraint nutnull as much as possible.
  36057. 22:17:50The nutnull is amazing. It has a lot of
  36058. 22:17:52advantages. Of course, the biggest
  36059. 22:17:53advantage is that's the data integrity
  36060. 22:17:55of your table. So with that, you make
  36061. 22:17:57sure no nulls are inserted in specific
  36062. 22:18:00column. But it is as well good practices
  36063. 22:18:02to use it for improving the performance
  36064. 22:18:05because if you are creating an index,
  36065. 22:18:06you're going to get a better index
  36066. 22:18:08performance since SQL knows there is no
  36067. 22:18:10nulls inside my tree inside the index.
  36068. 22:18:13And in the other side, if you are
  36069. 22:18:14writing query, we tend to use a filter
  36070. 22:18:17where we say a specific column should
  36071. 22:18:19not be null. But if you make sure that
  36072. 22:18:21in the DDL it is not null then you can
  36073. 22:18:23skip this filter and with that you are
  36074. 22:18:25reducing the size of your query. So what
  36075. 22:18:27we're going to do we're going to go
  36076. 22:18:28through all the columns and decide
  36077. 22:18:29whether it is not null and null. So for
  36078. 22:18:31example the first name and the last name
  36079. 22:18:33they should not be null. So that's why
  36080. 22:18:35I'm going to say not null and the same
  36081. 22:18:37thing for the last name not null. For
  36082. 22:18:39the customer ID we're going to talk
  36083. 22:18:40about it soon because we're going to
  36084. 22:18:41convert it to primary key and primary
  36085. 22:18:43keys are usually not null. So now for
  36086. 22:18:45the country we make have it in the
  36087. 22:18:47business that it should not be null. So
  36088. 22:18:49we go and make a constraint about it.
  36089. 22:18:51Now about the total purchases and
  36090. 22:18:53scores. If it is new customer, maybe we
  36091. 22:18:55can have a null inside our data. So
  36092. 22:18:57we're going to leave it empty. And I
  36093. 22:18:58think birthday is going to be usually
  36094. 22:19:00optional. So we're going to leave it as
  36095. 22:19:01well. And whether the customer is
  36096. 22:19:03employee or not. This could be as well a
  36097. 22:19:06null. So with that we have found out
  36098. 22:19:08like three columns where we can have a
  36099. 22:19:10constraint about the not null. And if we
  36100. 22:19:11go and create like an index on the
  36101. 22:19:14country, it's going to be a better
  36102. 22:19:15index. Okay. Moving on to the next one.
  36103. 22:19:17It says make sure that all your tables
  36104. 22:19:19inside the database have a clustered
  36105. 22:19:22primary key and as well it can help you
  36106. 22:19:24building the relationship between tables
  36107. 22:19:26where you have primary keys and foreign
  36108. 22:19:27keys and you can join tables then very
  36109. 22:19:30easily and as well a primary key has
  36110. 22:19:32importance for the performance and
  36111. 22:19:34incale server the default going to be a
  36112. 22:19:36clustered index which is really good to
  36113. 22:19:38have an index on the primary key because
  36114. 22:19:40sometimes you are doing like an update
  36115. 22:19:42operations or delete operations it's
  36116. 22:19:44going to help up by the lookups of
  36117. 22:19:46joining tables. So there are a lot of
  36118. 22:19:48performance benefits of having a primary
  36119. 22:19:50key and make sure that all your tables
  36120. 22:19:52having a primary key. So as you can see
  36121. 22:19:54the issue of our table we don't have a
  36122. 22:19:56primary key and our primary key going to
  36123. 22:19:58be the customer ID. So let's go and do
  36124. 22:19:59that primary key and as I said as a
  36125. 22:20:03default it can be clustered but I'm
  36126. 22:20:05going to write it down in case if you
  36127. 22:20:07are working with different databases
  36128. 22:20:08make sure it is clustered. Okay moving
  36129. 22:20:11on to the next one. It's not only about
  36130. 22:20:12the primary key we have to take care of
  36131. 22:20:14our foreign keys. So the best practice
  36132. 22:20:16says create non-clustered index for the
  36133. 22:20:20foreign keys if they are frequently
  36134. 22:20:22used. The foreign keys are usually
  36135. 22:20:24important in order to connect and join
  36136. 22:20:26two tables and usually we frequently use
  36137. 22:20:28it and not only that we use it sometimes
  36138. 22:20:30in order to filter the data and if you
  36139. 22:20:33create a nonclustered index for that it
  36140. 22:20:35can improve the speed. So what we can do
  36141. 22:20:37it's very simple we're going to go and
  36142. 22:20:38create a nclustered index on our table
  36143. 22:20:41customers info for the foreign key
  36144. 22:20:44employee ID. So how to do it is very
  36145. 22:20:46simple. We're going to go and say create
  36146. 22:20:48nonclustered index on our table the
  36147. 22:20:50customer's info on our foreign key the
  36148. 22:20:52employee ID. But again make sure that
  36149. 22:20:54this is an important foreign key that is
  36150. 22:20:57used frequently from your queries. All
  36151. 22:20:59right friends so as you can see there
  36152. 22:21:01are a lot of best practices on how to
  36153. 22:21:02improve and optimize the DDL. Having a
  36154. 22:21:05healthy DDL can improve the performance
  36155. 22:21:07of your queries. Now in the next section
  36156. 22:21:09I'm going to show you the best practices
  36157. 22:21:11and tips and tricks about indexing. So
  36158. 22:21:13let's go.
  36159. 22:21:18All right, the fifth best practices and
  36160. 22:21:20the most important one is avoid
  36161. 22:21:22overindexing because too many index is
  36162. 22:21:24going to slow down the insert, update,
  36163. 22:21:26delete operations and it's going to
  36164. 22:21:28confuse as well the execution plan about
  36165. 22:21:30choosing the right index and the
  36166. 22:21:32performance of the whole system going to
  36167. 22:21:33go down. And another tip is to monitor
  36168. 22:21:35the usage of the indexes and I can tell
  36169. 22:21:38you 90% of the indexes that is being
  36170. 22:21:41created usually are not used at all. So
  36171. 22:21:43they are taking a lot of space slowing
  36172. 22:21:46down everything. So go and drop those
  36173. 22:21:48unused indexes in your system. The next
  36174. 22:21:51best practice is to have a regular job
  36175. 22:21:53like maybe a weekly job. So first you
  36176. 22:21:56have to update the statistics regularly
  36177. 22:21:58as you are inserting new data and
  36178. 22:22:00modifying data inside your database. The
  36179. 22:22:02statistics and the metadata of your
  36180. 22:22:04tables might get outdated and this is
  36181. 22:22:06really bad because you will not get an
  36182. 22:22:08optimal execution plan for your queries
  36183. 22:22:10and this can slow down your queries of
  36184. 22:22:12course. So regularly make sure that all
  36185. 22:22:15the statistics are updated in order to
  36186. 22:22:17have an optimal execution plan. And what
  36187. 22:22:19else we can do in this weekly job is
  36188. 22:22:21that we can go and rebuild and
  36189. 22:22:23reorganize our indexes. And that is to
  36190. 22:22:26make sure that we are preventing data
  36191. 22:22:28fragmentations in our indexes. Data
  36192. 22:22:31fragmentations in your indexes is really
  36193. 22:22:33bad because there will be a lot of
  36194. 22:22:34unused spaces. The order of your
  36195. 22:22:36clustered index will not be correct. So
  36196. 22:22:39make sure that at least weekly you are
  36197. 22:22:41rebuilding and reorganizing all your
  36198. 22:22:43indexes. So those are the best practices
  36199. 22:22:45of improving the performance and
  36200. 22:22:47optimizing your indexing. If you are
  36201. 22:22:49struggling with very large tables in
  36202. 22:22:51your projects like having fact tables,
  36203. 22:22:54then go and use SQL partitioning in
  36204. 22:22:57order to divide these tables into
  36205. 22:22:59smaller pieces which can improve the
  36206. 22:23:02performance whether you are reading data
  36207. 22:23:04from the table or writing data. And of
  36208. 22:23:06course you can go and mix things where
  36209. 22:23:09you can go and apply a column store
  36210. 22:23:11index on this partition table then you
  36211. 22:23:14will get the best performance if you are
  36212. 22:23:17having large
  36213. 22:23:21tables. All right friends so that's all
  36214. 22:23:24those are the best practices tips and
  36215. 22:23:26tricks that I've collected in the many
  36216. 22:23:28years working with SQL. And now my final
  36217. 22:23:31thought about this is that try always to
  36218. 22:23:33focus on making clear queries. Make it
  36219. 22:23:36like easy to read and easy to understand
  36220. 22:23:38and try to optimize the performance only
  36221. 22:23:41if it's needed. So if you have like
  36222. 22:23:42small database don't worry a lot about
  36223. 22:23:44the performance because the SQL
  36224. 22:23:46optimizer going to pick the best plan
  36225. 22:23:48for you and focus only on having simple
  36226. 22:23:50queries and if there is like performance
  36227. 22:23:53problem always test using the execution
  36228. 22:23:55plan. It should be your judge. So if you
  36229. 22:23:57are applying any index or you are
  36230. 22:23:59rewriting your queries always compare
  36231. 22:24:02before and after using the execution
  36232. 22:24:04plan. And if you are gaining more
  36233. 22:24:05performance then adopt the new query or
  36234. 22:24:08the new index. All right my friends. So
  36235. 22:24:10that's all the tips and tricks best
  36236. 22:24:11practices that I have for you in order
  36237. 22:24:13to optimize the performance. And with
  36238. 22:24:15that we have covered now everything
  36239. 22:24:16about this chapter the performance
  36240. 22:24:17optimization. Now in the next chapter
  36241. 22:24:19I'm going to show you how I use AI in
  36242. 22:24:22order to assist me while I'm using SQL.
  36243. 22:24:24So let's
  36244. 22:24:28go. All right. Right. So now I would
  36245. 22:24:30like to share something important with
  36246. 22:24:32you especially as a future developer
  36247. 22:24:34that is working with AI. One of the best
  36248. 22:24:36ways in order to truly build skill and
  36249. 22:24:39to grow as a developer is by working on
  36250. 22:24:41complex task and issue on your own. So
  36251. 22:24:44when you are stuck on complex task and
  36252. 22:24:46you are pushing yourself to find a
  36253. 22:24:48solution for it and you are writing your
  36254. 22:24:50code in yourself here the magic happens
  36255. 22:24:53and the real learning can happen. And if
  36256. 22:24:56you jump too quickly and ask the AI for
  36257. 22:24:58a solution, what you are doing, you are
  36258. 22:25:00skipping an essential step in order to
  36259. 22:25:02become an expert. And more important
  36260. 22:25:04than that, you won't develop skills in
  36261. 22:25:07order to understand when and where the
  36262. 22:25:09AI was wrong. So my recommendation here
  36263. 22:25:12is to have a discipline. Always try to
  36264. 22:25:14solve the task on your own and only turn
  36265. 22:25:16to AI if you don't have any more ideas
  36266. 22:25:18on how to solve the task. So that's my
  36267. 22:25:21opinion and my advice for you.
  36268. 22:25:27So quickly what is shippet? It is an AI
  36269. 22:25:29program that is developed by open AI
  36270. 22:25:32that is trained to understand questions
  36271. 22:25:34and provide humanlike answers. So what
  36272. 22:25:37GPT stands for? The G stands for
  36273. 22:25:39generative. So that means the data model
  36274. 22:25:41can generate a new content new text and
  36275. 22:25:45P stands for pre-trained. The data model
  36276. 22:25:47is already trained on huge amount of
  36277. 22:25:50data. And the T stands for transformer.
  36278. 22:25:52It is type of neural network
  36279. 22:25:54architecture that processes your
  36280. 22:25:56sentences in the prompts in order to
  36281. 22:25:58understand the context behind it very
  36282. 22:26:01fast and accurate. And in the other hand
  36283. 22:26:03we have the GitHub copilot. It is
  36284. 22:26:05developed by the GitHub and as well
  36285. 22:26:07using the same data models from the open
  36286. 22:26:10AAI. So that means both shad and copilot
  36287. 22:26:14both of them are using the same language
  36288. 22:26:16model that is developed from OpenAI. So
  36289. 22:26:19the GitHub copilot did train on tons of
  36290. 22:26:22codes that is available in GitHub. So
  36291. 22:26:24how it works as you are writing a code
  36292. 22:26:26in the code editor like for example
  36293. 22:26:28visual studio it going to provide
  36294. 22:26:30realtime suggestions as you are writing
  36295. 22:26:33and typing your code. So now if we
  36296. 22:26:35compare those two shad and the copilot
  36297. 22:26:37we can say that the shajibet is a
  36298. 22:26:39standalone application where you can
  36299. 22:26:42interact with it using a website or an
  36300. 22:26:44app where you go and start a
  36301. 22:26:45conversation with the AI where in the
  36302. 22:26:48other hand the copilot is directly
  36303. 22:26:50integrated in your code editor like for
  36304. 22:26:52example the visual studio code this is
  36305. 22:26:55way better than shibility because you
  36306. 22:26:57have realtime interaction with the AI
  36307. 22:26:59this is a great advantage for the
  36308. 22:27:01copilot because everything in one place
  36309. 22:27:03so with the copilot pilot you are
  36310. 22:27:05getting realtime assistant during your
  36311. 22:27:07coding. So the main purpose of the ship
  36312. 22:27:10is to have a conversation with the AI
  36313. 22:27:12for any topic that you like not limited
  36314. 22:27:15only for software developments but in
  36315. 22:27:18the other hand a copilot focuses only on
  36316. 22:27:21assisting the software development where
  36317. 22:27:23you as a developer as you are writing
  36318. 22:27:25your code you are getting auto
  36319. 22:27:27completion of the code or maybe a block
  36320. 22:27:29of code as a suggestion. So these are
  36321. 22:27:31the key differences between shad and
  36322. 22:27:34copilot.
  36323. 22:27:38Now if you are doing software
  36324. 22:27:40developments or you are working with
  36325. 22:27:42data projects and of course it depends
  36326. 22:27:44on your role in the projects there will
  36327. 22:27:46be many different types of tasks and
  36328. 22:27:48activities that should be done in the
  36329. 22:27:50project like there will be a lot of
  36330. 22:27:52brainstormings about new ideas and
  36331. 22:27:54coding solutions debugging generating
  36332. 22:27:56documentations discussing the different
  36333. 22:27:58types of architecture doing road cause
  36334. 22:28:01analyzes. So the spectrum of activities
  36335. 22:28:03and tasks in each projects usually is
  36336. 22:28:06very huge. And of course we can go and
  36337. 22:28:08use the help of different AI tools to
  36338. 22:28:10assist us with those tasks and
  36339. 22:28:12activities and there is like not one AI
  36340. 22:28:14tool that can cover all those stuff. I
  36341. 22:28:17tend to jump between co-pilots and
  36342. 22:28:18something like Shajbet. Okay. So now I'm
  36343. 22:28:20going to go and map those different
  36344. 22:28:21tasks to either sht or copilot. So now
  36345. 22:28:24let's focus on the shibbet. The first
  36346. 22:28:26one is brainstorming and ideas. So now
  36347. 22:28:29if we have in our project a big task or
  36348. 22:28:31let's say a big issue that we want to
  36349. 22:28:33find solution for it. I tend to use of
  36350. 22:28:35course tools like shad in order to have
  36351. 22:28:38a discussion about the topic in order to
  36352. 22:28:41explore and discuss multiple ideas and
  36353. 22:28:43then start evaluating all those ideas.
  36354. 22:28:45The next one where I found myself using
  36355. 22:28:47shbt is doing the project planning. So
  36356. 22:28:49it is as well something high level. You
  36357. 22:28:51can go and discuss with the shaj GBT
  36358. 22:28:53about the design of your projects and
  36359. 22:28:55you can as well discuss the milestones
  36360. 22:28:58the road map of the projects. The next
  36361. 22:29:00thing that I find myself using shajbt is
  36362. 22:29:02for learning knowledge and research. If
  36363. 22:29:04you are working with big data projects
  36364. 22:29:06you will be overwhelmed with the amount
  36365. 22:29:08of cloud services and AI analytics
  36366. 22:29:11tools. So and of course you can go and
  36367. 22:29:13learn new stuff gather informations and
  36368. 22:29:15knowledge using shajibb. Okay, moving on
  36369. 22:29:18to the next task. We have generating
  36370. 22:29:19documentations. Writing documentations
  36371. 22:29:21is always painful process and consumes a
  36372. 22:29:24lot of time and I tend to use tools like
  36373. 22:29:26shibbit in order to generate those
  36374. 22:29:28documentations. But of course, I always
  36375. 22:29:30review the documentations and make it
  36376. 22:29:32short. Okay, moving on to another topic
  36377. 22:29:34where I use shadet is that to discuss
  36378. 22:29:36architecture. Of course, if you are
  36379. 22:29:37starting new projects, they will be like
  36380. 22:29:39different types of architecture in order
  36381. 22:29:41to implement the projects. And of
  36382. 22:29:43course, you can discuss with the
  36383. 22:29:44shajibility about the different types of
  36384. 22:29:46architecture and if you give the
  36385. 22:29:47specifications about your projects then
  36386. 22:29:49you can discuss with the shajibility
  36387. 22:29:51which architecture is suitable for the
  36388. 22:29:53project. And another task that I find
  36389. 22:29:55myself always like researching is
  36390. 22:29:58exploring the best practices, tips and
  36391. 22:30:00tricks. So you can have a discussion
  36392. 22:30:01with the SHP about the recommendations,
  36393. 22:30:04what are the best practices, what are
  36394. 22:30:06the common pitfalls in order to make
  36395. 22:30:08sure that your code and your solution is
  36396. 22:30:10always up to date with the best
  36397. 22:30:12practices. And one more thing, if
  36398. 22:30:14there's like in the projects a very
  36399. 22:30:16complex task, then I tend to have a
  36400. 22:30:18discussion with a tool like Shajibet in
  36401. 22:30:20order to break this complex task into
  36402. 22:30:22small pieces and start finding the
  36403. 22:30:24solution for each piece. And now in the
  36404. 22:30:26other hand, I'm using copilot in order
  36405. 22:30:28to solve different type of tasks. So
  36406. 22:30:30here where I get my hand dirty in the
  36407. 22:30:32code. So while I'm coding I'm using
  36408. 22:30:34alltime co-pilot in order to assist me
  36409. 22:30:37because it provide directly inline
  36410. 22:30:39suggestions and help me to code faster
  36411. 22:30:41and reduce the human error that I might
  36412. 22:30:43make. So while I'm writing a code or
  36413. 22:30:45debugging I tend to use copilot and I
  36414. 22:30:48don't find myself going to shy GBT to
  36415. 22:30:50ask about code or syntax. We can do it
  36416. 22:30:53directly in the copilot. And one task
  36417. 22:30:55that is very famous in any software
  36418. 22:30:57developments we have the refactoring. So
  36419. 22:30:59if you have like a code that is slow and
  36420. 22:31:01bad designs and you want to refactor the
  36421. 22:31:03whole codes, you can do it directly in
  36422. 22:31:05your code together with the copilot in
  36423. 22:31:06order to find optimizations. And I use
  36424. 22:31:09as well copilot in order to add inline
  36425. 22:31:11comments. So I don't find myself going
  36426. 22:31:13to ship and asking to add comments to my
  36427. 22:31:15codes. You can do it directly in your
  36428. 22:31:18code using cilot. And of course if
  36429. 22:31:20everything is working perfectly, I have
  36430. 22:31:22the best practices, the good
  36431. 22:31:23performance, I have the comments, it's
  36432. 22:31:24still you have to maintain nice style
  36433. 22:31:26and format of your code. And of course
  36434. 22:31:28now we can do that directly using the
  36435. 22:31:30copilot. We don't have to go and jump to
  36436. 22:31:31shajbt in order to style and format your
  36437. 22:31:33code. And as you can see I'm currently
  36438. 22:31:35using both of them for different types
  36439. 22:31:37of tasks. So again if I have the feeling
  36440. 22:31:39that I have to discuss something I go to
  36441. 22:31:41shbt. But once the idea is very clear
  36442. 22:31:44and I know the solution then I start
  36443. 22:31:47using copilot in order to write the code
  36444. 22:31:49and with the help of the copilot I can
  36445. 22:31:52deliver clean and professional code. So
  36446. 22:31:54this is how I currently use both
  36447. 22:31:56Shajbuty and
  36448. 22:32:01Copilot. Okay friends, so now what we're
  36449. 22:32:03going to do, I'm going to show you a
  36450. 22:32:04quick guide about the GitHub copilot in
  36451. 22:32:07the Visual Studio Code. Once you create
  36452. 22:32:09a profile and connect it to your Visual
  36453. 22:32:11Studio, you will get a new icon for the
  36454. 22:32:13copilot. So once you go there, you can
  36455. 22:32:15see quickly the status and as well you
  36456. 22:32:18can go and disable the copilot. So if
  36457. 22:32:20you have it like this, that's means your
  36458. 22:32:22co-pilot is active. So now once you have
  36459. 22:32:24everything up and running, what you have
  36460. 22:32:26to do is very simple. Just go and start
  36461. 22:32:28writing your code. So start typing any
  36462. 22:32:31select statements. And now you can see
  36463. 22:32:33that we have a gray text. This gray text
  36464. 22:32:36called the ghost text. It is an auto
  36465. 22:32:38completion from the copilot. And now it
  36466. 22:32:40says select star from table. And now as
  36467. 22:32:43you can see as I mouse hover on it, we
  36468. 22:32:46can see that I can go and switch between
  36469. 22:32:48different suggestions. So here we have
  36470. 22:32:50like three suggestions. One, two, three.
  36471. 22:32:52And I'm going to go with the third one.
  36472. 22:32:54So now here as it says if you want to
  36473. 22:32:56accept the suggestion all what you have
  36474. 22:32:58to do is to press tab. So let's go and
  36475. 22:33:00do it. So you are accepting the whole
  36476. 22:33:02thing. But now if you say you know what
  36477. 22:33:04I'm going to accept only part of the
  36478. 22:33:06code. So let's go again and write
  36479. 22:33:08select. So this time we're going to be
  36480. 22:33:10selective. In order to do that hold
  36481. 22:33:12control and then with the right arrow
  36482. 22:33:14and with that we are accepting part of
  36483. 22:33:17the ghost not everything. But of course
  36484. 22:33:19if you are accepting the whole thing
  36485. 22:33:20just go with the tab. And now there is
  36486. 22:33:22another way in order to trigger the
  36487. 22:33:24ghost text and that's by defining first
  36488. 22:33:27a comments. For example we want to
  36489. 22:33:28select the top three customers based on
  36490. 22:33:30the score. So now once you start writing
  36491. 22:33:32the query the co-pilot going to go and
  36492. 22:33:34write a query that is relevant for the
  36493. 22:33:37comments. So now as you can see we are
  36494. 22:33:38getting top three from customers because
  36495. 22:33:41we want the top three customers and here
  36496. 22:33:42we have like two suggestions like over
  36497. 22:33:45here we have the order buy or without
  36498. 22:33:46it. So I will go with order by and hit a
  36499. 22:33:48tap. And now here another suggestion
  36500. 22:33:50which is correct. In order to solve the
  36501. 22:33:51data from the highest to the lowest. All
  36502. 22:33:53right moving on to the next one. As we
  36503. 22:33:55learned in SQL in order to solve a task
  36504. 22:33:58there could be like multiple solutions
  36505. 22:34:00and multiple variants of queries that
  36506. 22:34:02solving the same task. So let's say that
  36507. 22:34:04we have this task rank customers based
  36508. 22:34:06on their total order sales. So what you
  36509. 22:34:08can do if you start writing the query we
  36510. 22:34:10are getting now the ghost text. But now
  36511. 22:34:12what we can do we can go and hit ct
  36512. 22:34:13controll enter. So now what happens on
  36513. 22:34:15the right side you will get different
  36514. 22:34:17suggestions and here we have like nine
  36515. 22:34:19suggestions on how to solve this task in
  36516. 22:34:21scale. So now what you have to do is to
  36517. 22:34:23go through all those suggestions and
  36518. 22:34:25pick one. For example I can go with the
  36519. 22:34:27suggestion number three and say accept
  36520. 22:34:29suggestion and you will get it in your
  36521. 22:34:31code editor. So this is what we mean
  36522. 22:34:32with the copilot autocomp completion and
  36523. 22:34:35integrating the AI directly as you are
  36524. 22:34:38developing and writing a code. Now in
  36525. 22:34:39the co-pilot, not only using the ghost
  36526. 22:34:41text and the autoco compilation, we can
  36527. 22:34:43go and interact with the AI using inline
  36528. 22:34:46shots. So it's something like shimity.
  36529. 22:34:48Now in order to trigger the shot, what
  36530. 22:34:50you're going to do, you're going to go
  36531. 22:34:51and hit control I and then you're going
  36532. 22:34:53to get a place in order to ask the
  36533. 22:34:55copilot any question like for example
  36534. 22:34:57join the query with the
  36535. 22:35:00table sales orders. So let's go and hit
  36536. 22:35:04it.
  36537. 22:35:06And now as you can see we got a full
  36538. 22:35:08query where the customers is joined with
  36539. 22:35:10the orders and it is totally correct how
  36540. 22:35:13the table are joins. So that means
  36541. 22:35:14copilot knows already all the tables
  36542. 22:35:17that I have in the database and as well
  36543. 22:35:20the columns and how to join them. This
  36544. 22:35:22is amazing. So if you like it you go and
  36545. 22:35:24accept it of course and this is way
  36546. 22:35:26faster than having shajibbd because in
  36547. 22:35:28shajibity you have to introduce your
  36548. 22:35:30database your columns and stuff before
  36549. 22:35:32even asking anything. This is exactly
  36550. 22:35:35the power of copilot. Now what else we
  36551. 22:35:38can do with that? We can go and
  36552. 22:35:39highlight part of our codes and then
  36553. 22:35:41start again the shots and here we can
  36554. 22:35:43say replace this column with an
  36555. 22:35:46aggregation of the sales. So let's go
  36556. 22:35:50and hit okay. Now as you can see it
  36557. 22:35:52replaced it with an aggregate function.
  36558. 22:35:53And one thing that is very important the
  36559. 22:35:55code is not changed yet. So it is
  36560. 22:35:58highlighted and showing you a suggestion
  36561. 22:36:00and now you have to accept it or discard
  36562. 22:36:02it. If you discard, nothing going to
  36563. 22:36:04change in your codes. But once you say
  36564. 22:36:06accept, it's going to go and replace
  36565. 22:36:07your original codes. So if you go and do
  36566. 22:36:10that, now your code is replaced with the
  36567. 22:36:12AI suggestion. Okay. Another thing about
  36568. 22:36:14the copilot, it's try to fix issues that
  36569. 22:36:17you have in your codes. So for example,
  36570. 22:36:19we have here an error. If you go and
  36571. 22:36:20mouse hover it, you can see a menu from
  36572. 22:36:22the copilot in order to view the error
  36573. 22:36:24or to fix it. And another way to do
  36574. 22:36:26that, if you right click on it, you go
  36575. 22:36:28to the copilot. And here you can see we
  36576. 22:36:30can explain or fix. So if you go and
  36577. 22:36:33explain, you will get another window
  36578. 22:36:34where you get an explanation about the
  36579. 22:36:36issue in your code. And once you
  36580. 22:36:38understand it, you can go and ask the
  36581. 22:36:39copilot in order to fix it. So let's go
  36582. 22:36:42over here and go to
  36583. 22:36:44fix. And with that, the copilot did fix
  36584. 22:36:46the issue. It was all about the order of
  36585. 22:36:49the select statements. So first you have
  36586. 22:36:50to do the group by then order by. So it
  36587. 22:36:52helps you to find issues and to fix it
  36588. 22:36:54as well. And now, as you might already
  36589. 22:36:56noticed, as we are writing the code and
  36590. 22:36:58interacting with the Visual Studio, you
  36591. 22:37:00will often get a sparkle, this little
  36592. 22:37:03yellow sparkle on the left side. So, you
  36593. 22:37:05will see this icon each time the copilot
  36594. 22:37:07thinks it can help. So, if you go and
  36595. 22:37:09click on it, you will get a menu of
  36596. 22:37:11different stuff that the copilot can do
  36597. 22:37:13for you, like fixing, explaining,
  36598. 22:37:15modifying, and so on. Well, my friends,
  36599. 22:37:17that's it. This is the copilot, and it
  36600. 22:37:19is very simple, but yet very powerful
  36601. 22:37:22for developers. And of course, not only
  36602. 22:37:24for SQL, for anything like for Python
  36603. 22:37:26and so on. Everything is integrated in
  36604. 22:37:28one place. I don't have to jump to
  36605. 22:37:29Shajibbet and ask stuff. It is live and
  36606. 22:37:32I can do it directly as I'm writing my
  36607. 22:37:34code. So that's all for Copilot. All
  36608. 22:37:36right friends. So now let's switch to
  36609. 22:37:38Shajibet. So let's start first by
  36610. 22:37:40understanding the structure and the
  36611. 22:37:42basic components of Shajbet prompts.
  36612. 22:37:49So the first component and the most
  36613. 22:37:50important one we have the tasks. You
  36614. 22:37:53have to be very clear by defining what
  36615. 22:37:55the AI should do and without having a
  36616. 22:37:57clear tasks the AI will not understand
  36617. 22:38:00what to do. So this is mandatory in each
  36618. 22:38:03prompt and then after that you have to
  36619. 22:38:05provide some context. So you give some
  36620. 22:38:07background informations like for example
  36621. 22:38:09you say I am students or I am a data
  36622. 22:38:11engineer and so on. And another
  36623. 22:38:13components we have to add
  36624. 22:38:15specifications. So in the task you give
  36625. 22:38:17the main task what the AI should do but
  36626. 22:38:20with the specifications you go in
  36627. 22:38:22details like for example which topic
  36628. 22:38:24should be added or maybe excluded the
  36629. 22:38:26number of word counts. So here you are
  36630. 22:38:29specifying a lot of wishes and small
  36631. 22:38:31details and specifications in order to
  36632. 22:38:33get an answer that meet your
  36633. 22:38:35expectations. So both of the context and
  36634. 22:38:37specifications they are important. And
  36635. 22:38:39then after that we have some nice to
  36636. 22:38:41have components like for example
  36637. 22:38:43specifying a rule. So here you give the
  36638. 22:38:45AI a role like for example you tell it
  36639. 22:38:48to act as an expert as a teacher
  36640. 22:38:51interviewer. So you are setting the AI
  36641. 22:38:53to play a role and the last component
  36642. 22:38:56that you can add as as well the tone.
  36643. 22:38:58Here you are defining like the voice of
  36644. 22:39:00the answer in order just to make the
  36645. 22:39:02answer like more friendly and easy to
  36646. 22:39:04read and engaging. So the role and the
  36647. 22:39:06tone they are nice to have and if you go
  36648. 22:39:08and use all those components you will
  36649. 22:39:10get a better results from the AI. So
  36650. 22:39:13let's take for example the following
  36651. 22:39:15prompts explain SQL window functions. So
  36652. 22:39:18this is very simple and very short and
  36653. 22:39:20here we have only one component the
  36654. 22:39:22task. So here you are not giving any
  36655. 22:39:24context whether it is for data analytics
  36656. 22:39:27or for data engineering. So you leave it
  36657. 22:39:29up to the AI and maybe the answer that
  36658. 22:39:31you will get will not meet the
  36659. 22:39:33expectation that you have. And now if
  36660. 22:39:35you want to shape it in the way that you
  36661. 22:39:37want you have to add more components
  36662. 22:39:39like for example this prompt you are
  36663. 22:39:40saying you are a senior SQL expert. So
  36664. 22:39:43here we are defining the rule for the
  36665. 22:39:46AI. So the AI should act now as an SQL
  36666. 22:39:49expert. And then the next section we are
  36667. 22:39:51adding a context to the prompts. So we
  36668. 22:39:53are saying I'm data analyst working on
  36669. 22:39:55SQL projects using SQL server. So now
  36670. 22:39:58the answer that you will get from the AI
  36671. 22:40:00going to use the syntax of the SQL
  36672. 22:40:02server and focus on the topic of
  36673. 22:40:03analytics. That's why the context is
  36674. 22:40:05very important and then we go specify in
  36675. 22:40:08the prompt the task the main task. So we
  36676. 22:40:10say explain the concept of SQL window
  36677. 22:40:12functions and do the following. And now
  36678. 22:40:14we go and give more fine details about
  36679. 22:40:17what the AI should provide. We are
  36680. 22:40:19saying explain each window function and
  36681. 22:40:22show the syntax. describe why they are
  36682. 22:40:24important and when to use them and list
  36683. 22:40:26the top three use cases. So you are now
  36684. 22:40:29specifying what you are expecting from
  36685. 22:40:31the AI and after that of course it is
  36686. 22:40:33nice to have we specify the tone of the
  36687. 22:40:36explanation. So we say the tone should
  36688. 22:40:38be conversational and direct as if you
  36689. 22:40:41are speaking to me onetoone so that it
  36690. 22:40:43is not like you are reading a document
  36691. 22:40:45you are reading something that is
  36692. 22:40:47engaging. So I know this prompt is
  36693. 22:40:49really big but still you will get way
  36694. 22:40:51better results than only saying explain
  36695. 22:40:54the concepts. So those are the main
  36696. 22:40:56components that I usually use if I'm
  36697. 22:40:58starting like a conversation and a
  36698. 22:41:00discussion with the
  36699. 22:41:05shajuti. Okay. Next I'm going to show
  36700. 22:41:07you the frequently used prompts that I
  36701. 22:41:09use in my projects. Now little bit
  36702. 22:41:11awareness about using shajib in
  36703. 22:41:13companies. If you are working in new
  36704. 22:41:15company, make sure to ask about the
  36705. 22:41:17rules of using Shia Gibbt because some
  36706. 22:41:19companies offer their own chatbots for
  36707. 22:41:22few security reasons. So make sure
  36708. 22:41:24always to check with the rules before
  36709. 22:41:26jumping immediately to sht. All right.
  36710. 22:41:28So let's start with the first prompts.
  36711. 22:41:30We can use shad in order to solve an SQL
  36712. 22:41:33task that you have in the project. So
  36713. 22:41:35let's see this prompts. It start first
  36714. 22:41:37with the context. So I'm telling that I
  36715. 22:41:40have an SQL server database and we have
  36716. 22:41:42like two tables. So now I have to
  36717. 22:41:44explain for shad the database that I
  36718. 22:41:46have. So I'm saying we have a table
  36719. 22:41:48called orders and we have the following
  36720. 22:41:50columns and we have another table called
  36721. 22:41:52customers and here are the columns for
  36722. 22:41:53the customers. So that I gave shy a
  36723. 22:41:56context about the tables that I have in
  36724. 22:41:58my database and as well I was precise
  36725. 22:42:01about the database. It is SQL server.
  36726. 22:42:03Now after we have the context the next
  36727. 22:42:05step is that I'm going to tell SQL what
  36728. 22:42:07to do. So I'm telling the AI do the
  36729. 22:42:09following. write a query to rank
  36730. 22:42:11customers based on their sales and then
  36731. 22:42:13I'm detailing what I'm expecting to have
  36732. 22:42:15at the output. So the result should
  36733. 22:42:17include customer ID, full name, country,
  36734. 22:42:19total sales and so on. And here I'm
  36735. 22:42:21adding like more tasks. It's not enough
  36736. 22:42:23to have a query. I would like as well to
  36737. 22:42:24have a comments. So I'm saying include
  36738. 22:42:27comments but avoid commenting on obvious
  36739. 22:42:29parts because if you tell just include
  36740. 22:42:32comments, you will get a lot of
  36741. 22:42:34unnecessary comments. Now of course in
  36742. 22:42:36square there is like not one solution
  36743. 22:42:37for a task. there is always like
  36744. 22:42:40different variants on how to achieve the
  36745. 22:42:42same task. So usually I would like to
  36746. 22:42:44understand what are my options. That's
  36747. 22:42:45why I'm telling Shaji write three
  36748. 22:42:48different versions of the query to
  36749. 22:42:50achieve this task and then I would like
  36750. 22:42:51to evaluate each of those versions and
  36751. 22:42:54that's why I'm giving the task for the
  36752. 22:42:55AI to evaluate those versions and to
  36753. 22:42:58focus on two things. It is easy to read
  36754. 22:43:00and as well has good performance. Okay.
  36755. 22:43:03So let's see what shajivity going to
  36756. 22:43:04give us the results. So we can see the
  36757. 22:43:06first solution over here where shadivity
  36758. 22:43:08is using the CTE. So we can see in the
  36759. 22:43:11CT over here that the table first are
  36760. 22:43:13joined and then we have like a group by
  36761. 22:43:15in order to aggregate the sales. In the
  36762. 22:43:18step two we can see over here we have
  36763. 22:43:20the rank window function in order to
  36764. 22:43:22rank the sales. So of course you can do
  36765. 22:43:24that. Let's check the version number two
  36766. 22:43:27over here. So they I used the subquery
  36767. 22:43:30and it is as well a nice solution where
  36768. 22:43:33the shad first prepared the data. So
  36769. 22:43:36first done the aggregation before
  36770. 22:43:38joining the data. Let's get the last
  36771. 22:43:40solution over here. So we have here
  36772. 22:43:42single query using window function which
  36773. 22:43:45is as you can see it is the smallest
  36774. 22:43:47one. We don't have CTE we don't have any
  36775. 22:43:49sub queries. So first it is joining the
  36776. 22:43:52tables and doing together the group by
  36777. 22:43:54together with the window function and
  36778. 22:43:56after that we get an evaluation from the
  36779. 22:43:59AI where where as you can see it focus
  36780. 22:44:01on two things the readability and the
  36781. 22:44:03performance. So it is saying with the
  36782. 22:44:05CTE the readability is really high
  36783. 22:44:08compared to the sub query and to the
  36784. 22:44:10last version where you have the group by
  36785. 22:44:12together with the window function. So I
  36786. 22:44:13totally agree with the shajibbity the
  36787. 22:44:15first version was the best one for the
  36788. 22:44:17readability. Now checking the
  36789. 22:44:18performance. You can see the performance
  36790. 22:44:20is moderate. The second one, the
  36791. 22:44:22subquery is good. And the last one is
  36792. 22:44:25the best for the performance. But of
  36793. 22:44:27course, always test with the execution
  36794. 22:44:28plan. So as you can see, there is like a
  36795. 22:44:30trade-off between the readability and
  36796. 22:44:32the performance. If the priority is
  36797. 22:44:34readability, then go with the version
  36798. 22:44:35one. But if the priority is the
  36799. 22:44:37performance, then go with the version
  36800. 22:44:39three. As you can see, we got three
  36801. 22:44:41solutions for our one task. And you can
  36802. 22:44:43now evaluate which one you want to use.
  36803. 22:44:46And this is really amazing, right? All
  36804. 22:44:48right, moving on to the next one that I
  36805. 22:44:49frequently use. We have
  36806. 22:44:52impromptability. As you are creating an
  36807. 22:44:54SQL query for a complex task, you might
  36808. 22:44:57end up writing a lot of CTE, sub
  36809. 22:44:59queries. You might end up having a lot
  36810. 22:45:01of joins, sub queries, CTE, hundreds of
  36811. 22:45:05lines, and you might lose the big
  36812. 22:45:07picture. So what I always do, I give the
  36813. 22:45:09query to the SHBT and ask it to optimize
  36814. 22:45:12it in order to be more readable and to
  36815. 22:45:14find any redundancy in my query in order
  36816. 22:45:17to consolidate it. So now let's check
  36817. 22:45:19the prompt. It says the following SQL
  36818. 22:45:21server query is long and hard to
  36819. 22:45:23understand. And then we're going to give
  36820. 22:45:24the AI tasks. So the first task is to
  36821. 22:45:27improve its readability and the next one
  36822. 22:45:29is to detect any redundancy in the code
  36823. 22:45:32in order to remove it and to consolidate
  36824. 22:45:34the query. So to make our query compact
  36825. 22:45:36and small and of course to include some
  36826. 22:45:38comments and not to comment the obvious
  36827. 22:45:40parts and now always if there is like
  36828. 22:45:42some optimizations there should be a
  36829. 22:45:44learning process. So I'm asking now the
  36830. 22:45:46AI to explain each improvement to
  36831. 22:45:49understand the reasons behind it so that
  36832. 22:45:51next time I'm writing the queries I can
  36833. 22:45:53avoid those mistakes and of course you
  36834. 22:45:55have to go and give the query to the AI.
  36835. 22:45:57All right. So now let's check the answer
  36836. 22:45:59from the ship for my prompt. So as you
  36837. 22:46:02can see we have a really long query and
  36838. 22:46:04here we have now from the result the
  36839. 22:46:06improved query. So we can see that we
  36840. 22:46:09have only one city. Well that is crazy.
  36841. 22:46:12We had before like five six cities and
  36842. 22:46:14we can see here that the team managed to
  36843. 22:46:17put everything in one city and then do
  36844. 22:46:20all the aggregations and the window
  36845. 22:46:21function and then we have here the final
  36846. 22:46:24select. Well this is huge improvement to
  36847. 22:46:26the previous query. Let's check here the
  36848. 22:46:28explanation. So it says it consolidated
  36849. 22:46:30the cities so combined all the cities
  36850. 22:46:33into one and many other stuff like there
  36851. 22:46:36were a lot of unnecessary joins and so
  36852. 22:46:38on. And here a small improvement where
  36853. 22:46:40it uses the concat instead of the plus
  36854. 22:46:43because concat is standards for multiple
  36855. 22:46:46databases. And here we have a final
  36856. 22:46:48benefits. So we have shorter query
  36857. 22:46:50instead of five CDs we have only one and
  36858. 22:46:53combining the logic you can reduce the
  36859. 22:46:55number of scans of the tables which is
  36860. 22:46:57correct. So as you can see it is the
  36861. 22:46:59magic of the AI. It found the issues in
  36862. 22:47:01my code, improved the readability and
  36863. 22:47:03reduced all the redundancy and
  36864. 22:47:05unnecessary joints and so on in the SQL
  36865. 22:47:08script. Okay, moving on to the next
  36866. 22:47:10prompt. It is about optimizing the
  36867. 22:47:12performance of my query. And if you are
  36868. 22:47:14working in big projects where you have
  36869. 22:47:16like millions of data in your tables, it
  36870. 22:47:18can be an issue if you are writing
  36871. 22:47:19queries that are not following the best
  36872. 22:47:21practices for performance. So that's why
  36873. 22:47:24I go and double check with the AI
  36874. 22:47:26whether my script is following the best
  36875. 22:47:28practices for the performance. So as
  36876. 22:47:30usual in the prompt we have to go and
  36877. 22:47:31give the context. So the following SQL
  36878. 22:47:34server query is slow and then we start
  36879. 22:47:36giving the AI some tasks. So propose
  36880. 22:47:38optimizations to improve its performance
  36881. 22:47:40and provide me then the improved SQL
  36882. 22:47:43query and I would like always to
  36883. 22:47:45understand the reason why it's better to
  36884. 22:47:47write it in another way so that by the
  36885. 22:47:49next time I improve while I'm writing
  36886. 22:47:51the query. So explain each improvement
  36887. 22:47:54to understand the reasoning behind it
  36888. 22:47:56and then at the end we go and give our
  36889. 22:47:58query. Okay. So now let's write the
  36890. 22:48:00prompts on the following query over
  36891. 22:48:02here. So on this query we have a lot of
  36892. 22:48:04bad practices like for example doing
  36893. 22:48:06aggregations using correlated subquery.
  36894. 22:48:09We are using a lot of functions inside
  36895. 22:48:11the work clause which is not really good
  36896. 22:48:13for indexing and we are using a lot of
  36897. 22:48:15or operators and here we have again a
  36898. 22:48:18subquery. So let's check whether shad
  36899. 22:48:20going to find all those bad practices.
  36900. 22:48:23So let's check the results from the
  36901. 22:48:24shad. And as you can see now we have an
  36902. 22:48:26optimized query. It is little bit longer
  36903. 22:48:29but I think we have here better
  36904. 22:48:30practices. So we have here a lot of
  36905. 22:48:32changes. Let's check what did. So first
  36906. 22:48:35it replaced the lower in the query. It
  36907. 22:48:37says it's not really good to use
  36908. 22:48:39functions in the works so that the index
  36909. 22:48:43can work. So it replaced the lower with
  36910. 22:48:46the order status without the function.
  36911. 22:48:48the next one. So it is avoiding the
  36912. 22:48:50correlated subquery. So instead of that
  36913. 22:48:53it is using a lift join. So it is
  36914. 22:48:55joining the table normally without doing
  36915. 22:48:57any correlated queries and as well it is
  36916. 22:49:00avoiding the function year in the works
  36917. 22:49:02and instead of that it is using the
  36918. 22:49:04range using between and the next one it
  36919. 22:49:07is using exist better than in which is
  36920. 22:49:09better for the performance of course. So
  36921. 22:49:11as you can see you can use the AI in
  36922. 22:49:13order to optimize the performance of
  36923. 22:49:14your query and to convert it to a script
  36924. 22:49:17that is following the best practices. Of
  36925. 22:49:20course my recommendations always don't
  36926. 22:49:22go blindly with all changes that is
  36927. 22:49:24suggested from the shajibity. Always
  36928. 22:49:26take each recommendation one by one.
  36929. 22:49:28Test it and evaluate it using your
  36930. 22:49:30knowledge. Okay to the next one. It is
  36931. 22:49:32interesting one. We can use
  36932. 22:49:35[Music]
  36933. 22:49:37impromptution plan. So now the execution
  36934. 22:49:39plans usually are advanced. So you need
  36935. 22:49:42a lot of knowhow and experience in order
  36936. 22:49:44to understand and read the execution
  36937. 22:49:46plan and if you have a big query it's
  36938. 22:49:48going to be really nightmare in order to
  36939. 22:49:50understand the flow and where is exactly
  36940. 22:49:52the issue. But now we are not alone. We
  36941. 22:49:54have assistant the AI in order to help
  36942. 22:49:57us understanding this complex stuff. So
  36943. 22:49:59what we can do we can take a screenshot
  36944. 22:50:01of the execution plan and upload it to
  36945. 22:50:03Shajib and we say the image is execution
  36946. 22:50:06plan of SQL server query and now we give
  36947. 22:50:09the following task to say describe the
  36948. 22:50:11execution plan step by step after that
  36949. 22:50:13I'm going to tell SQL to identify the
  36950. 22:50:15performance bottlenecks and where is
  36951. 22:50:17exactly the issue what makes my query
  36952. 22:50:20slow this is of course the hardest part
  36953. 22:50:22of reading an execution plan and once it
  36954. 22:50:25identify the performance issues I'm
  36955. 22:50:27going to ask it to suggest ways to
  36956. 22:50:28improve improve the performance and
  36957. 22:50:30optimize the execution plan. So first
  36958. 22:50:33understand the execution plan identify
  36959. 22:50:35the issues and how to optimize it. Okay.
  36960. 22:50:37So now after uploading the photo and
  36961. 22:50:39asking the AI we have the following
  36962. 22:50:41results. So now we can see a detailed
  36963. 22:50:44explanation about the execution plan and
  36964. 22:50:46there is like a lot of details. I will
  36965. 22:50:48not go through everything. So we start
  36966. 22:50:50with the table scans then the cluster
  36967. 22:50:52scan and the nested loops. So we have
  36968. 22:50:54several nested loops and then the
  36969. 22:50:56aggregation and the final step. So that
  36970. 22:50:58now we have like a nice explanation what
  36971. 22:51:00is SQL is doing behind the scenes for my
  36972. 22:51:03query and you don't have to be an expert
  36973. 22:51:05understanding the execution plan. You
  36974. 22:51:07can ask the AI about it. Now what is
  36975. 22:51:09very important is to understand where
  36976. 22:51:11are the bottlenecks what are the
  36977. 22:51:13problems. So let's see what's we have
  36978. 22:51:15here. So let's say the first one we have
  36979. 22:51:17a table scan which is really bad. That
  36980. 22:51:19means this table the orders archive does
  36981. 22:51:22not has any index. So it says the table
  36982. 22:51:24scan indicates a lake of useful index on
  36983. 22:51:26the table which forces the engine to
  36984. 22:51:28scan the whole table or rows. And now
  36985. 22:51:31what is very important is the nested
  36986. 22:51:33loops in the joins. This is really bad
  36987. 22:51:36if you have big tables. So here it's
  36988. 22:51:38saying it's fine if you have like small
  36989. 22:51:40data sets but it going to be really
  36990. 22:51:42problematic if you have many rows. So as
  36991. 22:51:45you can see we are getting more
  36992. 22:51:46knowledge about the issues that we have
  36993. 22:51:48from our execution plan. And the last
  36994. 22:51:50step it is the suggestions. So the first
  36995. 22:51:53one and the most obvious one is to add
  36996. 22:51:55an index to the orders archive. The
  36997. 22:51:57nonclustered index. Well, if there's no
  36998. 22:51:59index at all, I would go first with a
  36999. 22:52:01clustered index, not immediately with a
  37000. 22:52:03nonclustered index. And then some other
  37001. 22:52:05best practices, but I think this one is
  37002. 22:52:08very relevant is to change the join
  37003. 22:52:10type. So you can use the hints in order
  37004. 22:52:12to use a merge join or a hash join. So
  37005. 22:52:15now we understand how it works, where
  37006. 22:52:17are the issues and what the suggestions
  37007. 22:52:19to fix it. All right, the next prompt is
  37008. 22:52:21about debugging. As you are writing a
  37009. 22:52:23complex SQL query, you might get from
  37010. 22:52:25the database an error when you execute
  37011. 22:52:27it and sometimes it is challenging to
  37012. 22:52:30find the root cause of the issue. So we
  37013. 22:52:32have the following prompts. First the
  37014. 22:52:33context is going to say the following
  37015. 22:52:35SQL server query causing this error.
  37016. 22:52:38Then we can paste the error message that
  37017. 22:52:40we are getting and then we ask the AI to
  37018. 22:52:42do the following stuff. First explain
  37019. 22:52:44the error message. So I would like to
  37020. 22:52:45have better understanding of the error.
  37021. 22:52:47And then we ask the AI to find the root
  37022. 22:52:50cause of the issue from my scripts. And
  37023. 22:52:52after finding the problem and the issue,
  37024. 22:52:54we're going to ask the AI to suggest how
  37025. 22:52:56to fix it. And of course, we have to
  37026. 22:52:58give in the prompt as well our SQL
  37027. 22:53:00query. All right. So now I have the
  37028. 22:53:02following query and if I execute it, I'm
  37029. 22:53:04getting the following error. It says the
  37030. 22:53:06column sales.order dot sales in invalid
  37031. 22:53:10in the select list because it is not
  37032. 22:53:12contained in the aggregations and so on.
  37033. 22:53:14So I'm not really understanding what's
  37034. 22:53:15going on. Let's ask the AI about it. So
  37035. 22:53:18let's check what shity did answer. When
  37036. 22:53:20you are using group by every column in
  37037. 22:53:22the select must be used in the group by
  37038. 22:53:25as well. And it says in your query you
  37039. 22:53:27are selecting few columns which is this
  37040. 22:53:29one is valid. The other two as well
  37041. 22:53:31valid but we have one inside the rank
  37042. 22:53:34function. It is invalid. Okay. So now we
  37043. 22:53:37can see here more details about the root
  37044. 22:53:39cause. It is saying when you are using
  37045. 22:53:41window function like the rank it doesn't
  37046. 22:53:43directly work with the aggregate
  37047. 22:53:45functions. So here it's indicate clearly
  37048. 22:53:47that the sales inside the rank function
  37049. 22:53:50is the issue. So let's see the fix over
  37050. 22:53:53here. So since we don't have here sales
  37051. 22:53:55at all you cannot have here sales in the
  37052. 22:53:57partition. That's why the fix here is to
  37053. 22:54:00use the sum of sales because we have it
  37054. 22:54:02in the select. And here you have as well
  37055. 22:54:04a nice explanation about the fix. So you
  37056. 22:54:07can see here we have an explanation
  37057. 22:54:09about the error message the road cause
  37058. 22:54:11it's pointing exactly where there's the
  37059. 22:54:13issue suggesting a fix and explaining
  37060. 22:54:16the fix and this is exactly the steps
  37061. 22:54:18that you have to do if you are debugging
  37062. 22:54:20a code all right moving on to the next
  37063. 22:54:22prompt we can use AI to explain the
  37064. 22:54:24result that I'm getting from SQL well
  37065. 22:54:26sometimes you might have an SQL query
  37066. 22:54:29that you have in the project and you are
  37067. 22:54:30not understanding why you are getting
  37068. 22:54:32specific results so as usual we start
  37069. 22:54:34with the context we tell the AI I didn't
  37070. 22:54:37understand the result of the following
  37071. 22:54:38SQL server query and then we ask the AI
  37072. 22:54:41to do the following. First break down
  37073. 22:54:43how SQL processes the query step by step
  37074. 22:54:47and as well I would like to get an
  37075. 22:54:48explanation for each stage and how the
  37076. 22:54:51result is formed. So as you can see here
  37077. 22:54:53I don't need any optimizations. I don't
  37078. 22:54:55need in the output any query. I just
  37079. 22:54:58need an explanation and then at the end
  37080. 22:55:00you're going to go and paste your query.
  37081. 22:55:02Okay. So now we have the following
  37082. 22:55:03query. We have a recursive CTE where we
  37083. 22:55:05are generating like numbers between 1
  37084. 22:55:08and 20. Can tell you recursive CTE are
  37085. 22:55:10usually like complicated to understand.
  37086. 22:55:13So now maybe we are having hard time
  37087. 22:55:14understanding the result of this query.
  37088. 22:55:16After asking the AI about it, we got the
  37089. 22:55:19explanation first about the query
  37090. 22:55:21structure. So it says you are using the
  37091. 22:55:23CTE with the main query. Well, okay. But
  37092. 22:55:25what is very interesting is to
  37093. 22:55:27understand step by step how SQL executed
  37094. 22:55:30this query. So it tells the step one
  37095. 22:55:32it's going to go and execute the anchor
  37096. 22:55:33query and that's why we will get first
  37097. 22:55:35the one and then the next step the
  37098. 22:55:37recursive query going to be executed for
  37099. 22:55:39the first time. So it is saying okay we
  37100. 22:55:42are adding one to the current value. So
  37101. 22:55:44as you can see 1 + 1 we will get two and
  37102. 22:55:47then in the iteration two we will get 2
  37103. 22:55:49+ 1 3 and it will keep repeating this
  37104. 22:55:53process until we get all the result from
  37105. 22:55:551 to 20. And then as well we have here
  37106. 22:55:57an explanation about the termination of
  37107. 22:55:59the recursive query. So it's saying the
  37108. 22:56:01filter is the way out of the loop. So
  37109. 22:56:04once we reach the 20 it will stop. And
  37110. 22:56:07then a few informations about the main
  37111. 22:56:09query and with that you will get a deep
  37112. 22:56:11knowledge about how works and why you
  37113. 22:56:14are seeing those results. This is really
  37114. 22:56:16amazing use case for the GBT. All right
  37115. 22:56:19friends. So now we're going to talk
  37116. 22:56:20about my favorite prompts. So we can use
  37117. 22:56:23the AI to style and format my code. So
  37118. 22:56:26now once you are done writing a complex
  37119. 22:56:28query to solve a task and everything is
  37120. 22:56:30correct and optimized as well for the
  37121. 22:56:33performance. Now it's time to go and
  37122. 22:56:35review your code in order to style and
  37123. 22:56:37format your script. So we have the
  37124. 22:56:39following prompt. It says the following
  37125. 22:56:41SQL server query is hard to understand.
  37126. 22:56:44So now we ask the AI to do the
  37127. 22:56:45following. Restyle the code to make it
  37128. 22:56:47easier to read. And the next task for AI
  37129. 22:56:50is to align all the columns aliases.
  37130. 22:56:52Sometimes if you are using any tool to
  37131. 22:56:54style and format your code, you will
  37132. 22:56:56find that it is bringing a lot of new
  37133. 22:56:58lines. So I tell he AI, keep it compact,
  37134. 22:57:01do not introduce unnecessary new lines.
  37135. 22:57:04And the last task for the AI is to make
  37136. 22:57:06sure it is following the best practices.
  37137. 22:57:09And of course, what do we need at the
  37138. 22:57:10end? Our query. Okay, so now we have the
  37139. 22:57:12following query. And as you can see, we
  37140. 22:57:15have very annoying query where it is
  37141. 22:57:17really hard to read and that's because
  37142. 22:57:19the format and the styling of the query
  37143. 22:57:21is really bad. I don't want to speak
  37144. 22:57:23about the alignment and so on. But as
  37145. 22:57:25you can see, we have here lower cases,
  37146. 22:57:27we have here uppercase sometimes for the
  37147. 22:57:29keywords. And of course, if you are
  37148. 22:57:31developing and writing codes and you are
  37149. 22:57:32delivering something like this, it is
  37150. 22:57:34really not nice. So let's see how shipy
  37151. 22:57:36can fix it. Okay. So now after executing
  37152. 22:57:38the prompts, as you can see, now my
  37153. 22:57:41query looks way nicer. So first of all
  37154. 22:57:43all the keywords are uppercase and then
  37155. 22:57:46you can see our CTE are really nice to
  37156. 22:57:48read. We have here enough spacing. The
  37157. 22:57:50alignment of everything looks really
  37158. 22:57:52nice and the case is very clear and the
  37159. 22:57:55main query over here is as well easy to
  37160. 22:57:59read. So they done wonderful job styling
  37161. 22:58:01and formatting my code and here you have
  37162. 22:58:03like explanation what did change. So
  37163. 22:58:06first it is saying okay all the keywords
  37164. 22:58:08are capitalized the alignment of the
  37165. 22:58:10aliases and the columns and so on. So
  37166. 22:58:12with that we got a really nice style
  37167. 22:58:14formatted query that we can share with
  37168. 22:58:16others. Okay, moving on to the next one.
  37169. 22:58:19We can use AI in order to generate
  37170. 22:58:21documentations and as well to add
  37171. 22:58:23comments to my code. Creating
  37172. 22:58:25documentations and adding comments to
  37173. 22:58:27code is usually something very annoying
  37174. 22:58:29for the developers. And sadly I see a
  37175. 22:58:32lot of developers that they tend to not
  37176. 22:58:34add any comments or anything to their
  37177. 22:58:36code. And of course, this is really bad
  37178. 22:58:38because you are not thinking about other
  37179. 22:58:40developers that are reading your code.
  37180. 22:58:43No
  37181. 22:58:45god, no god, please no.
  37182. 22:58:50And since this process is annoying and
  37183. 22:58:53takes time, we can use the help of AI to
  37184. 22:58:56improve the speed of creating those
  37185. 22:58:57stuff. So let's check the following
  37186. 22:58:59prompt. It says the following SQL server
  37187. 22:59:01query lakes comments and documentation.
  37188. 22:59:04So we are saying first insert a leading
  37189. 22:59:07comment at the start of the query
  37190. 22:59:08describing its overall purpose. So this
  37191. 22:59:12is what we usually do. We add at the
  37192. 22:59:14start a short description about the
  37193. 22:59:16following code and then it should go and
  37194. 22:59:18add comments only where clarifications
  37195. 22:59:21is necessary and very important it
  37196. 22:59:23should avoid obvious statements. So it's
  37197. 22:59:25like indexing don't over commenting your
  37198. 22:59:28code and usually if you are creating
  37199. 22:59:30query for data analytics it's really
  37200. 22:59:32good to explain the business rules and
  37201. 22:59:34transformations that you are doing
  37202. 22:59:36inside your query and maybe another
  37203. 22:59:38documentations describing how the query
  37204. 22:59:41works. So for now we are asking to add
  37205. 22:59:43comments and documentations and of
  37206. 22:59:44course you have to go and add your
  37207. 22:59:46query. Okay. So now I just used this
  37208. 22:59:48prompt to one of my queries. Let's go
  37209. 22:59:50and check the results. Now the first
  37210. 22:59:52comment is the most important one
  37211. 22:59:54because it gives the overall purpose of
  37212. 22:59:56the whole query. So let's see what it's
  37213. 22:59:58saying. It's saying this query identify
  37214. 23:00:00customers based on their total salaries
  37215. 23:00:02and provide list of customers with their
  37216. 23:00:05total sales and their assigned segments.
  37217. 23:00:08So we have here like customer
  37218. 23:00:09segmentations. We have high value,
  37219. 23:00:11medium value and low value. So with this
  37220. 23:00:13comment we have the overall purpose of
  37221. 23:00:15the query and then we have the inline
  37222. 23:00:18comments like here. So it says it's
  37223. 23:00:20calculate the total sales for each
  37224. 23:00:21customer for the first CTE and now for
  37225. 23:00:23the second CTE we have here a full
  37226. 23:00:25description how the segment is built and
  37227. 23:00:28this is built of course from the
  37228. 23:00:30business rule of the customer segments.
  37229. 23:00:32So it say the high values for total
  37230. 23:00:34sales above like 100 and between and so
  37231. 23:00:37on. Well this case win is really easy.
  37232. 23:00:40So actually you can read it from the
  37233. 23:00:42case win. But if you have like complex
  37234. 23:00:44queries, it's really nice to have the
  37235. 23:00:45full text of the case win and then add
  37236. 23:00:48the main query. You can see here the
  37237. 23:00:50final output and the inline comments. So
  37238. 23:00:53as you can see it's really nice comments
  37239. 23:00:55inside our codes. And now the next one
  37240. 23:00:57we have like a document about the
  37241. 23:00:59business rule. And I totally agree with
  37242. 23:01:01the AI that the business rule is here
  37243. 23:01:03about the customer segmentations. So we
  37244. 23:01:06have here again very nice like short
  37245. 23:01:08documentations about the business rules
  37246. 23:01:10that we have and then we have another
  37247. 23:01:13document about how the query is working.
  37248. 23:01:15Well I think this is too much for small
  37249. 23:01:18query. We can go and ask the shibility
  37250. 23:01:20to make the documentation like shorter.
  37251. 23:01:23So as you can see we have a full
  37252. 23:01:24documentation about our query about our
  37253. 23:01:27business rules and we have really nice
  37254. 23:01:29comments in our code. All right. Now
  37255. 23:01:31moving on to the next prompts. It is
  37256. 23:01:33very important to improve the whole
  37257. 23:01:35project, the whole database. So what
  37258. 23:01:37we're going to do, we're going to go and
  37259. 23:01:38take our DDL scripts and give it to the
  37260. 23:01:41AI and start asking AI to optimize our
  37261. 23:01:44database DDL. So here there is a lot of
  37262. 23:01:47things that you can optimize with the
  37263. 23:01:48database. So let's check this prompts.
  37264. 23:01:50It's going to say the following SQL
  37265. 23:01:52server DDL script has to be optimized
  37266. 23:01:54and we ask the following task from the
  37267. 23:01:56AI. The first one is to check the
  37268. 23:01:58naming. So if you have a database where
  37269. 23:02:00you have a lot of tables and columns and
  37270. 23:02:02so on, you should be always working with
  37271. 23:02:04a specific naming convention. So here
  37272. 23:02:07just to make sure that the naming that
  37273. 23:02:09you are using is correct. Then what is
  37274. 23:02:11very important in DDLs is the data type.
  37275. 23:02:14Data types plays very crucial role in
  37276. 23:02:17optimizing your queries. So we are
  37277. 23:02:19telling the AI to check the data types
  37278. 23:02:21and whether they are optimized as well.
  37279. 23:02:23And now the next point is about the data
  37280. 23:02:26integrity. So if you are building a
  37281. 23:02:27relational database, you will have a lot
  37282. 23:02:29of primary keys and foreign keys and you
  37283. 23:02:31can tell the AI to check the integrity
  37284. 23:02:33of all those keys. The next point is
  37285. 23:02:35about indexes. Here you can tell the AI
  37286. 23:02:38to check the overall indexing that you
  37287. 23:02:40are using in the DDL scripts just to
  37288. 23:02:42make sure that you are not missing
  37289. 23:02:43anything and as well to check whether we
  37290. 23:02:46have duplicates. So it is really great
  37291. 23:02:48check and the last check is that to
  37292. 23:02:50check the normalizations of the table to
  37293. 23:02:52check the data model and whether there
  37294. 23:02:54is like any suggestions about splitting
  37295. 23:02:56tables and normalizing tables or they
  37296. 23:02:59are like some weird redundancy. Okay. So
  37297. 23:03:01now what we're going to do we're going
  37298. 23:03:02to let the chat activity to optimize the
  37299. 23:03:05DDL of the sales DB. So now we have here
  37300. 23:03:07the DDL of the customers employees
  37301. 23:03:09orders and so on. And after running it
  37302. 23:03:12we have the following results. So now we
  37303. 23:03:14have here again the DDL but optimized
  37304. 23:03:16one. And here the AI is adding comment
  37305. 23:03:19about the changes. So here it added the
  37306. 23:03:21auto incremental for the primary key.
  37307. 23:03:23And here for example a check that is not
  37308. 23:03:26a negative score and for the employees.
  37309. 23:03:29Here another check to make sure that the
  37310. 23:03:31birthday is not something in the future.
  37311. 23:03:33So all those constraints in order to
  37312. 23:03:35make sure that the quality of the table
  37313. 23:03:37is good. And here for the gender it is
  37314. 23:03:39restricting the valid values that could
  37315. 23:03:42be used inside this column and many
  37316. 23:03:44other stuff. And at the end we have like
  37317. 23:03:47the key changes. So about the naming
  37318. 23:03:49it's saying that we have to stick with
  37319. 23:03:51one naming convention. So here it did
  37320. 23:03:53understand that we are using the bascal
  37321. 23:03:55case and for those two columns we have
  37322. 23:03:57an issue like for example this product
  37323. 23:03:59it should called product name. And for
  37324. 23:04:01the data types I don't want to go in all
  37325. 23:04:02details. So here for example it says
  37326. 23:04:04don't use the int use a decimal for the
  37327. 23:04:06price and sales for the integrity saying
  37328. 23:04:09go and add foreign keys. I think for the
  37329. 23:04:11orders we don't have any foreign keys
  37330. 23:04:14that is used in the DDL. So the sht did
  37331. 23:04:16go and add all the foreign keys in the
  37332. 23:04:19DDL. So that was good. And now about the
  37333. 23:04:22indexing it says since we have primary
  37334. 23:04:24keys we will get automatically the
  37335. 23:04:26clustered indexing and the foreign keys
  37336. 23:04:28should get as well an index in order to
  37337. 23:04:31improve the queries and so on. So as you
  37338. 23:04:33can see there is a lot of optimizations
  37339. 23:04:35that could be done in our DDL. So now if
  37340. 23:04:38you are working on the project and you
  37341. 23:04:39have a DDL go ask the AI what could we
  37342. 23:04:42optimize I'm sure you will find
  37343. 23:04:44something and this is very critical
  37344. 23:04:46because having a solid and optimized DDL
  37345. 23:04:49improves of course the speed of the
  37346. 23:04:51queries. All right so now we come to
  37347. 23:04:53very useful use case of using AI for
  37348. 23:04:55your SQL projects and that is by using
  37349. 23:04:57AI to generate test data sets. It is
  37350. 23:05:00always really nice to have small data
  37351. 23:05:03sets in order to test the logic of your
  37352. 23:05:05query. Sometimes you are building a
  37353. 23:05:07logic that does not exist yet in your
  37354. 23:05:09database and of course if you are not
  37355. 23:05:11able to test the scenario that you are
  37356. 23:05:13developing it can be really bad and it
  37357. 23:05:15is always very painful process in order
  37358. 23:05:17to generate a data sets for your code
  37359. 23:05:19but of course now it is easier because
  37360. 23:05:21we have the help of AI. So let's check
  37361. 23:05:24the following prompt. It says I need the
  37362. 23:05:26data sets for testing the following SQL
  37363. 23:05:28server DDL. And now next we have to
  37364. 23:05:30specify for the AI different tasks. The
  37365. 23:05:32first one is we have to define the shape
  37366. 23:05:35of the data sets. So how do you want the
  37367. 23:05:37output? Do you want it as an insert
  37368. 23:05:39statements or do you want it as an excel
  37369. 23:05:41or a file and so on. Now the next
  37370. 23:05:43specifications I would like always to
  37371. 23:05:44have a data set that is realistic. So I
  37372. 23:05:47would like to always to have a data set
  37373. 23:05:48that is relevant and realistic not to
  37374. 23:05:51get dummy word data. So again he's like
  37375. 23:05:54only configurations about the data set.
  37376. 23:05:56The next configuration is that I would
  37377. 23:05:58like to have small data sets. Of course,
  37378. 23:05:59you can go and specify for charge the
  37379. 23:06:02exact size of your data sets. You can
  37380. 23:06:04say I would like to have like 100,000
  37381. 23:06:06rows or millions of rows and so on. So
  37382. 23:06:08you can define the size that you want.
  37383. 23:06:10For me, I would like to have like small
  37384. 23:06:12data sets. And now what is very
  37385. 23:06:14important that if you have multiple
  37386. 23:06:16tables in your DDL and those table have
  37387. 23:06:19primary keys and foreign keys, the data
  37388. 23:06:21set should be correct. So the AI should
  37389. 23:06:23generate keys that is joinable. So if
  37390. 23:06:26you go and join data together, you will
  37391. 23:06:28not get weird results. And of course,
  37392. 23:06:30you can go and keep adding
  37393. 23:06:31specifications whether you want to have
  37394. 23:06:33nulls or no nulls inside your data set.
  37395. 23:06:36So here for example, I'm saying don't
  37396. 23:06:38introduce any null values. And of course
  37397. 23:06:40at the end you have to go and give the
  37398. 23:06:41DDL for the AI. It could be one table or
  37399. 23:06:44the whole database. So you could
  37400. 23:06:46generate a data set for one table or
  37401. 23:06:48hundreds of tables. Okay. So now I'm
  37402. 23:06:50asking the SHT to create test data sets
  37403. 23:06:53for two tables. the employees and the
  37404. 23:06:55orders. Let's check the results. So now
  37405. 23:06:58we can see very small nice insert
  37406. 23:07:00statements for the table employees. So
  37407. 23:07:02we have over here like five employees
  37408. 23:07:04with the different informations. And now
  37409. 23:07:06for the table orders we have a lot of
  37410. 23:07:08columns. So as you can see we have four
  37411. 23:07:10orders. And what is very important is
  37412. 23:07:12that the salesperson ID comes from the
  37413. 23:07:15table employees. So as you can see we
  37414. 23:07:16have two and one where we have it
  37415. 23:07:18already in the employees. and the rest
  37416. 23:07:20of the informations we have like here
  37417. 23:07:22fake addresses and stuff. So with that
  37418. 23:07:25we have a very nice test data sets in
  37419. 23:07:27order to be inserted to our database to
  37420. 23:07:29test our queries. Of course we can go
  37421. 23:07:31and ask maybe to extend it maybe instead
  37422. 23:07:33of only four orders we can go with 20
  37423. 23:07:35orders and so on. So we can go and
  37424. 23:07:37change the size of it and here we have
  37425. 23:07:39some notes about the data itself. So it
  37426. 23:07:42is really amazing we are now generating
  37427. 23:07:44this data using our DLS. All right. So
  37428. 23:07:46now we have the following query and of
  37429. 23:07:48course we are using the SQL server and
  37430. 23:07:50let's say that you are migrating from
  37431. 23:07:51SQL server to MySQL. So let's ask
  37432. 23:07:54Shajbet to convert my code to MySQL. All
  37433. 23:07:57right. So after running it as we can see
  37434. 23:07:59now we have the same query but in MySQL.
  37435. 23:08:02So instead of the isnull we are using
  37436. 23:08:04Kawalis and here we are using the
  37437. 23:08:06concatenation instead of the plus
  37438. 23:08:08operator and instead of the get date in
  37439. 23:08:11MySQL we use the now function. And the
  37440. 23:08:13last thing we are using here top 10 but
  37441. 23:08:16in my scale we use limit 10. And here we
  37442. 23:08:19have really nice explanation about the
  37443. 23:08:21transition. So as you can see it is
  37444. 23:08:23amazing and if you are working on
  37445. 23:08:25companies and in projects this might
  37446. 23:08:27happen that there is like decision to
  37447. 23:08:29start migrating from one database to
  37448. 23:08:31another database and then your project
  37449. 23:08:33going to get a big task of migrating the
  37450. 23:08:35data migrating the DDLs and the queries
  37451. 23:08:38and everything and I really recommend
  37452. 23:08:40using the shad in order to help with the
  37453. 23:08:42migration otherwise this big task might
  37454. 23:08:45take really long time. So as you can see
  37455. 23:08:47this is really amazing how shad can
  37456. 23:08:49improve the speed of your
  37457. 23:08:54projects. Okay. Now in the next section
  37458. 23:08:56I'm going to show you the prompts that
  37459. 23:08:58you can use as a student or if you are
  37460. 23:09:00learning any new programming language.
  37461. 23:09:02Okay. So the first thing that you can do
  37462. 23:09:04with Shajibet is that you can ask it to
  37463. 23:09:06generate an SQL course. So you can ask
  37464. 23:09:09the shajibet to guide you step by step
  37465. 23:09:11in your journey learning any programming
  37466. 23:09:14language and you want to do it
  37467. 23:09:15completely onetoone with the AI. So
  37468. 23:09:17first it is very important in creating a
  37469. 23:09:20course is that to give enough context.
  37470. 23:09:22So in this example it is very short I'm
  37471. 23:09:24saying create an SQL course with a
  37472. 23:09:26detailed road map and agenda. But of
  37473. 23:09:29course you can go and give more
  37474. 23:09:31specifications. You can tell about your
  37475. 23:09:33current knowledge. You can specify which
  37476. 23:09:35database type you would like to work
  37477. 23:09:37with MySQL SQL server. So the more
  37478. 23:09:39context and details you give for the AI,
  37479. 23:09:42the better results you're going to get.
  37480. 23:09:43And then you go and configure your
  37481. 23:09:45course. So you can say for example start
  37482. 23:09:47with SQL fundamentals and advance to
  37483. 23:09:50complex topics. And as well we can say
  37484. 23:09:52make it beginner friendly and it is
  37485. 23:09:55important if it is the first time you
  37486. 23:09:56are learning about the topic. And now we
  37487. 23:09:58have to shape the focus of the course
  37488. 23:10:00like I'm saying here include topics that
  37489. 23:10:02is relevant for data analytics because
  37490. 23:10:05SQL is widely used in different topics
  37491. 23:10:07for data engineering data analytics and
  37492. 23:10:10it's really important in each course to
  37493. 23:10:12focus on use cases. So we are saying
  37494. 23:10:14focus on real world data analytics use
  37495. 23:10:17cases and scenarios and of course you
  37496. 23:10:19can go and add more details about your
  37497. 23:10:21course. Okay. So now I just asked the
  37498. 23:10:23shivity in order to make this course. So
  37499. 23:10:25now let's see the road map and the
  37500. 23:10:27structure of our course. So let's start
  37501. 23:10:29with the phase one with the SQL
  37502. 23:10:31fundamentals. So it start with the basic
  37503. 23:10:33select where and so on. Then the next
  37504. 23:10:35section we are talking about order by
  37505. 23:10:37group by and insert update delete. So
  37506. 23:10:39the basic stuff. Now in the road map you
  37507. 23:10:41get the phase two intermediate SQL. So
  37508. 23:10:44here we are talking about inner joins
  37509. 23:10:45few functions about the text the date
  37510. 23:10:48and the case statements and views. And
  37511. 23:10:50now to the phase three we have the
  37512. 23:10:52advanced SQL for analytics. So we have
  37513. 23:10:54the window functions, the CTE and data
  37514. 23:10:57cleaning using the null functions and
  37515. 23:10:59few transformations. Then we go to the
  37516. 23:11:02phase number four. Here in your road map
  37517. 23:11:04you start talking about real world use
  37518. 23:11:06cases. And here you have like multiple
  37519. 23:11:08projects. So as you can see this is
  37520. 23:11:10really solid road map in order to learn
  37521. 23:11:13SQL. And now in the next step what you
  37522. 23:11:15can do you can start deep diving into
  37523. 23:11:17each of those chapters until SQL to
  37524. 23:11:19start okay with the phase number one
  37525. 23:11:21with the week one to give more details.
  37526. 23:11:24All right. So now the next one once you
  37527. 23:11:25have the agenda and the road map
  37528. 23:11:27learning the SQL now you can go and
  37529. 23:11:29focus on specific chapter specific SQL
  37530. 23:11:32concepts. So in this prompt we are
  37531. 23:11:33saying the context first I want detailed
  37532. 23:11:36explanation about SQL window functions
  37533. 23:11:38and now after that we are specifying for
  37534. 23:11:40the AI the exact structure of the
  37535. 23:11:43explanation. So first it should explain
  37536. 23:11:45what are the window functions and maybe
  37537. 23:11:47as well to give an analogy in order to
  37538. 23:11:49understand exactly what is window
  37539. 23:11:51functions and after that it should
  37540. 23:11:53explain why we need them and when to use
  37541. 23:11:55the window functions. So once you
  37542. 23:11:57understand the basics then you can start
  37543. 23:11:59learning about the syntax of the window
  37544. 23:12:01functions and it should provide as well
  37545. 23:12:03few simple examples and at the end the
  37546. 23:12:06AI should show you the best or the most
  37547. 23:12:08frequently use cases used for the SQL
  37548. 23:12:11window functions. So this is the pattern
  37549. 23:12:13that I like in order to learn something
  37550. 23:12:15new. All right. So now let's see how the
  37551. 23:12:16AI going to explain the SQL window
  37552. 23:12:18functions. So as you can see it start
  37553. 23:12:19with the big title understanding SQL
  37554. 23:12:21with the functions. So we have here a
  37555. 23:12:24quick definition and then we have here
  37556. 23:12:25an analogy and the analogy about like a
  37557. 23:12:28teacher grading students. Well that's
  37558. 23:12:31nice because we have the rank function.
  37559. 23:12:33So you have here a nice analogy about
  37560. 23:12:34the window function and then we
  37561. 23:12:36understand why do we need the window
  37562. 23:12:38functions. Well I totally agree in order
  37563. 23:12:40to have row level details with the
  37564. 23:12:42aggregations. So you can do aggregations
  37565. 23:12:45while maintaining the raw level details
  37566. 23:12:47and as well you can do complex
  37567. 23:12:49calculations because you cannot do
  37568. 23:12:50everything with a group I there's
  37569. 23:12:52functions that only work with the window
  37570. 23:12:54and then we have some explanation when
  37571. 23:12:56to use them. So we see here for example
  37572. 23:12:58the syntax of the window function. So it
  37573. 23:13:01divided to a function partition order by
  37574. 23:13:03over and here few explanation about
  37575. 23:13:05that. Then we have few simple examples
  37576. 23:13:08with queries. So explaining the
  37577. 23:13:10different functions but not all of them.
  37578. 23:13:12Of course, you can go and ask the
  37579. 23:13:14schedule to extend the examples for all
  37580. 23:13:17functions. And now we can see the top
  37581. 23:13:19three use cases for the window
  37582. 23:13:20functions. So we use it in order to rank
  37583. 23:13:23the data and as well to build the
  37584. 23:13:25running totals and the moving average.
  37585. 23:13:27And at the end we have a summary. So as
  37586. 23:13:29you can see we have wonderful
  37587. 23:13:30explanation about the concept of the SQL
  37588. 23:13:33window functions. Okay, moving on to the
  37589. 23:13:35next one. And this one I use it very
  37590. 23:13:36frequently in my projects. There is like
  37591. 23:13:38in programming always different concepts
  37592. 23:13:41that are very close to each others and
  37593. 23:13:43sometimes it is confusing and naturally
  37594. 23:13:45clear what are the big differences
  37595. 23:13:47between them. So here I have for you a
  37596. 23:13:49prompt in order to compare different SQL
  37597. 23:13:51concepts. So now the prompt says I want
  37598. 23:13:53to understand the differences between
  37599. 23:13:55SQL window functions and the group by.
  37600. 23:13:58So both of them are used usually to
  37601. 23:14:00aggregate data in SQL and I would like
  37602. 23:14:02to understand more what are the
  37603. 23:14:03differences between them. So we define
  37604. 23:14:05for the AI the following task. Explain
  37605. 23:14:07the key differences between the two
  37606. 23:14:09concepts and then it's really important
  37607. 23:14:10to understand when to use what. So
  37608. 23:14:13describe when to use each concept with
  37609. 23:14:15examples and it's really nice to
  37610. 23:14:17understand as well the advantages and
  37611. 23:14:19the disadvantages of each concept and at
  37612. 23:14:21the end you would like maybe to get a
  37613. 23:14:23quick summarization about the
  37614. 23:14:25differences between those two functions
  37615. 23:14:26side by side in one table. Okay. So now
  37616. 23:14:29let's see how the share GBD can compare
  37617. 23:14:31those two concepts. So first we have
  37618. 23:14:32really nice table in order to see the
  37619. 23:14:34differences between those two. So for
  37620. 23:14:36example the output granularity it says
  37621. 23:14:38the wind function provides calculation
  37622. 23:14:41at the rowle details where the group by
  37623. 23:14:43provides aggregated results at the group
  37624. 23:14:46level detail and if you are talking
  37625. 23:14:47about the functions it allow ranking
  37626. 23:14:49running total moving average and the
  37627. 23:14:52group by it allows only the basic
  37628. 23:14:53aggregations like sum average count. So
  37629. 23:14:56this is really nice overview for the
  37630. 23:14:57differences. Then we have when to use
  37631. 23:15:00which concepts. So it's telling the
  37632. 23:15:02window function it is used if you want
  37633. 23:15:04role level details together with the
  37634. 23:15:06aggregations and here you have like a
  37635. 23:15:08nice example for the group by it says
  37636. 23:15:11you can use it for example when
  37637. 23:15:12summarizing data into categories like
  37638. 23:15:15here grouping up the data by the region
  37639. 23:15:17and then after that we have like pros
  37640. 23:15:19and cons for each concept. So the
  37641. 23:15:21advantage of the window function we get
  37642. 23:15:23all the rows and for the group I it is
  37643. 23:15:25like easier to understand and to use.
  37644. 23:15:28For the disadvantage of the window
  37645. 23:15:29function it is more complex. For the
  37646. 23:15:31group I the disadvantage is it removes
  37647. 23:15:34the details about the rows and at the
  37648. 23:15:36end we have like sideby-side comparison
  37649. 23:15:38between those two concepts. So as you
  37650. 23:15:40can see we have really nice full
  37651. 23:15:41detailed comparison between those two
  37652. 23:15:43SQL concepts. Practicing SQL with the
  37653. 23:15:46AI. Well, it is really not enough to
  37654. 23:15:49just read about something or maybe to
  37655. 23:15:51follow and watch a course in order to
  37656. 23:15:54learn something. You have always to
  37657. 23:15:55practice. And of course, it is really
  37658. 23:15:57hard to find a materials in order to
  37659. 23:15:59practice a new programming language. So,
  37660. 23:16:02we can do it like this. We give a rule
  37661. 23:16:04act as an SQL trainer and then a context
  37662. 23:16:06where we say and help me practice SQL
  37663. 23:16:09window functions and then we go and
  37664. 23:16:11configure this training this practice by
  37665. 23:16:13doing the following. We tell it to make
  37666. 23:16:15it interactive practicing. So the AI
  37667. 23:16:17provide a task and you give a solution.
  37668. 23:16:20And what else is important is that it
  37669. 23:16:21provides you a simple data set and of
  37670. 23:16:24course you can specify which data set
  37671. 23:16:26you want. Is it industrial data set or
  37672. 23:16:28healthcare or anything you want and then
  37673. 23:16:30we tell the AI give SQL task that
  37674. 23:16:33gradually increase in difficulty. So we
  37675. 23:16:35start with the basics until getting
  37676. 23:16:37advanced tasks. And you can tell the AI
  37677. 23:16:39to act as an SQL server and show the
  37678. 23:16:42results of your query. So you would like
  37679. 23:16:43to get as a result not only the correct
  37680. 23:16:46solution or feedback you want to see the
  37681. 23:16:48result of the query that you gives and
  37682. 23:16:50then finally the AI should go and review
  37683. 23:16:52your queries provide a feedback and
  37684. 23:16:54suggest improvements okay so now let's
  37685. 23:16:57start practicing I gave the prompt to
  37686. 23:16:58shity and now we have simple data sets
  37687. 23:17:02so it is very simple we have the sales
  37688. 23:17:04ID employee region sales dates and
  37689. 23:17:06amounts and then we have the first task
  37690. 23:17:08so it says write a query to rank
  37691. 23:17:11employees by their total sales. So here
  37692. 23:17:14you have like an example output and now
  37693. 23:17:16it says your turn. So the shad is
  37694. 23:17:18waiting for your answer. Okay. So now I
  37695. 23:17:21just prepared a query for it. Let's see
  37696. 23:17:23what can happen once I post it. Oh no, I
  37697. 23:17:26got some errors in the query. So let's
  37698. 23:17:28see what we have. So it says error in
  37699. 23:17:30the aggregations. You should use the
  37700. 23:17:32amount instead of sales. And it says
  37701. 23:17:35unnecessary partition by in the rank and
  37702. 23:17:37so on. So let's check the correct query.
  37703. 23:17:40So we have here the group pi and then we
  37704. 23:17:42have to do the window function without
  37705. 23:17:45using partition pi. So that was a
  37706. 23:17:47mistake and the result of this query
  37707. 23:17:49going to be this one. And here I have
  37708. 23:17:51really nice feedback about the first
  37709. 23:17:53task. So now it ask me about the next
  37710. 23:17:55task. So I'm going to say yes. So now we
  37711. 23:17:57have this task number two about the
  37712. 23:17:59running total. We have a task and we
  37713. 23:18:00have the data and we have now to write
  37714. 23:18:03query in order to solve the task. So my
  37715. 23:18:05friends it is nice right interactive and
  37716. 23:18:08not only SQL you can go and practice any
  37717. 23:18:10programming language. Now moving on to
  37718. 23:18:12the last prompt you can use AI in order
  37719. 23:18:14to prepare you for SQL interview. So
  37720. 23:18:17let's say that you are invited to an
  37721. 23:18:18interview and you would like to prepare
  37722. 23:18:20yourself for it. So you can do a quick
  37723. 23:18:22preparation together with the AI. So you
  37724. 23:18:24can say the following act as interviewer
  37725. 23:18:26and prepare me for SQL interview. And
  37726. 23:18:29now you can go and configure the
  37727. 23:18:30interview where you can say ask common
  37728. 23:18:32SQL interview questions and make it
  37729. 23:18:35interactive. So it provide a question
  37730. 23:18:37and then wait for you to answer and then
  37731. 23:18:39you can say gradually progress to
  37732. 23:18:41advanced topics. So from basics to
  37733. 23:18:43advanced and it is very important that
  37734. 23:18:45it evaluates your answer and give you a
  37735. 23:18:47feedback. So it is a really great way to
  37736. 23:18:50prepare for interviews and I really
  37737. 23:18:51recommended to do it and you can prepare
  37738. 23:18:53yourself not only for an SQL interview,
  37739. 23:18:55you can prepare yourself for an SQL
  37740. 23:18:57exam. Okay. Okay. So now let's prepare
  37741. 23:18:59for an ISQL interview. And here we have
  37742. 23:19:01the first question. Shibility says what
  37743. 23:19:03is the difference between where and
  37744. 23:19:05having. So now it is waiting for an
  37745. 23:19:07answer. We can say where filters data
  37746. 23:19:12before
  37747. 23:19:13aggregation and
  37748. 23:19:16having filters data after aggregation.
  37749. 23:19:21So let's check the answer. So here it is
  37750. 23:19:23giving me an example of a very solid
  37751. 23:19:26answer. But in general I have answered
  37752. 23:19:28correctly. So it says the answer is
  37753. 23:19:30correct. But the feedback says here
  37754. 23:19:32maybe the interviewer like needs more
  37755. 23:19:34details not only one sentence about the
  37756. 23:19:36differences. So here it is like
  37757. 23:19:38encouraging me to speak more and to give
  37758. 23:19:40more details as an answer but still the
  37759. 23:19:43answer is correct. So now let's go to
  37760. 23:19:45the next question. What we have here can
  37761. 23:19:47you explain the differences between
  37762. 23:19:48inner join and left join. So I hope you
  37763. 23:19:51know the answer but as you can see it is
  37764. 23:19:53very interactive and nice and I think
  37765. 23:19:55those questions are really relevant. So
  37766. 23:19:56if I'm interviewing someone I'm going to
  37767. 23:19:58go and ask this question. What is the
  37768. 23:20:01difference between where and having and
  37769. 23:20:02as well the differences between the
  37770. 23:20:04joint types. So this is amazing right? I
  37771. 23:20:07really recommend you if you have like an
  37772. 23:20:08interview go and prepare yourself using
  37773. 23:20:11shajbt and you can go and practice and
  37774. 23:20:13prepare yourself before going to the
  37775. 23:20:15interview. All right. So with that you
  37776. 23:20:16have learned how I use AI in order to
  37777. 23:20:18assist me while I'm coding using SQL.
  37778. 23:20:21And now my friends we come to the most
  37779. 23:20:23important chapter from the whole course.
  37780. 23:20:25You have now learned a lot of things
  37781. 23:20:27about SQL. A lot of advanced techniques,
  37782. 23:20:29a lot of functions, how to transform
  37783. 23:20:31data, how to aggregate data. But now
  37784. 23:20:33what you have to do is to take
  37785. 23:20:34everything and to apply it in SQL
  37786. 23:20:37projects. And those projects are not
  37787. 23:20:39only like easy projects. I bought
  37788. 23:20:41projects for you that is very similar to
  37789. 23:20:43the real project that I do in the
  37790. 23:20:44industry. So you will not learn only
  37791. 23:20:46like how to do project in SQL but as
  37792. 23:20:49well what are the main steps and how we
  37793. 23:20:51implement projects in real world. And
  37794. 23:20:53here I have for you three projects data
  37795. 23:20:55warehousing data exploration and
  37796. 23:20:57advanced data analytics. We're going to
  37797. 23:20:58start with the first one the data
  37798. 23:21:00warehousing projects. This one can be
  37799. 23:21:02amazing. So let's go and deep dive in
  37800. 23:21:08that. All right my friends. So now if
  37801. 23:21:10you want to do data analytics projects
  37802. 23:21:12using SQL we have three different types.
  37803. 23:21:14The first type of projects you can do
  37804. 23:21:16data warehousing. It's all about how to
  37805. 23:21:18organize, structure and prepare your
  37806. 23:21:21data for data analyszis. It is the
  37807. 23:21:23foundations of any data analytics
  37808. 23:21:25projects. And in the next step, you can
  37809. 23:21:27do exploratory data analyzes, EDA. And
  37810. 23:21:30all what you have to do is to understand
  37811. 23:21:31and cover insights about our data sets.
  37812. 23:21:34In this kind of project, you can learn
  37813. 23:21:36how to ask the right questions and how
  37814. 23:21:38to find the answer using SQL by just
  37815. 23:21:41using basic SQL skills. Now moving on to
  37816. 23:21:43the last stage where you can do advanced
  37817. 23:21:46analytics projects where you're going to
  37818. 23:21:47use advanced SQL techniques in order to
  37819. 23:21:50answer business questions like finding
  37820. 23:21:52trends over time, comparing the
  37821. 23:21:54performance, segmenting your data into
  37822. 23:21:56different sections and as well generate
  37823. 23:21:58reports for your stakeholders. So here
  37824. 23:22:00you will be solving real business
  37825. 23:22:02questions using advanced SQL techniques.
  37826. 23:22:04Now what we're going to do, we're going
  37827. 23:22:05to start with the first type of projects
  37828. 23:22:07SQL data warehousing where you will gain
  37829. 23:22:09the following skills. So first you will
  37830. 23:22:11learn how to do ETL ELT processing using
  37831. 23:22:14SQL in order to prepare the data. You
  37832. 23:22:16will learn as well how to build data
  37833. 23:22:17architecture, how to do data
  37834. 23:22:19integrations where we're going to merge
  37835. 23:22:21multiple sources together and as well
  37836. 23:22:22how to do data load and data modeling.
  37837. 23:22:25So if I got you interested, grab your
  37838. 23:22:26coffee and let's jump to the
  37839. 23:22:31projects. All right, my friends. So now
  37840. 23:22:33before we deep dive into the tools and
  37841. 23:22:35the cool stuff, we have first to have
  37842. 23:22:37good understanding about what is exactly
  37843. 23:22:40data warehouse why the companies try to
  37844. 23:22:42build such a data management system. So
  37845. 23:22:44now the question is what is a data
  37846. 23:22:46warehouse? I will just use the
  37847. 23:22:47definition of the father of the data
  37848. 23:22:49warehouse bill in a data warehouse is
  37849. 23:22:52subject-oriented integrated time variant
  37850. 23:22:55and nonvolatile collection of data
  37851. 23:22:57designed to support the management's
  37852. 23:22:59decision-making process. Okay, I I know
  37853. 23:23:01that might be confusing.
  37854. 23:23:03Subject-oriented it means that the
  37855. 23:23:04warehouses always focus on a business
  37856. 23:23:06area like the sales, customers, finance
  37857. 23:23:09and so on. Integrated because it goes
  37858. 23:23:11and integrate multiple source systems.
  37859. 23:23:13Usually you build a warehouse not only
  37860. 23:23:15for one source but for multiple sources.
  37861. 23:23:18Time variance it means you can keep
  37862. 23:23:20historical data inside the data
  37863. 23:23:22warehouse. Nonvolatile it means once the
  37864. 23:23:24data enter the data warehouse it is not
  37865. 23:23:26deleted or modified. So this is how
  37866. 23:23:29build inmon defined data warehouse.
  37867. 23:23:31Okay. So now I'm going to show you the
  37868. 23:23:32scenario where your company don't have a
  37869. 23:23:34real data management. So now let's say
  37870. 23:23:36that you have one system and you have
  37871. 23:23:38like one data analyst has to go to this
  37872. 23:23:40system and start collecting and
  37873. 23:23:42extracting the data and then he going to
  37874. 23:23:44spend days and sometimes weeks
  37875. 23:23:46transforming the raw data into something
  37876. 23:23:48meaningful. Then once they have the
  37877. 23:23:50reports they're going to go and share
  37878. 23:23:52it. And this data analyst is sharing the
  37879. 23:23:54report using an Excel. And then you have
  37880. 23:23:56like another source of data and you have
  37881. 23:23:58another data analyst that she is doing
  37882. 23:24:00maybe the same steps collecting the data
  37883. 23:24:02spending a lot of time transforming the
  37884. 23:24:04data and then share at the end like a
  37885. 23:24:06report and this time she is sharing the
  37886. 23:24:08data using PowerPoint and a third system
  37887. 23:24:10and the same story but this time he is
  37888. 23:24:12sharing the data using maybe PowerBI. So
  37889. 23:24:15now if the company works like this then
  37890. 23:24:17there is a lot of issues. First this
  37891. 23:24:19process it take two way long. I saw a
  37892. 23:24:22lot of scenarios where sometimes it
  37893. 23:24:23takes weeks and even months until the
  37894. 23:24:26employee manually generating those
  37895. 23:24:28reports. And of course, what can happen
  37896. 23:24:29for the users? They are consuming
  37897. 23:24:31multiple reports with multiple state of
  37898. 23:24:34the data. One report is 40 days old,
  37899. 23:24:36another one 10 days and a third one is
  37900. 23:24:39like 5 days. So it's going to be really
  37901. 23:24:41hard to make a real decision based on
  37902. 23:24:43this structure. A manual process is
  37903. 23:24:45always slow and stressful and the more
  37904. 23:24:47employees you involved in the process
  37905. 23:24:49the more you open the door for human
  37906. 23:24:51errors and errors of course in reports
  37907. 23:24:53leads to bad decisions and another issue
  37908. 23:24:56of course is handling the big data. If
  37909. 23:24:59one of your sources generating like
  37910. 23:25:01massive amount of data then the data
  37911. 23:25:03analyst going to struggle collecting the
  37912. 23:25:05data and maybe in some scenarios it will
  37913. 23:25:07not be anymore possible to get the data.
  37914. 23:25:09So the whole process can breaks and you
  37915. 23:25:11cannot generate anymore fresh data for
  37916. 23:25:14specific reports. And one last very big
  37917. 23:25:16issue with that. If one of your
  37918. 23:25:17stakeholders asks for an integrated
  37919. 23:25:20report from multiple sources, well good
  37920. 23:25:23luck with that because merging all those
  37921. 23:25:25data manually is very chaotic,
  37922. 23:25:27time-conuming and full of risk. So this
  37923. 23:25:29is just a picture. If a company is
  37924. 23:25:31working without a proper data
  37925. 23:25:33management, without a data leak, data
  37926. 23:25:36warehouse, data lake houses. So in order
  37927. 23:25:38to make real and good decisions, you
  37928. 23:25:40need data management. So now let's talk
  37929. 23:25:42about the scenario of a data warehouse.
  37930. 23:25:44So the first thing that's going to
  37931. 23:25:46happen is that you will not have your
  37932. 23:25:48data team collecting manually the data.
  37933. 23:25:51You're going to have a very important
  37934. 23:25:52component called ETL. ETL stands for
  37935. 23:25:55extract, transform and load. It is a
  37936. 23:25:58process that you do in order to extract
  37937. 23:26:00the data from the sources and then apply
  37938. 23:26:02multiple transformations on those
  37939. 23:26:04sources and at the end it loads the data
  37940. 23:26:06to the data warehouse and this one going
  37941. 23:26:08to be the single point of truth for
  37942. 23:26:10analyzes and reporting and it is called
  37943. 23:26:13data warehouse. So now what can happen
  37944. 23:26:15all your reports going to be consuming
  37945. 23:26:18this single point of truth. So with that
  37946. 23:26:20you create your multiple reports and as
  37947. 23:26:22well you can create integrated reports
  37948. 23:26:25from multiple sources not only from one
  37949. 23:26:27single source. So now by looking to the
  37950. 23:26:29right side it looks already organized
  37951. 23:26:31right and the whole process is
  37952. 23:26:33completely automated. There is no more
  37953. 23:26:35manual steps which of course it reduces
  37954. 23:26:38the human error and as well it is pretty
  37955. 23:26:40fast. So usually you can load the data
  37956. 23:26:42from the sources until the reports in
  37957. 23:26:45matter of hours or sometimes in minutes.
  37958. 23:26:48So there is no need to wait like weeks
  37959. 23:26:50and months in order to refresh anything.
  37960. 23:26:52And of course the big advantage is that
  37961. 23:26:54the data warehouse itself it is
  37962. 23:26:56completely integrated. So that means it
  37963. 23:26:58goes and bring all those sources
  37964. 23:27:00together in one place which makes it
  37965. 23:27:02really easier for reporting and not only
  37966. 23:27:05integrated you can build in the data
  37967. 23:27:07warehouse as well history. So we have
  37968. 23:27:09now the possibility to access historical
  37969. 23:27:11data and what is also amazing is that
  37970. 23:27:14all those reports having the same data
  37971. 23:27:16status. So all those reports can have
  37972. 23:27:18the same status maybe sometimes one day
  37973. 23:27:20old or something. And of course if you
  37974. 23:27:22have a modern data warehouse in cloud
  37975. 23:27:24platforms you can really easily handle
  37976. 23:27:27any big data sources. So no need to
  37977. 23:27:29panic if one of your sources is
  37978. 23:27:31delivering massive amount of data. And
  37979. 23:27:33of course in order to build the data
  37980. 23:27:35warehouse you need different types of
  37981. 23:27:36developers. So usually the one that
  37982. 23:27:38builds the ETL component and the data
  37983. 23:27:41warehouse is the data engineer. So they
  37984. 23:27:44are the one that is accessing the
  37985. 23:27:45sources, scripting the ATLs and building
  37986. 23:27:48the database for the data warehouse. And
  37987. 23:27:50now for the other part, the one that is
  37988. 23:27:52responsible for that is the data
  37989. 23:27:54analyst. They are the one that is
  37990. 23:27:56consuming the data warehouse, building
  37991. 23:27:58different data models and reports and
  37992. 23:28:01sharing it with the stakeholders. So
  37993. 23:28:03they are usually contacting the
  37994. 23:28:04stakeholders, understanding the
  37995. 23:28:06requirements and building multiple
  37996. 23:28:08reports based on the data warehouse. So
  37997. 23:28:10now if you have a look to those two
  37998. 23:28:11scenarios, this is exactly why we need
  37999. 23:28:14data management. Your data team is not
  38000. 23:28:17wasting time and fighting with the data.
  38001. 23:28:20They are now more organized and more
  38002. 23:28:22focused and with like a data warehouse
  38003. 23:28:24and you are delivering professional and
  38004. 23:28:26fresh reports that your company can
  38005. 23:28:29count on in order to make good and fast
  38006. 23:28:32decisions. So this is why you need a
  38007. 23:28:34data management like a data warehouse.
  38008. 23:28:36Think about data warehouse as a busy
  38009. 23:28:38restaurant. Every day different
  38010. 23:28:39suppliers bring in fresh ingredients,
  38011. 23:28:42vegetables, spices, meat, you name it.
  38012. 23:28:44They don't just use it immediately and
  38013. 23:28:46throw everything in one pot, right? They
  38014. 23:28:48clean it, shop it, and organize
  38015. 23:28:50everything and store each ingredients in
  38016. 23:28:53the right place, fridge or freezer. So,
  38017. 23:28:55this is the preparing phase. And when
  38018. 23:28:57the order comes in, they quickly grab
  38019. 23:28:59the prepared ingredients and create a
  38020. 23:29:02perfect dish and then serve it to the
  38021. 23:29:04customers of the restaurant. And this
  38022. 23:29:06process is exactly like the data
  38023. 23:29:07warehouse process. It is like the
  38024. 23:29:09kitchen where the raw ingredients, your
  38025. 23:29:11data are cleaned, sorted and stored. And
  38026. 23:29:14when you need a report or analyzes, it
  38027. 23:29:16is ready to serve up exactly like what
  38028. 23:29:19you
  38029. 23:29:22need. Okay. So now we're going to zoom
  38030. 23:29:24in and focus on the component ETL. If
  38031. 23:29:27you are building such a project, you're
  38032. 23:29:28going to spend almost 90% just building
  38033. 23:29:31this component, the ETL. So it is the
  38034. 23:29:34core element of the data warehouse and I
  38035. 23:29:36want you to have a clear understanding
  38036. 23:29:38what is exactly an ETL. So our data
  38037. 23:29:41exist in a source system. And now what
  38038. 23:29:43we want to do is is to get our data from
  38039. 23:29:45the source and move it to the target.
  38040. 23:29:48Source and target could be like database
  38041. 23:29:49tables. So now the first step that we
  38042. 23:29:51have to do is to specify which data we
  38043. 23:29:54have to load from the source. Of course
  38044. 23:29:56we can say that we want to load
  38045. 23:29:58everything but let's say that we are
  38046. 23:29:59doing incremental loads. So we're going
  38047. 23:30:01to go and specify a subset of the data
  38048. 23:30:03from the source in order to prepare it
  38049. 23:30:05and load it later to the target. So this
  38050. 23:30:07step in the ATL process we call it
  38051. 23:30:09extract. We are just identifying the
  38052. 23:30:12data that we need. We pull it out and we
  38053. 23:30:14don't change anything. It's going to be
  38054. 23:30:16like one to one like the source system.
  38055. 23:30:18So the extract has only one task to
  38056. 23:30:20identify the data that we have to pull
  38057. 23:30:23out from the source and to not change
  38058. 23:30:25anything. So we will not manipulate the
  38059. 23:30:26data at all. It can stay as it is. So
  38060. 23:30:29this is the first step in the ETL
  38061. 23:30:31process, the extract. Now moving on to
  38062. 23:30:33the stage number two. We're going to
  38063. 23:30:35take this extract data and we will do
  38064. 23:30:37some manipulations, transformations and
  38065. 23:30:40we're going to change the shape of those
  38066. 23:30:42data. And this process is really heavy
  38067. 23:30:45working. We can do a lot of stuff like
  38068. 23:30:47data cleansing, data integration and a
  38069. 23:30:49lot of formatting and data
  38070. 23:30:51normalizations. So a lot of stuff we can
  38071. 23:30:53do in this step. So this is the second
  38072. 23:30:55step in the ETL process, the
  38073. 23:30:56transformation. We're going to take the
  38074. 23:30:58original data and reshape it, transform
  38075. 23:31:01it into exactly the format that we need
  38076. 23:31:04into a new format and shapes that we
  38077. 23:31:06need for analyzes and reporting. Now,
  38078. 23:31:08finally, we get to the last step in the
  38079. 23:31:10ATL process. We have the load. So, in
  38080. 23:31:12this step, we're going to take this new
  38081. 23:31:14data and we're going to insert it into
  38082. 23:31:16the target. So, it is very simple. We're
  38083. 23:31:18going to take this prepared data from
  38084. 23:31:20the transformation step and we're going
  38085. 23:31:22to move it into its final destination,
  38086. 23:31:24the target like for example data
  38087. 23:31:26warehouse. So that's ETL in a nutshell.
  38088. 23:31:29First extract the raw data, then
  38089. 23:31:31transform it into something meaningful
  38090. 23:31:33and finally load it to a target where
  38091. 23:31:35it's going to make a difference. So
  38092. 23:31:37that's it. This is what we mean with the
  38093. 23:31:39ETL process. Now in real projects, we
  38094. 23:31:41don't have like only source and targets.
  38095. 23:31:43Our data architecture going to have like
  38096. 23:31:45multiple layers depend on your design
  38097. 23:31:48whether you are building a warehouse or
  38098. 23:31:49a data lake or a data warehouse. And
  38099. 23:31:52usually there are like different ways on
  38100. 23:31:53how to load the data between all those
  38101. 23:31:55layers. And in order now to load the
  38102. 23:31:57data from one layer to another one there
  38103. 23:31:59are like multiple ways on how to use the
  38104. 23:32:01ATL process. So usually if you are
  38105. 23:32:03loading the data from the source to the
  38106. 23:32:05layer number one like only extract the
  38107. 23:32:07data from the source and load it
  38108. 23:32:09directly to the layer number one without
  38109. 23:32:11doing any transformations because I want
  38110. 23:32:13to see the data as it is in the first
  38111. 23:32:16layer. And now between the layer number
  38112. 23:32:17one and the layer number two you might
  38113. 23:32:19go and use the full ETL. So we're going
  38114. 23:32:22to extract from the layer one, transform
  38115. 23:32:24it and then load it to the layer number
  38116. 23:32:26two. So with that we are using the whole
  38117. 23:32:28process the ATL. And now between layer
  38118. 23:32:30two and layer three we can do only
  38119. 23:32:32transformation and then load. So we
  38120. 23:32:34don't have to deal with how to extract
  38121. 23:32:36the data because it is maybe using the
  38122. 23:32:38same technology and we are taking all
  38123. 23:32:40data from layer 2 to layer three. So we
  38124. 23:32:43transform the whole layer 2 and then
  38125. 23:32:44load it to layer three. And now between
  38126. 23:32:47three and four you can use only the LM.
  38127. 23:32:49So maybe it's something like duplicating
  38128. 23:32:51and replicating the data and then you
  38129. 23:32:54are doing the transformation. So you
  38130. 23:32:56load to the new layer and then transform
  38131. 23:32:58it. Of course, this is not a real
  38132. 23:32:59scenario. I'm just showing you that in
  38133. 23:33:01order to move from source to a target,
  38134. 23:33:03you don't have always to use a complete
  38135. 23:33:06ETL. Depend on the design of your data
  38136. 23:33:08architecture. You might use only few
  38137. 23:33:10components from the ETL. Okay. So this
  38138. 23:33:13is how ETL looks like in real projects.
  38139. 23:33:16Okay. So now I would like to show you an
  38140. 23:33:17overview of the different techniques and
  38141. 23:33:19methods in the ETLs. We have wide range
  38142. 23:33:22of possibilities where you have to make
  38143. 23:33:24decisions on which one you want to apply
  38144. 23:33:26to your projects. So let's start first
  38145. 23:33:28with the extraction. The first thing
  38146. 23:33:30that I want to show you is we have
  38147. 23:33:31different methods of extraction. Either
  38148. 23:33:33you are going to the source system and
  38149. 23:33:35pulling the data from the source or the
  38150. 23:33:37source system is pushing the data to the
  38151. 23:33:40data warehouse. So those are the two
  38152. 23:33:41main methods on how to extract data. And
  38153. 23:33:44then we have in the extraction two
  38154. 23:33:46types. We have a full extraction
  38155. 23:33:48everything all the records from tables
  38156. 23:33:50and every day we load all the data to
  38157. 23:33:52the data warehouse or we make more
  38158. 23:33:54smarter one where we say we're going to
  38159. 23:33:55do an incremental extraction where every
  38160. 23:33:57day we're going to identify only the new
  38161. 23:34:00changing data. So we don't have to load
  38162. 23:34:02the whole thing only the new data we go
  38163. 23:34:04extract it and then load it to the data
  38164. 23:34:06warehouse. And in data extraction we
  38165. 23:34:08have different techniques. The first one
  38166. 23:34:09is like manually where someone has to
  38167. 23:34:11access a source system and extract the
  38168. 23:34:14data manually or we connect ourselves to
  38169. 23:34:16a database and we have then a query in
  38170. 23:34:18order to extract the data or we have a
  38171. 23:34:20file that we have to parse it to the
  38172. 23:34:22data warehouse or another technique is
  38173. 23:34:24to connect ourself to API and do their
  38174. 23:34:27calls in order to extract the data or if
  38175. 23:34:29the data is available in streaming like
  38176. 23:34:31in CFKA we can do eventbased streaming
  38177. 23:34:34in order to extract the data. Another
  38178. 23:34:36way is to use the change data capture
  38179. 23:34:39CDC is as well something very similar to
  38180. 23:34:41streaming or another way is by using web
  38181. 23:34:44scrabbing where you have a code that
  38182. 23:34:46going to run and extract all the
  38183. 23:34:47informations from the web. So those are
  38184. 23:34:49the different techniques and types that
  38185. 23:34:51we have in the extraction. Now if you
  38186. 23:34:53are talking on the transformation there
  38187. 23:34:55are wide range of different
  38188. 23:34:57transformations that we can do on our
  38189. 23:34:59data like for example doing data
  38190. 23:35:01enrichment where we add values to our
  38191. 23:35:03data sets or we do a data integration
  38192. 23:35:05where we have multiple sources and we
  38193. 23:35:07bring everything to one data model or we
  38194. 23:35:09derive new columns based on already
  38195. 23:35:12existing one. Another type of data
  38196. 23:35:14transformations we have the data
  38197. 23:35:15normalization. So the sources has values
  38198. 23:35:18that are like a code and you go and map
  38199. 23:35:20it to more friendly values for the
  38200. 23:35:22analyzers which is more easier to
  38201. 23:35:24understand and to use. Another
  38202. 23:35:26transformations we have the business
  38203. 23:35:28rules and logic depend on the business
  38204. 23:35:30you can define different criterias in
  38205. 23:35:32order to build like new columns. And
  38206. 23:35:34what belongs to transformations is the
  38207. 23:35:36data aggregation. So here we aggregate
  38208. 23:35:38the data to a different granularity and
  38209. 23:35:41then we have type of transformation
  38210. 23:35:42called data cleansing. There are many
  38211. 23:35:44different ways on how to clean our data.
  38212. 23:35:47For example, removing the duplicates,
  38213. 23:35:49doing data filtering, handling the
  38214. 23:35:51missing data, handling invalid values or
  38215. 23:35:54removing unwanted spaces, casting the
  38216. 23:35:56data types and detecting the outliers
  38217. 23:35:59and many more. So we have different
  38218. 23:36:01types of data cleansing that we can do
  38219. 23:36:03in our data warehouse and this is very
  38220. 23:36:06important transformation. So as you can
  38221. 23:36:07see we have different types of
  38222. 23:36:09transformations that we can do in our
  38223. 23:36:11data warehouse. Now moving on to the
  38224. 23:36:13load. So what do we have over here? We
  38225. 23:36:15have different processing types. So
  38226. 23:36:17either we are doing patch processing or
  38227. 23:36:20stream processing. Patch processing
  38228. 23:36:22means we are loading the data warehouse
  38229. 23:36:24in one big patch of data that's going to
  38230. 23:36:26run and load the data warehouse. So it
  38231. 23:36:29is only one time job in order to refresh
  38232. 23:36:31the content of the data warehouse and as
  38233. 23:36:33well the reports. So that means we are
  38234. 23:36:35scheduling the data warehouse in order
  38235. 23:36:37to load it in the day once or twice. And
  38236. 23:36:39the other type we have the stream
  38237. 23:36:41processing. So this means if there is
  38238. 23:36:43like a change in the source system,
  38239. 23:36:44we're going to process this change as
  38240. 23:36:46soon as possible. So we're going to
  38241. 23:36:48process it through all the layers of the
  38242. 23:36:50data warehouse once something changes
  38243. 23:36:52from the source system. So we are
  38244. 23:36:53streaming the data in order to have real
  38245. 23:36:56time data warehouse which is very
  38246. 23:36:58challenging things to do in data
  38247. 23:36:59warehousing. And if you are talking
  38248. 23:37:01about the loads we have two methods
  38249. 23:37:03either we are doing a full load or
  38250. 23:37:05incremental load. It's the same thing as
  38251. 23:37:07extraction right? So for the full load
  38252. 23:37:09in databases there are like different
  38253. 23:37:11methods on how to do it like for example
  38254. 23:37:13we truncate and then insert that means
  38255. 23:37:15we make the table completely empty and
  38256. 23:37:17then we insert everything from the
  38257. 23:37:19scratch or another one you are doing an
  38258. 23:37:21update insert we call it upsert. So we
  38259. 23:37:24can go and update all the records and
  38260. 23:37:26then insert the new one and another way
  38261. 23:37:28is to drop create and insert. So that
  38262. 23:37:30means we drop the whole table and then
  38263. 23:37:32we create it from scratch and then we
  38264. 23:37:34insert the data. It is very similar to
  38265. 23:37:36the truncate but here we are as well
  38266. 23:37:38removing and dropping the whole table.
  38267. 23:37:40So those are the different methods of
  38268. 23:37:42full loads. The incremental load we can
  38269. 23:37:44use as well the upserts. So update and
  38270. 23:37:46insert. So we're going to do an update
  38271. 23:37:48or insert statements to our tables. Or
  38272. 23:37:50if the source is something like a log,
  38273. 23:37:52we can do only insert. So we can go and
  38274. 23:37:54append the data always to the table
  38275. 23:37:56without having to update anything.
  38276. 23:37:58Another way to do incremental load is to
  38277. 23:38:00do a merge. And here it is very similar
  38278. 23:38:02to the upsert but as well with a delete.
  38279. 23:38:04So update, insert, delete. So those are
  38280. 23:38:07the different methods on how to load the
  38281. 23:38:09data to your tables. And one more thing
  38282. 23:38:10in data warehousing, we have something
  38283. 23:38:12called slowly changing dimensions. So
  38284. 23:38:14here it's all about the historicizations
  38285. 23:38:16of your table. And there are many
  38286. 23:38:18different ways on how to handle the
  38287. 23:38:20historiizations in your table. The first
  38288. 23:38:22type is sedd0. We say there is
  38289. 23:38:24notoriizations and nothing should be
  38290. 23:38:26changed at all. So that means you are
  38291. 23:38:28not going to update anything. The second
  38292. 23:38:30one which is more famous, it is the sedd
  38293. 23:38:33one. you are doing an overwrite. So that
  38294. 23:38:35means you are updating the records with
  38295. 23:38:38the new informations from the source
  38296. 23:38:39system by overwriting the old value. So
  38297. 23:38:41we are doing something like the upsert.
  38298. 23:38:43So update and insert but you are losing
  38299. 23:38:46of course history. Another one we have
  38300. 23:38:47the sedd2 and here you want to add
  38301. 23:38:49historiizations to your table. So what
  38302. 23:38:51we do each change that we get from the
  38303. 23:38:53source system that means we are
  38304. 23:38:55inserting new records and we are not
  38305. 23:38:57going to overwrite or delete the old
  38306. 23:38:59data. we are just going to make it
  38307. 23:39:01inactive and the new record going to be
  38308. 23:39:03active one. So there are different
  38309. 23:39:05methods on how to do historiizations as
  38310. 23:39:07well while you are loading the data to
  38311. 23:39:10the data warehouse. All right. So those
  38312. 23:39:12are the different types and techniques
  38313. 23:39:13that you might encounter in data
  38314. 23:39:15management projects. So now what I'm
  38315. 23:39:16going to show you quickly which of those
  38316. 23:39:18types we will be using in our projects.
  38317. 23:39:20So now if we are talking about the
  38318. 23:39:21extraction over here we will be doing a
  38319. 23:39:24pull extraction and about the full or
  38320. 23:39:26incremental it's going to be a full
  38321. 23:39:28extraction. And about the technique we
  38322. 23:39:30are going to be parsing files to the
  38323. 23:39:32data warehouse. And now about the data
  38324. 23:39:35transformations. Well, this one we will
  38325. 23:39:37cover everything all those types of
  38326. 23:39:39transformations that I'm showing you now
  38327. 23:39:41is going to be part of the project
  38328. 23:39:43because I believe in each data project
  38329. 23:39:45you will be facing those
  38330. 23:39:46transformations. Now if you have a look
  38331. 23:39:48to the load our project going to be
  38332. 23:39:50patch processing and about the load
  38333. 23:39:52methods we will be doing a full load
  38334. 23:39:54since we have full extraction and it's
  38335. 23:39:56going to be truncate and inserts. And
  38336. 23:39:59now about the historiizations we will be
  38337. 23:40:01doing the sedd one. So that means we
  38338. 23:40:04will be updating the content of the data
  38339. 23:40:06warehouse. So those are the different
  38340. 23:40:07techniques and types that we will be
  38341. 23:40:09using in our ETL process for this
  38342. 23:40:11project. All right. So with that we have
  38343. 23:40:13now clear understanding what is a data
  38344. 23:40:15warehouse and we are done with the
  38345. 23:40:17theory parts. So now the next step we're
  38346. 23:40:19going to start with the projects. The
  38347. 23:40:20first thing that we have to do is to
  38348. 23:40:22prepare our environment to develop the
  38349. 23:40:24projects. So let's start with
  38350. 23:40:29that. All right. So now we go to the
  38351. 23:40:32link in the description and from there
  38352. 23:40:34we're going to go to the downloads and
  38353. 23:40:35you can find all the materials of all
  38354. 23:40:37courses and projects. But the one that
  38355. 23:40:39we need now is the SQL data warehouse
  38356. 23:40:41projects. So let's go to the link and
  38357. 23:40:43here we have bunch of links that we need
  38358. 23:40:45for the projects. But the most important
  38359. 23:40:47one to get all data and files is this
  38360. 23:40:49one download all project files. So let's
  38361. 23:40:52go and do that. And after you do that
  38362. 23:40:54you're going to get a zip file where you
  38363. 23:40:56have there a lot of stuff. So let's go
  38364. 23:40:58and extract it. And now inside it if you
  38365. 23:41:00go over here you will find the
  38366. 23:41:01repository structure from git. And the
  38367. 23:41:04most important one here is the data
  38368. 23:41:05sets. So you have two sources the CRM
  38369. 23:41:08and the ARP. And in each one of them
  38370. 23:41:10there are three CSV files. So those are
  38371. 23:41:13the data set for the projects. For the
  38372. 23:41:15other stuffs don't worry about it. We
  38373. 23:41:17will be explaining that during the
  38374. 23:41:18project. So go and get the data and put
  38375. 23:41:21it somewhere at your PC where you don't
  38376. 23:41:22lose it. Okay. So now what else do we
  38377. 23:41:24have? We have here a link to the get
  38378. 23:41:26repository. So this is the link to my
  38379. 23:41:28repository that I have created through
  38380. 23:41:30the projects. So you can go and access
  38381. 23:41:32it. But don't worry about it. We're
  38382. 23:41:33going to explain the whole structure
  38383. 23:41:34during the projects and you will be
  38384. 23:41:36creating your own repository. And as
  38385. 23:41:38well we have the link to the notion.
  38386. 23:41:40Here we are doing the project
  38387. 23:41:42management. Here you're going to find
  38388. 23:41:43the main steps the main phases of the
  38389. 23:41:45SQL projects that we will do and as well
  38390. 23:41:48all the task that we will be doing
  38391. 23:41:49together during the projects. And now we
  38392. 23:41:52have links to the project tools. So if
  38393. 23:41:54you don't have it already go and
  38394. 23:41:55download the SQL server express. So it's
  38395. 23:41:58like a server that's going to run
  38396. 23:41:59locally at your PC where your database
  38397. 23:42:01going to live. Another one that you have
  38398. 23:42:03to download is the SQL Server Management
  38399. 23:42:05Studio. It is just a client in order to
  38400. 23:42:07interact with the database and there
  38401. 23:42:09we're going to run all our queries and
  38402. 23:42:11then link to the GitHub and as well link
  38403. 23:42:13to the draw AO if you don't have it
  38404. 23:42:15already go and download it. It is free
  38405. 23:42:17and amazing tool in order to draw
  38406. 23:42:19diagrams. So through the projects we
  38407. 23:42:21will be drawing data models the data
  38408. 23:42:24architecture a data lineage. So a lot of
  38409. 23:42:26stuff we'll be doing using this tool. So
  38410. 23:42:29go and download it. And the last thing
  38411. 23:42:30it is nice to have you have a link to
  38412. 23:42:32the notion where you can go and create
  38413. 23:42:34of course free accounts if you want to
  38414. 23:42:36build the project plan and as well
  38415. 23:42:38follow me by creating the project steps
  38416. 23:42:41and the projects tasks. Okay. So that's
  38417. 23:42:43all those are all the links for the
  38418. 23:42:45projects. So go and download all those
  38419. 23:42:47stuff create the accounts and once you
  38420. 23:42:49are ready then we continue with the
  38421. 23:42:54projects. All right. So now I hope that
  38422. 23:42:56you have downloaded all the tools and
  38423. 23:42:58created the accounts. Now it's time to
  38424. 23:43:00move to very important step that almost
  38425. 23:43:02all people skip while doing projects and
  38426. 23:43:05that is by creating the project plan and
  38427. 23:43:08for that we will be using the tool
  38428. 23:43:10notion. Notion is of course a free tool
  38429. 23:43:12and it can help you to organize your
  38430. 23:43:14ideas, your plans and resources all in
  38431. 23:43:17one place. I use it very intensively for
  38432. 23:43:20my private projects like for example
  38433. 23:43:21creating this course and I can tell you
  38434. 23:43:23creating a project plan is the key to
  38435. 23:43:25success. Creating a data warehouse
  38436. 23:43:27project is usually very complex. And
  38437. 23:43:29according to Gartner reports, over 50%
  38438. 23:43:32of data warehouse projects fail. In my
  38439. 23:43:35opinion about any complex project, the
  38440. 23:43:37key to success is to have a clear
  38441. 23:43:40project plan. So now at this phase of
  38442. 23:43:41the project, we're going to go and
  38443. 23:43:43create a rough project plan because at
  38444. 23:43:45the moment we don't have yet clear
  38445. 23:43:47understanding about the data
  38446. 23:43:49architecture. So let's go. Okay. So now
  38447. 23:43:51let's create a new page and let's call
  38448. 23:43:52it data warehouse projects. The first
  38449. 23:43:54thing is that we have to go and create
  38450. 23:43:56the main phases and stages of the
  38451. 23:43:59projects and for that we need a table.
  38452. 23:44:00So in order to do that hit slash and
  38453. 23:44:03then type database in line and then
  38454. 23:44:05let's go and call it something like data
  38455. 23:44:08warehouse epics and we're going to go
  38456. 23:44:10and hide it because I don't like it. And
  38457. 23:44:12then on the table we can go and rename
  38458. 23:44:14it like for example projects epics
  38459. 23:44:17something like that. And now what we're
  38460. 23:44:18going to do we're going to go and list
  38461. 23:44:20all the big task of the project. So an
  38462. 23:44:22epic is usually like a large task that
  38463. 23:44:24needs a lot of efforts in order to solve
  38464. 23:44:26it. So you can call it epics, stages,
  38465. 23:44:29phases of the project, whatever you
  38466. 23:44:30want. So we're going to go and list our
  38467. 23:44:32project steps. So let's start with the
  38468. 23:44:35requirements analyzes and then designing
  38469. 23:44:38data
  38470. 23:44:39architecture and another one we have the
  38471. 23:44:42project
  38472. 23:44:44initialization. So those are the three
  38473. 23:44:46big task in the project first. And now
  38474. 23:44:48what do we need? We need another table
  38475. 23:44:50for the small chunks of the tasks, the
  38476. 23:44:52subtasks and we're going to do the same
  38477. 23:44:54thing. So we're going to go and hit
  38478. 23:44:55slash and we're going to search for the
  38479. 23:44:56table in line and we're going to do the
  38480. 23:44:58same thing. So first we're going to call
  38481. 23:45:00it data warehouse tasks and then we're
  38482. 23:45:03going to hide it and over here we're
  38483. 23:45:05going to rename it and say this is the
  38484. 23:45:07project tasks. So now what we're going
  38485. 23:45:09to do, we're going to go to the plus
  38486. 23:45:10icon over here and then search for
  38487. 23:45:12relation. This one over here with the
  38488. 23:45:14arrow. And now we're going to search for
  38489. 23:45:16the name of the first table. So we
  38490. 23:45:18called it data warehouse eix. So let's
  38491. 23:45:21go and click it and we're going to say
  38492. 23:45:22as well two-way relation. So let's go
  38493. 23:45:25and add the relation. So with that we
  38494. 23:45:27got a field in the new table called data
  38495. 23:45:29warehouse eix. This comes from this
  38496. 23:45:31table and as well we have here data
  38497. 23:45:33warehouse tasks that comes from the
  38498. 23:45:35below table. So as you can see we have
  38499. 23:45:37linked them together. Now what I'm going
  38500. 23:45:38to do I'm going to take this to the left
  38501. 23:45:40side and then what we're going to do
  38502. 23:45:41we're going to go and select one of
  38503. 23:45:43those epics. Like for example let's take
  38504. 23:45:45design the data architecture. And now
  38505. 23:45:47what we're going to do, we're going to
  38506. 23:45:48go and break down this epic into
  38507. 23:45:50multiple tasks. Like for example, choose
  38508. 23:45:53data management approach. And then we
  38509. 23:45:57have another task. What we're going to
  38510. 23:45:58do, we're going to go and select as well
  38511. 23:45:59the same epic. So maybe the next step is
  38512. 23:46:02brainstorm and design the layers. And
  38513. 23:46:06then let's go to another epic for
  38514. 23:46:08example the project initialization. And
  38515. 23:46:10we say over here for example create get
  38516. 23:46:13repo prepare the structure. we can go
  38517. 23:46:16and make another one in the same epic.
  38518. 23:46:19Let's say we're going to go and create
  38519. 23:46:20the database and the schemas. So, as you
  38520. 23:46:23can see, I'm just defining the subtasks
  38521. 23:46:25of those epics. So, now what we're going
  38522. 23:46:27to do, we're going to go and add a
  38523. 23:46:28checkbox in order to understand whether
  38524. 23:46:30we have done the task or not. So, we go
  38525. 23:46:32to the plus and search for check. We
  38526. 23:46:34need a checkbox. And what we're going to
  38527. 23:46:36do, we're going to make it really small
  38528. 23:46:39like this. And with that, each time we
  38529. 23:46:41are done with the task, we're going to
  38530. 23:46:42go and click on it just to make sure
  38531. 23:46:44that we have done the task. Now, there
  38532. 23:46:46is one more thing that is not really
  38533. 23:46:47working nice and that is here. We're
  38534. 23:46:49going to have like a long list of tasks
  38535. 23:46:51and it's really annoying. So, what we're
  38536. 23:46:53going to do, we're going to go to the
  38537. 23:46:54plus over here and let's search for roll
  38538. 23:46:56up. So, let's go and select it. So, now
  38539. 23:46:58what we're going to do, we have to go
  38540. 23:46:59and select the relationship. It's going
  38541. 23:47:01to be the data warehouse task. And after
  38542. 23:47:03that, we're going to go to the property
  38543. 23:47:04and make it as a checkbox. So, now as
  38544. 23:47:06you can see in the first table, we are
  38545. 23:47:08saying how many tasks is closed. But I
  38546. 23:47:10don't want to show it like this. What we
  38547. 23:47:12can do, we're going to go to the
  38548. 23:47:12calculation and to the percent and then
  38549. 23:47:15percent checked. And with that, we can
  38550. 23:47:17see the progress of our project. And now
  38551. 23:47:19instead of the numbers, we can have
  38552. 23:47:21really nice bar. Great. So as well, we
  38553. 23:47:23can go and give it a name like progress.
  38554. 23:47:25So that's it. And we can go and hide the
  38555. 23:47:27data warehouse tasks. And now with that,
  38556. 23:47:29we have really nice progress bar for
  38557. 23:47:31each epic. And if we close all the tasks
  38558. 23:47:33of this epic, we can see that we have
  38559. 23:47:35reached 100%. So this is the main
  38560. 23:47:37structure. Now we can go and add some
  38561. 23:47:39cosmetics and rename stuff in order to
  38562. 23:47:41make things looks nicer. Like for
  38563. 23:47:43example, if I go to the tasks over here,
  38564. 23:47:45I can go and call it tasks and as well
  38565. 23:47:48go and change the icon to something like
  38566. 23:47:50this. And if you'd like to have an icon
  38567. 23:47:52for all those epics, what you're going
  38568. 23:47:54to do, we're going to go to the epic for
  38569. 23:47:55example design data architecture. And
  38570. 23:47:57then if you hover on top of the title,
  38571. 23:47:59you can see add an icon. And you can go
  38572. 23:48:01and pick any icon that you want. So for
  38573. 23:48:04example, this one. And now as you can
  38574. 23:48:05see, we have defined it here in the top.
  38575. 23:48:07And the icon going to be as well in the
  38576. 23:48:09below table. Okay. So now one more thing
  38577. 23:48:11that we can do for the project tasks is
  38578. 23:48:13that we can go and group them by the
  38579. 23:48:15epics. So if you go to the three dots
  38580. 23:48:17and then we go to groups and then we can
  38581. 23:48:19group up by the epics. As you can see
  38582. 23:48:22now we have like a section for each epic
  38583. 23:48:24and you can go and sort the epics if you
  38584. 23:48:26want. If you go over here sort then
  38585. 23:48:28manual and you can go over here and
  38586. 23:48:30start sorting the epics as you want. And
  38587. 23:48:33with that you can expand and minimize
  38588. 23:48:35each task. if you don't want to see
  38589. 23:48:37always all tasks in one go. So this is
  38590. 23:48:40really nice way in order to build like
  38591. 23:48:41data management for your projects. Of
  38592. 23:48:43course, in companies, we use
  38593. 23:48:45professional tools in order to do
  38594. 23:48:46projects like for example Gyra. But for
  38595. 23:48:49private personal projects that I do, I
  38596. 23:48:51always do it like this and I really
  38597. 23:48:53recommend you to do it not only for this
  38598. 23:48:55project, for any project that you are
  38599. 23:48:56doing. Cuz if you see the whole project
  38600. 23:48:58in one go, you can see the big picture
  38601. 23:49:00and closing tasks and doing it like
  38602. 23:49:02this. These small things going to makes
  38603. 23:49:04you really satisfied and keeps you
  38604. 23:49:06motivated to finish the whole project
  38605. 23:49:08and makes you proud. Okay friends, so
  38606. 23:49:10now I just went and added few icons, a
  38607. 23:49:13renamed stuff and as well more tasks for
  38608. 23:49:15each epic and this going to be our
  38609. 23:49:17starting point in the project and once
  38610. 23:49:19we have more informations we're going to
  38611. 23:49:20go and add more details on how exactly
  38612. 23:49:23we're going to build the data warehouse.
  38613. 23:49:25So at the start we're going to go and
  38614. 23:49:26analyze and understand the requirements
  38615. 23:49:28and only after that we're going to start
  38616. 23:49:30designing the data architecture and here
  38617. 23:49:33we have three tasks. First we have to
  38618. 23:49:35choose the data management approach and
  38619. 23:49:37after that we're going to do
  38620. 23:49:38brainstorming and designing the layers
  38621. 23:49:40of the data warehouse and at the end
  38622. 23:49:42we're going to go and draw a data
  38623. 23:49:44architecture. So with that we have clear
  38624. 23:49:46understanding how the data architecture
  38625. 23:49:48looks like and after that we're going to
  38626. 23:49:50go to the next epic where we're going to
  38627. 23:49:52start preparing our projects. So once we
  38628. 23:49:54have clear understanding of the data
  38629. 23:49:56architecture the first task here is to
  38630. 23:49:58go and create detailed project tasks. So
  38631. 23:50:01we're going to go and add more AP and
  38632. 23:50:02more tasks. And once we are done then
  38633. 23:50:04we're going to go and create the naming
  38634. 23:50:06conventions for the project just to make
  38635. 23:50:08sure that we have rules and standards in
  38636. 23:50:10the whole project. And next we're going
  38637. 23:50:12to go and create a repository in the git
  38638. 23:50:14and we're going to prepare as well the
  38639. 23:50:15structure of the repository so that we
  38640. 23:50:17always commit our work there. And then
  38641. 23:50:19we're going to start with the first
  38642. 23:50:21script where we're going to create a
  38643. 23:50:22database and schemas. So my friends this
  38644. 23:50:25is the initial plan for the project. Now
  38645. 23:50:27let's start with the first epic. We have
  38646. 23:50:29the requirements
  38647. 23:50:34analyzes. Now analyzing the requirement,
  38648. 23:50:36it is very important to understand which
  38649. 23:50:39type of data warehouse you're going to
  38650. 23:50:40go and build because there is like not
  38651. 23:50:42only one standard on how to build it.
  38652. 23:50:44And if you go blindly implementing the
  38653. 23:50:46data warehouse, you might be doing a lot
  38654. 23:50:48of stuff that is totally unnecessary and
  38655. 23:50:50you will be burning a lot of time. So
  38656. 23:50:53that's why you have to sit with the
  38657. 23:50:54stakeholders with the department and
  38658. 23:50:56understand what we exactly have to build
  38659. 23:50:58and depend on the requirements you
  38660. 23:51:00design the shape of the data warehouse.
  38661. 23:51:03So now let's go and analyze the
  38662. 23:51:04requirement of this project. Now the
  38663. 23:51:06whole project is splitted into two main
  38664. 23:51:08sections. The first section we have to
  38665. 23:51:10go and build a data warehouse. So this
  38666. 23:51:12is a data engineering task and we will
  38667. 23:51:14go and develop ETLs and data warehouse.
  38668. 23:51:17And once we have done that we have to go
  38669. 23:51:20and build analytics and reporting
  38670. 23:51:22business intelligence. So we're going to
  38671. 23:51:24do data analyszis. But now first we will
  38672. 23:51:26be focusing on the first part building
  38673. 23:51:28the data warehouse. So what do we have
  38674. 23:51:30here? The statement is very simple. It
  38675. 23:51:32says develop a modern data warehouse
  38676. 23:51:35using SQL server to consolidate sales
  38677. 23:51:38data enabling analytical reporting and
  38678. 23:51:41informed decision making. So this is the
  38679. 23:51:43main statements and then we have
  38680. 23:51:45specifications. The first one is about
  38681. 23:51:47the data sources. It says import data
  38682. 23:51:49from two source systems ERB and CRM and
  38683. 23:51:52they are provided as CSV files. And now
  38684. 23:51:55the second task is talking about the
  38685. 23:51:57data quality. We have to clean and fix
  38686. 23:51:59data quality issues before we do the
  38687. 23:52:02data analyzers because let's be real
  38688. 23:52:04there is no raw data that is perfect is
  38689. 23:52:06always messy and we have to clean that
  38690. 23:52:08up. Now the next task is talking about
  38691. 23:52:10the integration. So it says we have to
  38692. 23:52:12go and combine both of the sources into
  38693. 23:52:15one single userfriendly data model that
  38694. 23:52:18is designed for analytics and reporting.
  38695. 23:52:21So that means we have to go and merge
  38696. 23:52:22those two sources into one single data
  38697. 23:52:25model. And now we have here another
  38698. 23:52:26specifications. It says focus on the
  38699. 23:52:29latest data sets. So there is no need
  38700. 23:52:31for historiization. So that means we
  38701. 23:52:33don't have to go and build histories in
  38702. 23:52:34the database. And the final requirement
  38703. 23:52:36is talking about the documentation. So
  38704. 23:52:38it says provide clear documentations of
  38705. 23:52:40the data model. So that means the last
  38706. 23:52:42product of the data warehouse to support
  38707. 23:52:45the business users and the analytical
  38708. 23:52:47teams. So that means we have to generate
  38709. 23:52:49a manual that's going to help the users
  38710. 23:52:51that makes lives easier for the
  38711. 23:52:53consumers of our data. So as you can see
  38712. 23:52:55maybe this is very generic requirements
  38713. 23:52:57but it has a lot of informations already
  38714. 23:52:59for you. So it's saying that we have to
  38715. 23:53:01use the platform SQL server. We have two
  38716. 23:53:04source systems using the CSV files and
  38717. 23:53:06it sounds that we really have a bad data
  38718. 23:53:08quality in the sources and as well it
  38719. 23:53:10wants us to focus on building completely
  38720. 23:53:13new data model that is designed for
  38721. 23:53:16reporting and it says we don't have to
  38722. 23:53:18do historiization and it is expected
  38723. 23:53:20from us to generate documentations of
  38724. 23:53:22the system. So these are the
  38725. 23:53:24requirements for the data engineering
  38726. 23:53:26part where we're going to go and build a
  38727. 23:53:28data warehouse that fulfill these
  38728. 23:53:30requirements. All right. Right. So with
  38729. 23:53:31that we have analyzed the requirements
  38730. 23:53:33and as well we have closed the first
  38731. 23:53:35easiest ebick. So we are done with this.
  38732. 23:53:38Let's go and close it. And now let's
  38733. 23:53:39open another one. Here we have to design
  38734. 23:53:42the data architecture and the first task
  38735. 23:53:44is to choose data management approach.
  38736. 23:53:47So let's
  38737. 23:53:50go. Now designing the data architecture
  38738. 23:53:53it is exactly like building a house. So
  38739. 23:53:56before construction starts, an
  38740. 23:53:57architect's going to go and design a
  38741. 23:54:00plan, a blueprint for the house. How the
  38742. 23:54:02rooms will be connected, how to make the
  38743. 23:54:04house functional, safe and wonderful.
  38744. 23:54:07And without this blueprint from the
  38745. 23:54:08architects, the builders might create
  38746. 23:54:10something unstable, inefficient or maybe
  38747. 23:54:13unlivable. The same goes for data
  38748. 23:54:15projects. A data architect is like a
  38749. 23:54:16house architecture. They design how your
  38750. 23:54:19data will flow, integrate and be
  38751. 23:54:21accessed. So as data architects we make
  38752. 23:54:23sure that the data warehouse is not only
  38753. 23:54:25functioning but also scalable and easy
  38754. 23:54:27to maintain. And this is exactly what we
  38755. 23:54:29will do now. We will play the role of
  38756. 23:54:31the data architect and we will start
  38757. 23:54:33brainstorming and designing the
  38758. 23:54:35architecture of the data warehouse. So
  38759. 23:54:37now I'm going to show you a sketch in
  38760. 23:54:39order to understand what are the
  38761. 23:54:40different approaches in order to design
  38762. 23:54:42a data architecture. And this phase of
  38763. 23:54:44the projects usually is very exciting
  38764. 23:54:46for me because this is my main role in
  38765. 23:54:48data projects. I am a data architect and
  38766. 23:54:51I discuss a lot of different projects
  38767. 23:54:53where we try to find out the best design
  38768. 23:54:55for the projects. All right. So now
  38769. 23:54:56let's
  38770. 23:55:00go. Now the first step of building a
  38771. 23:55:02data architecture is to make a very
  38772. 23:55:04important decision to choose between
  38773. 23:55:07four major types. The first approach is
  38774. 23:55:09to build a data warehouse. It is very
  38775. 23:55:11suitable if you have only structured
  38776. 23:55:13data and your business want to build
  38777. 23:55:15solid foundations for reporting and
  38778. 23:55:18business intelligence. And another
  38779. 23:55:20approach is to build a data leak. This
  38780. 23:55:22one is way more flexible than a data
  38781. 23:55:24warehouse where you can store not only
  38782. 23:55:26structured data but as well semi and
  38783. 23:55:29unstructured data. We usually use this
  38784. 23:55:31approach if you have mixed types of data
  38785. 23:55:33like database tables, logs, images,
  38786. 23:55:35videos and your business want to focus
  38787. 23:55:37not only on reporting but as well on
  38788. 23:55:40advanced analytics or machine learning
  38789. 23:55:42but it's not that organized like a data
  38790. 23:55:44warehouse and data leaks if it's too
  38791. 23:55:46much unorganized and turns into data
  38792. 23:55:49swamp and this is where we need the next
  38793. 23:55:51approach. So the next one we can go and
  38794. 23:55:53build data lakehouse. So it is like a
  38795. 23:55:56mix between data warehouse and data
  38796. 23:55:58lake. You get the flexibility of having
  38797. 23:56:00different types of data from the data
  38798. 23:56:02lake but you still want to structure and
  38799. 23:56:04organize your data like we do in the
  38800. 23:56:06data warehouse. So you mix those two
  38801. 23:56:07words into one and this is a very modern
  38802. 23:56:10way on how to build that architecture
  38803. 23:56:12and this is currently my favorite way of
  38804. 23:56:14building data management system. Now the
  38805. 23:56:16last and very recent approach is to
  38806. 23:56:18build data mesh. So this is a little bit
  38807. 23:56:20different. Instead of having centralized
  38808. 23:56:22data management system the idea now in
  38809. 23:56:24the data mesh is to make it
  38810. 23:56:26decentralized. You cannot have like one
  38811. 23:56:28centralized data management system
  38812. 23:56:29because always if you say centralized
  38813. 23:56:31then it means bottleneck. So instead you
  38814. 23:56:34have multiple departments and multiple
  38815. 23:56:35domains where each one of them is
  38816. 23:56:37building a data product and sharing it
  38817. 23:56:39with others. So now you have to go and
  38818. 23:56:41pick one of those approaches and in this
  38819. 23:56:43project we will be focusing on the data
  38820. 23:56:45warehouse. So now the question is how to
  38821. 23:56:47build the data warehouse. Well there is
  38822. 23:56:49as well four different approaches on how
  38823. 23:56:51to build it. The first one is the
  38824. 23:56:53enimmon approach. So again you have your
  38825. 23:56:55sources and the first layer you start
  38826. 23:56:57with the staging where the row data is
  38827. 23:56:59landing and then the next layer you
  38828. 23:57:01organize your data in something called
  38829. 23:57:03enterprise data warehouse where you go
  38830. 23:57:06and model the data using the third
  38831. 23:57:08normal format. It's about like how to
  38832. 23:57:10structure and normalize your tables. So
  38833. 23:57:12you are building a new integrated data
  38834. 23:57:15model from the multiple sources. And
  38835. 23:57:17then we go to the third layer. It's
  38836. 23:57:18called the data marts where you go and
  38837. 23:57:20take like small subset of the data
  38838. 23:57:22warehouse and you design it in a way
  38839. 23:57:25that is ready to be consumed from
  38840. 23:57:27reporting and it focus on only one topic
  38841. 23:57:29like for example the customers sales or
  38842. 23:57:32products and after that you go and
  38843. 23:57:34connect your BI tool like PowerBI or
  38844. 23:57:36Tableau to the data marts. So with that
  38845. 23:57:38you have three layers to prepare the
  38846. 23:57:40data before reporting. Now moving on to
  38847. 23:57:42the next one we have the Kimple
  38848. 23:57:44approach. He says you know what building
  38849. 23:57:46this enterprise data warehouse it is
  38850. 23:57:48wasting a lot of time. So what we can do
  38851. 23:57:50we can jump immediately from the stage
  38852. 23:57:53layer to the final data because building
  38853. 23:57:55this enterprise data warehouse it is a
  38854. 23:57:58big struggle and usually waste a lot of
  38855. 23:58:00time. So he always want you to focus and
  38856. 23:58:02building the data ms quickly as
  38857. 23:58:04possible. So it is faster approach than
  38858. 23:58:06in but with the time you might get chaos
  38859. 23:58:09in the data MS cuz you are not always
  38860. 23:58:10focusing in the big picture and you
  38861. 23:58:12might be repeating same transformations
  38862. 23:58:14and integrations in different data ms.
  38863. 23:58:17So there is like trade-off between the
  38864. 23:58:19speed and consistent data warehouse. Now
  38865. 23:58:22moving on to the third approach we have
  38866. 23:58:23the data vault. So we still have the
  38867. 23:58:25stage and the data marts but it says we
  38868. 23:58:28still need this central data warehouse
  38869. 23:58:30in the middle but this middle layer
  38870. 23:58:32we're going to bring more standards and
  38871. 23:58:34rules. So it tells you to split this
  38872. 23:58:36middle layer into two layers the row
  38873. 23:58:38vault and the business vault. In the row
  38874. 23:58:41vault you have the original data but in
  38875. 23:58:43the business vault you have all the
  38876. 23:58:44business rules and transformations that
  38877. 23:58:46prepares the data for the data marks. So
  38878. 23:58:49that vault it is very similar to the
  38879. 23:58:50inmon but it brings more standards and
  38880. 23:58:53rules to the middle layer. Now I'm going
  38881. 23:58:56to go and add a fourth one that I'm
  38882. 23:58:58going to call it medallion architecture
  38883. 23:59:00and this one is my favorite one because
  38884. 23:59:02it is very easy to understand and to
  38885. 23:59:04build. So it says you're going to go and
  38886. 23:59:06build three layers bronze, silver and
  38887. 23:59:08gold. The bronze layer it is very
  38888. 23:59:10similar to the stage but we have
  38889. 23:59:12understood with the time that the stage
  38890. 23:59:14layer is very important because having
  38891. 23:59:16the original data as it is it going to
  38892. 23:59:18helps a lot by traceability and finding
  38893. 23:59:20issues. Then the next layer we have the
  38894. 23:59:22silver layer. It is where we do
  38895. 23:59:24transformations data cleansing but we
  38896. 23:59:26don't apply yet any business rules. Now
  38897. 23:59:28moving on to the last layer the gold
  38898. 23:59:30layer. It is as well very similar to the
  38899. 23:59:32data marts but there we can build
  38900. 23:59:34different type of objects not only for
  38901. 23:59:36reporting but as well for machine
  38902. 23:59:38learning for AI and for many different
  38903. 23:59:41purposes. So they are like business
  38904. 23:59:43ready objects that you want to share as
  38905. 23:59:45a data products. So those are the four
  38906. 23:59:47approaches that you can use in order to
  38907. 23:59:49build a data warehouse. So again if you
  38908. 23:59:52are building a data architecture you
  38909. 23:59:54have to specify which approach you want
  38910. 23:59:56to follow. So at the start we said we
  38911. 23:59:57want to build a data warehouse and then
  38912. 23:59:59we have to decide between those four
  38913. 24:00:00approaches on how to build a data
  38914. 24:00:02warehouse and in this project we will be
  38915. 24:00:04using the medallion architecture. So
  38916. 24:00:06this is a very important question that
  38917. 24:00:08you have to answer as the first step of
  38918. 24:00:10building a data architecture. All right.
  38919. 24:00:12So with that we have decided on the
  38920. 24:00:13approach. So we can go and mark it as
  38921. 24:00:16done. The next step we're going to go
  38922. 24:00:17and design the layers of the data
  38923. 24:00:20warehouse.
  38924. 24:00:24Now there is like not 100% standard way
  38925. 24:00:28and rules for each layer. What you have
  38926. 24:00:30to do as a data architects you have to
  38927. 24:00:32define exactly what is the purpose of
  38928. 24:00:35each layer. So we start with the bronze
  38929. 24:00:36layer. So we say it's going to store row
  38930. 24:00:39and unprocessed data as it is from the
  38931. 24:00:41sources. And why we are doing that it is
  38932. 24:00:43for traceability and debugging. If you
  38933. 24:00:46have a layer where you are keeping the
  38934. 24:00:47raw data, it is very important to have
  38935. 24:00:49the data as it is from the sources
  38936. 24:00:51because we can go always back to the
  38937. 24:00:53bronze layer and investigate the data of
  38938. 24:00:55specific source if something goes wrong.
  38939. 24:00:58So the main objective is to have raw
  38940. 24:01:01untouched data that's going to helps you
  38941. 24:01:03as a data engineer by analyzing the root
  38942. 24:01:05cause of issues. Now moving on to the
  38943. 24:01:07server layer. It is the layer where
  38944. 24:01:09we're going to store clean and
  38945. 24:01:10standardized data and this is the place
  38946. 24:01:13where we're going to do basic
  38947. 24:01:14transformations in order to prepare the
  38948. 24:01:16data for the final layer. Now for the go
  38949. 24:01:19layer it's going to contain business
  38950. 24:01:20ready data. So the main goal here is to
  38951. 24:01:23provide data that could be consumed by
  38952. 24:01:25business users and analysts in order to
  38953. 24:01:27build reporting and analytics. So with
  38954. 24:01:29that we have defined the main goal for
  38955. 24:01:31each layer. Now next what I would like
  38956. 24:01:33to do is to define the object types and
  38957. 24:01:36since we are talking about a data
  38958. 24:01:37warehouse in database we have here
  38959. 24:01:39generally two types either a table or a
  38960. 24:01:42view. So we are going for the bronze
  38961. 24:01:43layer and the silver layer with tables
  38962. 24:01:45but for the gold layer we are going with
  38963. 24:01:47the views. So the best practice says for
  38964. 24:01:50the last layer in your data warehouse
  38965. 24:01:52make it virtual using views. It going to
  38966. 24:01:54gives you a lot of dynamic and of course
  38967. 24:01:56speed in order to build it since we
  38968. 24:01:58don't have to make a load process for
  38969. 24:01:59it. And now the next step is that we're
  38970. 24:02:01going to go and define the load method.
  38971. 24:02:03So in this project I have decided to go
  38972. 24:02:04with the full load using the method of
  38973. 24:02:06truncating and inserting. It is just
  38974. 24:02:08faster and way easier. So we're going to
  38975. 24:02:10say for the bronze layer we're going to
  38976. 24:02:11go with the full load. And you have to
  38977. 24:02:13specify as well for the silver layer as
  38978. 24:02:15well. We're going to go with the full
  38979. 24:02:16load. And of course for the views we
  38980. 24:02:18don't need any load process. So each
  38981. 24:02:20time you decide to go with tables you
  38982. 24:02:22have to define the load methods with our
  38983. 24:02:24full load, incremental loads and so on.
  38984. 24:02:25Now we come to the very interesting part
  38985. 24:02:27the data transformations. Now for the
  38986. 24:02:29bronze layer, it is the easiest one
  38987. 24:02:31about this topic because we don't have
  38988. 24:02:33any transformations. We have to commit
  38989. 24:02:35ourself to not touch the data, do not
  38990. 24:02:38manipulate it, don't change anything. So
  38991. 24:02:40it's going to stay as it is. If it comes
  38992. 24:02:42bad, it's going to stay bad in the
  38993. 24:02:43bronze layer. And now we come to the
  38994. 24:02:45silver layer where we have the heavy
  38995. 24:02:46lifting. As we committed in the
  38996. 24:02:48objective, we have to make clean and
  38997. 24:02:50standardized data. And for that we have
  38998. 24:02:52different types of transformations. So
  38999. 24:02:54we have to do data cleansing, data
  39000. 24:02:56standardizations, data normalizations.
  39001. 24:02:58We have to go and derive new columns and
  39002. 24:03:01data enrichment. So there are like bunch
  39003. 24:03:03of transformations that we have to do in
  39004. 24:03:06order to prepare the data. Our focus
  39005. 24:03:07here is to transform the data to make it
  39006. 24:03:10clean and following standards and try to
  39007. 24:03:12push all business transformations to the
  39008. 24:03:14next layer. So that means in the god
  39009. 24:03:16layer we will be focusing on business
  39010. 24:03:19transformations that is needed for the
  39011. 24:03:21consumers for the use cases. So what we
  39012. 24:03:23do here we do data integrations between
  39013. 24:03:25source system we do data aggregations we
  39014. 24:03:28apply a lot of business logics and rules
  39015. 24:03:30and we build a data model that is ready
  39016. 24:03:32for for example business intelligence.
  39017. 24:03:34So here we do a lot of business
  39018. 24:03:36transformations and in the silver layer
  39019. 24:03:38we do basic data transformations. So it
  39020. 24:03:40is really here very important to make
  39021. 24:03:43the fine decisions what type of
  39022. 24:03:45transformations to be done in each layer
  39023. 24:03:47and make sure that you commit to those
  39024. 24:03:49rules. Now the next aspect is about the
  39025. 24:03:51data modeling in the bronze layer and
  39026. 24:03:53the silver layer. We will not break the
  39027. 24:03:55data model that comes from the source
  39028. 24:03:57system. So if the source system deliver
  39029. 24:03:59five tables, we're going to have here
  39030. 24:04:00like five tables and as well in the
  39031. 24:04:02silver layer. We will not go and
  39032. 24:04:04denormalize or normalize or like make
  39033. 24:04:06something new, we're going to leave it
  39034. 24:04:08exactly like it comes from the source
  39035. 24:04:09system because what we're going to do,
  39036. 24:04:11we're going to build the data model in
  39037. 24:04:13the gold layer. And here you have to
  39038. 24:04:14define which data model you want to
  39039. 24:04:16follow. Are you following the star
  39040. 24:04:18schema, the snowflake or are you just
  39041. 24:04:20making aggregated objects? So you have
  39042. 24:04:22to go and make a list of all data models
  39043. 24:04:24types that you're going to follow in the
  39044. 24:04:26gold layer. And at the end, what you can
  39045. 24:04:27specify in each layer is the target
  39046. 24:04:29audience. And this is of course very
  39047. 24:04:31important decision. In the bronze layer,
  39048. 24:04:33you don't want to give access to any end
  39049. 24:04:35user. It is really important to make
  39050. 24:04:36sure that only data engineers access the
  39051. 24:04:39bronze layer. It makes no sense for data
  39052. 24:04:41analysts or data scientists to go to the
  39053. 24:04:44bad data because you have a better
  39054. 24:04:46version for that in the silver layer. So
  39055. 24:04:48in the silver layer of course the data
  39056. 24:04:50engineers have to have an access to it
  39057. 24:04:51and as well the data analysts and the
  39058. 24:04:54data scientists and so on but still you
  39059. 24:04:55don't give it to any business user that
  39060. 24:04:58can't deal with the raw data model from
  39061. 24:05:00the sources because for the business
  39062. 24:05:02users you're going to get a better layer
  39063. 24:05:04for them and that is the go layer. So in
  39064. 24:05:06the gold layer it is suitable for the
  39065. 24:05:09data analyst and as well the business
  39066. 24:05:11users because usually the business users
  39067. 24:05:13don't have a deep knowledge on the
  39068. 24:05:14technicality of the server layer. So if
  39069. 24:05:17you are designing multiple layers you
  39070. 24:05:18have to discuss all those topics and
  39071. 24:05:20make clear decision for each layer. All
  39072. 24:05:23right my friends. So now before we
  39073. 24:05:24proceed with the design I want to tell
  39074. 24:05:26you a secret principle concept that each
  39075. 24:05:29data architect must know and that is the
  39076. 24:05:32separation of concerns. So what is that?
  39077. 24:05:34As you are designing an architecture,
  39078. 24:05:36you have to make sure to break down the
  39079. 24:05:38complex system into smaller independent
  39080. 24:05:41parts and each part is responsible for a
  39081. 24:05:44specific task. And here comes the magic.
  39082. 24:05:47The component of your architecture must
  39083. 24:05:49not be duplicated. So you cannot have
  39084. 24:05:51two parts are doing the same thing. So
  39085. 24:05:53the idea here is to not mix everything.
  39086. 24:05:56And this is one of the biggest mistakes
  39087. 24:05:58in any big projects and I have shown
  39088. 24:06:00that almost everywhere. So a good data
  39089. 24:06:03architects follow this concept this
  39090. 24:06:05principle. So for example if you are
  39091. 24:06:07looking to our data architecture we have
  39092. 24:06:09already done that. So we have defined
  39093. 24:06:11unique set of tasks for each layer. So
  39094. 24:06:14for example we have said in the server
  39095. 24:06:16layer we do data cleansing but in the
  39096. 24:06:18gold layer we do business
  39097. 24:06:20transformations and with that you will
  39098. 24:06:22not be allowing to do any business
  39099. 24:06:24transformations. In the server layer and
  39100. 24:06:26the same thing goes for the gold layer.
  39101. 24:06:28You don't do in the gold layer any data
  39102. 24:06:29cleansing. So each layer has its own
  39103. 24:06:32unique tasks and the same thing goes for
  39104. 24:06:34the bronze layer and the silver layer.
  39105. 24:06:36You do not allow to load data from the
  39106. 24:06:38source systems directly to the silver
  39107. 24:06:40layer because we have decided the
  39108. 24:06:42landing layer. The first layer is the
  39109. 24:06:45bronze layer otherwise you will have
  39110. 24:06:46like set of source systems that are
  39111. 24:06:48loaded first to the bronze layer and
  39112. 24:06:50another set is skipping the layer and
  39113. 24:06:52going to the silver and with that we
  39114. 24:06:54have overlapping. You are doing data
  39115. 24:06:56ingestion in two different layers. So my
  39116. 24:06:59friends, if you have this mindset,
  39117. 24:07:01separation of concerns, I promise you,
  39118. 24:07:03you're going to be a top data architect.
  39119. 24:07:05So think about it. All right, my
  39120. 24:07:06friends. So with that, we have designed
  39121. 24:07:08the layers of the data warehouse. We can
  39122. 24:07:10go ahead close it. The next step, we're
  39123. 24:07:12going to go to DYO and start drawing the
  39124. 24:07:14data
  39125. 24:07:18architecture. So there is like no one
  39126. 24:07:20standard on how to build a data
  39127. 24:07:22architecture. You can add your style and
  39128. 24:07:24the way that you want. So now the first
  39129. 24:07:26thing that we have to show in that
  39130. 24:07:27architecture is the different layers
  39131. 24:07:29that we have. The first layer is the
  39132. 24:07:31source system layer. So let's go and
  39133. 24:07:33take a box like this and make it a
  39134. 24:07:35little bit bigger. And I'm just going to
  39135. 24:07:37go and make the design. So I'm going to
  39136. 24:07:38remove the fill and make the line dotted
  39137. 24:07:41one. And after that I'm going to go and
  39138. 24:07:42change maybe the color to something like
  39139. 24:07:44this gray. So now we have like a
  39140. 24:07:46container for the first layer. And then
  39141. 24:07:48we have to go and add like a text on top
  39142. 24:07:50of it. So what I'm going to do, I'm
  39143. 24:07:51going to take another box. Let's go and
  39144. 24:07:53type inside it sources. And now I'm
  39145. 24:07:55going to go and style it. So I'm going
  39146. 24:07:56to go to the text and make it maybe 24.
  39147. 24:07:59And then remove the lines like this.
  39148. 24:08:02Make it a little bit smaller and put it
  39149. 24:08:04on top. So this is the first layer. This
  39150. 24:08:06is where the data come from. And then
  39151. 24:08:08the data going to go inside a data
  39152. 24:08:10warehouse. So I'm just going to go and
  39153. 24:08:12duplicate this one. This one is the data
  39154. 24:08:18warehouse. All right. So now the third
  39155. 24:08:20layer what it going to be? It's going to
  39156. 24:08:22be the consumers. who will be consuming
  39157. 24:08:24this data warehouse. So I'm going to put
  39158. 24:08:27another box and say this is the consume
  39159. 24:08:30layer. Okay. So those are the three
  39160. 24:08:32containers. Now inside the data
  39161. 24:08:34warehouse, we have decided to build it
  39162. 24:08:36using the medallion architecture. So
  39163. 24:08:38we're going to have three layers inside
  39164. 24:08:40the warehouse. So I'm going to take
  39165. 24:08:41again another box. I'm going to call
  39166. 24:08:44this one. This is the bronze layer. And
  39167. 24:08:47now we have to go and put a design for
  39168. 24:08:49it. So I'm going to go with this color
  39169. 24:08:50over here. And then the text and maybe
  39170. 24:08:52something like 20. And then make it a
  39171. 24:08:55little bit smaller and just put it here.
  39172. 24:08:57And beneath that we're going to have the
  39173. 24:09:00component. So this is just a title of a
  39174. 24:09:02container. So I'm going to have it like
  39175. 24:09:03this. Remove the text from inside it.
  39176. 24:09:06And remove the filling. So this
  39177. 24:09:09container is for the bronze layer. Let's
  39178. 24:09:11go and duplicate it for the next one. So
  39179. 24:09:14this one going to be the silver layer.
  39180. 24:09:17And of course, we can go and change the
  39181. 24:09:19coloring to gray because it is silver.
  39182. 24:09:21And as well the lines and remove the
  39183. 24:09:23filling. Great. And now maybe I'm going
  39184. 24:09:25to make the font as bold. All right. Now
  39185. 24:09:28the third layer going to be the gold
  39186. 24:09:31layer. And we have to go and pick a
  39187. 24:09:33color for that. So style and here we
  39188. 24:09:36have like something like yellow. The
  39189. 24:09:38same thing for the container. I remove
  39190. 24:09:40the filling. So with that we are showing
  39191. 24:09:42now the different layers inside our data
  39192. 24:09:44warehouse. Now those containers are
  39193. 24:09:46empty. What we're going to do, we're
  39194. 24:09:47going to go inside each one of them and
  39195. 24:09:48start adding contents. So now in the
  39196. 24:09:50sources, it is very important to make it
  39197. 24:09:52clear what are the different types of
  39198. 24:09:54source systems that you are connecting
  39199. 24:09:56to the data warehouse because in real
  39200. 24:09:58project there are like multiple types.
  39201. 24:09:59You might have a database, API, files,
  39202. 24:10:02cafka and here it's important to show
  39203. 24:10:04those different types. In other projects
  39204. 24:10:06we have folders and inside those folders
  39205. 24:10:08we have CSV files. So now what you have
  39206. 24:10:09to do we have to make it clear in this
  39207. 24:10:11layer that the input for our project is
  39208. 24:10:14CSV file. So it really depend how you
  39209. 24:10:16want to show that. I'm going to go over
  39210. 24:10:18here and say maybe folder and then I'm
  39211. 24:10:20going to go and take the folder and put
  39212. 24:10:21it here inside and then maybe search for
  39213. 24:10:24file more results and go pick one of
  39214. 24:10:26those icons. For example, I'm going to
  39215. 24:10:28go with this one over here. So I'm going
  39216. 24:10:30to make it smaller and add it on top of
  39217. 24:10:32the folder. So with that we make it
  39218. 24:10:34clear for everyone seeing the
  39219. 24:10:35architecture that the sources is not a
  39220. 24:10:38database is not an API it is a file
  39221. 24:10:41inside the folder. So now very important
  39222. 24:10:42here to show is the source systems. What
  39223. 24:10:45are the sources that is involved in the
  39224. 24:10:47project. So here what we're going to do
  39225. 24:10:48we're going to go and give it a name.
  39226. 24:10:49For example we have one source called
  39227. 24:10:51CRM like this and maybe make the icon
  39228. 24:10:54and we have another source called ERP.
  39229. 24:10:56So we're going to go and duplicate it
  39230. 24:10:58put it over here and then rename it ERP.
  39231. 24:11:01So now it is for everyone clear. We have
  39232. 24:11:02two sources for this project and the
  39233. 24:11:04technology is used is simply a file. So
  39234. 24:11:06now what we can do as well we can go and
  39235. 24:11:08add some descriptions inside this box to
  39236. 24:11:10make it more clear. So what I'm going to
  39237. 24:11:12do, I'm going to take a line because I
  39238. 24:11:14want to split the description from the
  39239. 24:11:16icons something like this and make it
  39240. 24:11:18gray. And then below it, we're going to
  39241. 24:11:19go and add some text and we're going to
  39242. 24:11:21say is CSV file. And the next point and
  39243. 24:11:25we can say the interface is simply files
  39244. 24:11:29in folder. And of course you can go and
  39245. 24:11:31add any specifications and explanation
  39246. 24:11:34about the sources. If it is a database,
  39247. 24:11:36you can say the type of the database and
  39248. 24:11:37so on. So that we made it in the data
  39249. 24:11:39architecture clear what are the sources
  39250. 24:11:41of our data warehouse. And now the next
  39251. 24:11:43step what we're going to do we're going
  39252. 24:11:44to go and design the content of the
  39253. 24:11:46bronze silver and gold. So I'm going to
  39254. 24:11:48start by adding like an icon in each
  39255. 24:11:50container. It is to show about that we
  39256. 24:11:52are talking about database. So what
  39257. 24:11:54we're going to do we're going to go and
  39258. 24:11:55search for database and then more
  39259. 24:11:58result. More results. I'm going to go
  39260. 24:12:00with this icon over here. So let's go
  39261. 24:12:03and make it bigger. Something like this.
  39262. 24:12:05Maybe change the color of dots. So,
  39263. 24:12:07we're going to have the bronze and as
  39264. 24:12:09well here the silver and the gold. So,
  39265. 24:12:12now what we can do, we're going to go
  39266. 24:12:13and add some arrows between those
  39267. 24:12:15layers. So, we're going to go over here.
  39268. 24:12:17So, we can go and search for arrow and
  39269. 24:12:18maybe go and pick one of those. Let's go
  39270. 24:12:21and put it here. And we can go and pick
  39271. 24:12:23a color for that. Maybe something like
  39272. 24:12:25this. And adjust it. So, now we're going
  39273. 24:12:27to have this nice arrow between all the
  39274. 24:12:29layers just to explain the direction of
  39275. 24:12:31our architecture, right? So we can read
  39276. 24:12:33it from left to right and as well
  39277. 24:12:36between the go layer and the consume.
  39278. 24:12:38Okay. So now what I'm going to do next
  39279. 24:12:40we're going to go and add one statement
  39280. 24:12:42about each layer the main objective. So
  39281. 24:12:44let's go and grab a text and put it
  39282. 24:12:46beneath the database and we're going to
  39283. 24:12:48say for example for the bronze layer
  39284. 24:12:49it's going to be the row data. Maybe
  39285. 24:12:51make the text bigger so you are the row
  39286. 24:12:54data. And then the next one in the
  39287. 24:12:56silver you are clean standard data. And
  39288. 24:13:01then the last one for the gold we can
  39289. 24:13:03say business
  39290. 24:13:05ready data. So with that we make the
  39291. 24:13:08objective clear for each layer. Now
  39292. 24:13:10below all those icons what we're going
  39293. 24:13:11to do we're going to have a separator
  39294. 24:13:13again like this. Make it like colored.
  39295. 24:13:16And beneath it we're going to add the
  39296. 24:13:17most important specifications of this
  39297. 24:13:19layer. So let's go and add those
  39298. 24:13:21separators in each layer. Okay. So now
  39299. 24:13:24we need a text below it. Let's take this
  39300. 24:13:26one here. So what is the object type of
  39301. 24:13:29the bronze layer? That's going to be a
  39302. 24:13:31table and we can go and add the load
  39303. 24:13:34methods. We say this is patch
  39304. 24:13:36processing. Since we are not doing
  39305. 24:13:38streaming, we can say it is a full load.
  39306. 24:13:41We are not doing incremental load. So we
  39307. 24:13:43can say here trank and insert. And then
  39308. 24:13:48we add one more section maybe about the
  39309. 24:13:50transformations. So we can say no
  39310. 24:13:53transformations. And one more about the
  39311. 24:13:55data model. We're going to say none as
  39312. 24:13:58is. And now what I'm going to do I'm
  39313. 24:14:00going to go and add those specifications
  39314. 24:14:01as well for the silver and gold. So here
  39315. 24:14:03what we have discussed the object type
  39316. 24:14:05the load process the
  39317. 24:14:07transformations and whether we are
  39318. 24:14:08breaking the data model or not the same
  39319. 24:14:11thing for the gold layer. So I can say
  39320. 24:14:13with that we have really nice layering
  39321. 24:14:15of the data warehouse and what we are
  39322. 24:14:16left is with the consumers over here you
  39323. 24:14:19can go and add the different use cases
  39324. 24:14:20and tools that can access your data
  39325. 24:14:22warehouse like for example I'm adding
  39326. 24:14:24here business intelligence and reporting
  39327. 24:14:26maybe using PowerBI or Tableau or you
  39328. 24:14:29can say you can access my data warehouse
  39329. 24:14:30in order to do at analyzes using the SQL
  39330. 24:14:33queries and this is what we're going to
  39331. 24:14:35focus on the projects after we build the
  39332. 24:14:37data warehouse and as well you can offer
  39333. 24:14:39it for machine learning purposes and of
  39334. 24:14:41course it It's really nice to add some
  39335. 24:14:43icons in your architecture and usually I
  39336. 24:14:44use this nice websites called flat icon.
  39337. 24:14:47It has really amazing icons that you can
  39338. 24:14:49go and use it in your architecture. Now,
  39339. 24:14:51of course, we can go and keep adding
  39340. 24:14:53icons and stuff to explain the data
  39341. 24:14:55architecture and as well the system.
  39342. 24:14:56Like for example, it is very important
  39343. 24:14:58here to say which tools you are using in
  39344. 24:15:00order to build this data warehouse. Is
  39345. 24:15:02it in the cloud? Are using Azure datab
  39346. 24:15:04bricks or maybe snowflake? So we're
  39347. 24:15:06going to go and add for our project the
  39348. 24:15:08icon of SQL server since we are building
  39349. 24:15:11this data warehouse completely in the
  39350. 24:15:13SQL server. So for now I'm really happy
  39351. 24:15:14about it. As you can see we have now a
  39352. 24:15:16plan right. All right guys so with that
  39353. 24:15:18we have designed the data architecture
  39354. 24:15:20using the doyo and with that we have
  39355. 24:15:22done the last step in this epic and now
  39356. 24:15:24with that we have a design for the data
  39357. 24:15:26architecture and we can say we have
  39358. 24:15:28closed this epic. Now let's go to the
  39359. 24:15:30next one. We will start doing the first
  39360. 24:15:32step to prepare our project. And the
  39361. 24:15:34first task here is to create a detailed
  39362. 24:15:36project
  39363. 24:15:40plan. All right, my friends. So now it's
  39364. 24:15:43clear for us that we have three layers
  39365. 24:15:44and we have to go and build them. So
  39366. 24:15:46that means our big epics going to be
  39367. 24:15:48after the layers. So here I have added
  39368. 24:15:50three more epics. So we have build
  39369. 24:15:53bronze layer, build silver layer and
  39370. 24:15:55gold layer. And after that I went and
  39371. 24:15:57start defining all the different tasks
  39372. 24:16:00that we have to follow in the projects.
  39373. 24:16:02So at the start we will be analyzing
  39374. 24:16:04then coding and after that we're going
  39375. 24:16:06to go and do testing and once everything
  39376. 24:16:08is ready we're going to go and document
  39377. 24:16:10stuff and at the end we have to commit
  39378. 24:16:12our work in the get repo. All those
  39379. 24:16:14epics are following the same like
  39380. 24:16:16pattern in the tasks. So as you can see
  39381. 24:16:18now we have a very detailed project
  39382. 24:16:20structure and now things are more
  39383. 24:16:22cleared for us how we're going to build
  39384. 24:16:24the data warehouse. So with that we are
  39385. 24:16:26done from this task and now the next
  39386. 24:16:29task we have to go and define the naming
  39387. 24:16:31convention of the
  39388. 24:16:36projects. All right. So now at this
  39389. 24:16:38phase of the projects we usually define
  39390. 24:16:40the naming conventions. So what is that?
  39391. 24:16:42It is set of rules that you define for
  39392. 24:16:45naming everything in the projects
  39393. 24:16:47whether it is a database, schema,
  39394. 24:16:49tables, stored procedures, folders,
  39395. 24:16:52anything. And if you don't do that at
  39396. 24:16:54the early phase of the projects, I
  39397. 24:16:56promise you chaos can happen because
  39398. 24:16:58what going to happen? You will have
  39399. 24:16:59different developers in your projects
  39400. 24:17:01and each of those developers have their
  39401. 24:17:03own style of course. So one developer
  39402. 24:17:05might name a table dimension customers
  39403. 24:17:08where everything is lowerase and between
  39404. 24:17:10them underscore and you have another
  39405. 24:17:12developer creating another table called
  39406. 24:17:14dimension products but using the camel
  39407. 24:17:16case. So there is no separation between
  39408. 24:17:18the words and the first character is
  39409. 24:17:20capitalized and maybe another one using
  39410. 24:17:22some prefixes like
  39411. 24:17:24dim categories. So we have here like a
  39412. 24:17:26shortcut of the dimension. So as you can
  39413. 24:17:28see there are different designs and
  39414. 24:17:30styles and if you leave the door open
  39415. 24:17:32what can happen in the middle of the
  39416. 24:17:33project you will notice okay everything
  39417. 24:17:35looks inconsistent and you can define a
  39418. 24:17:38big task to go and rename everything
  39419. 24:17:41following a specific rule. So instead of
  39420. 24:17:43wasting all this time at this phase you
  39421. 24:17:46go and define the naming conventions and
  39422. 24:17:48let's go and do that. So we usually
  39423. 24:17:50start with a very important decision and
  39424. 24:17:52that is which naming convention we going
  39425. 24:17:55to follow in the whole project. So you
  39426. 24:17:56have different cases like the camel
  39427. 24:17:58case, the Pascal case, the kebab case,
  39428. 24:18:02and the snake case. And for this
  39429. 24:18:04project, we're going to go with the
  39430. 24:18:05snake case where all the letters of a
  39431. 24:18:08word going to be lowercased. And the
  39432. 24:18:10separation between words going to be an
  39433. 24:18:13underscore. For example, a table name
  39434. 24:18:15called customer info. Customer is
  39435. 24:18:17lowercased. Info is as well lowercased.
  39436. 24:18:19And between them an underscore. So this
  39437. 24:18:21is always the first thing that you have
  39438. 24:18:23to decide for your data projects. The
  39439. 24:18:25second thing is to decide the language.
  39440. 24:18:28So for example, I work in Germany and
  39441. 24:18:30there is always like a decision that we
  39442. 24:18:31have to make whether we use Germany or
  39443. 24:18:34English. So we have to decide for our
  39444. 24:18:35project which language we're going to
  39445. 24:18:37use. And a very important general rule
  39446. 24:18:40is that avoid reserved words. So don't
  39447. 24:18:43use a square reserved word as an object
  39448. 24:18:45name like for example table. Don't give
  39449. 24:18:47a table name as a table. So those are
  39450. 24:18:50the general principles. So those are the
  39451. 24:18:52general rules that you have to follow in
  39452. 24:18:54the whole project. This applies for
  39453. 24:18:56everything for tables, columns, stored
  39454. 24:18:58procedures, any names that you are
  39455. 24:19:00giving in your scripts. Now moving on,
  39456. 24:19:02we have specifications for the table
  39457. 24:19:04names. And here we have different set of
  39458. 24:19:06rules for each layer. So here the rule
  39459. 24:19:09says source system underscore entity. So
  39460. 24:19:12we are saying all the tables in the
  39461. 24:19:14bronze layer should start first with the
  39462. 24:19:16source system name like for example CRM
  39463. 24:19:19or ARB and after that we have an
  39464. 24:19:21underscore and then at the end we have
  39465. 24:19:23the entity name or the table name. So
  39466. 24:19:25for example we have this table name CRM.
  39467. 24:19:28So that means this table comes from the
  39468. 24:19:31source system CRM and then we have the
  39469. 24:19:34table name the entity name customer
  39470. 24:19:35info. So this is the rule that we're
  39471. 24:19:37going to follow in naming all tables in
  39472. 24:19:39the bronze layer. Then moving on to the
  39473. 24:19:41silver layer, it is exactly like the
  39474. 24:19:43bronze because we are not going to
  39475. 24:19:45rename anything. We are not going to
  39476. 24:19:47build any new data model. So the naming
  39477. 24:19:50going to be one one to one like the
  39478. 24:19:52bronze. So it is exactly the same rules
  39479. 24:19:54as the bronze. But if we go to the gold
  39480. 24:19:56here, since we are building new data
  39481. 24:19:58model, we have to go and rename things.
  39482. 24:20:01And since as well we are integrating
  39483. 24:20:02multiple sources together, we will not
  39484. 24:20:05be using the source system name in the
  39485. 24:20:07tables because inside one table you
  39486. 24:20:09could have multiple sources. So the rule
  39487. 24:20:11says all the names must be meaningful
  39488. 24:20:13business aligned names for the tables
  39489. 24:20:16starting with the category prefix. So
  39490. 24:20:18here the rule says it start with
  39491. 24:20:20category then underscore and then
  39492. 24:20:22entity. Now what is category? We have in
  39493. 24:20:25the code layer different types of
  39494. 24:20:27tables. So we could build a table called
  39495. 24:20:29a fact table. Another one could be a
  39496. 24:20:31dimension. A third type could be an
  39497. 24:20:33aggregation or a report. So we have
  39498. 24:20:36different types of tables and we can
  39499. 24:20:38specify those types as a prefix at the
  39500. 24:20:41start. So for example we are saying here
  39501. 24:20:44effect sales. So the category is fact
  39502. 24:20:47and the table name called sales. And
  39503. 24:20:49here I just made like a table with
  39504. 24:20:51different type of patterns. So we could
  39505. 24:20:53have a dimension. So we say it start
  39506. 24:20:55with the dim underscore for example
  39507. 24:20:57dimim customers or products. And then we
  39508. 24:21:00have another type called fact table. So
  39509. 24:21:02it start with fact underscore or
  39510. 24:21:04aggregated table where we have the first
  39511. 24:21:06three characters like aggregating the
  39512. 24:21:08customers or the sales monthly. So as
  39513. 24:21:11you can see as you are creating a naming
  39514. 24:21:13convention you have first to make it
  39515. 24:21:15clear what is the rule describe each
  39516. 24:21:17part of the rule and start giving
  39517. 24:21:19examples. So with that we make it clear
  39518. 24:21:21for the whole team which names they
  39519. 24:21:23should follow. So we talked here about
  39520. 24:21:25the table naming convention. Then you
  39521. 24:21:27can as well go and make naming
  39522. 24:21:29convention for the columns. Like for
  39523. 24:21:30example in the code layer we're going to
  39524. 24:21:32go and have surrogate keys. So we can
  39525. 24:21:34define it like this. The surrogate key
  39526. 24:21:36should start with a table name and then
  39527. 24:21:38underscore a key. Like for example we
  39528. 24:21:40can call it customer key. It is a
  39529. 24:21:43surrogate key in the dimension
  39530. 24:21:45customers. The same thing for technical
  39531. 24:21:47columns. As a data engineer, we might
  39532. 24:21:49add our own columns to the tables that
  39533. 24:21:51don't come from the source system. And
  39534. 24:21:53those columns are the technical columns
  39535. 24:21:55or sometimes we call them metadata
  39536. 24:21:57columns. Now, in order to separate them
  39537. 24:21:59from the original columns that comes
  39538. 24:22:02from the source system, we can have like
  39539. 24:22:04a prefix for that. Like for example, the
  39540. 24:22:06rule says if you are building any
  39541. 24:22:08technical or metadata columns, the
  39542. 24:22:10column should start with DWH underscore
  39543. 24:22:13and then the column name. For example,
  39544. 24:22:15if you want the metadata load dates, we
  39545. 24:22:17can have
  39546. 24:22:18DWH load dates. So with that, if anyone
  39547. 24:22:21sees that column starts with DWH, we
  39548. 24:22:24understand this data comes from a data
  39549. 24:22:26engineer. And we can keep adding rules
  39550. 24:22:28like for example the store procedure
  39551. 24:22:30over here. If you are making an ETL
  39552. 24:22:32script, then it should start with the
  39553. 24:22:34prefix load underscore and then the
  39554. 24:22:36layer. For example, the store procedure
  39555. 24:22:38that is responsible for loading the
  39556. 24:22:39bronze going to be called load bronze.
  39557. 24:22:43and for the silver load underscore
  39558. 24:22:45silver. So those are currently the rules
  39559. 24:22:47for the start procedure. So this is how
  39560. 24:22:49I do it usually in my projects. All
  39561. 24:22:50right my friends. So with that we have a
  39562. 24:22:52solid naming conventions for our
  39563. 24:22:54projects. So this is done and now the
  39564. 24:22:56next step is that we're going to go to
  39565. 24:22:57git and you will create a brand new
  39566. 24:22:59repository and we're going to prepare
  39567. 24:23:01its structure. So let's
  39568. 24:23:06go. All right. Right. So now we come to
  39569. 24:23:08as well important step in any projects
  39570. 24:23:10and that's by creating the G repository.
  39571. 24:23:12So if you are new to Git, don't worry
  39572. 24:23:14about it. It is simpler than it sounds.
  39573. 24:23:16So it's all about to have a safe place
  39574. 24:23:18where you can put your codes that you
  39575. 24:23:20are developing and you will have the
  39576. 24:23:21possibility to track everything happens
  39577. 24:23:23to the codes and as well you can use it
  39578. 24:23:25in order to collaborate with your team
  39579. 24:23:27and if something goes wrong you can
  39580. 24:23:29always roll back. And the best part here
  39581. 24:23:31once you are done with the project you
  39582. 24:23:32can share your repository as a part of
  39583. 24:23:34your portfolio and it is really amazing
  39584. 24:23:36thing if you are applying for a job by
  39585. 24:23:38showcasing your skills that you have
  39586. 24:23:40built a data warehouse by using well
  39587. 24:23:42doumented get repository. So now let's
  39588. 24:23:44go and create the repository of the
  39589. 24:23:46project. Now we are at the overview of
  39590. 24:23:48our account. So the first thing that we
  39591. 24:23:50have to do is to go to the repositories
  39592. 24:23:52over here and then we're going to go to
  39593. 24:23:54this green button and click on new. The
  39594. 24:23:56first thing that we have to do is to
  39595. 24:23:57give the repository name. So let's call
  39596. 24:24:00it SQL data warehouse project and then
  39597. 24:24:04here we can go and give it a
  39598. 24:24:05description. So for example I'm saying
  39599. 24:24:08building a modern data warehouse with
  39600. 24:24:09SQL server. Now the next option whether
  39601. 24:24:11you want to make it public and private.
  39602. 24:24:13I'm going to leave it as a public and
  39603. 24:24:15then let's go and add here a readme
  39604. 24:24:17file. And then here about the license we
  39605. 24:24:20can go over here and select the MIT. MIT
  39606. 24:24:23license gives everyone the freedom of
  39607. 24:24:25using and modifying your code. Okay. So
  39608. 24:24:27I think I'm happy with the setup. Let's
  39609. 24:24:29go and create the repository. And with
  39610. 24:24:32that we have our brand new repository.
  39611. 24:24:34Now the next step that I usually do is
  39612. 24:24:36to create the structure of the
  39613. 24:24:38repository. And usually I always follow
  39614. 24:24:40the same patterns in any projects. So
  39615. 24:24:42here we need few folders in order to put
  39616. 24:24:44our files right. So what I usually do I
  39617. 24:24:47go over here to add file create a new
  39618. 24:24:49file and I start creating the structure
  39619. 24:24:51over here. So the first thing is that we
  39620. 24:24:53need data sets then slash and with that
  39621. 24:24:56the repository going to understand this
  39622. 24:24:58is a folder not a file and then you can
  39623. 24:25:00go and add anything like here
  39624. 24:25:03placeholder just an empty file this just
  39625. 24:25:06going to help me to create the folders
  39626. 24:25:07so let's go and commit so commit the
  39627. 24:25:10changes and now if you go back to the
  39628. 24:25:12main projects you can see now we have a
  39629. 24:25:14folder called data sets so I'm going to
  39630. 24:25:16go and keep creating stuff so I will go
  39631. 24:25:19and create the documents placeholder
  39632. 24:25:22commit the changes and then I'm going to
  39633. 24:25:24go and create the scripts
  39634. 24:25:28placeholder and the final one what I
  39635. 24:25:31usually add is the
  39636. 24:25:33tests something like
  39637. 24:25:35this. So that as you can see now we have
  39638. 24:25:38the main folders of our repository. Now
  39639. 24:25:41what I usually do the next that I'm
  39640. 24:25:42going to go and edit the main readme. So
  39641. 24:25:45you can see it over here as well. So
  39642. 24:25:46what we're going to do, we're going to
  39643. 24:25:47go inside the readme and then we're
  39644. 24:25:49going to go to the edit button here and
  39645. 24:25:51we're going to start writing the main
  39646. 24:25:53information about our project. This is
  39647. 24:25:55really depend on your style. So you can
  39648. 24:25:56go and add whatever you want. This is
  39649. 24:25:59the main page of your repository. And
  39650. 24:26:02now as you can see the file name here is
  39651. 24:26:04MD. It stands for markdown. It is just
  39652. 24:26:07an easy and friendly format in order to
  39653. 24:26:10write a text. So if you have like
  39654. 24:26:11documentations, you are writing a text.
  39655. 24:26:13It is a really nice format in order to
  39656. 24:26:15organize it, structure it and it is very
  39657. 24:26:18friendly. So what I'm going to do at the
  39658. 24:26:20start I'm going to give a few
  39659. 24:26:21description about the project. So we
  39660. 24:26:23have the main title and then we have
  39661. 24:26:25like a welcome message and what this
  39662. 24:26:27repository is about. And in the next
  39663. 24:26:29section maybe we can start with the
  39664. 24:26:30project requirements and then maybe at
  39665. 24:26:33the end you can say a few words about
  39666. 24:26:35the licensing and few words about you.
  39667. 24:26:38So as you can see it's like the homepage
  39668. 24:26:39of the project and the repository. So
  39669. 24:26:41once you are done we're going to go and
  39670. 24:26:43commit the changes. And now if you go to
  39671. 24:26:45the main page of the repository you can
  39672. 24:26:48see always the folder and files at the
  39673. 24:26:50start and then below it we're going to
  39674. 24:26:52see the informations from the readme. So
  39675. 24:26:54again here we have the welcome statement
  39676. 24:26:56and then the projects requirements and
  39677. 24:26:59at the end we have the licensing and
  39678. 24:27:00about me. So my friends that's it. We
  39679. 24:27:03have now a repository and we have now
  39680. 24:27:05the main structure of the project and
  39681. 24:27:07through the projects as we are building
  39682. 24:27:09the data warehouse we're going to go and
  39683. 24:27:11commit all our work in this repository.
  39684. 24:27:13Nice, right? All right. So with that we
  39685. 24:27:16have now your repository ready and as we
  39686. 24:27:18go in the project we will be adding
  39687. 24:27:20stuff to it. So this step is done and
  39688. 24:27:23now the last step finally we're going to
  39689. 24:27:25go to the SQL server and we're going to
  39690. 24:27:27write our first script where we're going
  39691. 24:27:28to create a database and schemas.
  39692. 24:27:35All right. Now the first step is we have
  39693. 24:27:36to go and create a brand new database.
  39694. 24:27:39So now in order to do that first we have
  39695. 24:27:41to switch to the database master. So you
  39696. 24:27:43can do it like this. Use master and
  39697. 24:27:46semicolon. And if you go and execute it
  39698. 24:27:48now we are switched to the master
  39699. 24:27:49database. It is a system database in SQL
  39700. 24:27:52server where you can go and create other
  39701. 24:27:54databases. And you can see here from the
  39702. 24:27:55toolbar that we are now logged into the
  39703. 24:27:58master database. Now the next step we
  39704. 24:28:00have to go and create our new database.
  39705. 24:28:02So we're going to say create database
  39706. 24:28:04and you can call it whatever you want.
  39707. 24:28:06So I'm going to go with data warehouse
  39708. 24:28:09semicolon. Let's go and execute it. And
  39709. 24:28:12with that we have created our database.
  39710. 24:28:14Let's go and check it from the object
  39711. 24:28:15explorer. Let's go and refresh. And you
  39712. 24:28:17can see our new data warehouse. This is
  39713. 24:28:19our new database. Awesome. Right now to
  39714. 24:28:22the next step we're going to go and
  39715. 24:28:23switch to the new database. So we're
  39716. 24:28:25going to say use data
  39717. 24:28:28warehouse and semicolon. So let's go and
  39718. 24:28:31switch to it. And you can see now we are
  39719. 24:28:32logged into the data warehouse database.
  39720. 24:28:35And now we can go and start building
  39721. 24:28:36stuff inside this data warehouse. So now
  39722. 24:28:39the first step that I usually do is I go
  39723. 24:28:41and start creating the schemas. So what
  39724. 24:28:44is schema? Think about it. It's like a
  39725. 24:28:46folder or a container that helps you to
  39726. 24:28:48keep things organized. So now as we
  39727. 24:28:50decided in the architecture we have
  39728. 24:28:52three layers, bronze, silver, gold. And
  39729. 24:28:54now we're going to go and create for
  39730. 24:28:55each layer a schema. So let's go and do
  39731. 24:28:58that. We're going to start with the
  39732. 24:28:59first one. Create schema. And the first
  39733. 24:29:02one is bronze. So let's do it like this.
  39734. 24:29:04And a semicolon. Let's go and create the
  39735. 24:29:07first schema. Nice. So we have new
  39736. 24:29:09schema. Let's go to our database. And
  39737. 24:29:12then in order to check the schemas, we
  39738. 24:29:13go to the security and then to the
  39739. 24:29:15schemas over here. And as you can see,
  39740. 24:29:17we have the bronze. And if you don't
  39741. 24:29:19find it, you have to go and refresh the
  39742. 24:29:21whole schemas. and then you will find
  39743. 24:29:23the new schema. Great. So now we have
  39744. 24:29:24the first schema. Now what we're going
  39745. 24:29:26to do, we're going to go and create the
  39746. 24:29:28others two. So I'm just going to go and
  39747. 24:29:29duplicate it. So the next one going to
  39748. 24:29:31be the silver and the third one going to
  39749. 24:29:33be the gold. So let's go and execute
  39750. 24:29:36those two together. We will get an error
  39751. 24:29:38and that's because we are not having the
  39752. 24:29:40go in between. So after each command,
  39753. 24:29:43let's have a go. And now if I highlight
  39754. 24:29:46the silver and gold and then execute, it
  39755. 24:29:49will be working. the go in SQL it is
  39756. 24:29:51like separator. So it tells SQL first
  39757. 24:29:54execute completely the first command
  39758. 24:29:56before go to the next one. So it is just
  39759. 24:29:58separator. Now let's go to our schemas
  39760. 24:30:00refresh and now we can see as well we
  39761. 24:30:02have the gold and the silver. So with
  39762. 24:30:04that we have now a database. We have the
  39763. 24:30:06three layers and we can start developing
  39764. 24:30:09each layer
  39765. 24:30:14individually. Okay. So now let's go and
  39766. 24:30:16commit our work in the git. So now since
  39767. 24:30:18it is a script and code we're going to
  39768. 24:30:20go to the folder scripts over here and
  39769. 24:30:22then we're going to go and add a new
  39770. 24:30:23file let's call it in it
  39771. 24:30:26database.sql and now we're going to go
  39772. 24:30:28and paste our code over here. So now I
  39773. 24:30:30have done few modifications like for
  39774. 24:30:33example before we create the database we
  39775. 24:30:35have to check whether the database
  39776. 24:30:37exists. This is an important step if you
  39777. 24:30:39are recreating the database otherwise if
  39778. 24:30:41you don't do that you will get an error
  39779. 24:30:43where it's going to say the database
  39780. 24:30:45already exists. So first it is checking
  39781. 24:30:47whether the database exists then it
  39782. 24:30:49drops it. I have added few comments like
  39783. 24:30:52here we are saying creating the data
  39784. 24:30:53warehouse creating the schemas and now
  39785. 24:30:56we have a very important step. We have
  39786. 24:30:58to go and add a header comment at the
  39787. 24:31:00start of each script. To be honest after
  39788. 24:31:023 months from now you will not be
  39789. 24:31:04remembering all the details of this
  39790. 24:31:06script. And adding a comment like this
  39791. 24:31:08it is like a sticky note for you later
  39792. 24:31:10once you visit this script again. And it
  39793. 24:31:13is as well very important for the other
  39794. 24:31:14developers in the team because each time
  39795. 24:31:16you open the scripts the first question
  39796. 24:31:18going to be what is the purpose of this
  39797. 24:31:20script because if you or anyone in the
  39798. 24:31:23team open the file the first question
  39799. 24:31:25going to be what is the purpose of this
  39800. 24:31:27scripts why we are doing this stuff. So
  39801. 24:31:30as you can see here we have a comment
  39802. 24:31:31saying this script creates a new data
  39803. 24:31:33warehouse after checking if it already
  39804. 24:31:36exists. If the database exists, it's
  39805. 24:31:38going to drop it and recreate it. And
  39806. 24:31:40additionally, it's going to go and
  39807. 24:31:41create three schemas, bronze, silver,
  39808. 24:31:43gold. So that it gives clarity what this
  39809. 24:31:46script is about. And it makes everyone
  39810. 24:31:48life easier. Now, the second reason why
  39811. 24:31:50this is very important to add is that
  39812. 24:31:52you can add warnings and especially for
  39813. 24:31:55this script, it is very important to add
  39814. 24:31:57these notes because if you run this
  39815. 24:31:59script, what's going to happen? It's
  39816. 24:32:00going to go and destroy the whole
  39817. 24:32:02database. Imagine someone open this
  39818. 24:32:04script and run it. Imagine an admin open
  39819. 24:32:07this script and run it in your database.
  39820. 24:32:09Everything going to be destroyed and all
  39821. 24:32:11the data will be lost and this can be a
  39822. 24:32:14disaster if you don't have any backup.
  39823. 24:32:16So with that we have nice header
  39824. 24:32:17comments and we have added few comments
  39825. 24:32:19in our code and now we are ready to
  39826. 24:32:22commit our code. So let's go and commit
  39827. 24:32:24it. And now we have our script in the
  39828. 24:32:27git as well. And of course if you are
  39829. 24:32:29doing any modifications make sure to
  39830. 24:32:31update the changes in the git. Okay my
  39831. 24:32:33friends. So with that we have an empty
  39832. 24:32:35database and schemas and we are done
  39833. 24:32:38with this task and as well we are done
  39834. 24:32:39with the whole epic. So we have
  39835. 24:32:41completed the project initialization and
  39836. 24:32:43now we're going to go to the interesting
  39837. 24:32:45stuff. We will go and build the bronze
  39838. 24:32:47layer. So now the first task is to
  39839. 24:32:49analyze the source systems. So let's
  39840. 24:32:54go. All right. So now the big question
  39841. 24:32:56is how to build the bronze layer. So
  39842. 24:32:59first thing first we do analyzing. As
  39843. 24:33:01you are developing anything, you don't
  39844. 24:33:03immediately start writing a code. So
  39845. 24:33:05before we start coding the bronze layer,
  39846. 24:33:07what we usually do is we have to
  39847. 24:33:09understand the source system. So what I
  39848. 24:33:11usually do, I make an interview with the
  39849. 24:33:13source system experts and ask them many
  39850. 24:33:15many questions in order to understand
  39851. 24:33:18the nature of the source system that I'm
  39852. 24:33:20connecting to the data warehouse. And
  39853. 24:33:22once you know the source systems, then
  39854. 24:33:24we can start coding. And the main focus
  39855. 24:33:26here is to do the data ingestion. So
  39856. 24:33:29that means we have to find a way on how
  39857. 24:33:31to load the data from the source into
  39858. 24:33:33the data warehouse. So it's like we are
  39859. 24:33:35building a bridge between the source and
  39860. 24:33:38our target system the data warehouse.
  39861. 24:33:39And once we have the code ready, the
  39862. 24:33:41next step is we have to do data
  39863. 24:33:43validation. So here comes the quality
  39864. 24:33:45control. It is very important in the
  39865. 24:33:47bronze layer to check the data
  39866. 24:33:48completeness. So that means we have to
  39867. 24:33:50compare the number of records between
  39868. 24:33:53the source system and the bronze layer
  39869. 24:33:56just to make sure we are not losing any
  39870. 24:33:57data in between. And another check that
  39871. 24:33:59we will be doing is the schema checks
  39872. 24:34:01and that's to make sure that the data is
  39873. 24:34:03placed on the right position. And
  39874. 24:34:05finally we don't have to forget about
  39875. 24:34:07documentation and committing our work in
  39876. 24:34:09the G. So this is the process that we're
  39877. 24:34:11going to follow to build the bronze
  39878. 24:34:16layer. All right my friends. So now
  39879. 24:34:19before connecting any source systems to
  39880. 24:34:20our data warehouse, we have to make very
  39881. 24:34:22important step is to understand the
  39882. 24:34:25sources. So how I usually do it, I set
  39883. 24:34:27up a meeting with the source systems
  39884. 24:34:29expert in order to interview them to ask
  39885. 24:34:31them a lot of stuff about the source.
  39886. 24:34:33And gaining this knowledge is very
  39887. 24:34:35important because asking the right
  39888. 24:34:36question will help you to design the
  39889. 24:34:39correct scripts in order to extract the
  39890. 24:34:41data and to avoid a lot of mistakes and
  39891. 24:34:43challenges. And now I'm going to show
  39892. 24:34:44you the most common questions that I
  39893. 24:34:46usually ask before connecting anything.
  39894. 24:34:48Okay. So we start first by understanding
  39895. 24:34:50the business context and the ownership.
  39896. 24:34:53So I would like to understand the story
  39897. 24:34:54behind the data. I would like to
  39898. 24:34:56understand who is responsible for the
  39899. 24:34:57data, which IT departments and so on.
  39900. 24:35:00And then it's nice to understand as well
  39901. 24:35:02what business process it supports. Does
  39902. 24:35:04it support the customer transactions,
  39903. 24:35:06the supply chain, logistics or maybe
  39904. 24:35:09finance reporting. So with that you can
  39905. 24:35:11understand the importance of your data.
  39906. 24:35:12And then I ask about the system and data
  39907. 24:35:15documentation. So having documentations
  39908. 24:35:17from the source is your learning
  39909. 24:35:19materials about your data. And it's
  39910. 24:35:20going to saves you a lot of time later
  39911. 24:35:23when you are working and designing maybe
  39912. 24:35:25new data models. And as well I would
  39913. 24:35:27like always to understand the data model
  39914. 24:35:29for the source system. And if they have
  39915. 24:35:31like descriptions of the columns and the
  39916. 24:35:33tables, it's going to be nice to have
  39917. 24:35:34the data catalog. This can helps me a
  39918. 24:35:36lot in the data warehouse. How I'm going
  39919. 24:35:38to go and join the tables together. So
  39920. 24:35:40with that you get a solid foundations
  39921. 24:35:42about the business context, the
  39922. 24:35:44processes and the ownership of the data.
  39923. 24:35:46And now in the next step we're going to
  39924. 24:35:47start talking about the technicality. So
  39925. 24:35:49I would like to understand the
  39926. 24:35:50architecture and as well the technology
  39927. 24:35:52stack. So the first question that I
  39928. 24:35:54usually ask is how the source system is
  39929. 24:35:56storing the data. Do we have the data on
  39930. 24:35:58the on-prem like in SQL server, Oracle
  39931. 24:36:01or is it in the cloud like Azure, AWS
  39932. 24:36:04and so on. And then once we understand
  39933. 24:36:06that then we can discuss what are the
  39934. 24:36:08integration capabilities like how I'm
  39935. 24:36:11going to go and get the data. Do the
  39936. 24:36:12source system offer APIs maybe cafka or
  39937. 24:36:15they have only like file extractions or
  39938. 24:36:18they're going to give you like a direct
  39939. 24:36:19connection to the database. So once you
  39940. 24:36:21understand the technology that you're
  39941. 24:36:23going to use in order to extract the
  39942. 24:36:24data then we're going to deep dive into
  39943. 24:36:26more technical questions and here we're
  39944. 24:36:28going to understand how to extract the
  39945. 24:36:30data from the source system and then
  39946. 24:36:32load it into the data warehouse. So the
  39947. 24:36:34first things that we have to discuss
  39948. 24:36:35with the experts can we do an
  39949. 24:36:37incremental load or a full load and then
  39950. 24:36:40after that we're going to discuss the
  39951. 24:36:41data scope the historicizations do we
  39952. 24:36:44need all data do we need only maybe 10
  39953. 24:36:46years of the data are there histories
  39954. 24:36:48already in the source system or should
  39955. 24:36:50we build it in the data warehouse and so
  39956. 24:36:52on and then we're going to go and
  39957. 24:36:54discuss what is the expected size of the
  39958. 24:36:57extracts are we talking here about
  39959. 24:36:58megabytes gigabytes terabytes and this
  39960. 24:37:01is very important to understand whether
  39961. 24:37:03we have the right tools and platform to
  39962. 24:37:06connect that source system and then I
  39963. 24:37:08try to understand whether there are any
  39964. 24:37:09data volume limitations like if you have
  39965. 24:37:11some old source systems they might
  39966. 24:37:13struggle a lot with performance and so
  39967. 24:37:15on. So if you have like an ETL that is
  39968. 24:37:17extracting large amount of data you
  39969. 24:37:19might bring the performance down of the
  39970. 24:37:21source system. So that's why you have to
  39971. 24:37:23try to understand whether there are any
  39972. 24:37:25limitations for your extracts and as
  39973. 24:37:27well other aspects that might impact the
  39974. 24:37:30performance of the source system. This
  39975. 24:37:31is very important. If they give you an
  39976. 24:37:33access to the database, you have to be
  39977. 24:37:35responsible that you are not bringing
  39978. 24:37:37the performance of the database down.
  39979. 24:37:39And of course, very important question
  39980. 24:37:40is to ask about the authentication and
  39981. 24:37:43the authorization like how you going to
  39982. 24:37:44go and access the data in the source
  39983. 24:37:46system. Do you need any tokens, keys,
  39984. 24:37:48password and so on. So those are the
  39985. 24:37:50questions that you have to ask if you
  39986. 24:37:52are connecting a new source system to
  39987. 24:37:54the data warehouse. And once you have
  39988. 24:37:56the answers for those questions, you can
  39989. 24:37:58proceed with the next steps to connect
  39990. 24:38:00the sources to the data warehouse. All
  39991. 24:38:02right, my friends. So with that, you
  39992. 24:38:04have learned how to analyze a new source
  39993. 24:38:06systems that you want to connect to your
  39994. 24:38:08data warehouse. So this step is done and
  39995. 24:38:10now we're going to go back to coding
  39996. 24:38:12where we're going to write scripts in
  39997. 24:38:13order to do the data ingestion from the
  39998. 24:38:16CSV files to the pros
  39999. 24:38:20layer. And let's have a quick look again
  40000. 24:38:23to our bronze layer specifications. So
  40001. 24:38:25we just have to load the data from the
  40002. 24:38:27sources to the data warehouse. We're
  40003. 24:38:29going to build tables in the bronze
  40004. 24:38:31layer. We are doing a full load. So that
  40005. 24:38:33means we are truncating and then
  40006. 24:38:34inserting the data. There will be no
  40007. 24:38:36data transformations at all in the
  40008. 24:38:38bronze layer. And as well we will not be
  40009. 24:38:40creating any data model. So this is the
  40010. 24:38:42specifications of the bronze layer. All
  40011. 24:38:45right. Right now in order to create the
  40012. 24:38:46DDL script for the bronze layer creating
  40013. 24:38:48the tables of the bronze we have to
  40014. 24:38:50understand the metadata the structure
  40015. 24:38:52the schema of the incoming data and here
  40016. 24:38:55either you ask the technical experts
  40017. 24:38:57from the source system about these
  40018. 24:38:58informations or you can go and explore
  40019. 24:39:01the incoming data and try to define the
  40020. 24:39:04structure of your tables. So now what
  40021. 24:39:05we're going to do we're going to start
  40022. 24:39:06with the first source system the CRM. So
  40023. 24:39:09let's go inside it and we're going to
  40024. 24:39:11start with the first table the customer
  40025. 24:39:12info. Now if you open the file and check
  40026. 24:39:14the data inside it, you see we have a
  40027. 24:39:16header information and that is very good
  40028. 24:39:18because now we have the names of the
  40029. 24:39:21columns that are coming from the source
  40030. 24:39:22and from the content you can define of
  40031. 24:39:24course the data types. So let's go and
  40032. 24:39:26do that. First we're going to say create
  40033. 24:39:28table and then we have to define the
  40034. 24:39:31layer. It's going to be the bronze. And
  40035. 24:39:32now very important we have to follow the
  40036. 24:39:34naming convention. So we start with the
  40037. 24:39:36name of the source system. It is CRM
  40038. 24:39:38underscore and then after that the table
  40039. 24:39:40name from the source system. So it's
  40040. 24:39:42going to be the cost underscore info. So
  40041. 24:39:45this is the name of our first table in
  40042. 24:39:47the bronze layer. Then the next step we
  40043. 24:39:48have to go and define of course the
  40044. 24:39:50columns. And here again the column names
  40045. 24:39:52in the bronze layer going to be one to
  40046. 24:39:54one exactly like the source system. So
  40047. 24:39:56the first one going to be the ID and I
  40048. 24:39:59will go with the data type integer. Then
  40049. 24:40:01the next one going to be the key invar
  40050. 24:40:04char and the length I will go with 50.
  40051. 24:40:10[Music]
  40052. 24:40:13And the last one going to be the create
  40053. 24:40:16date. It's going to be date. So with
  40054. 24:40:18that we have covered all the columns
  40055. 24:40:20available from the source system. So
  40056. 24:40:22let's go and check. And yes the last one
  40057. 24:40:24is the create date. So that's it for the
  40058. 24:40:26first table. Now a semicolon of course
  40059. 24:40:28at the end. Let's go and execute it. And
  40060. 24:40:30now we're going to go to the object
  40061. 24:40:32explorer over here. Refresh. And we can
  40062. 24:40:34see the first table inside our data
  40063. 24:40:36warehouse. Amazing right? So now next
  40064. 24:40:38what you have to do is to go and create
  40065. 24:40:41a DDL statement for each file for those
  40066. 24:40:44two systems. So for the CRM we need
  40067. 24:40:46three DDLs and as well for the other
  40068. 24:40:49system the ERP we have as well to create
  40069. 24:40:52three DDLs for the three files. So at
  40070. 24:40:54the end we're going to have in the
  40071. 24:40:55bronze layer six tables six DTLs. So now
  40072. 24:40:59pause the video go create those DDLs. I
  40073. 24:41:01will be doing the same as well and we
  40074. 24:41:03will see you soon.
  40075. 24:41:06[Music]
  40076. 24:41:09All right. So now I hope you have
  40077. 24:41:10created all those details. I'm going to
  40078. 24:41:12show you what I have just created. So
  40079. 24:41:13the second table in the source CRM we
  40080. 24:41:16have the product informations and the
  40081. 24:41:18third one is the sales details. Then we
  40082. 24:41:21go to the second system and here we make
  40083. 24:41:23sure that we are following the naming
  40084. 24:41:24convention. So first the source system
  40085. 24:41:26ERB and then the table name. So the
  40086. 24:41:29second system was really easy. You can
  40087. 24:41:31see we have only here like two columns
  40088. 24:41:32and for the customers like only three
  40089. 24:41:35and for the categories only four
  40090. 24:41:36columns. All right. So after defining
  40091. 24:41:38those stuff of course we have to go and
  40092. 24:41:40execute them. So let's go and do that.
  40093. 24:41:43And then we go to the object explorer
  40094. 24:41:44over here. Refresh the tables. And with
  40095. 24:41:47that you can see we have six empty
  40096. 24:41:49tables in the bronze layer. And with
  40097. 24:41:51that we have all the tables from the two
  40098. 24:41:53source systems inside our database. But
  40099. 24:41:56still we don't have any data. And you
  40100. 24:41:58can see our naming convention is really
  40101. 24:41:59nice. You see the first three tables
  40102. 24:42:01comes from the CRM source system and
  40103. 24:42:04then the other three comes from the ERB.
  40104. 24:42:06So we can see in the bronze layer the
  40105. 24:42:08things are really splitted nicely and
  40106. 24:42:10you can identify quickly which table
  40107. 24:42:12belong to which source system. Now there
  40108. 24:42:14is something else that I usually add to
  40109. 24:42:16the DDL script is to check whether the
  40110. 24:42:19table exists before creating. So for
  40111. 24:42:21example, let's say that you are renaming
  40112. 24:42:23or you would like to change the data
  40113. 24:42:25type of specific field. If you just go
  40114. 24:42:27and run this query, you will get an
  40115. 24:42:29error because the database going to say
  40116. 24:42:31we have already this table. So in other
  40117. 24:42:33databases you can say create or replace
  40118. 24:42:35table. But in the SQL server you have to
  40119. 24:42:37go and build a TSQL logic. So it is very
  40120. 24:42:40simple. First we have to go and check
  40121. 24:42:41whether the object exists in the
  40122. 24:42:43database. So we say if object ID and
  40123. 24:42:47then we have to go and specify the table
  40124. 24:42:48name. So let's go and copy the whole
  40125. 24:42:51thing over here and make sure you get
  40126. 24:42:54exactly the same name as the table name.
  40127. 24:42:56So there you see like space. I'm just
  40128. 24:42:57going to go and remove it. And then
  40129. 24:42:59we're going to go and define the object
  40130. 24:43:00type. So it's going to be the U. It
  40131. 24:43:02stands for user. It is the user defined
  40132. 24:43:04tables. So if this table is not null. So
  40133. 24:43:08that means the database did find this
  40134. 24:43:10object in the database. So what's going
  40135. 24:43:12to happen? We say go and drop the table.
  40136. 24:43:16So the whole thing again and semicolon.
  40137. 24:43:18So again if the table exist in the
  40138. 24:43:21database is not null then go and drop
  40139. 24:43:23the table and after that go and create
  40140. 24:43:26it. So now if you go and highlight the
  40141. 24:43:28whole thing and then execute it it will
  40142. 24:43:30be working. So first drop the table if
  40143. 24:43:33it exist then go and create the table
  40144. 24:43:36from scratch. Now what you have to do is
  40145. 24:43:37to go and add this check before creating
  40146. 24:43:40any table inside our database. So it's
  40147. 24:43:42going to be the same thing for the next
  40148. 24:43:44table and so on. I went and added all
  40149. 24:43:47those checks for each table and what can
  40150. 24:43:50happen if I go and execute the whole
  40151. 24:43:52thing it going to work. So with that I'm
  40152. 24:43:54recreating all the tables in the bronze
  40153. 24:43:57layer from the
  40154. 24:44:01scratch. Now the methods that we're
  40155. 24:44:03going to use in order to load the data
  40156. 24:44:05from the source to the data warehouse is
  40157. 24:44:07the bulk inserts. Pulk insert is a
  40158. 24:44:09method of loading massive amount of data
  40159. 24:44:12very quickly from files like CSV files
  40160. 24:44:15or maybe a text file directly into a
  40161. 24:44:18database. It is not like the classical
  40162. 24:44:20normal inserts where it's going to go
  40163. 24:44:22and insert the data row by row but
  40164. 24:44:24instead the bulk insert is one operation
  40165. 24:44:27that's going to load all the data in one
  40166. 24:44:29go into the database and that's what
  40167. 24:44:31makes it very fast. So let's go and use
  40168. 24:44:33this method. Okay. Okay, so now let's
  40169. 24:44:34start writing the script in order to
  40170. 24:44:36load the first table in the source CRM.
  40171. 24:44:39So we're going to go and load the table
  40172. 24:44:41customer info from the CSV file to the
  40173. 24:44:44database table. So the syntax is very
  40174. 24:44:46simple. We're going to start with saying
  40175. 24:44:48bulk insert. So with that SQL understand
  40176. 24:44:50we are doing not a normal insert, we are
  40177. 24:44:52doing a bulk insert and then we have to
  40178. 24:44:54go and specify the table name. So it is
  40179. 24:44:57bronze dot CRM cost info. So now we have
  40180. 24:45:01to specify the full location of the file
  40181. 24:45:04that we are trying to load in this
  40182. 24:45:06table. So now what we have to do is to
  40183. 24:45:08go and get the path where the file is
  40184. 24:45:10stored. So I'm going to go and copy the
  40185. 24:45:12whole path and then add it to the bulk
  40186. 24:45:14insert exactly like where the data
  40187. 24:45:17exists. So for me it is in CSQL data
  40188. 24:45:20warehouse project data set in the source
  40189. 24:45:23CRM. And then I have to specify the file
  40190. 24:45:25name. So it's going to be like cost
  40191. 24:45:27info. CSV. You have to get it exactly
  40192. 24:45:31like the path of your files otherwise it
  40193. 24:45:33will not be working. So after the path
  40194. 24:45:35now we come to the with clause. Now we
  40195. 24:45:38have to tell the SQL server how to
  40196. 24:45:39handle our file. So here comes the
  40197. 24:45:42specifications. There is a lot of stuff
  40198. 24:45:44that we can define. So let's start with
  40199. 24:45:46the very important one is the row
  40200. 24:45:48header. Now if you check the content of
  40201. 24:45:50our files you can see always the first
  40202. 24:45:53row includes the header information of
  40203. 24:45:55the file. So those informations are
  40204. 24:45:58actually not the data. It's just the
  40205. 24:46:00column names. The actual data starts
  40206. 24:46:02from the second row and we have to tell
  40207. 24:46:05the database about this information. So
  40208. 24:46:07we're going to say first row is actually
  40209. 24:46:10the second row. So with that we are
  40210. 24:46:12telling SQL to skip the first row in the
  40211. 24:46:15file. We don't need to load those
  40212. 24:46:16informations because we have already
  40213. 24:46:18defined the structure of our table. So
  40214. 24:46:21this is the first specifications. The
  40215. 24:46:23next one which is as well very important
  40216. 24:46:25in loading any CSV file is the separator
  40217. 24:46:28between fields. The delimiter between
  40218. 24:46:30fields. So it's really depend on the
  40219. 24:46:32file structure that you are getting from
  40220. 24:46:33the source. As you can see all those
  40221. 24:46:35values are splitted with a comma and we
  40222. 24:46:38call this comma as a file separator or a
  40223. 24:46:41delimter and I saw a lot of different
  40224. 24:46:42CSVs like sometime they use a semicolon
  40225. 24:46:45or a pipe or special character like a
  40226. 24:46:47hash and so on. So you have to
  40227. 24:46:49understand how the values are splitted
  40228. 24:46:51and in this file it's splitted by the
  40229. 24:46:53comma and we have to tell SQL about this
  40230. 24:46:55info. It's very important. So we're
  40231. 24:46:57going to say filled terminator and then
  40232. 24:46:59we're going to say it is the comma and
  40233. 24:47:02basically those two informations are
  40234. 24:47:03very important for SQL in order to be
  40235. 24:47:05able to read your CSV file. Now there
  40236. 24:47:08are like many different options that you
  40237. 24:47:10can go and add. For example, tape lock.
  40238. 24:47:13It is an option in order to improve the
  40239. 24:47:15performance where you are locking the
  40240. 24:47:17entire table during loading it. So as
  40241. 24:47:20SQL is loading the data to this table,
  40242. 24:47:22it going to go and lock the whole table.
  40243. 24:47:25So that's it for now. I'm just going to
  40244. 24:47:26go and add the semicolon and let's go
  40245. 24:47:28and insert the data from the file inside
  40246. 24:47:30our bronze table. Let's execute it. And
  40247. 24:47:32now we can see SQL did insert around
  40248. 24:47:3480,000 rows inside our table. So it is
  40249. 24:47:37working. We just loaded the file into
  40250. 24:47:38our database. But now it is not enough
  40251. 24:47:41to just write this script. you have to
  40252. 24:47:43test the quality of your bronze table
  40253. 24:47:45especially if you are working with
  40254. 24:47:47files. So let's go and just do a simple
  40255. 24:47:49select. So from our new
  40256. 24:47:53table and let's run it. So now the first
  40257. 24:47:56thing that I check is do we have data
  40258. 24:47:58like in each column? Well yes as you can
  40259. 24:48:00see we have data and the second thing is
  40260. 24:48:03do we have the data in the correct
  40261. 24:48:05column. This is very critical as you are
  40262. 24:48:07loading the data from a file to a
  40263. 24:48:09database. Do we have the data in the
  40264. 24:48:11correct column? So for example, here we
  40265. 24:48:12have the first name which of course
  40266. 24:48:14makes sense and here we have the last
  40267. 24:48:15name. But what could happen and this
  40268. 24:48:17mistakes happens a lot is that you find
  40269. 24:48:20the first name informations inside the
  40270. 24:48:22key and as well you see the last name
  40271. 24:48:24inside the first name and the status
  40272. 24:48:27inside the last name. So there is like
  40273. 24:48:29shifting of the data and this data
  40274. 24:48:31engineering mistake is very common if
  40275. 24:48:33you are working with CSV files and there
  40276. 24:48:35are like different reasons why it
  40277. 24:48:36happens. Maybe the definition of your
  40278. 24:48:38table is wrong or the field separator is
  40279. 24:48:41wrong. Maybe it's not a comma, it's
  40280. 24:48:43something else or the separator is a bad
  40281. 24:48:45separator because sometimes maybe in the
  40282. 24:48:47keys or in the first name there is a
  40283. 24:48:50comma and the SQL is not able to split
  40284. 24:48:52the data correctly. So the quality of
  40285. 24:48:54the CSV file is not really good and
  40286. 24:48:56there are many different reasons why you
  40287. 24:48:58are not getting the data in the correct
  40288. 24:49:00column. But for now everything looks
  40289. 24:49:02fine for us. And the next step is that
  40290. 24:49:04I'll go and count the rows inside this
  40291. 24:49:07table. So let's go and select that. So
  40292. 24:49:09we can see we have
  40293. 24:49:1218,493. And now what we can do, we can
  40294. 24:49:14go to our CSV file and check how many
  40295. 24:49:16rows do we have inside this file. And as
  40296. 24:49:18you can see we have
  40297. 24:49:2118,494. We are almost there. There is
  40298. 24:49:23like one extra row inside the file. And
  40299. 24:49:25that's because of the header. the first
  40300. 24:49:28header information is not loaded inside
  40301. 24:49:30our table and that's why always in our
  40302. 24:49:32tables we're going to have one less row
  40303. 24:49:34than the original files. So everything
  40304. 24:49:37looks nice and we have done this step
  40305. 24:49:38correctly. Now if I go and run it again
  40306. 24:49:41what's going to happen we will get
  40307. 24:49:43duplicates inside the bronze layer. So
  40308. 24:49:46now we have loaded the file like twice
  40309. 24:49:48inside the same table which is not
  40310. 24:49:50really correct. The method that we have
  40311. 24:49:52discussed is first to make the table
  40312. 24:49:54empty and then load truncate and then
  40313. 24:49:57insert. In order to do that before the
  40314. 24:50:00bulk inserts, what we're going to do,
  40315. 24:50:01we're going to say truncate table and
  40316. 24:50:04then we're going to have our
  40317. 24:50:06table and that's it with a semicolon. So
  40318. 24:50:09now what we are doing is first we are
  40319. 24:50:12making the table empty and then we start
  40320. 24:50:14loading from the scratch. We are loading
  40321. 24:50:16the whole content of the file inside the
  40322. 24:50:19table and this is what we call full
  40323. 24:50:20load. So now let's go and mark
  40324. 24:50:22everything together and execute. And
  40325. 24:50:24again if you go and check the content of
  40326. 24:50:27the table you can see we have only
  40327. 24:50:2918,000 rows. Let's go and run it again.
  40328. 24:50:32The count of the bronze layer you can
  40329. 24:50:34see we still have the 18,000. So each
  40330. 24:50:36time you run this script now we are
  40331. 24:50:39refreshing the table customer info from
  40332. 24:50:41the file into the database table. So we
  40333. 24:50:44are refreshing the bronze layer table.
  40334. 24:50:46So that means if there's like now any
  40335. 24:50:47changes in the file, it will be loaded
  40336. 24:50:50to the table. So this is how we do a
  40337. 24:50:52full load in the bronze layer by
  40338. 24:50:54truncating the table and then doing the
  40339. 24:50:57inserts. And now of course what we have
  40340. 24:50:58to do is to pause the video and go and
  40341. 24:51:00write the same script for all six files.
  40342. 24:51:04So let's go and do
  40343. 24:51:08[Music]
  40344. 24:51:09that. Okay, back. So I hope that you
  40345. 24:51:12have as well written all those scripts.
  40346. 24:51:14So I have the three tables in order to
  40347. 24:51:16load the first source system and then
  40348. 24:51:18three sections in order to load the
  40349. 24:51:20second source system. And as I'm writing
  40350. 24:51:22those scripts, make sure to have the
  40351. 24:51:23correct path. So for the second source
  40352. 24:51:26system, you have to go and change the
  40353. 24:51:27path for the other folder. And as well,
  40354. 24:51:29don't forget the table name on the
  40355. 24:51:30bronze layer is different from the file
  40356. 24:51:32name because we start always with the
  40357. 24:51:34source system name with the files. We
  40358. 24:51:37don't have that. So now I think I have
  40359. 24:51:38everything is ready. So let's go and
  40360. 24:51:41execute the whole thing. Perfect.
  40361. 24:51:43Awesome. So everything is working. Let
  40362. 24:51:45me check the messages. So we can see
  40363. 24:51:47from the message how many rows are
  40364. 24:51:49inserted in each table. And now of
  40365. 24:51:51course the task is to go through each
  40366. 24:51:53table and check the
  40367. 24:51:58content. So that means now we have
  40368. 24:52:00really nice script in order to load the
  40369. 24:52:03bronze layer. And we will use this
  40370. 24:52:05script in daily basis. every day we have
  40371. 24:52:07to run it in order to get a new content
  40372. 24:52:10to the data warehouse. And as we learned
  40373. 24:52:12before, if you have like a script of SQL
  40374. 24:52:14that is frequently used, what we can do,
  40375. 24:52:17we can go and create a stored procedure
  40376. 24:52:20from those scripts. So let's go and do
  40377. 24:52:22that. It's going to be very simple.
  40378. 24:52:23We're going to go over here and say
  40379. 24:52:25create or alter procedure. And now we
  40380. 24:52:28have to define the name of the S
  40381. 24:52:30procedure. I'm going to go and put it in
  40382. 24:52:31the schema bronze because it belongs to
  40383. 24:52:34the bronze layer. So then we're going to
  40384. 24:52:36go and follow the naming convention. The
  40385. 24:52:38source procedure start with load
  40386. 24:52:39underscore and then the bronze layer. So
  40387. 24:52:42that's it about the name and then very
  40388. 24:52:44important we have to define the begin
  40389. 24:52:45and as well the end of our skill
  40390. 24:52:47statements. So here is the begin and
  40391. 24:52:50let's go to the end and say this is the
  40392. 24:52:53end. And then let's go highlight
  40393. 24:52:55everything in between and give it one
  40394. 24:52:57push with tab. So with that it is easier
  40395. 24:52:59to read. So now next what we're going to
  40396. 24:53:01do we're going to go and execute it. So
  40397. 24:53:02let's go and create this store
  40398. 24:53:04procedure. And now if you want to go and
  40399. 24:53:05check your store procedure, you go to
  40400. 24:53:07the database and then we have here a
  40401. 24:53:08folder called programmability. And then
  40402. 24:53:10inside it we have start procedure. So if
  40403. 24:53:12you go and refresh, you will see our new
  40404. 24:53:14stored procedure. Let's go and test it.
  40405. 24:53:16So I'm going to go and have a new query.
  40406. 24:53:18And what we're going to do, we're going
  40407. 24:53:19to say execute
  40408. 24:53:22bronze.load bronze. So let's go and
  40409. 24:53:25execute it. And with that, we have just
  40410. 24:53:27loaded completely the bronze layer. So
  40411. 24:53:29as you can see SQL did go and insert all
  40412. 24:53:32the data from the files to the bronze
  40413. 24:53:34layer. It is way easier than each time
  40414. 24:53:36running those scripts of course. All
  40415. 24:53:38right. So now the next step is that as
  40416. 24:53:39you can see the output message it is
  40417. 24:53:42really not having a lot of informations.
  40418. 24:53:44The message of your ETL sold procedure
  40419. 24:53:47it will not be really clear. So that's
  40420. 24:53:49why if you are writing an ETL script
  40421. 24:53:51always take care of the messaging of
  40422. 24:53:53your code. So let me show you a nice
  40423. 24:53:55design. Let's go back to our store
  40424. 24:53:57procedure. So now what we can do we can
  40425. 24:53:58go and divide the message based on our
  40426. 24:54:01code. So now we can start with the
  40427. 24:54:03message for example over here let's say
  40428. 24:54:04print and we say what we are doing with
  40429. 24:54:07this store procedure we are loading the
  40430. 24:54:09bronze liar. So this is the main message
  40431. 24:54:12the most important one and we can go and
  40432. 24:54:14play with the separators like this. So
  40433. 24:54:16we can say print and now we can go and
  40434. 24:54:18add some nice separators like for
  40435. 24:54:20example the equals at the start and at
  40436. 24:54:23the end just to have like a section. So
  40437. 24:54:25this is just a nice message at the
  40438. 24:54:26start. So now by looking to our code we
  40439. 24:54:29can see that our code is splitted into
  40440. 24:54:31two sections. The first section we are
  40441. 24:54:33loading all the tables from the source
  40442. 24:54:35system CRM and the second section is
  40443. 24:54:37loading the tables from the ERP. So we
  40444. 24:54:39can split the prints by the source
  40445. 24:54:41system. So let's go and do that. So
  40446. 24:54:43we're going to say print and we're going
  40447. 24:54:45to say loading CRM tables. This is for
  40448. 24:54:49the first section. And then we can go
  40449. 24:54:51and add some nice separators like the
  40450. 24:54:53one. Let's take the minus. And of
  40451. 24:54:56course, don't forget to add semicolons
  40452. 24:54:58like me. So, we're going to have
  40453. 24:55:00semicolon for each prints. Same thing
  40454. 24:55:03over here. I will go and copy the whole
  40455. 24:55:05thing because we're going to have it at
  40456. 24:55:06the start and as well at the ends. Let's
  40457. 24:55:09go copy the whole thing for the second
  40458. 24:55:11section. So, for the ERP, it starts over
  40459. 24:55:13here. And we're going to have it like
  40460. 24:55:15this. And we're going to call it loading
  40461. 24:55:17ERP. So, with that in the output, we can
  40462. 24:55:20see nice separation between loading each
  40463. 24:55:22source system. Now we go to the next
  40464. 24:55:24step where we go and add like a print
  40465. 24:55:26for each action. So for example here we
  40466. 24:55:29are truncating the table. So we say
  40467. 24:55:31print and now what we can do we can go
  40468. 24:55:33and add two arrows and we say what we
  40469. 24:55:36are doing. So we are truncating the
  40470. 24:55:38table and then we can go and add the
  40471. 24:55:40table name in the message as well. So
  40472. 24:55:42this is the first action that we are
  40473. 24:55:43doing and we can go and add another
  40474. 24:55:45print for inserting the data. So we can
  40475. 24:55:48say inserting data into and then we have
  40476. 24:55:53the table name. So with that in the
  40477. 24:55:54output we can understand what SQL is
  40478. 24:55:56doing. So let's go and repeat this for
  40479. 24:55:58all other tables. Okay. So I just added
  40480. 24:56:01all those prints and don't forget the
  40481. 24:56:03semicolon at the end. So I would say
  40482. 24:56:05let's go and execute it and check the
  40483. 24:56:07output. So let's go and do that and then
  40484. 24:56:09maybe at the start just to have quick
  40485. 24:56:11output execute our stored procedure like
  40486. 24:56:14this. So let's see now if you check the
  40487. 24:56:17output you can see things are more
  40488. 24:56:19organized than before. So at the start
  40489. 24:56:21we are reading okay we are loading the
  40490. 24:56:23bronze layer. Now first we are loading
  40491. 24:56:25the source system CRM and then the
  40492. 24:56:27second section is for the ERP and we can
  40493. 24:56:29see the actions. So we are truncating
  40494. 24:56:31inserting truncating inserting for each
  40495. 24:56:33table and as well the same thing for the
  40496. 24:56:35second source. So as you can see it is
  40497. 24:56:37nice and cosmetic but it's very
  40498. 24:56:39important as you are debugging any
  40499. 24:56:41errors. And speaking of errors, we have
  40500. 24:56:43to go and handle the errors in our store
  40501. 24:56:46procedure. So let's go and do that. It's
  40502. 24:56:48going to be the first thing that we do.
  40503. 24:56:50We say begin try and then we go to the
  40504. 24:56:52end of our script and we say before the
  40505. 24:56:55last end we say end try and then the
  40506. 24:56:58next thing we have to add the catch. So
  40507. 24:57:01we're going to say begin catch and end
  40508. 24:57:04catch. So now first let's go and
  40509. 24:57:06organize our code. I'm going to take the
  40510. 24:57:08whole codes and give it one more push
  40511. 24:57:11and as well the begin try. So it is more
  40512. 24:57:14organized and as you know the try and
  40513. 24:57:16catch going to go and execute the try
  40514. 24:57:19and if there is like any errors during
  40515. 24:57:22executing this script the second section
  40516. 24:57:24going to be executed. So the catch will
  40517. 24:57:26be executed only if the SQL failed to
  40518. 24:57:30run the try. So now what we have to do
  40519. 24:57:32is to go and define for SQL what to do
  40520. 24:57:34if there's like an error in your code.
  40521. 24:57:36And here we can do multiple stuff like
  40522. 24:57:38maybe creating a logging tables and add
  40523. 24:57:40the messages inside this table or we can
  40524. 24:57:43go and add some nice messaging to the
  40525. 24:57:45output like for example we can go and
  40526. 24:57:47add like a section again over here. So
  40527. 24:57:50again some equals and we can go and
  40528. 24:57:53repeat it over here and then add some
  40529. 24:57:54content in between. So we can start with
  40530. 24:57:57something like to say error
  40531. 24:58:00accord during loading bronze layer and
  40532. 24:58:04then we can go and add many stuff like
  40533. 24:58:06for example we can go and add the error
  40534. 24:58:10message and here we can go and call the
  40535. 24:58:12function
  40536. 24:58:13error message and we can go and add as
  40537. 24:58:17well for example the error number. So
  40538. 24:58:20error number and of course the output of
  40539. 24:58:22this going to be a number but the error
  40540. 24:58:24message here is a text. So we have to go
  40541. 24:58:26and change the data type. So we're going
  40542. 24:58:28to do a cast as invar like this and then
  40543. 24:58:33there is like many functions that you
  40544. 24:58:34can add to the output like for example
  40545. 24:58:37the error state and so on. So you can
  40546. 24:58:39design what can happen if there is an
  40547. 24:58:41error in the ETL. Now what else is very
  40548. 24:58:43important in each ATL process is to add
  40549. 24:58:46the duration of each like step. So for
  40550. 24:58:49example, I would like to understand how
  40551. 24:58:51long it takes to load this table over
  40552. 24:58:53here. But looking to the output, I don't
  40553. 24:58:55have any informations how long is taking
  40554. 24:58:57to load my tables. And this is very
  40555. 24:58:59important because as you are building
  40556. 24:59:01like a big data warehouse, the ETL
  40557. 24:59:04process going to take long time and you
  40558. 24:59:05would like to understand where is the
  40559. 24:59:07issue, where is the bottleneck, which
  40560. 24:59:09table is consuming a lot of time to be
  40561. 24:59:11loaded. So that's why we have to add
  40562. 24:59:13those informations as well to the output
  40563. 24:59:16or even maybe to protocol it in a table.
  40564. 24:59:18So let's go and add as well this step.
  40565. 24:59:20So we're going to go to the start and
  40566. 24:59:21now in order to calculate the duration
  40567. 24:59:23you need the starting time and the end
  40568. 24:59:25time. So we have to understand when we
  40569. 24:59:28start loaded and when we ended loading
  40570. 24:59:30the table. So now the first thing is we
  40571. 24:59:32have to go and declare the variables. So
  40572. 24:59:35we're going to say declare and then
  40573. 24:59:36let's make one called start time and the
  40574. 24:59:39data type of this going to be the date
  40575. 24:59:40time. I need exactly the second when it
  40576. 24:59:43started and then another one for the end
  40577. 24:59:45time. So another variable end time and
  40578. 24:59:49as well the same thing date time. So
  40579. 24:59:51with that we have declared the variables
  40580. 24:59:53and the next step is to go and use them.
  40581. 24:59:55So now let's go to the first table to
  40582. 24:59:57the customer info and at the start we're
  40583. 24:59:59going to say set start
  40584. 25:00:01time equal to get date. So we will get
  40585. 25:00:05the exact time when we start loading
  40586. 25:00:08this table. And then let's go and copy
  40587. 25:00:10the whole thing and go to the end of
  40588. 25:00:12loading over here. So we're going to say
  40589. 25:00:14set this time the end time equal as well
  40590. 25:00:17to the get dates. So with that now we
  40591. 25:00:20have the values of when we start loading
  40592. 25:00:22this table and when we completed loading
  40593. 25:00:25the table. And now the next step is we
  40594. 25:00:26have to go and print the duration those
  40595. 25:00:29informations. So over here we can go and
  40596. 25:00:31say print and we can go and have as
  40597. 25:00:33again the same design. So two arrows and
  40598. 25:00:35we can say very simply load duration and
  40599. 25:00:38then double points and a space. And now
  40600. 25:00:41what we have to do is to calculate the
  40601. 25:00:43duration and we can do that using the
  40602. 25:00:45date and time function date diff in
  40603. 25:00:47order to find the interval between two
  40604. 25:00:50dates. So we're going to say plus over
  40605. 25:00:52here and then use date diff. And here we
  40606. 25:00:54have to define three arguments. First
  40607. 25:00:56one is the unit. So here you can define
  40608. 25:00:58second, minute, hours and so on. So
  40609. 25:01:00we're going to go with the second and
  40610. 25:01:01then we're going to define the start of
  40611. 25:01:03the interval. It's going to be the start
  40612. 25:01:04time. And then the last argument it
  40613. 25:01:06going to be the end of the boundary.
  40614. 25:01:08It's going to be the end time. And now
  40615. 25:01:10of course the output of this going to be
  40616. 25:01:11a number that's why we have to go and
  40617. 25:01:13cast it. So we're going to say cast as
  40618. 25:01:16invar and then we're going to close it
  40619. 25:01:18like this and maybe at the end we're
  40620. 25:01:20going to say
  40621. 25:01:21plus space seconds in order to have a
  40622. 25:01:24nice message. So again what we have done
  40623. 25:01:26we have declared the two variables and
  40624. 25:01:28we are using them at the start we are
  40625. 25:01:30getting the current date and time and at
  40626. 25:01:33the end of loading the table we are
  40627. 25:01:34getting the current date and time and
  40628. 25:01:36then we are finding the differences
  40629. 25:01:38between them in order to get the load
  40630. 25:01:40duration and in this case we are just
  40631. 25:01:42printing this information and now we can
  40632. 25:01:44go of course and add some nice separator
  40633. 25:01:46between each table so I'm going to go
  40634. 25:01:48and do it like this just few minuses not
  40635. 25:01:51a lot of stuff so now what we have to do
  40636. 25:01:53is to go and add this mechanism for each
  40637. 25:01:56table in order to measure the speed of
  40638. 25:01:59the ETL for each one of
  40639. 25:02:03[Music]
  40640. 25:02:05them. Okay. So now I have added all
  40641. 25:02:08those configurations for each table and
  40642. 25:02:11let's go and run the whole thing now. So
  40643. 25:02:14let's go and edit the store procedure
  40644. 25:02:16this and we're going to go and run it.
  40645. 25:02:19So let's go and execute. So now as you
  40646. 25:02:21can see we have here one more info about
  40647. 25:02:23the load durations and it is everywhere
  40648. 25:02:25I can see we have zero seconds and
  40649. 25:02:28that's because it is super fast of
  40650. 25:02:30loading those informations we are doing
  40651. 25:02:32everything locally at PC so loading the
  40652. 25:02:34data from files to database going to be
  40653. 25:02:36mega fast but of course in real projects
  40654. 25:02:38you have like different servers and
  40655. 25:02:40networking between them and you have
  40656. 25:02:42millions of rows in the tables of course
  40657. 25:02:44the duration going to be not like 0
  40658. 25:02:46seconds things going to be slower and
  40659. 25:02:48now you can see easily how long it takes
  40660. 25:02:51to load each of your tables. And now of
  40661. 25:02:53course what is very interesting is to
  40662. 25:02:55understand how long it takes to load the
  40663. 25:02:58whole bronze layer. So now your task is
  40664. 25:03:00as well to print at the end informations
  40665. 25:03:03about the whole patch. How long it took
  40666. 25:03:05to load the bronze
  40667. 25:03:07[Music]
  40668. 25:03:11layer. Okay, I hope we are done. Now I
  40669. 25:03:14have done it like this. We have to
  40670. 25:03:16define two new variables. So the start
  40671. 25:03:19time of the batch and the end time of
  40672. 25:03:21the batch. And the first step in the
  40673. 25:03:23start procedure is to get the date and
  40674. 25:03:25time informations for the first
  40675. 25:03:26variable. And exactly at the end the
  40676. 25:03:29last thing that we do in the start
  40677. 25:03:31procedure, we're going to go and get the
  40678. 25:03:33date and time informations for the end
  40679. 25:03:36time. So we say again set get date for
  40680. 25:03:38the patch and time. And then all what we
  40681. 25:03:40have to do is to go and print a message.
  40682. 25:03:42So we are saying loading bronze layer is
  40683. 25:03:45completed and then we are printing total
  40684. 25:03:47load duration and the same thing with a
  40685. 25:03:49date difference between the patch start
  40686. 25:03:51time and the end time and we are
  40687. 25:03:53calculating the seconds and so on. So
  40688. 25:03:55now what we have to do is to go and
  40689. 25:03:56execute the whole thing. So let's go and
  40690. 25:03:59refresh the definition of the start
  40691. 25:04:01procedure and then let's go and execute
  40692. 25:04:03it. So in the output we have to go to
  40693. 25:04:05the last message and we can see loading
  40694. 25:04:08bronze layer is completed and the total
  40695. 25:04:10load duration is as well 0 seconds
  40696. 25:04:13because the execution time is less than
  40697. 25:04:151 second. So with that you are getting
  40698. 25:04:17now a feeling about how to build an ETL
  40699. 25:04:19process. So as you can see the data
  40700. 25:04:21engineering is not all about how to load
  40701. 25:04:24the data. It's how to engineer the whole
  40702. 25:04:26pipeline. how to measure the speed of
  40703. 25:04:28loading the data. What can happen if
  40704. 25:04:30there is like an error and to print each
  40705. 25:04:32step in your ETL process and make
  40706. 25:04:35everything organized and cleared in the
  40707. 25:04:37output and maybe in the logging just to
  40708. 25:04:39make debugging and optimizing the
  40709. 25:04:41performance way easier. And there's like
  40710. 25:04:43a lot of things that we can add. We can
  40711. 25:04:45add the quality measures and stuff. So
  40712. 25:04:48we can add many stuff to our ETL script
  40713. 25:04:50to make our data warehouse professional.
  40714. 25:04:53All right, my friends. So with that we
  40715. 25:04:54have developed a code in order to load
  40716. 25:04:56the bronze layer and we have tested that
  40717. 25:04:58as well. And now in the next step we're
  40718. 25:05:00going to go back to draw because we want
  40719. 25:05:02to draw a diagram about the data flow.
  40720. 25:05:04So let's
  40721. 25:05:08go. So now what is a data flow diagram?
  40722. 25:05:11We're going to draw a simple visual in
  40723. 25:05:12order to map the flow of your data where
  40724. 25:05:15it come from and where it ends up. So we
  40725. 25:05:18want just to make clear how the data
  40726. 25:05:20flows through different layers of your
  40727. 25:05:22projects. And that's help us to create
  40728. 25:05:24something called the data lineage. And
  40729. 25:05:26this is really nice especially if you
  40730. 25:05:28are analyzing an issue. So if you have
  40731. 25:05:30like multiple layers and you don't have
  40732. 25:05:32a real data lineage or flow, it's going
  40733. 25:05:34to be really hard to analyze the scripts
  40734. 25:05:36in order to understand the origin of the
  40735. 25:05:39data and having this diagram going to
  40736. 25:05:41improve the process of finding issues.
  40737. 25:05:43So now let's go and create one. Okay. So
  40738. 25:05:45now back to draw and we're going to go
  40739. 25:05:47and build the flow diagram. So we're
  40740. 25:05:48going to start first with the source
  40741. 25:05:51system. So, let's build the layer. I'm
  40742. 25:05:53going to go and remove the fill dot it.
  40743. 25:05:55And then we're going to go and add like
  40744. 25:05:57a box saying sources and we're going to
  40745. 25:06:00put it over here. Increase the size 24
  40746. 25:06:04and as well without any lines. Now, what
  40747. 25:06:07do we have inside the sources? We have
  40748. 25:06:09like folder and files. So, let's go and
  40749. 25:06:12search for a folder icon. I'm going to
  40750. 25:06:14go and take this one over here and say
  40751. 25:06:16you are the CRM. And we can as well
  40752. 25:06:18increase the size. And we have another
  40753. 25:06:20source. We have the
  40754. 25:06:23ERP. Okay. So, this is the first layer.
  40755. 25:06:26Let's go and now have the bronze layer.
  40756. 25:06:29So, we're going to go and grab another
  40757. 25:06:31box. And we're going to go and make the
  40758. 25:06:33coloring like this. And instead of auto,
  40759. 25:06:35maybe take the hatch, maybe something
  40760. 25:06:37like this, whatever, you know. So,
  40761. 25:06:40rounded. And then we can go and put on
  40762. 25:06:42top of it like the title. So, we can say
  40763. 25:06:46you are the bronze layer. and increase
  40764. 25:06:49as well the size of the font. So now
  40765. 25:06:51what we're going to do, we're going to
  40766. 25:06:52go and add boxes for each table that we
  40767. 25:06:55have in the bronze layer. So for
  40768. 25:06:56example, we have the sales details. We
  40769. 25:06:58can go and make it a little bit smaller.
  40770. 25:07:00So maybe 16 and not bold. And we have
  40771. 25:07:04other two tables from the CRM. We have
  40772. 25:07:07the customer info and as well the
  40773. 25:07:10product info. So those are the three
  40774. 25:07:12tables that comes from the CRM. And now
  40775. 25:07:15what we're going to do, we're going to
  40776. 25:07:16go and connect now the source CRM with
  40777. 25:07:20those three tables. So what we're going
  40778. 25:07:21to do, we're going to go to the folder
  40779. 25:07:22and start making arrows from the folder
  40780. 25:07:26to the bronze layer like this. And now
  40781. 25:07:28we have to do the same thing for the ERP
  40782. 25:07:31source. So as you can see the data flow
  40783. 25:07:33diagram shows us in one picture the data
  40784. 25:07:36lineage between the two layers. So here
  40785. 25:07:38we can see easily those three tables
  40786. 25:07:40actually comes from the CRM and as well
  40787. 25:07:42those three tables in the bronze layer
  40788. 25:07:44are coming from the ERP. I understand if
  40789. 25:07:46we have like a lot of tables it's going
  40790. 25:07:48to be a huge mess. But if you have like
  40791. 25:07:50small or medium data warehouse building
  40792. 25:07:53those diagrams going to make things
  40793. 25:07:54really easier to understand how
  40794. 25:07:56everything is flowing from the sources
  40795. 25:07:59into the different layers in your data
  40796. 25:08:01warehouse. All right. So with that we
  40797. 25:08:03have the first version of the data flow.
  40798. 25:08:05So this step is done and the final step
  40799. 25:08:07is to commit our code in the get
  40800. 25:08:13repo. Okay. So now let's go and commit
  40801. 25:08:15our work. Since it is scripts, we're
  40802. 25:08:17going to go to the folder scripts. And
  40803. 25:08:18here we're going to have like script for
  40804. 25:08:20the bronze, silver, and gold. That's why
  40805. 25:08:22maybe it makes sense to create a folder
  40806. 25:08:24for each layer. So let's go and start
  40807. 25:08:26creating the bronze folder. So I'm going
  40808. 25:08:28to go and create a new file. And then
  40809. 25:08:30I'm going to say bronze slash. And then
  40810. 25:08:32we can have the DDL script of the bronze
  40811. 25:08:35layer SQL. So now I'm going to go and
  40812. 25:08:37paste the DDL codes that we have
  40813. 25:08:39created. So those six tables and as
  40814. 25:08:42usual at the start we have a comment
  40815. 25:08:44where we are explaining the purpose of
  40816. 25:08:45this script. So we are saying this
  40817. 25:08:47scripts creates tables in the bronze
  40818. 25:08:49schema. And by running this scripts you
  40819. 25:08:51are redefining the DDL structure of the
  40820. 25:08:53bronze tables. So let's have it like
  40821. 25:08:55that. And I'm going to go and commit the
  40822. 25:08:58changes. All right. So now as you can
  40823. 25:09:00see inside the scripts we have a folder
  40824. 25:09:02called bronze and inside it we have the
  40825. 25:09:05DDL script for the bronze layer and as
  40826. 25:09:07well in the bronze layer we're going to
  40827. 25:09:08go and put our start procedure. So we're
  40828. 25:09:10going to go and create a new file let's
  40829. 25:09:12call it proc load bronze dossql and then
  40830. 25:09:17let's go and paste our script and as
  40831. 25:09:19usual I have put it at the start an
  40832. 25:09:21explanation about the store procedure.
  40833. 25:09:23So we are saying this third procedure
  40834. 25:09:25going to go and load the data from the
  40835. 25:09:26CSV files into the bronze schema. So it
  40836. 25:09:29going to go and truncate first the
  40837. 25:09:31tables and then do a bulk insert. And
  40838. 25:09:33about the parameters, this source
  40839. 25:09:35procedure does not accept any parameter
  40840. 25:09:37or return any values. And here a quick
  40841. 25:09:39example how to execute it. All right. So
  40842. 25:09:41I think I'm happy with that. So let's go
  40843. 25:09:44and commit it. All right. My friends, so
  40844. 25:09:47with that we have committed our code
  40845. 25:09:49into the g. And with that we are done
  40846. 25:09:51building the bronze layer. So the whole
  40847. 25:09:53op is done. Now we're going to go to the
  40848. 25:09:55next one. This one going to be more
  40849. 25:09:57advanced than the bronze layer because
  40850. 25:09:59there will be a lot of struggle with
  40851. 25:10:01cleaning the data and so on. So we're
  40852. 25:10:02going to start with the first task where
  40853. 25:10:04we're going to analyze and explore the
  40854. 25:10:06data in the source systems. So let's
  40855. 25:10:11go. Okay. So now we're going to start
  40856. 25:10:13with the big question. How to build the
  40857. 25:10:15server layer? What is the process? Okay.
  40858. 25:10:17As usual, first things first, we have to
  40859. 25:10:19analyze. And now the task before
  40860. 25:10:21building anything in the server layer we
  40861. 25:10:23have to go and explore the data in order
  40862. 25:10:26to understand the content of our sources
  40863. 25:10:28once we have it what we're going to do
  40864. 25:10:29we will be starting coding and here the
  40865. 25:10:32transformation that we're going to do is
  40866. 25:10:33data cleansing this is usually process
  40867. 25:10:35that take really long time and I usually
  40868. 25:10:37do it in three steps the first step is
  40869. 25:10:40to check first the data quality issues
  40870. 25:10:42that we have in the bronze layer so
  40871. 25:10:44before writing any data transformations
  40872. 25:10:46first we have to understand what are the
  40873. 25:10:48issues and only then I start writing
  40874. 25:10:50think data transformations in order to
  40875. 25:10:52fix all those quality issues that we
  40876. 25:10:54have in the bronze and the last step
  40877. 25:10:56once I have clean results what we're
  40878. 25:10:58going to do we're going to go and insert
  40879. 25:11:00it into the server layer and those are
  40880. 25:11:02the three faces that we will be doing as
  40881. 25:11:04we are writing the code for the silver
  40882. 25:11:06layer and the third step once we have
  40883. 25:11:07all the data in the server layer we have
  40884. 25:11:09to make sure that the data is now
  40885. 25:11:11correct and we don't have any quality
  40886. 25:11:13issues anymore and if you find any
  40887. 25:11:15issues of course what you going to do
  40888. 25:11:16we're going to go back to coding we're
  40889. 25:11:18going to do the data cleansing and again
  40890. 25:11:19object. So it is like a cycle between
  40891. 25:11:21validating and coding. Once the quality
  40892. 25:11:24of the silver layer is good, we cannot
  40893. 25:11:26skip the last phase where we're going to
  40894. 25:11:28document and commit our work in the G.
  40895. 25:11:30And here we're going to have two new
  40896. 25:11:31documentations. We're going to build the
  40897. 25:11:33data flow diagram and as well the data
  40898. 25:11:36integration diagram after we understood
  40899. 25:11:38the relationship between the sources
  40900. 25:11:40from the first step. So this is the
  40901. 25:11:42process and this is how we're going to
  40902. 25:11:43build the server layer.
  40903. 25:11:49All right. So now exploring the data in
  40904. 25:11:51the bronze layer. So why it is very
  40905. 25:11:52important? Because understanding the
  40906. 25:11:54data it is the key to make smart
  40907. 25:11:56decisions in the server layer. It was
  40908. 25:11:58not the focus in the bronze layer to
  40909. 25:12:00understand the content of the data at
  40910. 25:12:02all. We focus only how to get the data
  40911. 25:12:04to the data warehouse. So that's why we
  40912. 25:12:06have now to take a moment in order to
  40913. 25:12:09explore and understand the tables and as
  40914. 25:12:11well how to connect them. what are the
  40915. 25:12:13relationship between these tables and it
  40916. 25:12:15is very important as you are learning
  40917. 25:12:17about the new source system is to create
  40918. 25:12:19like some kind of documentation. So now
  40919. 25:12:21let's go and explore the sources. Okay.
  40920. 25:12:24So now let's go and explore them one by
  40921. 25:12:26one. We can start with the first one
  40922. 25:12:27from the CRM. We have the customer info.
  40923. 25:12:30So right click on it and say select top
  40924. 25:12:32thousand rows. And this is of course
  40925. 25:12:33important if you have like a lot of
  40926. 25:12:35data. Don't go and explore millions of
  40927. 25:12:37rows. Always limit your query. So for
  40928. 25:12:39example here we are using the top
  40929. 25:12:40thousands just to make sure that you are
  40930. 25:12:42not impacting the system with your
  40931. 25:12:43queries. So now let's have a look to the
  40932. 25:12:45content of this table. So we can see
  40933. 25:12:46that we have here customer informations.
  40934. 25:12:49So we have an ID, we have a key for the
  40935. 25:12:51customer, we have first name, last name,
  40936. 25:12:53marital status, gender and the creation
  40937. 25:12:56date of the customer. So simply this is
  40938. 25:12:58a table for the customer information and
  40939. 25:13:00a lot of details for the customers. And
  40940. 25:13:02here we have like two identifiers. one
  40941. 25:13:05it is like technical ID and another one
  40942. 25:13:07it's like the customer number so maybe
  40943. 25:13:10we can use either the ID or the key in
  40944. 25:13:12order to join it with other tables so
  40945. 25:13:14now what I usually do is to go and draw
  40946. 25:13:16like data model or let's say integration
  40947. 25:13:19model just to document and visual what I
  40948. 25:13:21am understanding because if you don't do
  40949. 25:13:23that you're going to forget it after a
  40950. 25:13:24while so now we go and search for a
  40951. 25:13:26shape let's search for a table and I'm
  40952. 25:13:28going to go and pick this one over here
  40953. 25:13:30so here we can go and change the style
  40954. 25:13:32for example we can make it rounded or
  40955. 25:13:34you can go make it sketch and so on. And
  40956. 25:13:37we can go and change the color. I'm
  40957. 25:13:39going to make it blue. Then go to the
  40958. 25:13:41text. Make sure to select the whole
  40959. 25:13:42thing. And let's make it bigger. 26. And
  40960. 25:13:46then what I'm going to do for those
  40961. 25:13:48items, I'm just going to select them and
  40962. 25:13:50go to our range and maybe make it 40.
  40963. 25:13:53Something like this. So now what we're
  40964. 25:13:55going to do, we're going to just go and
  40965. 25:13:56put the table name. So this is the one
  40966. 25:13:58that we are now learning about. And what
  40967. 25:14:01I'm going to do, I'm just going to go
  40968. 25:14:02and put here the primary key. I will not
  40969. 25:14:04go and list all the informations. So the
  40970. 25:14:06primary key was the ID. And I will go
  40971. 25:14:09and remove all those stuff. I don't need
  40972. 25:14:11it. Now, as you can see, the table name
  40973. 25:14:12is not really friendly. So I can go and
  40974. 25:14:14bring a text and put it here on top and
  40975. 25:14:17say this is the customer information.
  40976. 25:14:20Just to make it friendly and to not
  40977. 25:14:22forget about it. And as well going to
  40978. 25:14:24increase the size to maybe 20 something
  40979. 25:14:27like this. Okay. With that, we have our
  40980. 25:14:29first table. and we're going to go and
  40981. 25:14:31keep exploring. So let's move to the
  40982. 25:14:33second one. We're going to take the
  40983. 25:14:34product information, right click on it
  40984. 25:14:37and select the top thousand rows. I will
  40985. 25:14:39just put it below the previous query.
  40986. 25:14:41Query it. Now by looking to this table
  40987. 25:14:43we can see we have product informations.
  40988. 25:14:46So we have here a primary key for the
  40989. 25:14:48product and then we have like key or
  40990. 25:14:50let's say product number and after that
  40991. 25:14:52we have the full name of the product the
  40992. 25:14:54product costs and then we have the
  40993. 25:14:56product line and then we have like start
  40994. 25:14:58and end. Well this is interesting to
  40995. 25:15:01understand why we have start and ends.
  40996. 25:15:03Let's have a look for example for those
  40997. 25:15:05three rows all of those three having the
  40998. 25:15:08same key but they have different ids. So
  40999. 25:15:10it is the same product but with
  41000. 25:15:13different costs. So for 2011 we have the
  41001. 25:15:16cost of 12. Then 2012 we have 14 and for
  41002. 25:15:20the last year 2013 we have 13. So it's
  41003. 25:15:23like we have like a history for the
  41004. 25:15:25changes. So this table not only holding
  41005. 25:15:27the current informations of the product
  41006. 25:15:30but also history informations of the
  41007. 25:15:32product and that's why we have those to
  41008. 25:15:34date start and end. Now let's go back
  41009. 25:15:36and draw this information over here. So
  41010. 25:15:38I'm just going to go and duplicate it.
  41011. 25:15:40So the name of this table going to be
  41012. 25:15:42the BRD info and let's go and give it
  41013. 25:15:44like a short description current and
  41014. 25:15:47history products information something
  41015. 25:15:51like this just to not forget that we
  41016. 25:15:53have history in this table and here we
  41017. 25:15:54have as well the PRD ID and there is
  41018. 25:15:57like nothing that we can use in order to
  41019. 25:15:59join those two tables we don't have like
  41020. 25:16:02a customer ID here or in the other table
  41021. 25:16:04we don't have any product ID okay so
  41022. 25:16:06that's it for this table let's jump to
  41023. 25:16:07the third table and the last one in the
  41024. 25:16:09CRM M. So let's go and select. I just
  41025. 25:16:12made the other queries as well short. So
  41026. 25:16:14let's go and execute. So what do we have
  41027. 25:16:15over here? We have a lot of informations
  41028. 25:16:17about the order, the sales and a lot of
  41029. 25:16:20measures. Order number. We have the
  41030. 25:16:22product key. So this is something that
  41031. 25:16:24we can use in order to join it with the
  41032. 25:16:26product table. We have the customer ID.
  41033. 25:16:28We don't have the customer key. So here
  41034. 25:16:30we have like ID and here we have key. So
  41035. 25:16:33there's like two different ways on how
  41036. 25:16:35to join tables. And then we have here
  41037. 25:16:37like dates. the order date, the shipping
  41038. 25:16:40date, the due date and then we have the
  41039. 25:16:42sales amount, the quantity and the
  41040. 25:16:44price. So this is like an event table.
  41041. 25:16:46It is transactional table about the
  41042. 25:16:48orders and sales and it is great table
  41043. 25:16:51in order to connect the customers with
  41044. 25:16:53the products and as well with the
  41045. 25:16:55orders. So let's document this new
  41046. 25:16:57information that we have. So the table
  41047. 25:17:00name is the sales details. So we can go
  41048. 25:17:02and describe it like this.
  41049. 25:17:05Transactional records about sales and
  41050. 25:17:10orders. And now we have to go and
  41051. 25:17:12describe how we can connect this table
  41052. 25:17:14to the other two. So we are not using
  41053. 25:17:16the product ID. We are using the
  41054. 25:17:18products key. And now we need a new
  41055. 25:17:21column over here. So you can hold
  41056. 25:17:22control and enter or you can go over
  41057. 25:17:24here and add a new row. And the other
  41058. 25:17:27row going to be the customer ID. So now
  41059. 25:17:29for the customer ID it is easy. we can
  41060. 25:17:31go and grab an arrow in order to connect
  41061. 25:17:33those two tables. But for the product
  41062. 25:17:34key, we are not using the ID. So that's
  41063. 25:17:37why I'm just going to go and remove this
  41064. 25:17:39one and say product key. Let's have
  41065. 25:17:41again a check. So this is a product key.
  41066. 25:17:44It's not the product ID. And if we go
  41067. 25:17:46and check the old table, the products
  41068. 25:17:47info, you can see we are using this key
  41069. 25:17:50and not the primary key. So what we're
  41070. 25:17:52going to do now, we will just go and
  41071. 25:17:54link it like this. And maybe switch
  41072. 25:17:56those two tables. So I will put the
  41073. 25:17:58customers below. Just perfect. It looks
  41074. 25:18:01nice. Okay. So, let's keep moving. Let's
  41075. 25:18:03go now to the other source system. We
  41076. 25:18:05have the ARP and the first one is ARB
  41077. 25:18:07cost and we have this cryptical name.
  41078. 25:18:10Let's go and select the data. So, now
  41079. 25:18:12here it's small table and we have only
  41080. 25:18:14three informations. So, we have here
  41081. 25:18:16something called CD and then we have
  41082. 25:18:18something I think this is the birthday
  41083. 25:18:20and the gender information. So, we have
  41084. 25:18:22here male, female and so on. So, it
  41085. 25:18:24looks again like the customer
  41086. 25:18:26informations but here we have like extra
  41087. 25:18:27data about the birthday. And now if you
  41088. 25:18:30go and compare it to the customer table
  41089. 25:18:32that we have from the other source
  41090. 25:18:33system. Let's go and query it. You can
  41091. 25:18:35see the new table from the ARB don't
  41092. 25:18:37have ids. It has actually the customer
  41093. 25:18:41number or the key. So we can go and join
  41094. 25:18:43those two tables using the customer key.
  41095. 25:18:46Let's go and document this information.
  41096. 25:18:48So I will just go and copy paste and put
  41097. 25:18:50it here on the right side. I will just
  41098. 25:18:51go and change the color now since we are
  41099. 25:18:53now talking about different source
  41100. 25:18:55system. And here the table name going to
  41101. 25:18:57be this one. and the key called C ID.
  41102. 25:19:01Now, in order to join this table with
  41103. 25:19:03the customer info, we cannot join it
  41104. 25:19:05with the customer ID. We need the
  41105. 25:19:06customer key. That's why here we have to
  41106. 25:19:08go and add a new row. So, ctrl enter and
  41107. 25:19:10we're going to say customer key. And
  41108. 25:19:13then we have to go and make a nice arrow
  41109. 25:19:15between those two keys. So, we're going
  41110. 25:19:17to go and give it a description,
  41111. 25:19:20customer information. And here we have
  41112. 25:19:23the birth date. Okay. So, now let's keep
  41113. 25:19:26going. We're going to go to the next
  41114. 25:19:28one. We have the ERP location. Let's go
  41115. 25:19:32and query this table. So, what do we
  41116. 25:19:34have over here? We have the CD again.
  41117. 25:19:36And as you can see, we have country
  41118. 25:19:38informations. And this is of course
  41119. 25:19:40again the customer number. And we have
  41120. 25:19:42only this information, the country. So,
  41121. 25:19:44let's go and document this information.
  41122. 25:19:46This is the customer location. Table
  41123. 25:19:48name going to be like this. And we still
  41124. 25:19:50have the same ID. So, we have here still
  41125. 25:19:53the customer ID and we can go and join
  41126. 25:19:55it using the customer key. And we have
  41127. 25:19:57to give it the description location of
  41128. 25:20:00customers and we can say here the
  41129. 25:20:02country. Okay. So now let's go to the
  41130. 25:20:05last table and explore it. We have the
  41131. 25:20:07ERP ex catalog. So let's go and query
  41132. 25:20:12those informations. So what do we have
  41133. 25:20:14here? We have like an ID, a category, a
  41134. 25:20:17subcategory and the maintenance. Here we
  41135. 25:20:19have like either yes and no. So by
  41136. 25:20:21looking to this table we have all the
  41137. 25:20:23categories and the subcategories of the
  41138. 25:20:26products and here we have like special
  41139. 25:20:28identifier for those informations. Now
  41140. 25:20:30the question is how to join it. So I
  41141. 25:20:33would like to join it actually with the
  41142. 25:20:34product informations. So let's go and
  41143. 25:20:36check those two tables together. Okay.
  41144. 25:20:38So in the product we don't have any ID
  41145. 25:20:40for the categories but we have these
  41146. 25:20:42informations actually in the product
  41147. 25:20:45key. So the first five characters of the
  41148. 25:20:47product key is actually the category ID.
  41149. 25:20:50So we can use this information over here
  41150. 25:20:53in order to join it with the categories.
  41151. 25:20:55So we can go and describe this
  41152. 25:20:57information like this and then we have
  41153. 25:20:59to go and give it a name. And then here
  41154. 25:21:01we have the ID and the ID could be
  41155. 25:21:03joined using the product key. So that
  41156. 25:21:06means for the product information we
  41157. 25:21:08don't need at all the product ID the
  41158. 25:21:10primary key. All what we need is the
  41159. 25:21:13product key or the product number. And
  41160. 25:21:15what I would like to do is like to group
  41161. 25:21:16those informations in a box. So, let's
  41162. 25:21:20go grab like any boxes here on the left
  41163. 25:21:22side and make it bigger and then make
  41164. 25:21:26the edges a little bit smaller. Let's
  41165. 25:21:28remove the fill and the line. I will
  41166. 25:21:31make a dotted line. And then let's grab
  41167. 25:21:33another box over here and say this is
  41168. 25:21:36the CRM. And we can go and increase the
  41169. 25:21:38size maybe something like 40 smaller 35
  41170. 25:21:42bold and change the color to blue and
  41171. 25:21:44just place it here on top of this box.
  41172. 25:21:46So with that we can understand all those
  41173. 25:21:48tables belongs to the source system CRM
  41174. 25:21:51and we can do the same stuff for the
  41175. 25:21:53right side as well. Now of course we
  41176. 25:21:55have to go and add the description here.
  41177. 25:21:58So it's going to be the products
  41178. 25:22:00categories. All right. So with that we
  41179. 25:22:02have now a clear understanding how the
  41180. 25:22:04tables are connected to each others. We
  41181. 25:22:07understand now the content of each table
  41182. 25:22:09and of course it can help us to clean up
  41183. 25:22:11the data in the silver layer in order to
  41184. 25:22:13prepare it. So as you can see it is very
  41185. 25:22:16important to take time understanding the
  41186. 25:22:18structure of the tables the relationship
  41187. 25:22:20between them before start writing any
  41188. 25:22:22code. All right. So with that we have
  41189. 25:22:24now clear understanding about the
  41190. 25:22:25sources and with that we have as well
  41191. 25:22:27created a data integration in the draw.
  41192. 25:22:30So with that we have more understanding
  41193. 25:22:32about how to connect the sources. And
  41194. 25:22:34now in the next two task we will go back
  41195. 25:22:36to SQL where we're going to start
  41196. 25:22:38checking the quality and as well doing a
  41197. 25:22:40lot of data transformations. So let's
  41198. 25:22:42go.
  41199. 25:22:46Okay, so now let's have a quick look to
  41200. 25:22:48the specifications of the server layer.
  41201. 25:22:50So the main objective to have clean and
  41202. 25:22:52standardized data. We have to prepare
  41203. 25:22:54the data before going to the gold layer.
  41204. 25:22:57And we will be building tables inside
  41205. 25:22:59the silver layer. And the way of loading
  41206. 25:23:01the data from the bronze to the silver
  41207. 25:23:03is a full load. So that means we're
  41208. 25:23:05going to truncate and then insert. And
  41209. 25:23:06here we're going to have a lot of data
  41210. 25:23:08transformations. So we're going to clean
  41211. 25:23:09the data. We're going to bring
  41212. 25:23:11normalizations, standardizations. We're
  41213. 25:23:13going to derive new columns. We will be
  41214. 25:23:15doing as well data enrichments. So a lot
  41215. 25:23:18of things to be done in the data
  41216. 25:23:19transformation. But we will not be
  41217. 25:23:21building any new data model. So those
  41218. 25:23:23are the specifications and we have to
  41219. 25:23:25commit ourself to this scope. Okay. So
  41220. 25:23:27now building the DDL script for the
  41221. 25:23:28silver layer going to be way easier than
  41222. 25:23:31the bronze because the definition and
  41223. 25:23:33the structure of each table in the
  41224. 25:23:34silver going to be identical to the
  41225. 25:23:36bronze layer. We are not doing anything
  41226. 25:23:39new. So all what you have to do is to
  41227. 25:23:40take the DDL script from the bronze
  41228. 25:23:42layer and just go and search and replace
  41229. 25:23:45for the schema. I'm just using the
  41230. 25:23:46Notepad++ for the scripts. So I'm going
  41231. 25:23:49to go over here and say replace the
  41232. 25:23:51bronze dots with silver dots and I'm
  41233. 25:23:53going to go and replace all. So with
  41234. 25:23:55that now all the DDL is targeting the
  41235. 25:23:58schema silver layer which is exactly
  41236. 25:24:01what we need. All right. Now before we
  41237. 25:24:03execute our new DDL script for the
  41238. 25:24:05silver, we have to talk about something
  41239. 25:24:07called the metadata columns. They are
  41240. 25:24:09additional columns or fields that the
  41241. 25:24:11data engineers add to each table that
  41242. 25:24:14don't come directly from the source
  41243. 25:24:16systems. But the data engineers use it
  41244. 25:24:18in order to provide extra informations
  41245. 25:24:21for each record. Like we can add a
  41246. 25:24:23column called create date is when the
  41247. 25:24:25record was loaded or an update date when
  41248. 25:24:28the record got updated or we can add the
  41249. 25:24:31source system in order to understand the
  41250. 25:24:33origin of the data that we have or
  41251. 25:24:36sometimes we can add the file location
  41252. 25:24:38in order to understand the lineage from
  41253. 25:24:40which file the data come from. Those are
  41254. 25:24:43great tool if you have data issue in
  41255. 25:24:45your data warehouse if there is like
  41256. 25:24:46corrupt data and so on. This can help
  41257. 25:24:49you to track exactly where this issue
  41258. 25:24:52happens and when. And as well it is
  41259. 25:24:54great in order to understand whether I
  41260. 25:24:56have gap in my data especially if you
  41261. 25:24:57are doing incremental loads. It is like
  41262. 25:24:59putting labels on everything and you
  41263. 25:25:02will thank yourself later when you start
  41264. 25:25:04using them in hard times as you have an
  41265. 25:25:06issue in your data warehouse. So now
  41266. 25:25:08back to our DDL scripts and all what you
  41267. 25:25:10have to do is to go and do the
  41268. 25:25:11following. So for example for the first
  41269. 25:25:13table I will go and add at the end one
  41270. 25:25:16more extra column. So it start with the
  41271. 25:25:18prefix TWW as we have defined in the
  41272. 25:25:21naming convention and then underscore
  41273. 25:25:23let's have the create date and the data
  41274. 25:25:26type going to be date time 2 and now
  41275. 25:25:28what we can do is we can go and add a
  41276. 25:25:30default value for it. I want the
  41277. 25:25:32database to generate these informations
  41278. 25:25:34automatically. We don't have to specify
  41279. 25:25:36that in any scripts. So which value?
  41280. 25:25:38It's going to be the get date. So each
  41281. 25:25:41record going to be inserted in this
  41282. 25:25:42table will get automatically a value
  41283. 25:25:45from the current date and time. So now
  41284. 25:25:47as you can see the naming convention it
  41285. 25:25:49is very important. All those columns
  41286. 25:25:51comes from the source system and only
  41287. 25:25:53this one column comes from the data
  41288. 25:25:55engineer of the data warehouse. Okay. So
  41289. 25:25:57that's it. Let's go and repeat the same
  41290. 25:25:59thing for all other tables. So I will
  41291. 25:26:01just go and add this piece of
  41292. 25:26:03information for each
  41293. 25:26:06DDL. All right. So I think that's it.
  41294. 25:26:09All what you have to do is now to go and
  41295. 25:26:11execute the whole DDL script for the
  41296. 25:26:13silver layer. Let's go and do that. All
  41297. 25:26:15right, perfect. There's no errors. Let's
  41298. 25:26:17go and refresh the tables on the object
  41299. 25:26:19explorer. And with that, as you can see,
  41300. 25:26:21we have six tables for the silver layer.
  41301. 25:26:23It is identical to the bronze layer, but
  41302. 25:26:25we have one extra column for the
  41303. 25:26:31metadata. All right. All right. So now
  41304. 25:26:33in the server layer before we start
  41305. 25:26:35writing any data transformations and
  41306. 25:26:37cleansing we have first to detect the
  41307. 25:26:39quality issues in the bronze without
  41308. 25:26:41knowing the issues we cannot find
  41309. 25:26:43solution right we will explore first the
  41310. 25:26:45quality issues only then we start
  41311. 25:26:47writing the transformation scripts. So
  41312. 25:26:50let's
  41313. 25:26:56go. Okay. Okay. So now what we're going
  41314. 25:26:58to do, we're going to go through all the
  41315. 25:26:59tables over the bronze layer, clean up
  41316. 25:27:01the data, and then insert it to the
  41317. 25:27:04server layer. So let's start with the
  41318. 25:27:05first table, the first bronze table from
  41319. 25:27:08the source CRM. So we're going to go to
  41320. 25:27:09the bronze CRM customer info. So let's
  41321. 25:27:13go and query the data over here. Now, of
  41322. 25:27:15course, before writing any data
  41323. 25:27:17transformations, we have to go and
  41324. 25:27:19detect and identify the quality issues
  41325. 25:27:22of this table. So usually I start with
  41326. 25:27:24the first check where we go and check
  41327. 25:27:26the primary key. So we have to go and
  41328. 25:27:28check whether there are nulls inside the
  41329. 25:27:30primary key and whether there are
  41330. 25:27:31duplicates. So now in order to detect
  41331. 25:27:34the duplicates in the primary key what
  41332. 25:27:35we have to do is to go and aggregate the
  41333. 25:27:38primary key. If we find any value in the
  41334. 25:27:40primary key that exist more than once
  41335. 25:27:42that means it is not unique and we have
  41336. 25:27:44duplicates in the table. So let's go and
  41337. 25:27:46write query for that. So what we're
  41338. 25:27:48going to do, we're going to go with the
  41339. 25:27:50customer ID and then we're going to go
  41340. 25:27:51and count and then we have to group up
  41341. 25:27:54the data. So group by based on the
  41342. 25:27:56primary key and of course we don't need
  41343. 25:27:58all the results. We need only where we
  41344. 25:28:00have an issue. So we're going to say
  41345. 25:28:02having
  41346. 25:28:04count higher than one. So we are
  41347. 25:28:06interested in the values where the count
  41348. 25:28:09is higher than one. So let's go and
  41349. 25:28:11execute it. Now as you can see we have
  41350. 25:28:13issue in this table. we have duplicates
  41351. 25:28:15because all those ids exist more than
  41352. 25:28:18one in the table which is completely
  41353. 25:28:20wrong. We should have the primary key
  41354. 25:28:21unique and you can see as well we have
  41355. 25:28:23three records where the primary key is
  41356. 25:28:25empty which is as well a bad thing. Now
  41357. 25:28:28there is an issue here. If we have only
  41358. 25:28:30one null it will not be here at the
  41359. 25:28:32result. So what I'm going to do I'm
  41360. 25:28:34going to go over here and say or the
  41361. 25:28:36primary key is null just in case if we
  41362. 25:28:39have only one null I'm still interested
  41363. 25:28:41to see the results. So if I go and run
  41364. 25:28:44it again, we'll get the same results. So
  41365. 25:28:46this is equality check that you can do
  41366. 25:28:47on the table. And as you can see, it is
  41367. 25:28:49not meeting the expectation. So that
  41368. 25:28:51means we have to do something about it.
  41369. 25:28:53So let's go and create a new query. So
  41370. 25:28:56here what we're going to do, we can
  41371. 25:28:57start writing the query that is doing
  41372. 25:28:59the data transformation and the data
  41373. 25:29:01cleansing. So let's start again by
  41374. 25:29:03selecting the
  41375. 25:29:07data and execute it again. So now what I
  41376. 25:29:10usually do I go and focus on the issue.
  41377. 25:29:13So for example let's go and take one of
  41378. 25:29:15those values and I focus on it before
  41379. 25:29:17start writing the transformation. So
  41380. 25:29:19we're going to say where customer ID
  41381. 25:29:21equal to this value. All right. So now
  41382. 25:29:24as you can see we have here the issue
  41383. 25:29:25where the ID exist three times but
  41384. 25:29:28actually we are interested only on one
  41385. 25:29:30of them. So the question is how to pick
  41386. 25:29:32one of those. Usually we search for a
  41387. 25:29:34time stamp or date value to help us. So
  41388. 25:29:36if you check the creation date over here
  41389. 25:29:38we can understand that this record this
  41390. 25:29:41one over here is the newest one and the
  41391. 25:29:44previous two are older than it. So that
  41392. 25:29:46means if I have to go and pick one of
  41393. 25:29:48those values I would like to get the
  41394. 25:29:50latest one because it holds the most
  41395. 25:29:53fresh information. So what we have to do
  41396. 25:29:55is we have to go and rank all those
  41397. 25:29:57values based on the create dates and
  41398. 25:30:00only pick the highest one. So that means
  41399. 25:30:03we need a racking function and for that
  41400. 25:30:05in scale we have the amazing window
  41401. 25:30:07functions. So let's go and do that. We
  41402. 25:30:10will use the function row number over
  41403. 25:30:14and then partition by and here we have
  41404. 25:30:17to divide the table by the customer ID.
  41405. 25:30:20So we're going to divide it by the
  41406. 25:30:22customer ID and in order now to rank
  41407. 25:30:24those rows we have to sort the data by
  41408. 25:30:26something. So order by and as we
  41409. 25:30:28discussed we want to sort the data by
  41410. 25:30:30the creation date. So create
  41411. 25:30:33date and we're going to sort it
  41412. 25:30:35descending. So the highest first then
  41413. 25:30:37the lowest. So let's go and do that. And
  41414. 25:30:39now we're going to go and give it a name
  41415. 25:30:41flag last. So now let's go and execute
  41416. 25:30:44it. Now the data is sorted by the
  41417. 25:30:46creation date. And you can see over here
  41418. 25:30:48that this record is the number one. Then
  41419. 25:30:51the one that is older is two and the
  41420. 25:30:53oldest one is three. Of course we are
  41421. 25:30:55interested in the rank number one. Now
  41422. 25:30:57let's go and remove the filter and check
  41423. 25:30:59everything. So now if you have a look to
  41424. 25:31:01the table you can see that on the flag
  41425. 25:31:03we have everywhere like one and that's
  41426. 25:31:06because the those primary keys exist
  41427. 25:31:08only one but sometimes we will not have
  41428. 25:31:10one we'll have two three and so on. If
  41429. 25:31:12there's like duplicates we can go of
  41430. 25:31:13course and do a double check. So let's
  41431. 25:31:15go over here and say select
  41432. 25:31:18star from this query we can say where
  41433. 25:31:21flag last is in equal to one. So let's
  41434. 25:31:24go and query it. And now we can see all
  41435. 25:31:26the data that we don't need because they
  41436. 25:31:28are causing duplicates in the primary
  41437. 25:31:30key and they have like an old status. So
  41438. 25:31:32what we're going to do we're going to
  41439. 25:31:34say equal to one. And with that we
  41440. 25:31:36guarantee that our primary key is unique
  41441. 25:31:38and each value exist only once. So if I
  41442. 25:31:40go and query it like this you will see
  41443. 25:31:42we will not find any duplicate inside
  41444. 25:31:44our table. And we can go and check that
  41445. 25:31:46of course. So let's go and check this
  41446. 25:31:48primary key. And we're going to say and
  41447. 25:31:50customer ID equal to this value. And you
  41448. 25:31:53can see it exists now only once and we
  41449. 25:31:56are getting the freshest data from this
  41450. 25:31:58primary key. So with that we have
  41451. 25:31:59defined like transformation in order to
  41452. 25:32:02remove any duplicates. Okay. So now
  41453. 25:32:04moving on to the next one. As you can
  41454. 25:32:06see in our table we have a lot of values
  41455. 25:32:08where they are like string values. Now
  41456. 25:32:11for these string values we have to check
  41457. 25:32:13the unwanted spaces. So now let's go and
  41458. 25:32:16write a query that's going to detect
  41459. 25:32:17those unwanted spaces. So we're going to
  41460. 25:32:20say select this column the first name
  41461. 25:32:24from our table bronze customer
  41462. 25:32:27information. So let's go and query it.
  41463. 25:32:29Now by just looking to the data it's
  41464. 25:32:31going to be really hard to find those
  41465. 25:32:33unwanted spaces especially if they are
  41466. 25:32:35at the end of the word. But there is a
  41467. 25:32:37very easy way in order to detect those
  41468. 25:32:39issues. So what we're going to do we're
  41469. 25:32:41going to do a filter. So now we're going
  41470. 25:32:42to say the first name is not equal to
  41471. 25:32:46the first name after trimming the
  41472. 25:32:48values. So if you use the function trim,
  41473. 25:32:50what it going to do? It's going to go
  41474. 25:32:51and remove all the leading and trailing
  41475. 25:32:54spaces. So the first name. So if this
  41476. 25:32:57value is not equal to the first name
  41477. 25:33:00after trimming it, then we have an
  41478. 25:33:02issue. So it is very simple. Let's go
  41479. 25:33:04and execute it. So now in the result, we
  41480. 25:33:06will get a list of all first names where
  41481. 25:33:08we have spaces either at the start or at
  41482. 25:33:11the end. So again the expectation here
  41483. 25:33:15is no results. And the same thing we can
  41484. 25:33:18go and check something else like for
  41485. 25:33:19example the last name. So let's go and
  41486. 25:33:22do that over here and here. Let's go and
  41487. 25:33:25execute it. We see in the results we
  41488. 25:33:27have as well 17 customers where they
  41489. 25:33:30have like space in their last name which
  41490. 25:33:32is not really good. And we can go and
  41491. 25:33:34keep checking all the string values that
  41492. 25:33:37we have inside the table. So for example
  41493. 25:33:38the gender. So let's go and check
  41494. 25:33:41that and execute. Now as you can see we
  41495. 25:33:44don't have any results. That means the
  41496. 25:33:46quality of the gender is better and we
  41497. 25:33:48don't have any unwanted spaces. So now
  41498. 25:33:51we have to go and write transformation
  41499. 25:33:53in order to clean up those two columns.
  41500. 25:33:55Now what I'm going to do, I'm just going
  41501. 25:33:56to go and list all the columns in the
  41502. 25:33:58query instead of the star. All right. So
  41503. 25:34:01now I have a list of all the columns
  41504. 25:34:02that I need. And now what we have to do
  41505. 25:34:04is to go to those two columns and start
  41506. 25:34:06removing the unwanted spaces. So we will
  41507. 25:34:09just use the trim. It's very
  41508. 25:34:11simple. And give it a name, of course,
  41509. 25:34:14the same name. And we will trim as well
  41510. 25:34:17the last name. So let's go and query
  41511. 25:34:19this. And with that we have cleaned up
  41512. 25:34:21those two columns from any unwanted
  41513. 25:34:23spaces. Okay. So now moving on we have
  41514. 25:34:25those two informations. We have the
  41515. 25:34:27maritalial status and as well the
  41516. 25:34:29gender. If you check the values inside
  41517. 25:34:31those two columns as you can see we have
  41518. 25:34:33here low cardality. So we have limited
  41519. 25:34:35numbers of possible values that is used
  41520. 25:34:37inside those two columns. So what we
  41521. 25:34:40usually do is to go and check the data
  41522. 25:34:42consistency inside those two columns. So
  41523. 25:34:45it's very simple what we're going to do.
  41524. 25:34:47We're going to do the following. We're
  41525. 25:34:48going to say
  41526. 25:34:50distinct and we're going to check the
  41527. 25:34:52values. Let's go and do that. And now as
  41528. 25:34:54you can see we have only three possible
  41529. 25:34:56values either null, f or m which is
  41530. 25:34:59okay. We can stay like this of course.
  41531. 25:35:01But we can make a rule in our project
  41532. 25:35:03where we can say we will not be working
  41533. 25:35:05with data abbreviations. We will go and
  41534. 25:35:07use only friendly full names. So instead
  41535. 25:35:10of having an F, we're going to have like
  41536. 25:35:12a full word female. And instead of m
  41537. 25:35:15we're going to have like male and we
  41538. 25:35:16make it as a rule for the whole project.
  41539. 25:35:18So each time we find the gender
  41540. 25:35:20informations we try to give the full
  41541. 25:35:22name of it. So let's go and map those
  41542. 25:35:24two values to a friendly one. So we're
  41543. 25:35:26going to go to the gender over here and
  41544. 25:35:28say case when and we're going to say the
  41545. 25:35:31gender is equal to f then make it a
  41546. 25:35:36female. And when it
  41547. 25:35:39is equal to
  41548. 25:35:41m then map it to male. And now we have
  41549. 25:35:46to make decision about the nulls. As you
  41550. 25:35:48can see over here we have nulls. So do
  41551. 25:35:50we want to leave it as a null or we want
  41552. 25:35:52to use always the value unknown. So with
  41553. 25:35:55that we are replacing the missing values
  41554. 25:35:58with a standard default value or you can
  41555. 25:36:00leave it as null. But let's say in our
  41556. 25:36:02project that we are replacing all the
  41557. 25:36:04missing value with a default value. So
  41558. 25:36:06let's go and do that. We're going to say
  41559. 25:36:09else I'm going to go with the NA not
  41560. 25:36:12available or you can go with the unknown
  41561. 25:36:14of course. So that's for the gender
  41562. 25:36:16information like this. And we can go and
  41563. 25:36:19remove the old one. And now there is one
  41564. 25:36:21thing that I usually do in this case
  41565. 25:36:22where sometimes what happens currently
  41566. 25:36:24we are getting the capital F and the
  41567. 25:36:26capital M but maybe in the time
  41568. 25:36:28something change and you will get like
  41569. 25:36:30lower M and lower F. So just to make
  41570. 25:36:32sure in those cases we still are able to
  41571. 25:36:34map those values to the correct value.
  41572. 25:36:37What we're going to do we're going to
  41573. 25:36:38just use the function upper just to make
  41574. 25:36:41sure that if you get any lowerase values
  41575. 25:36:44we are able to catch it. So the same
  41576. 25:36:47thing over here as well. And now one
  41577. 25:36:49more thing that you can add as well. Of
  41578. 25:36:51course, if you are not trusting the data
  41579. 25:36:53because we saw some unwanted spaces in
  41580. 25:36:55the first name and the last name, you
  41581. 25:36:57might not trust that in the future. You
  41582. 25:36:58will get here as well unwanted spaces.
  41583. 25:37:01You can go and make sure to trim
  41584. 25:37:04everything just to make sure that you
  41585. 25:37:07are catching all those cases. So that's
  41586. 25:37:10it for now. Let's go and execute. Now,
  41587. 25:37:12as you can see, we don't have an M and
  41588. 25:37:14an F. We have a full word, male and
  41589. 25:37:17female. And if we don't have a value, we
  41590. 25:37:19don't have a null, we are getting here
  41591. 25:37:21not available. Now we can go and do the
  41592. 25:37:23same stuff for the maritial status. You
  41593. 25:37:25can see as well we have only three
  41594. 25:37:27possibilities. The s null and an M. We
  41595. 25:37:30can go and do the same stuff. So I will
  41596. 25:37:32just go and copy everything from here.
  41597. 25:37:34And I will go and use the marital status
  41598. 25:37:37and just remove this one from here. And
  41599. 25:37:39now what are the possible values? We
  41600. 25:37:41have the S. So it's going to be single.
  41601. 25:37:44We have an M for married. And we have as
  41602. 25:37:47well a null and with that we are getting
  41603. 25:37:50the not available. So with that we are
  41604. 25:37:52making as well data standardizations for
  41605. 25:37:54this column. So let's go and execute it.
  41606. 25:37:57Now as you can see we don't have those
  41607. 25:37:59short values. We have a full friendly
  41608. 25:38:01value for the status and as well for the
  41609. 25:38:04gender. And at the same time we are
  41610. 25:38:06handling the nulls inside those two
  41611. 25:38:08columns. So with that we are done with
  41612. 25:38:10those two columns. And now we can go to
  41613. 25:38:11the last one that create date. For this
  41614. 25:38:13type of informations, we make sure that
  41615. 25:38:15this column is a real date and not as a
  41616. 25:38:18string or varchar. And as we defined it
  41617. 25:38:20in the data type, it is a date which is
  41618. 25:38:22completely correct. So nothing to do
  41619. 25:38:25with this column. And now the next step
  41620. 25:38:26is that we're going to go and write the
  41621. 25:38:28insert statement. So how we going to do
  41622. 25:38:30it? We're going to go to the start over
  41623. 25:38:31here and say insert into
  41624. 25:38:36silverm customer info. Now we have to go
  41625. 25:38:38and specify all the columns that should
  41626. 25:38:41be inserted. So we're going to go and
  41627. 25:38:43type it. So something like this. And
  41628. 25:38:45then we have the query over here. Let's
  41629. 25:38:47go and execute it. So let's do that. So
  41630. 25:38:50with that we have inserted clean data
  41631. 25:38:52inside the silver table. So now what
  41632. 25:38:54we're going to do we're going to go and
  41633. 25:38:55take all the queries that we have used
  41634. 25:38:58in order to check the quality of the
  41635. 25:38:59bronze and let's go and take it to
  41636. 25:39:01another query and instead of having
  41637. 25:39:03bronze we're going to say silver. So
  41638. 25:39:05this is about the primary key. Let's go
  41639. 25:39:08and execute it. Perfect. We don't have
  41640. 25:39:10any results. So we don't have any
  41641. 25:39:12duplicates. The same thing for the next
  41642. 25:39:14one. So the silver and it was for the
  41643. 25:39:18first name. So let's go and check the
  41644. 25:39:21first name and run it. As you can see
  41645. 25:39:23there is no results. It is perfect. We
  41646. 25:39:25don't have any issues. You can of course
  41647. 25:39:27go and check the last
  41648. 25:39:30name and run it again. We don't have any
  41649. 25:39:33results over here. And now we can go and
  41650. 25:39:35check those low cardality columns like
  41651. 25:39:38for
  41652. 25:39:39example the gender. Let's go and execute
  41653. 25:39:42it. So as you can see we have the not
  41654. 25:39:43available or the unknown male and
  41655. 25:39:46female. So perfect and you can go and
  41656. 25:39:48have a final look to the table to the
  41657. 25:39:50silver customer info. Let's go and check
  41658. 25:39:53that. So now we can have a look to all
  41659. 25:39:54those columns. As you can see everything
  41660. 25:39:56looks perfect and you can see it is
  41661. 25:39:58working this metadata information that
  41662. 25:40:00we have added to the table definition.
  41663. 25:40:03Now it says when we have inserted all
  41664. 25:40:05those records to the table which is
  41665. 25:40:08really amazing information to have a
  41666. 25:40:09track and audit. Okay. So now by looking
  41667. 25:40:11to this script we have done different
  41668. 25:40:13types of data transformations. The first
  41669. 25:40:15one is with the first name and the last
  41670. 25:40:17name. Here we have done trimming
  41671. 25:40:19removing unwanted spaces. This is one of
  41672. 25:40:22the types of data cleansing. So we
  41673. 25:40:24remove unnecessary spaces or unwanted
  41674. 25:40:26characters to ensure data consistency.
  41675. 25:40:29Now moving on to the next
  41676. 25:40:30transformation. we have this case when
  41677. 25:40:32so what we have done here is data
  41678. 25:40:34normalization or we call it sometimes
  41679. 25:40:37data standardization so this
  41680. 25:40:38transformation is type of data cleansing
  41681. 25:40:41where we're going to map coded values to
  41682. 25:40:43meaningful user friendly description and
  41683. 25:40:46we have done the same transformation as
  41684. 25:40:48well to the gender another type of
  41685. 25:40:50transformation that we have done as well
  41686. 25:40:52in the same case when is that we have
  41687. 25:40:54handled the missing values so instead of
  41688. 25:40:57nulls we going to have not available so
  41689. 25:40:59handling missing data is as type of data
  41690. 25:41:02cleansing where we are filling the
  41691. 25:41:03blanks by adding for example a default
  41692. 25:41:06value. So instead of having an empty
  41693. 25:41:08string or a null we're going to have a
  41694. 25:41:10default value like the not available or
  41695. 25:41:12unknown. Another type of data and
  41696. 25:41:13transformations that we have done in
  41697. 25:41:15this script is we have removed the
  41698. 25:41:17duplicates. So removing duplicates is as
  41699. 25:41:19well type of data cleansing where we
  41700. 25:41:21ensure only one record for each primary
  41701. 25:41:24key by identifying and retaining only
  41702. 25:41:27the most relevant row to ensure there is
  41703. 25:41:30no duplicates inside our data and as we
  41704. 25:41:32are removing the duplicates of course we
  41705. 25:41:34are doing data filtering. So those are
  41706. 25:41:36the different types of data
  41707. 25:41:38transformations that we have done in
  41708. 25:41:40this script.
  41709. 25:41:44All right, moving on to the second table
  41710. 25:41:46in the bronze layer from the CRM. We
  41711. 25:41:48have the product info. And of course, as
  41712. 25:41:50usual, before we start writing any
  41713. 25:41:52transformations, we have to search for
  41714. 25:41:54data quality issues. And we start with
  41715. 25:41:56the first one, we have to check the
  41716. 25:41:57primary key. So we have to check whether
  41717. 25:41:59we have duplicates or nulls inside this
  41718. 25:42:01key. So what we have to do, we have to
  41719. 25:42:03group up the data by the primary key or
  41720. 25:42:05check whether we have nulls. So let's go
  41721. 25:42:07and execute it. So as you can see,
  41722. 25:42:09everything is safe. We don't have
  41723. 25:42:10duplicates or nulls in the primary key.
  41724. 25:42:12Now moving on to the next one, we have
  41725. 25:42:14the product key. Here we have in this
  41726. 25:42:16column a lot of informations. So now
  41727. 25:42:18what we have to do is to go and split
  41728. 25:42:20this string into two informations. So we
  41729. 25:42:22are deriving new two columns. So now
  41730. 25:42:24let's start with the first one is the
  41731. 25:42:26category ID. The first five characters
  41732. 25:42:29they are actually the category ID and we
  41733. 25:42:31can go and use the substring function in
  41734. 25:42:33order to extract part of a string. It
  41735. 25:42:36needs three arguments. The first one
  41736. 25:42:38going to be the column that we want to
  41737. 25:42:40extract from. And then we have to define
  41738. 25:42:43the position where to extract. And since
  41739. 25:42:45the first part is on the left side, we
  41740. 25:42:47going to start from the first position.
  41741. 25:42:49And then we have to specify the length.
  41742. 25:42:51So how many characters we want to
  41743. 25:42:52extract, we need five characters. So 1 2
  41744. 25:42:553 4 5. So that's it for the category ID.
  41745. 25:42:59Category ID. Let's go and execute it.
  41746. 25:43:02Now, as you can see, we have a new
  41747. 25:43:03column called the category ID. and it
  41748. 25:43:05contains the first part of the string
  41749. 25:43:07and in our database from the other
  41750. 25:43:09source system we have as well the
  41751. 25:43:11category ID. Now we can go and double
  41752. 25:43:13check just in order to make sure that we
  41753. 25:43:16can join data together. So we're going
  41754. 25:43:17to go and check the ID from the bronze
  41755. 25:43:20table ERP and this canopy from the
  41756. 25:43:24category. So in this table we have the
  41757. 25:43:26category ids and you can see over here
  41758. 25:43:29those are the ids of the category and in
  41759. 25:43:31the code layer we have to go and join
  41760. 25:43:33those two tables. But here we still have
  41761. 25:43:35an issue. We have here an underscore
  41762. 25:43:38between the category and the
  41763. 25:43:39subcategory. But in our table we have
  41764. 25:43:42actually a minus. So we have to replace
  41765. 25:43:45that with an underscore in order to have
  41766. 25:43:47matching informations between those two
  41767. 25:43:49tables. Otherwise we will not be able to
  41768. 25:43:50join the tables. So we're going to use
  41769. 25:43:52the function
  41770. 25:43:53replace. And what we are replacing? We
  41771. 25:43:56are replacing the minus with an
  41772. 25:43:59underscore something like this. And if
  41773. 25:44:01you go now and execute it, we will get
  41774. 25:44:04an underscore exactly like the other
  41775. 25:44:06table. And of course we can go and check
  41776. 25:44:08whether everything is matching by having
  41777. 25:44:10very simple query where we say this new
  41778. 25:44:13information not in. And then we have
  41779. 25:44:17this nice subquery. So we are trying to
  41780. 25:44:19find any category ID that is not
  41781. 25:44:22available in the second table. So let's
  41782. 25:44:24go and execute it. Now as you can see we
  41783. 25:44:26have only one category that is not
  41784. 25:44:28matching. We are not finding it in this
  41785. 25:44:30table which is maybe correct. So if you
  41786. 25:44:32go over here you will not find this
  41787. 25:44:35category. I just make it a little bit
  41788. 25:44:36bigger. So we are not finding this one
  41789. 25:44:38category from this table which is fine.
  41790. 25:44:41So our check is okay. Okay. So that we
  41791. 25:44:43have the first part. Now we have to go
  41792. 25:44:45and extract the second part and we're
  41793. 25:44:47going to do the same thing. So we're
  41794. 25:44:48going to use the substring and the three
  41795. 25:44:50argument the product key but this time
  41796. 25:44:53we will not start cutting from the first
  41797. 25:44:54position we have to be in the middle. So
  41798. 25:44:561 2 3 4 5 6 7. So we start from the
  41799. 25:45:01position number seven. And now we have
  41800. 25:45:03to define the length how many characters
  41801. 25:45:06to be extracted. But if you look over
  41802. 25:45:07here you can see that we have different
  41803. 25:45:10length of the product keys. It is not
  41804. 25:45:12fixed like the category ID. So we cannot
  41805. 25:45:15go and here specify number. We have to
  41806. 25:45:17make something dynamic and there is
  41807. 25:45:18trick in order to do that. We're going
  41808. 25:45:20to go and use the length of the whole
  41809. 25:45:22column. With that we make sure that we
  41810. 25:45:24are always getting enough characters to
  41811. 25:45:26be extracted and we will not be losing
  41812. 25:45:28any informations. So we will make it
  41813. 25:45:31dynamic like this. We will not have it
  41814. 25:45:33as a fixed length and with that we have
  41815. 25:45:35the product key. So let's go and execute
  41816. 25:45:38it. As you can see we are now extracting
  41817. 25:45:41the second part from this string. Now
  41818. 25:45:44why we need the product key? We need it
  41819. 25:45:46in order to join it with another table
  41820. 25:45:48called sales details. So let's go and
  41821. 25:45:51check the sales details. So let me just
  41822. 25:45:54check the column name. It is SLS product
  41823. 25:45:57key. So from bronze
  41824. 25:46:01CRM sales. Let's go and check the data
  41825. 25:46:04over here. And it looks wonderful. So
  41826. 25:46:08actually we can go and join those
  41827. 25:46:09informations together. But of course
  41828. 25:46:11we're going to go and check that. So
  41829. 25:46:12we're going to say where and we're going
  41830. 25:46:14to take our new column and we're going
  41831. 25:46:15to say not in the sub query just to make
  41832. 25:46:19sure that we are not missing anything.
  41833. 25:46:21So let's go and execute. So it looks
  41834. 25:46:23like we have a lot of products that
  41835. 25:46:26don't have any orders. Well, I don't
  41836. 25:46:28have a nice feelings about it. Let's go
  41837. 25:46:30and try something like this one here.
  41838. 25:46:33And we say where sld key like this value
  41839. 25:46:39over here. So I'll just cut the last
  41840. 25:46:42three just to search inside this table.
  41841. 25:46:44So we really don't have such a keys. Let
  41842. 25:46:47me just cut the second one. So let's go
  41843. 25:46:50and search for it. We don't have it as
  41844. 25:46:52well. So anything that starts with the F
  41845. 25:46:55key, we don't have any order with the
  41846. 25:46:57product where it starts with the F key.
  41847. 25:46:59So let's go and remove it. But still we
  41848. 25:47:02are able to join the tables, right? So
  41849. 25:47:04if I go and say in instead of not in. So
  41850. 25:47:07with that you are able to match all
  41851. 25:47:09those products. So that means everything
  41852. 25:47:11is fine. Actually it's just products
  41853. 25:47:14that don't have any orders. So with that
  41854. 25:47:16I'm happy with this transformation. Now
  41855. 25:47:19moving on to the next one. We have here
  41856. 25:47:21the name of the product. We can go and
  41857. 25:47:23check whether there is unwanted spaces.
  41858. 25:47:26So let's go to our quality checks. Make
  41859. 25:47:28sure to use the same table and we're
  41860. 25:47:31going to use the product name and check
  41861. 25:47:33whether we find any unmatching after
  41862. 25:47:36trimming. So let's go and do it. Well,
  41863. 25:47:38it looks really fine. So we don't have
  41864. 25:47:40to trim anything. This column is safe.
  41865. 25:47:42Now moving on to the next one. We have
  41866. 25:47:44the costs. So here we have numbers and
  41867. 25:47:47we have to check the quality of the
  41868. 25:47:48numbers. So what we can do? We can check
  41869. 25:47:50whether we have nulls or negative
  41870. 25:47:52numbers. So negative costs or negative
  41871. 25:47:55prices which is not realistic depend on
  41872. 25:47:58the business of course. So let's say in
  41873. 25:47:59our business we don't have any negative
  41874. 25:48:02costs. So it's going to be like this.
  41875. 25:48:04Let's go and check whether it's
  41876. 25:48:06something less than zero or whether we
  41877. 25:48:09have costs that is null. So let's go and
  41878. 25:48:14check those informations. Well, as you
  41879. 25:48:15can see, we don't have any negative
  41880. 25:48:17values, but we have nulls. So we can go
  41881. 25:48:19and handle that by replacing the null
  41882. 25:48:21with a zero. Of course, if the business
  41883. 25:48:24allow that. So in SQL server, in order
  41884. 25:48:26to replace the null with a zero, we have
  41885. 25:48:28a very nice function called is null. So
  41886. 25:48:32we are saying if it is null then replace
  41887. 25:48:35this value with a zero. It is very
  41888. 25:48:37simple like this and we give it a name
  41889. 25:48:40of course. So let's go and execute it.
  41890. 25:48:42And as you can see we don't have any
  41891. 25:48:44more nulls. We have zero which is better
  41892. 25:48:46for the calculations if you are later
  41893. 25:48:48doing any aggregate functions like the
  41894. 25:48:50average. Now moving on to the next one
  41895. 25:48:52we have the product line. This is again
  41896. 25:48:55abbreviation of something and the
  41897. 25:48:57cardinality is low. So let's go and
  41898. 25:48:58check all possible values inside this
  41899. 25:49:01column. So we're just going to use the
  41900. 25:49:03distinct going to be BRD line. So let's
  41901. 25:49:06go and execute it. And as you can see
  41902. 25:49:08the possible values are null M R ST. And
  41903. 25:49:11again those are abbreviations but in our
  41904. 25:49:13data warehouse we have decided to give
  41905. 25:49:16full nice names. So we have to go and
  41906. 25:49:18replace those codes those abbreviations
  41907. 25:49:21with a friendly value. And of course in
  41908. 25:49:23order to get those informations I
  41909. 25:49:24usually go and ask the expert from the
  41910. 25:49:27source system or an expert from the
  41911. 25:49:29process. So let's start building our
  41912. 25:49:31case win. And then let's use the upper
  41913. 25:49:34and as well the trim just to make sure
  41914. 25:49:36that we are having all the cases. So the
  41915. 25:49:39BRD
  41916. 25:49:40line is equal to so let's start with the
  41917. 25:49:44first value the M. Then we will get the
  41918. 25:49:48friendly value it's going to be
  41919. 25:49:50mountain. then to the next one. So I
  41920. 25:49:52will just copy and paste here. If it is
  41921. 25:49:55an R then it is road and another one for
  41922. 25:50:00let me check what do we have here? We
  41923. 25:50:03have M R and then S. The S stands for
  41924. 25:50:06other sales and we have the T. So let's
  41925. 25:50:10go and get the T. So the T stands for
  41926. 25:50:14touring. We have at the end an else for
  41927. 25:50:17unknown not available. So we don't need
  41928. 25:50:20any nulls. So that's it. And we're going
  41929. 25:50:22to name it as before. So product line.
  41930. 25:50:24So let's remove the old one. And let's
  41931. 25:50:27execute it. And as you can see, we don't
  41932. 25:50:30have here anymore those shortcuts and
  41933. 25:50:32the abbreviations. We have now full
  41934. 25:50:34friendly value. But I will go and have
  41935. 25:50:37here like capital O. It looks nicer. So
  41936. 25:50:40that we have nice friendly value. Now by
  41937. 25:50:42looking to this case when as you can see
  41938. 25:50:43it is always like we are mapping one
  41939. 25:50:45value to another value and we are
  41940. 25:50:47repeating all time upper time upper time
  41941. 25:50:50and so on. We have here a quick form in
  41942. 25:50:52the case when if it is just a simple
  41943. 25:50:54mapping. So the syntax is very simple we
  41944. 25:50:57say case and then we have the column. So
  41945. 25:51:00we are evaluating this value over here
  41946. 25:51:02and then we just say when without the
  41947. 25:51:05equal so if it is an M then make it
  41948. 25:51:08mountain. the same thing for the next
  41949. 25:51:10one and so so with that we have the
  41950. 25:51:13functions only once and we don't have to
  41951. 25:51:15go and keep repeating the same function
  41952. 25:51:16over and over and this one only if you
  41953. 25:51:18are mapping values but if you have
  41954. 25:51:20complex conditions you cannot do it like
  41955. 25:51:22this but for now I'm going to stay with
  41956. 25:51:24the quick form of the case when it looks
  41957. 25:51:26nicer and shorter so let's go and
  41958. 25:51:28execute it we will get the same results
  41959. 25:51:30okay so now back to our table let's go
  41960. 25:51:31to the last two columns we have the
  41961. 25:51:33start and end date so it's like defining
  41962. 25:51:36an interval we have start and end so
  41963. 25:51:38Let's go and check the quality of the
  41964. 25:51:39start and end dates. We're going to go
  41965. 25:51:41and say select star from our bronze
  41966. 25:51:45table. And now we're going to go and
  41967. 25:51:47search it like this. We are searching
  41968. 25:51:48for the end date that is smaller than
  41969. 25:51:52the start. So we are key to start dates.
  41970. 25:51:56So let's go and query this. So you can
  41971. 25:51:58see the start is always like after the
  41972. 25:52:01end which makes no sense at all. So we
  41973. 25:52:03have here data issue with those two
  41974. 25:52:05dates. So now for this kind of data
  41975. 25:52:07transformations what I usually do is I
  41976. 25:52:09go and grab few examples and put it in
  41977. 25:52:11Excel and try to think about how I'm
  41978. 25:52:13going to go and fix it. So here I took
  41979. 25:52:15like two products this one and this one
  41980. 25:52:17over here. And for that we have like
  41981. 25:52:18three rows for each one of them. And we
  41982. 25:52:20have this situation over here. So the
  41983. 25:52:22question now how we going to go and fix
  41984. 25:52:24it? I will go and make like a copy of
  41985. 25:52:26one solution where we're going to say
  41986. 25:52:28it's very simple. Let's go and switch
  41987. 25:52:29the start date with the end date. So if
  41988. 25:52:32I go and grab the end date and put it at
  41989. 25:52:35the start, things going to look way
  41990. 25:52:37nicer, right? So we have the start is
  41991. 25:52:39always younger than the end. But my
  41992. 25:52:41friends, the data now makes no sense
  41993. 25:52:43because we say it start from 2007 and
  41994. 25:52:46ends by 2011 the price was 12. But
  41995. 25:52:50between 2008 and 2012, we have 14. which
  41996. 25:52:54is not really good because if you take
  41997. 25:52:55for example the year 2010 for 2010 it
  41998. 25:52:59was 12 and at the same time 14. So it is
  41999. 25:53:02really bad to have an overlapping
  42000. 25:53:04between those two dates. It should start
  42001. 25:53:06from 2007 and end with 11 and then start
  42002. 25:53:09Feb from 12 and end with something else.
  42003. 25:53:12There should be no overlapping between
  42004. 25:53:14years. So it's not enough to say the
  42005. 25:53:17start should be always smaller than the
  42006. 25:53:19ends but as well the end of the first
  42007. 25:53:22history should be younger than the start
  42008. 25:53:25of the next records. This is as well a
  42009. 25:53:27rule in order to have no overlapping.
  42010. 25:53:30This one has no start but has already an
  42011. 25:53:32end which is not really okay because we
  42012. 25:53:35have always to have a start. Each new
  42013. 25:53:37record in historiizations has to has a
  42014. 25:53:40start. So for this record over here this
  42015. 25:53:42is as well wrong. And of course it is
  42016. 25:53:44okay to have the start without an end.
  42017. 25:53:47So in this scenario it's fine because
  42018. 25:53:49this indicate this is the current
  42019. 25:53:52informations about the costs. So again
  42020. 25:53:54this solution is not working at all. So
  42021. 25:53:56now for the solution two what we can say
  42022. 25:53:58let's go and ignore completely the end
  42023. 25:54:01date and we take only the start date. So
  42024. 25:54:03let's go and paste it over here. But now
  42025. 25:54:05we go and rebuild the end date
  42026. 25:54:07completely from the start date following
  42027. 25:54:09the rules that we have defined. So the
  42028. 25:54:11rule says the end of date of the current
  42029. 25:54:14records comes from the start date from
  42030. 25:54:17the next records. So here this end date
  42031. 25:54:20comes from this value over here from the
  42032. 25:54:22next record. So that means we take the
  42033. 25:54:24next start date and put it at the end
  42034. 25:54:27date for the previous records. So with
  42035. 25:54:29that as you can see it is working the
  42036. 25:54:30end date is higher than the start date.
  42037. 25:54:34And as well we are making sure this date
  42038. 25:54:36is not overlapping with the next record.
  42039. 25:54:38But as well in order to make it way
  42040. 25:54:40nicer we can subtract it with one. So we
  42041. 25:54:43can take the previous day like this. So
  42042. 25:54:45with that we are making sure the end
  42043. 25:54:47date is smaller than the next start. And
  42044. 25:54:50now for the next record this one over
  42045. 25:54:53here the end date going to come from the
  42046. 25:54:55next start date. So we will take this
  42047. 25:54:57one for here and put it as an end date
  42048. 25:54:59and subtract it with one. So we will get
  42049. 25:55:02the previous day. So now if you compare
  42050. 25:55:04those two you can see it's still higher
  42051. 25:55:07than the start. And if you compare it
  42052. 25:55:08with the next record this one over here
  42053. 25:55:11it is still smaller than the next one.
  42054. 25:55:13So there is no overlapping. And now for
  42055. 25:55:15the last record since we don't have here
  42056. 25:55:17any informations it will be a null which
  42057. 25:55:20is totally fine. So as you can see I'm
  42058. 25:55:22really happy with this scenario over
  42059. 25:55:24here. Of course you can go and validate
  42060. 25:55:25this with an expert from the source
  42061. 25:55:27system. But let's say I have done that
  42062. 25:55:29and they approved it and now I can go
  42063. 25:55:30and clean up the data using this new
  42064. 25:55:33logic. So this is how I usually
  42065. 25:55:34brainstorm about fixing an issues. If I
  42066. 25:55:37have like a complex stuff, I go and use
  42067. 25:55:39Excel and then discuss it with the
  42068. 25:55:40expert using this example. It's way
  42069. 25:55:42better than showing a database queries
  42070. 25:55:45and so on. It just makes things easier
  42071. 25:55:47to explain and as well to discuss. So
  42072. 25:55:49now how I usually do it, I usually go
  42073. 25:55:51and make a focus on only the columns
  42074. 25:55:53that I need and take only one two
  42075. 25:55:55scenarios while I'm building the logic
  42076. 25:55:57and once everything is ready I go and
  42077. 25:55:59integrate it in the query. So now I'm
  42078. 25:56:01focusing only on these columns and only
  42079. 25:56:03for these products. So now let's go and
  42080. 25:56:06build our logic. Now in SQL if you are
  42081. 25:56:08at specific record and you want to
  42082. 25:56:10access another information from another
  42083. 25:56:12records and for that we have two amazing
  42084. 25:56:14window functions. We have the lead and
  42085. 25:56:17log. In this scenario, we want to access
  42086. 25:56:19the next records. That's why we have to
  42087. 25:56:21go with the function leads. So, let's go
  42088. 25:56:23and build it lead. And then what do we
  42089. 25:56:25need? We need the lead of the
  42090. 25:56:27start date. So, we want the start date
  42091. 25:56:30of the next record. And then we say over
  42092. 25:56:33and we have to partition the data. So,
  42093. 25:56:36the window going to be focusing on only
  42094. 25:56:38one product which is the product key and
  42095. 25:56:41not the product ID. So, we are dividing
  42096. 25:56:43the data by product key. And of course,
  42097. 25:56:45we have to go and sort the data. So
  42098. 25:56:47order by and we are sorting the data by
  42099. 25:56:49the start
  42100. 25:56:50date and ascending. So from the lowest
  42101. 25:56:53to the highest and let's go and give it
  42102. 25:56:55another name. So as let's say test for
  42103. 25:56:58example just to test the data. So let's
  42104. 25:57:01go and execute. And I think I missed
  42105. 25:57:03something here. It is partition by. So
  42106. 25:57:05let's go and execute again. And now
  42107. 25:57:07let's go and check the results for the
  42108. 25:57:09first partition over here. So the start
  42109. 25:57:10is 2011 and the end is 2012. And this
  42110. 25:57:14information came from the next record.
  42111. 25:57:17So this data is moved to the previous
  42112. 25:57:19record over here. And the same thing for
  42113. 25:57:21this record. So the end date comes from
  42114. 25:57:24the next record. So our logic is
  42115. 25:57:26working. And the last record over here
  42116. 25:57:28is null because we are at the end of the
  42117. 25:57:30window and there is no next data. That's
  42118. 25:57:32why we will get null and this is perfect
  42119. 25:57:34of course. So it looks really awesome.
  42120. 25:57:36But what is missing is we have to go and
  42121. 25:57:39get the previous day. And we can do that
  42122. 25:57:41very simply using minus one. we are just
  42123. 25:57:43subtracting one day. So we have no
  42124. 25:57:45overlapping between those two dates and
  42125. 25:57:47the same thing for those two dates. So
  42126. 25:57:49as you can see we have just built a
  42127. 25:57:51perfect end date which is way better
  42128. 25:57:53than the original data that we got from
  42129. 25:57:55the source system. Now let's take this
  42130. 25:57:57one over here and put it inside our
  42131. 25:57:59query. So we don't need the end date, we
  42132. 25:58:02need our new end date. Let's just remove
  42133. 25:58:05that test and execute. Now it looks
  42134. 25:58:08perfect. All right. Now we are not done
  42135. 25:58:10yet with those two dates. Actually we
  42136. 25:58:12are saying all time dates because we
  42137. 25:58:14don't have here any informations about
  42138. 25:58:16the time always zero. So it makes no
  42139. 25:58:18sense to have these informations inside
  42140. 25:58:21our data. So what we can do we can do a
  42141. 25:58:23very simple cast and we make this column
  42142. 25:58:26as a date instead of date time. So this
  42143. 25:58:29is for the first one and as well for the
  42144. 25:58:31next one as date. So let's try that out.
  42145. 25:58:34And as you can see it is nicer. We don't
  42146. 25:58:36have the time informations. Of course,
  42147. 25:58:38we can tell the source systems about all
  42148. 25:58:40those issues. But since they don't
  42149. 25:58:42provide a time, it makes no sense to
  42150. 25:58:44have date and time. Okay, so it was a
  42151. 25:58:46long run, but we have now a cleaned
  42152. 25:58:49product informations. And this is way
  42153. 25:58:51nicer than the original product
  42154. 25:58:53information that we got from the source
  42155. 25:58:54CRM. So if you grab the DDL of the
  42156. 25:58:56server table, you can see that we don't
  42157. 25:58:58have a category ID. So we have product
  42158. 25:59:00ID and product key. And as well those
  42159. 25:59:03two columns, we just changed the data
  42160. 25:59:04type. So it's date time here but we have
  42161. 25:59:06changed that to a date. So that means we
  42162. 25:59:09have to go and do few modifications to
  42163. 25:59:11the DDL. So what we're going to do we're
  42164. 25:59:12going to go over here and say category
  42165. 25:59:14ID and I will be using the same data
  42166. 25:59:16type for the start and the end. This
  42167. 25:59:18time going to be date and not date and
  42168. 25:59:20time. So that's it for now. Let's go and
  42169. 25:59:22execute it in order to repair the DDL.
  42170. 25:59:25And this is what happen in the silver
  42171. 25:59:27layer. Sometimes we have to adjust the
  42172. 25:59:29metadata if the quality of the data
  42173. 25:59:31types and so on is not good or we are
  42174. 25:59:33building new derived informations in
  42175. 25:59:35order later to integrate the data. So it
  42176. 25:59:38will be like very close to the bronze
  42177. 25:59:40layer but with few modifications. So
  42178. 25:59:42make sure to update your DTL scripts.
  42179. 25:59:45And now the next step is that we're
  42180. 25:59:46going to go and insert the data into the
  42181. 25:59:48table. And now the next we're going to
  42182. 25:59:49go and insert the result of this query
  42183. 25:59:52that is cleaning up the bronze table
  42184. 25:59:54into the silver table. So as we done it
  42185. 25:59:57before insert into silver the product
  42186. 26:00:00info and then we have to go and list all
  42187. 26:00:02the columns. I've just prepared those
  42188. 26:00:04columns. So with that we can go and now
  42189. 26:00:07run our query in order to insert the
  42190. 26:00:09data. So now as you can see this did
  42191. 26:00:11insert the data and the very important
  42192. 26:00:13step is now to check the quality of the
  42193. 26:00:15silver table. So we go back to our data
  42194. 26:00:17quality checks and we go switch to the
  42195. 26:00:20silver. So let's check the primary key.
  42196. 26:00:22There is no issues and we can go and
  42197. 26:00:24check for example here the trims there
  42198. 26:00:27is as well no issue and now let's go and
  42199. 26:00:29check the costs it should not be
  42200. 26:00:31negative or null which is perfect let's
  42201. 26:00:34go and check the data standardizations
  42202. 26:00:36as you can see they are friendly and we
  42203. 26:00:38don't have any nulls and now very
  42204. 26:00:40interesting the order of the dates so
  42205. 26:00:43let's go and check that as you can see
  42206. 26:00:45we don't have any issues and finally
  42207. 26:00:47what I do I go and have a final look to
  42208. 26:00:50the silver table and As we can see
  42209. 26:00:53everything is inserted correctly in the
  42210. 26:00:55correct columns. So all those columns
  42211. 26:00:57comes from the source system and the
  42212. 26:00:59last one is automatically generated from
  42213. 26:01:01the DDL indicate when we loaded this
  42214. 26:01:04table. Now let's sit back and have a
  42215. 26:01:06look to our script. What are the
  42216. 26:01:07different types of data transformations
  42217. 26:01:09that we have done here is for example
  42218. 26:01:10over here the category ID and the
  42219. 26:01:12product key we have derived new columns.
  42220. 26:01:15So it is when we create a new column
  42221. 26:01:17based on calculations or transformations
  42222. 26:01:20of an existing one. So sometimes we need
  42223. 26:01:22columns only for analytics and we cannot
  42224. 26:01:25each time go to the source system and
  42225. 26:01:26ask them to create it. So instead of
  42226. 26:01:28that we derive our own columns that we
  42227. 26:01:31need for the analytics. Another
  42228. 26:01:33transformation we have is the is null
  42229. 26:01:35over here. So we are handling here
  42230. 26:01:37missing information. Instead of null
  42231. 26:01:39we're going to have a zero. And one more
  42232. 26:01:40transformation we have over here for the
  42233. 26:01:42product line. We have done here data
  42234. 26:01:45normalization. Instead of having a code
  42235. 26:01:47value we have a friendly value. And as
  42236. 26:01:49well we have handled the missing data.
  42237. 26:01:51For example, over here instead of having
  42238. 26:01:53a null, we're going to have not
  42239. 26:01:55available. All right, moving on to
  42240. 26:01:56another data transformation. We have
  42241. 26:01:58done data type casting. So we are
  42242. 26:02:00converting the data type from one to
  42243. 26:02:02another. And this considered as well to
  42244. 26:02:04be a data transformation. And now moving
  42245. 26:02:06on to the last one. We are doing as well
  42246. 26:02:08data type casting. But what's more
  42247. 26:02:10important, we are doing data enrichment.
  42248. 26:02:12This type of transformation, it's all
  42249. 26:02:14about adding a value to your data. So we
  42250. 26:02:17are adding new relevant data to our data
  42251. 26:02:20sets. So those are the different types
  42252. 26:02:21of data transformations that we have
  42253. 26:02:24done for this
  42254. 26:02:28table. Okay. So let's keep going. We
  42255. 26:02:30have the sales details and this is the
  42256. 26:02:32last table in the CRM. So what do we
  42257. 26:02:33have over here? We have the order number
  42258. 26:02:35and this is a string. Of course we can
  42259. 26:02:36go and check whether we have an issue
  42260. 26:02:38with the unwanted spaces. So we can
  42261. 26:02:40search whether we're going to find
  42262. 26:02:42something. So we can say trim and
  42263. 26:02:45something like this. and let's go and
  42264. 26:02:46execute it. So we can see that we don't
  42265. 26:02:48have any unwanted spaces. That means we
  42266. 26:02:50don't have to transform this column. So
  42267. 26:02:51we can leave it as it is. Now the next
  42268. 26:02:53two columns they are like keys and ids
  42269. 26:02:56in order to connect it with the other
  42270. 26:02:58tables. As we learned before we are
  42271. 26:02:59using the product key in order to
  42272. 26:03:02connect it with the product informations
  42273. 26:03:04and we are connecting the customer ID
  42274. 26:03:06with the customer ID from the customer
  42275. 26:03:07info. So that means we have to go and
  42276. 26:03:09check whether everything is working
  42277. 26:03:10perfectly. So we can go and check the
  42278. 26:03:12integrity of those columns where we say
  42279. 26:03:14the product key not in and then we make
  42280. 26:03:17a subquery and this time we can work
  42281. 26:03:19with the silver layer right so we can
  42282. 26:03:21say the product key from silver dot
  42283. 26:03:25product info so let's go and query this
  42284. 26:03:27and as you can see we are not getting
  42285. 26:03:28any issue that means all the product
  42286. 26:03:30keys from the sales details can be used
  42287. 26:03:33and connected with the product info the
  42288. 26:03:35same thing we can go and check the
  42289. 26:03:36integrity of the customer ID and we can
  42290. 26:03:39use not the product we and go to the
  42291. 26:03:41customer info and the name was CST ID.
  42292. 26:03:45So let's go and query that and the same
  42293. 26:03:47thing we don't have here any issues. So
  42294. 26:03:49that means we can go and connect the
  42295. 26:03:50sales with the customers using the
  42296. 26:03:52customer ID and we don't have to do any
  42297. 26:03:54transformations for it. So things looks
  42298. 26:03:56really nice for those three columns. Now
  42299. 26:03:58we come to the challenging one. We have
  42300. 26:04:00here the dates. Now those dates are not
  42301. 26:04:03actual dates. They are integer. So those
  42302. 26:04:05are numbers and we don't want to have it
  42303. 26:04:07like this. We would like to clean that
  42304. 26:04:09up. we have to change the data type from
  42305. 26:04:11integer to a dates. Now if you want to
  42306. 26:04:13convert an integer to a date, we have to
  42307. 26:04:15be careful with the values that we have
  42308. 26:04:17inside each of those columns. So now
  42309. 26:04:19let's check the quality for example of
  42310. 26:04:21the order dates. Let's say where order
  42311. 26:04:23dates is less than zero for example
  42312. 26:04:26something negative. Well, we don't have
  42313. 26:04:28any negative values which is good. Let's
  42314. 26:04:29go and check whether we have any zeros.
  42315. 26:04:32Well, this is bad. So we have here a lot
  42316. 26:04:34of zeros. Now what we can do? We can
  42317. 26:04:36replace those informations with a null.
  42318. 26:04:38We can use of course the null if
  42319. 26:04:40function like this. We can say null if
  42320. 26:04:42and if it is zero then make it null. So
  42321. 26:04:45let's execute it. And as you can see now
  42322. 26:04:47all those informations are null. Now
  42323. 26:04:49let's go and check again the data. So
  42324. 26:04:51now this integer has the year's
  42325. 26:04:53information at the start then the months
  42326. 26:04:55and then the day. So here we have to
  42327. 26:04:57have like 1 2 3 4 5. So the length of
  42328. 26:05:00each number should be h. And if the
  42329. 26:05:02length is less than eight or higher than
  42330. 26:05:04eight then we have an issue. Let's go
  42331. 26:05:06and check that. So we're going to say or
  42332. 26:05:09length sales order is not equal to h
  42333. 26:05:12that means less or higher. Let's go and
  42334. 26:05:14execute it. Now let's go and check the
  42335. 26:05:16results over here. And those two
  42336. 26:05:18informations they don't look like a
  42337. 26:05:20date. So we cannot go and make from
  42338. 26:05:22these informations a real date. They are
  42339. 26:05:24just bad data quality. And of course you
  42340. 26:05:26can go and check the boundaries of a
  42341. 26:05:28date. Like for example it should not be
  42342. 26:05:31higher than for example let's go and get
  42343. 26:05:33this value 2050 and then any for the
  42344. 26:05:36month and the date. So let's go and
  42345. 26:05:37execute it. And if we just remove those
  42346. 26:05:39informations just to make sure. So we
  42347. 26:05:41don't have any date that is outside of
  42348. 26:05:43the boundaries that you have in your
  42349. 26:05:45business. Or you go for example and say
  42350. 26:05:47the boundary should be not less than
  42351. 26:05:49depend when your business started. Maybe
  42352. 26:05:51something like this. We are getting of
  42353. 26:05:53course those values because they are
  42354. 26:05:55less than null. But if you have values
  42355. 26:05:57around this dates you will get it as
  42356. 26:05:59well in the query. So we can go and add
  42357. 26:06:01the rests. So all those checks like
  42358. 26:06:03validate the column that has a date
  42359. 26:06:05informations and it has the data type
  42360. 26:06:07integer. So again what are the issues
  42361. 26:06:09over here? We have zeros and sometimes
  42362. 26:06:11we have like strange numbers that cannot
  42363. 26:06:14be converted to a dates. So let's go and
  42364. 26:06:16fix that in our query. So we can say
  42365. 26:06:18case when the sales order the order
  42366. 26:06:21dates is equal to zero or of the order
  42367. 26:06:25date is not equal to 8 then null. Right?
  42368. 26:06:28We don't want to deal with those values.
  42369. 26:06:30they are just wrong and they they are
  42370. 26:06:31not real dates otherwise we say else
  42371. 26:06:34it's going to be the order date. Now
  42372. 26:06:36what we're going to do we're going to go
  42373. 26:06:37and convert this to a date. We don't
  42374. 26:06:39want this as an integer. So how we can
  42375. 26:06:41do that? We can go and cast it first to
  42376. 26:06:43a varchar because we cannot cast from
  42377. 26:06:46integer to date in SQL server. First you
  42378. 26:06:49have to convert it to a varchchar and
  42379. 26:06:51then from varchchar you go to a date.
  42380. 26:06:53Well this is how we do it in SQL server.
  42381. 26:06:55So we cast it first to a varchar and
  42382. 26:06:58then we cast it to a date like this.
  42383. 26:07:01That's it. So we have end and we are
  42384. 26:07:03using the same column
  42385. 26:07:05name. So this is how we transform an
  42386. 26:07:08integer to a date. So let's go and query
  42387. 26:07:11this. And as you can see the order date
  42388. 26:07:13now is a real date. It is not a number.
  42389. 26:07:16So we can go and get rid of the old
  42390. 26:07:18column. Now we have to go and do the
  42391. 26:07:19same stuff for the shipping dates. So,
  42392. 26:07:21we can go over here and replace
  42393. 26:07:24everything with the shipping date and
  42394. 26:07:26let's go and query. Well, as you can
  42395. 26:07:27see, the shipping date is perfect. We
  42396. 26:07:29don't have any issue with this column.
  42397. 26:07:31But still, I don't like that we found a
  42398. 26:07:32lot of issues with the order date. So,
  42399. 26:07:34what we're going to do just in case this
  42400. 26:07:36happens for the shipping date in the
  42401. 26:07:38future, I will go and apply the same
  42402. 26:07:39rules to the shipping dates. Oh, let's
  42403. 26:07:42take the shipping
  42404. 26:07:43date like this. And if you don't want to
  42405. 26:07:46apply it now, you have always to build
  42406. 26:07:48like quality checks that runs every day
  42407. 26:07:50in order to detect those issues. And
  42408. 26:07:53once you detect it, then you can go and
  42409. 26:07:55do the transformations. But for now, I'm
  42410. 26:07:56going to apply it right away. So that is
  42411. 26:07:58for the shipping date. Now we go to the
  42412. 26:08:00due date and we will do the same test.
  42413. 26:08:04Let's go and execute it. And as well, it
  42414. 26:08:06is perfect. So still, I'm going to apply
  42415. 26:08:09the same rules. So let's get the due
  42416. 26:08:11date everywhere here in the query. Just
  42417. 26:08:13make sure you don't miss anything here.
  42418. 26:08:15So let's go and execute now. Perfect. As
  42419. 26:08:18you can see, we have the order date,
  42420. 26:08:20shipping date, and due date. And all of
  42421. 26:08:21them are date and don't have any wrong
  42422. 26:08:24data inside those columns. Now, still
  42423. 26:08:26there is one more check that we can do
  42424. 26:08:27and it's that the order date should be
  42425. 26:08:30always smaller than the shipping date or
  42426. 26:08:32the due date because it makes no sense,
  42427. 26:08:34right? If you are delivering an item
  42428. 26:08:36without an order. So first the order
  42429. 26:08:38should happen then we are shipping the
  42430. 26:08:40items. So there is like an order of
  42431. 26:08:42those dates and we can go and check
  42432. 26:08:43that. So we are checking now for invalid
  42433. 26:08:45date orders where we can say the order
  42434. 26:08:48date is higher than the shipping date or
  42435. 26:08:52we are searching as well for an order
  42436. 26:08:54where the order date is higher than the
  42437. 26:08:56due date. So we can have it like this
  42438. 26:08:58due date. So let's go and check. Well,
  42439. 26:09:01that's really good. We don't have such a
  42440. 26:09:03mistake on the data and the quality
  42441. 26:09:05looks good. So the order date is always
  42442. 26:09:07smaller than the shipping date or the
  42443. 26:09:10due date. So we don't have to do any
  42444. 26:09:12transformations or cleanup. Okay
  42445. 26:09:13friends, now moving on to the last three
  42446. 26:09:15columns. We have the sales, quantity and
  42447. 26:09:18the price. All those informations are
  42448. 26:09:20connected to each others. So we have a
  42449. 26:09:21business rule or calculation. It says
  42450. 26:09:24the sales must be equal to quantity
  42451. 26:09:26multiplied by the price. And all sales
  42452. 26:09:28quantity and price informations must be
  42453. 26:09:31positive numbers. So it's not allowed to
  42454. 26:09:33be negative, zero or null. So those are
  42455. 26:09:36the business rules and we have to check
  42456. 26:09:38the data consistency in our table. Does
  42457. 26:09:40all those three informations following
  42458. 26:09:42our rules? So we're going to start first
  42459. 26:09:44with our rule, right? So we're going to
  42460. 26:09:46say if the sales is not equal to
  42461. 26:09:50quantity multiplied by the price. So we
  42462. 26:09:53are searching where the result is not
  42463. 26:09:55matching our expectation. And as well we
  42464. 26:09:58can go and check other stuff like the
  42465. 26:09:59nulls. So for example we can say or
  42466. 26:10:01sales is null or quantity is
  42467. 26:10:06null and the last one for the price and
  42468. 26:10:10as well we can go and check whether they
  42469. 26:10:12are negative numbers or zero. So we can
  42470. 26:10:14go over here and say less or equal to
  42471. 26:10:17zero and apply it for the other columns
  42472. 26:10:19as well. So with that we are checking
  42473. 26:10:22the calculation and as well we are
  42474. 26:10:24checking whether we have null, zero or
  42475. 26:10:25negative numbers. Let's go and check our
  42476. 26:10:28informations. I'm going to have here
  42477. 26:10:29extinct. So let's go and query it. And
  42478. 26:10:32of course we have here bad data. But we
  42479. 26:10:35can go and sort the data by the sales
  42480. 26:10:38quantity and the price. So let's do it.
  42481. 26:10:41Now by looking to the data we can see in
  42482. 26:10:43the sales we have nulls. We have
  42483. 26:10:45negative numbers and zeros. So we have
  42484. 26:10:48all bad combinations and as well we have
  42485. 26:10:50here bad calculations. So as you can see
  42486. 26:10:52the price here is 50, the quantity is
  42487. 26:10:54one but the sales is two which is not
  42488. 26:10:56correct. And here we have as well wrong
  42489. 26:10:58calculations. Here we have to have a 10
  42490. 26:11:00and here nine or maybe the price is
  42491. 26:11:02wrong. And by looking to the quantity
  42492. 26:11:04now you can see we don't have any nulls.
  42493. 26:11:06We don't have any zeros or negative
  42494. 26:11:08numbers. So the quantity looks better
  42495. 26:11:10than the sales. And if you look to the
  42496. 26:11:12prices we have nulls we have negatives
  42497. 26:11:14and yeah we don't have zeros. So that
  42498. 26:11:17means the quality of the sales and the
  42499. 26:11:18price is wrong. The calculation is not
  42500. 26:11:21working and we have these scenarios. Now
  42501. 26:11:23of course how I do it here I don't go
  42502. 26:11:24and try now to transform everything on
  42503. 26:11:26my own. I usually go and talk to an
  42504. 26:11:29expert maybe someone from the business
  42505. 26:11:31or from the source system and I show
  42506. 26:11:32those scenarios and discuss and usually
  42507. 26:11:34there is like two answers either they
  42508. 26:11:36going to tell me you know what I will
  42509. 26:11:38fix it in my source so I have to live
  42510. 26:11:40with it there is incoming bad data and
  42511. 26:11:42the bad data going to be presented in
  42512. 26:11:44the warehouse until the source system
  42513. 26:11:46clean up those issues. And the other
  42514. 26:11:48answer you might get you know what we
  42515. 26:11:49don't have the budget and those data are
  42516. 26:11:51really old and we are not going to do
  42517. 26:11:53anything. So here you have to decide
  42518. 26:11:55either you leave it as it is or you say
  42519. 26:11:57you know what let's go and improve the
  42520. 26:11:59quality of the data. But here you have
  42521. 26:12:00to ask for the experts to support you
  42522. 26:12:03solving these issues because it really
  42523. 26:12:05depend on the rules. Different rules
  42524. 26:12:07makes different transformations. So now
  42525. 26:12:09let's say that we have the following
  42526. 26:12:11rules. If the sales informations are
  42527. 26:12:13null or negative or zero, then use the
  42528. 26:12:16calculation the formula by multiplying
  42529. 26:12:18the quality with the price. And now if
  42530. 26:12:20the prices are wrong, for example, we
  42531. 26:12:22have here a null or zero, then go and
  42532. 26:12:24calculate it from the sales and the
  42533. 26:12:26quantity. And if you have a price that
  42534. 26:12:28is a minus like minus 21, a negative
  42535. 26:12:31number, then you have to go and convert
  42536. 26:12:33it to a 21. So from a negative to a
  42537. 26:12:36positive without any calculations. So
  42538. 26:12:38those are the rules and now we're going
  42539. 26:12:39to go and build the transformations.
  42540. 26:12:41based on those rules. So let's do it
  42541. 26:12:43step by step. I will go over here and
  42542. 26:12:45we're going to start building the new
  42543. 26:12:46sales. So what is the rule says case
  42544. 26:12:49when of course as usual if the
  42545. 26:12:52sales is null or let's say the sales is
  42546. 26:12:56negative number or equal to zero or
  42547. 26:12:59another scenario we have a sales
  42548. 26:13:00information but it is not following the
  42549. 26:13:03calculation. So we have wrong
  42550. 26:13:04information in the sales. So we're going
  42551. 26:13:06to say the sales is not equal to the
  42552. 26:13:09quantity multiplied by the price. But of
  42553. 26:13:13course we will not leave the price like
  42554. 26:13:14this by using the function APS. The
  42555. 26:13:17absolute is going to go and convert
  42556. 26:13:19everything from negative to a positive.
  42557. 26:13:21Then what we have to do is to go and use
  42558. 26:13:23the calculation. So it going to be the
  42559. 26:13:26quantity multiplied by the price. So
  42560. 26:13:29that means we are not using the value
  42561. 26:13:31that's come from the source system. We
  42562. 26:13:33are recalculating it. Now let's say the
  42563. 26:13:35sales is correct and not one of those
  42564. 26:13:37scenarios. So we're going to say else.
  42565. 26:13:39We will go with the sales as it is that
  42566. 26:13:41comes from the source because it is
  42567. 26:13:43correct. It's really nice. Let's go and
  42568. 26:13:45say an end and give it the same name. I
  42569. 26:13:47will go and rename the old one here as
  42570. 26:13:50an old value and the same for the price.
  42571. 26:13:53The quantity will not touch it because
  42572. 26:13:56it is correct. So like this. And now
  42573. 26:13:58let's go and transform the prices. So
  42574. 26:14:00again as usual we go with case when. So
  42575. 26:14:03what are the scenarios? The price is
  42576. 26:14:06null or the price is less or equal to
  42577. 26:14:10zero. Then what we going to do? We're
  42578. 26:14:12going to do the calculation. So it's
  42579. 26:14:14going to be the sales divided by the
  42580. 26:14:16quantity the SLS quantity. But here we
  42581. 26:14:20have to make sure that we are not
  42582. 26:14:21dividing by zero. Currently we don't
  42583. 26:14:23have any zeros in the quantity but you
  42584. 26:14:24don't know in the future you might get a
  42585. 26:14:26zero and the whole code going to break.
  42586. 26:14:28So what you have to do is to go and say
  42587. 26:14:30if you get any zero replace it with a
  42588. 26:14:33null. So null if if it is zero then make
  42589. 26:14:36it null. So that's it. Now if the price
  42590. 26:14:38is not null and the price is not
  42591. 26:14:40negative or equal to zero then
  42592. 26:14:42everything is fine and that's why we're
  42593. 26:14:44going to have now the else it going to
  42594. 26:14:46be the price as it is from the source
  42595. 26:14:48system. So that's it. We're going to say
  42596. 26:14:50end as price. So I'm totally happy with
  42597. 26:14:53that. Let's go and execute it and check
  42598. 26:14:55of course. So those are the old
  42599. 26:14:57informations and those are the new
  42600. 26:14:59transformed cleaned up informations. So
  42601. 26:15:00here previously we have a null but now
  42602. 26:15:02we have two. So two multiplied with one
  42603. 26:15:05we are getting two. So the sales is here
  42604. 26:15:07correct. Now moving on to the next one
  42605. 26:15:09we have in the sales 40 but the price is
  42606. 26:15:12two. So two multiplied with one we
  42607. 26:15:14should get two. So the new sales is
  42608. 26:15:16correct. It is two and not 40. Now to
  42609. 26:15:18the next one over here the old sales is
  42610. 26:15:20zero. But if you go and multiply the
  42611. 26:15:22four with the quantity you will get
  42612. 26:15:24four. So the sales here is not correct.
  42613. 26:15:26That's why in the new sales we have it
  42614. 26:15:28correct as a four. And let's go and get
  42615. 26:15:30a minus. So in this case we have a minus
  42616. 26:15:32which is not correct. So we are getting
  42617. 26:15:34the price multiplied with one. We should
  42618. 26:15:36get here a nine. And this sales here is
  42619. 26:15:39correct. Now let's go and get a scenario
  42620. 26:15:41where the price is null like this here.
  42621. 26:15:44So we don't have here a price but we
  42622. 26:15:45calculated from the sales and the
  42623. 26:15:47quantity. So we divided the 10 by two
  42624. 26:15:49and we have five. So the new price is
  42625. 26:15:52better. And the same thing for the
  42626. 26:15:54minuses. So we have here minus 21 and in
  42627. 26:15:56the output we have 21 which is correct.
  42628. 26:15:58So for now I don't see any scenario
  42629. 26:16:01where the data is wrong. So everything
  42630. 26:16:03looks better than before. And with that
  42631. 26:16:05we have applied the business rules from
  42632. 26:16:07the experts and we have cleaned up the
  42633. 26:16:09data in the data warehouse. And this is
  42634. 26:16:12way better than before because we are
  42635. 26:16:13presenting now better data for analyszis
  42636. 26:16:16and reporting but it is challenging and
  42637. 26:16:18you have exactly to understand the
  42638. 26:16:20business. So now what we're going to do
  42639. 26:16:21we're going to go and copy those
  42640. 26:16:22informations and integrate it in our
  42641. 26:16:24query. So instead of sales we're going
  42642. 26:16:27to get our new calculation and instead
  42643. 26:16:30of the price we will get our correct
  42644. 26:16:32calculation and here I'm missing the
  42645. 26:16:35end. Let's go and run the whole thing
  42646. 26:16:37again. So with that we have as well now
  42647. 26:16:40cleaned sales quantity and price and it
  42648. 26:16:43is following our business rules. So with
  42649. 26:16:45that we are done cleaning up the sales
  42650. 26:16:47details. The next step we're going to go
  42651. 26:16:48and insert it to the sales details. But
  42652. 26:16:51we have to go and check again the DDL.
  42653. 26:16:53So now all what you have to do is to
  42654. 26:16:54compare those results with the DDL. So
  42655. 26:16:57the first one is the order number. It's
  42656. 26:16:58fine. The product key, the customer ID,
  42657. 26:17:01but here we have an issue. All those
  42658. 26:17:02informations now are date and not an
  42659. 26:17:04integer. So we have to go and change the
  42660. 26:17:07data type. And with that we have better
  42661. 26:17:09data type than before. Then the sales
  42662. 26:17:11quantity price it is correct. Let's go
  42663. 26:17:13and drop the table and create it from
  42664. 26:17:15scratch again. And don't forget to
  42665. 26:17:17update your DDL script. So that's it for
  42666. 26:17:20this. And we're going to go now and
  42667. 26:17:21insert the results into our silver table
  42668. 26:17:24sales details. And we have to go and
  42669. 26:17:26list now all the columns. I have already
  42670. 26:17:28prepared the list of all the columns. So
  42671. 26:17:31make sure that you have the correct
  42672. 26:17:32order of the columns. So let's go now
  42673. 26:17:34and insert the data. And with that and
  42674. 26:17:37with that we can see that the SQL did
  42675. 26:17:39insert data to our sales details. But
  42676. 26:17:41now very important is to check the
  42677. 26:17:43health of the silver table. So what
  42678. 26:17:45we're going to do instead here of
  42679. 26:17:46bronze, we're going to go and switch it
  42680. 26:17:48to silver. So let's check over here. So
  42681. 26:17:51here always the order is smaller than
  42682. 26:17:53the shipping and the due date, which is
  42683. 26:17:55really nice. But now I'm very interested
  42684. 26:17:58on the calculations. So here we're going
  42685. 26:17:59to switch it from bronze to silver. And
  42686. 26:18:01I'm going to go and get rid of all those
  42687. 26:18:03calculations because we don't need it
  42688. 26:18:06this. And now let's see whether we have
  42689. 26:18:08any issue. Well, perfect. Our data is
  42690. 26:18:11following the business rules. We don't
  42691. 26:18:12have any nulls, negative values, zeros.
  42692. 26:18:14Now as usual the last step the final
  42693. 26:18:17check we will just have a final look to
  42694. 26:18:19the table. So we have the order number
  42695. 26:18:21the product key the customer ID those
  42696. 26:18:23three dates we have the sales quantity
  42697. 26:18:26and the price and of course we have our
  42698. 26:18:29metadata column. Everything is perfect.
  42699. 26:18:31So now by looking to our code what are
  42700. 26:18:33the different types of data
  42701. 26:18:34transformation that we are doing. So in
  42702. 26:18:36those three columns we are doing the
  42703. 26:18:38following. So at the start we are
  42704. 26:18:39handling invalid data and this is as
  42705. 26:18:42well type of transformation and as well
  42706. 26:18:44at the same time we are doing data type
  42707. 26:18:47casting. So we are changing it to more
  42708. 26:18:49correct data type. And if you are
  42709. 26:18:51looking to the sales over here then what
  42710. 26:18:53we are doing over here is we are
  42711. 26:18:55handling the missing data and as well
  42712. 26:18:57the invalid data by deriving the column
  42713. 26:19:00from already existing one. And it is as
  42714. 26:19:03well very similar for the price. We are
  42715. 26:19:05handling as well the invalid data by
  42716. 26:19:08deriving it from specific calculation
  42717. 26:19:10over here. So those are the different
  42718. 26:19:12types of data transformations that you
  42719. 26:19:14have done in these
  42720. 26:19:18scripts. All right. Now let's keep
  42721. 26:19:20moving to the next system. We have the
  42722. 26:19:22customer AZ2. So here we have like only
  42723. 26:19:25three columns and let's start with the
  42724. 26:19:27ID first. So here again we have the
  42725. 26:19:29customer's informations and if we go and
  42726. 26:19:31check again our model you can see that
  42727. 26:19:34we can connect this table with the CRM
  42728. 26:19:36table customer info using the customer
  42729. 26:19:39key. So that means we have to go and
  42730. 26:19:40make sure that we can go and connect
  42731. 26:19:42those two tables. So let's go and check
  42732. 26:19:46the other table. We can go and check of
  42733. 26:19:47course the server layer. So let's query
  42734. 26:19:50it and we can query both of the tables.
  42735. 26:19:53Now we can see there is here like extra
  42736. 26:19:55characters that are not included in the
  42737. 26:19:57customer key from the CRM. So let's go
  42738. 26:20:00and search for example for this customer
  42739. 26:20:02over here where C ID like so we are
  42740. 26:20:08searching for customer has similar ID.
  42741. 26:20:10Now as you can see we are finding this
  42742. 26:20:12customer but the issue is that we have
  42743. 26:20:14those three characters NAS. There is no
  42744. 26:20:17specifications or explanation why we
  42745. 26:20:19have the NAS. So actually what we have
  42746. 26:20:21to do is to go and remove those
  42747. 26:20:22informations. We don't need it. So let's
  42748. 26:20:24again check the data. So it looks like
  42749. 26:20:27the old data have an NAS at the start
  42750. 26:20:29and then afterward we have new data
  42751. 26:20:31without those three characters. So we
  42752. 26:20:33have to clean up those ids in order to
  42753. 26:20:35be able to connect it with other tables.
  42754. 26:20:38So we're going to do it like this. We're
  42755. 26:20:39going to start with the case when since
  42756. 26:20:41we have like two scenarios in our data.
  42757. 26:20:43So if the C ID is like the three
  42758. 26:20:47characters in as so if the ID start with
  42759. 26:20:50those three characters then we're going
  42760. 26:20:52to go and apply transformation function
  42761. 26:20:54otherwise it's going to stay like it is.
  42762. 26:20:58So that's it. So now we have to go and
  42763. 26:21:00build the transformation. So we're going
  42764. 26:21:02to use substring and then we have to
  42765. 26:21:05define the string. It's going to be the
  42766. 26:21:07CD and then we have to define the
  42767. 26:21:09position where it start cutting or
  42768. 26:21:11extracting. So we can say 1 2 3 and then
  42769. 26:21:15four. So we have to define the position
  42770. 26:21:17number four. And then we have to define
  42771. 26:21:19the string how many characters should be
  42772. 26:21:21extracted. I will make it dynamic. So I
  42773. 26:21:24will go with the length. I will not go
  42774. 26:21:26and count how much. So we're going to
  42775. 26:21:27say the C ID. So it looks good. If it's
  42776. 26:21:30like NAS then go and extract from the CD
  42777. 26:21:34at the position number four the rest of
  42778. 26:21:36the characters. So let's go and execute
  42779. 26:21:38it. And I'm missing here a comma again
  42780. 26:21:41where we don't have any NAS at the
  42781. 26:21:43start. And if you scroll down you can
  42782. 26:21:46see those as well are not affected. So
  42783. 26:21:48with that we have now a nice ID to be
  42784. 26:21:51joined with other table. Of course we
  42785. 26:21:53can go and test it like this where then
  42786. 26:21:55we take the whole thing the whole
  42787. 26:21:57transformation and say not in we remove
  42788. 26:22:00of course the alias name we don't need
  42789. 26:22:02it. And then we make very simple
  42790. 26:22:04substring select
  42791. 26:22:06distinct CST key the customer key from
  42792. 26:22:10the silver table can be silver CRM cost
  42793. 26:22:14info. So that's it. So let's go and
  42794. 26:22:17check. So as you can see it is working
  42795. 26:22:19fine. So we are not able to find any
  42796. 26:22:21unmatching data between the customer
  42797. 26:22:23info from ERB and the CRM. But of course
  42798. 26:22:26after the transformation if you don't
  42799. 26:22:28use the transformation. So if I just
  42800. 26:22:30remove it like this, we will find a lot
  42801. 26:22:32of unmatching data. So this means our
  42802. 26:22:34transformation is working perfectly and
  42803. 26:22:36we can go and remove the original value.
  42804. 26:22:38So that's it for the first column. Okay.
  42805. 26:22:41Now moving on to the next field, we have
  42806. 26:22:43the birthday of the customers. So the
  42807. 26:22:45first thing to do is to check the data
  42808. 26:22:46type. It is a date. So it's fine. It is
  42809. 26:22:49not an integer or a string. So we don't
  42810. 26:22:51have to convert anything. But still
  42811. 26:22:53there is something to check with the
  42812. 26:22:55birth date. So we can check whether we
  42813. 26:22:57have something out of range. So for
  42814. 26:22:58example, we can go and check whether we
  42815. 26:23:00have really old dates at the birth
  42816. 26:23:02dates. So let's take 19, 100, and let's
  42817. 26:23:05say 24 and we can take the first date of
  42818. 26:23:08the month. So let's go and check that.
  42819. 26:23:10Well, it looks like that we have
  42820. 26:23:12customers that are older than 100 year.
  42821. 26:23:14Well, I don't know. Maybe this is
  42822. 26:23:16correct, but it sounds of course strange
  42823. 26:23:18to do the business. Of course.
  42824. 26:23:20Hey, this is Creed and he is in charge
  42825. 26:23:24of something. That is correct. Say hi to
  42826. 26:23:27the kids. Hi kids. Yay. And then we can
  42827. 26:23:30go and check the other boundary where it
  42828. 26:23:32is almost impossible to have a customer
  42829. 26:23:35that the birthday is in the future. So
  42830. 26:23:37we can say birth date is higher than the
  42831. 26:23:41current date like this. So let's go and
  42832. 26:23:44query this information. Well, it will
  42833. 26:23:45not work because we have to have like an
  42834. 26:23:47or between them. And now if we check the
  42835. 26:23:49list over here, we have dates that are
  42836. 26:23:52invalid for the birth dates. So all
  42837. 26:23:54those dates they are all per day in the
  42838. 26:23:57future and this is totally unacceptable.
  42839. 26:23:59So this is an indicator for bad data
  42840. 26:24:01quality. Of course you can go and report
  42841. 26:24:03it to the source system in order to
  42842. 26:24:04correct it. So here it's up to you what
  42843. 26:24:06to do with those dates. Either leave it
  42844. 26:24:08as it is as a bad data or we can go and
  42845. 26:24:11clean that up by replacing all those
  42846. 26:24:13dates with a null or maybe replacing
  42847. 26:24:15only the one that is extreme where it is
  42848. 26:24:18100% is incorrect. So let's go and write
  42849. 26:24:21the transformation for that. As usual,
  42850. 26:24:22we're going to start with case when
  42851. 26:24:24birth date is larger than the current
  42852. 26:24:28date and time then null. Otherwise, we
  42853. 26:24:32can have an else where we have the birth
  42854. 26:24:34date as it is and then we have an end as
  42855. 26:24:38birth date. So, let's go and execute it.
  42856. 26:24:41And with that, we should not get any
  42857. 26:24:43customer where the birthday in the
  42858. 26:24:45future. So, that's it for the birth
  42859. 26:24:47date. Now, let's move to the next one.
  42860. 26:24:49We have the gender. Now again the gender
  42861. 26:24:51informations is low cardalities. So we
  42862. 26:24:53have to go and check all the possible
  42863. 26:24:55values inside this column. So in order
  42864. 26:24:57to check all the possible values we're
  42865. 26:24:59going to use select distinct gen from
  42866. 26:25:02our table. So let's go and execute it.
  42867. 26:25:04And now the data doesn't look really
  42868. 26:25:06good. So we have here a null, we have an
  42869. 26:25:08f, we have here an empty string, we have
  42870. 26:25:11male, female, and again we have the M.
  42871. 26:25:14So this is not really good. And what
  42872. 26:25:15we're going to do, we're going to go and
  42873. 26:25:16clean up all those informations in order
  42874. 26:25:18to have only three values. Male, female,
  42875. 26:25:21and not available. So, we're going to do
  42876. 26:25:23it like this. We're going to say case
  42877. 26:25:25when and now we're going to go and trim
  42878. 26:25:26the values just to make sure there is
  42879. 26:25:28like no empty spaces. And as well, I'm
  42880. 26:25:31going to go and use the upper function
  42881. 26:25:32just to make sure that in the future if
  42882. 26:25:34we get any lower cases and so on, we are
  42883. 26:25:37covering all the different scenarios. So
  42884. 26:25:40case this is in F or let's say
  42885. 26:25:44female then make it as female and we can
  42886. 26:25:48go and do the same thing for the male
  42887. 26:25:51like this. So if it is an M or a male
  42888. 26:25:54make sure it is capital letters because
  42889. 26:25:56here we are using the upper then it is a
  42890. 26:25:58male otherwise all other scenarios it
  42891. 26:26:01should be not available. So whether it
  42892. 26:26:03is an empty string or nulls and so on.
  42893. 26:26:06So we have to have an end of course as
  42894. 26:26:09gen. So now let's go and test it and
  42895. 26:26:10check whether we have covered
  42896. 26:26:11everything. So you can see the M is now
  42897. 26:26:13male. The empty is not available. The F
  42898. 26:26:16is female. The empty string or maybe
  42899. 26:26:19spaces here is not available. Female
  42900. 26:26:21going to stay as it is. And the same for
  42901. 26:26:23the male. So with that we are covering
  42902. 26:26:25all the scenarios and we are following
  42903. 26:26:27our standards in the project. So I'm
  42904. 26:26:29going to go and cut this and put it in
  42905. 26:26:31our original query over here. So let's
  42906. 26:26:34go and execute the whole thing. And with
  42907. 26:26:36that we have cleaned up all those three
  42908. 26:26:39columns. Now the question is did we
  42909. 26:26:40change anything in the DDL? Well we
  42910. 26:26:42didn't change anything. We didn't
  42911. 26:26:44introduce any new column or change any
  42912. 26:26:46data type. So that means the next step
  42913. 26:26:48is we're going to go and insert it in
  42914. 26:26:50the server layer. So as usual we're
  42915. 26:26:52going to say here insert into silver ERP
  42916. 26:26:56the customer and then we're going to go
  42917. 26:26:58and list all the column names. So C ID
  42918. 26:27:01birth date and the gender. All right. So
  42919. 26:27:04let's go and execute it. And with that
  42920. 26:27:06we can see it inserted all the data. And
  42921. 26:27:08of course the very important step as the
  42922. 26:27:10next is to check the data quality. So
  42923. 26:27:12let's go back to our query over here and
  42924. 26:27:15change it from bronze to silver. So
  42925. 26:27:17let's go and check the silver layer.
  42926. 26:27:19Well of course we are getting those very
  42927. 26:27:21old customers but we didn't change that.
  42928. 26:27:24We only change the birthday that is in
  42929. 26:27:26the future and we don't see it here in
  42930. 26:27:28the results. So that means everything is
  42931. 26:27:29clean. So for the next one, let's go and
  42932. 26:27:32check the different genders. And as you
  42933. 26:27:34can see, we have only those three
  42934. 26:27:35values. And of course, we can go and
  42935. 26:27:37take a final look to our table. So you
  42936. 26:27:40can see the C ID here, the birth date,
  42937. 26:27:42the gender, and then we see our metadata
  42938. 26:27:44column. And everything looks amazing. So
  42939. 26:27:47that's it. What are the different types
  42940. 26:27:49of data transformations that we have
  42941. 26:27:50done? First with the ID, what we have
  42942. 26:27:52done, we have handled invalid values. So
  42943. 26:27:55we have removed this part where it is
  42944. 26:27:57not needed. And the same thing goes for
  42945. 26:27:59the birth dates. We have handled as well
  42946. 26:28:02invalid values. And then for the last
  42947. 26:28:04one, for the gender, we have done data
  42948. 26:28:06normalizations by mapping the code to
  42949. 26:28:08more friendly value. And as well, we
  42950. 26:28:10have handled the missing values. So
  42951. 26:28:12those are the types that we have done in
  42952. 26:28:14this
  42953. 26:28:18code. Okay. Moving on to the second
  42954. 26:28:20table, we have the location
  42955. 26:28:22informations. So we have ERP location
  42956. 26:28:25A101. So now here the task is easy
  42957. 26:28:27because we have only two columns and if
  42958. 26:28:29you go and check the integration model
  42959. 26:28:30we can find our table over here. So we
  42960. 26:28:33can go and connect it together with the
  42961. 26:28:35customer info from the other system
  42962. 26:28:36using a CID with the customer key. So
  42963. 26:28:40those two informations must be matching
  42964. 26:28:42in order to join the tables. So that
  42965. 26:28:44means we have to go and check the data.
  42966. 26:28:46So let's go and select the data CST key
  42967. 26:28:50from let's go and get the silver data
  42968. 26:28:52customer info. So let's go. Now if you
  42969. 26:28:54go and check the result you can see over
  42970. 26:28:56here that we have an issue with the CI
  42971. 26:28:59ID there is like a minus between the
  42972. 26:29:02characters and the numbers but the
  42973. 26:29:03customer ID the customer number we don't
  42974. 26:29:05have anything that splits the characters
  42975. 26:29:08with the numbers. So if you go and join
  42976. 26:29:10those two informations it will not be
  42977. 26:29:11working. So what we have to do we have
  42978. 26:29:13to go and get rid of this minus because
  42979. 26:29:15it is totally unnecessary. So let's go
  42980. 26:29:17and fix that. It's going to be very
  42981. 26:29:19simple. So what we're going to do we're
  42982. 26:29:20going to say CI ID. So we're going to go
  42983. 26:29:22and search for the minus and replace it
  42984. 26:29:25with nothing. It's very simple like
  42985. 26:29:27this. So let's go and query it again.
  42986. 26:29:30And with that things looks very similar
  42987. 26:29:31to each others. And as well we can go
  42988. 26:29:33and query it. So we're going to say
  42989. 26:29:35where our transformation is not in then
  42990. 26:29:39we can go and use this as a subquery
  42991. 26:29:41like this. So let's go and execute it.
  42992. 26:29:44And as you can see we are not finding
  42993. 26:29:46any unmatching data now. So that means
  42994. 26:29:48our transformation is working. And with
  42995. 26:29:50that we can go and connect those two
  42996. 26:29:52tables together. So if I take the
  42997. 26:29:54transformation away you can see that we
  42998. 26:29:56will find a lot of unmatching data. So
  42999. 26:29:58the transformation is okay. We're going
  43000. 26:30:00to stay with it. And now let's speak
  43001. 26:30:02about the countries. Now we have here
  43002. 26:30:04multiple values and so on. What I'm
  43003. 26:30:06going to do this is low cardinality and
  43004. 26:30:08we have to go and check all possible
  43005. 26:30:10values inside this column. So that means
  43006. 26:30:12we are checking whether the data is
  43007. 26:30:14consistent. So we can do it like this.
  43008. 26:30:17distinct the
  43009. 26:30:19country from our table. I'm just going
  43010. 26:30:21to go and copy it like this. And as
  43011. 26:30:23well, I'm going to go and sort the data
  43012. 26:30:25by the country. So, let's go and check
  43013. 26:30:28the informations. Now, you can see we
  43014. 26:30:30have a null. We have an empty string,
  43015. 26:30:32which is really bad. And then we have a
  43016. 26:30:34full name of country and then we have as
  43017. 26:30:36well an abbreviation of the countries.
  43018. 26:30:39Well, this is a mix. This is not really
  43019. 26:30:41good because sometimes we have DE and
  43020. 26:30:43sometimes we have Germany and then we
  43021. 26:30:45have the United Kingdom and then for the
  43022. 26:30:47United States we have like three
  43023. 26:30:49versions of the same information which
  43024. 26:30:51is as well not really good. So the
  43025. 26:30:53quality of the country is not really
  43026. 26:30:55good. So let's go and work on the
  43027. 26:30:57transformation. As usual we're going to
  43028. 26:30:58start with the case win. If trim
  43029. 26:31:01country is equal to D, then we're going
  43030. 26:31:06to transform it to Germany. And the next
  43031. 26:31:09one it's going to be about the USA. So
  43032. 26:31:11if trim country is in. So now let's go
  43033. 26:31:15and get those two values the US and the
  43034. 26:31:17USA. So US and USA then it's going to be
  43035. 26:31:23the United States states. So with us we
  43036. 26:31:26have covered as well those three cases.
  43037. 26:31:29Now we have to talk about the null and
  43038. 26:31:30the empty string. So we're going to say
  43039. 26:31:32when trim country is equal to empty
  43040. 26:31:36string or country is null then it's
  43041. 26:31:41going to be not available otherwise I
  43042. 26:31:44would like to get the country as it is.
  43043. 26:31:45So trim country just to make sure that
  43044. 26:31:48we don't have any leading or trailing
  43045. 26:31:50spaces. So that's it. Let's go and say
  43046. 26:31:53this is the country. So it is working
  43047. 26:31:56and the country information is
  43048. 26:31:58transformed. And now what I'm going to
  43049. 26:31:59do, I'm going to take the whole new
  43050. 26:32:00transformation and compare it to the old
  43051. 26:32:03one. Let me just call this as old
  43052. 26:32:07country and let's go and query it. So
  43053. 26:32:09now we can check those values state as
  43054. 26:32:11before. So nothing did change. The DE is
  43055. 26:32:14now Germany. The empty string is not
  43056. 26:32:16available. The null the same thing and
  43057. 26:32:18the United Kingdom stayed as like it's
  43058. 26:32:21like before. And now we have one value
  43059. 26:32:23for all those information. So it's only
  43060. 26:32:26the United States. So it looks perfect.
  43061. 26:32:28And with that we have cleaned as well
  43062. 26:32:30the second column. So with that we have
  43063. 26:32:32now clean results. And now the question
  43064. 26:32:34did we change anything in the DDL? Well
  43065. 26:32:36we haven't changed anything. Both of
  43066. 26:32:38them are varchar. So we can go now
  43067. 26:32:40immediately and insert it into our
  43068. 26:32:42table. So insert into silver customer
  43069. 26:32:46location. And here we have to specify
  43070. 26:32:48the columns. It's very simple the ID and
  43071. 26:32:50the country. So let's go and execute it.
  43072. 26:32:53And as you can see we got now inserted
  43073. 26:32:55all those values. Of course, as a next,
  43074. 26:32:57we go and double check those
  43075. 26:32:59informations. I would just go and remove
  43076. 26:33:01all those stuff as well here. And
  43077. 26:33:03instead of bronze, let's go with the
  43078. 26:33:05silver. So, as you can see, all the
  43079. 26:33:08values of the country looks good. And
  43080. 26:33:10let's have a final look to the table.
  43081. 26:33:12So, like this. So, we have the ids
  43082. 26:33:14without the separator. We have the
  43083. 26:33:16countries and as well our metadata
  43084. 26:33:19information. So, with that, we have
  43085. 26:33:20cleaned up the data for the location.
  43086. 26:33:22Okay. So now what are the different
  43087. 26:33:23types of data transformation that we
  43088. 26:33:25have done here is first we have handled
  43089. 26:33:27invalid values. So we have removed the
  43090. 26:33:30minus with an empty string and for the
  43091. 26:33:32country we have done data normalization.
  43092. 26:33:35So we have replaced codes with friendly
  43093. 26:33:37values and as well at the same time we
  43094. 26:33:40have handled missing values by replacing
  43095. 26:33:42the empty string and null with not
  43096. 26:33:44available. And one more thing of course
  43097. 26:33:46we have removed the unwanted spaces. So
  43098. 26:33:49those are the different types of
  43099. 26:33:50transformation that we have done for
  43100. 26:33:52this
  43101. 26:33:55table. Okay guys, now keep the energy
  43102. 26:33:58up, keep the spirit up. We have to go
  43103. 26:34:00and clean up the last table in the
  43104. 26:34:02bronze layer. And of course, we cannot
  43105. 26:34:04go and skip anything. We have to check
  43106. 26:34:06the quality and to detect all the
  43107. 26:34:08errors. So now we have a table about the
  43108. 26:34:10categories for the products. And here we
  43109. 26:34:12have like four columns. Let's go and
  43110. 26:34:14start with the first one, the ID. As you
  43111. 26:34:16can see in our integration model, we can
  43112. 26:34:18connect this table together with the
  43113. 26:34:20product info from the CRM using the
  43114. 26:34:22product key. And as you remember in the
  43115. 26:34:24silver layer, we have created an extra
  43116. 26:34:26column for that in the product info. So
  43117. 26:34:29if you go and select those data, you can
  43118. 26:34:31see we have a column called category ID
  43119. 26:34:34and this one is exactly matching the ID
  43120. 26:34:36that we have in this table and we have
  43121. 26:34:38done the testing. So this ID is ready to
  43122. 26:34:41be used together with the other table.
  43123. 26:34:43So there is nothing to do over here. And
  43124. 26:34:46now for the next columns they are
  43125. 26:34:47string. And of course we can go and
  43126. 26:34:49check whether there are any unwanted
  43127. 26:34:51spaces. So we are checking for the
  43128. 26:34:52unwanted spaces. So let's go and check
  43129. 26:34:56select start from and we're going to go
  43130. 26:34:58and get the same table like this here.
  43131. 26:35:00And first we are checking the category.
  43132. 26:35:02So the category is not equal to the
  43133. 26:35:05category after trimming the unwanted
  43134. 26:35:07spaces. So let's go and execute it. And
  43135. 26:35:10as you can see we don't have any
  43136. 26:35:12results. So there are no unwanted
  43137. 26:35:14spaces. Let's go and check the other
  43138. 26:35:15column. For example, the subcategory,
  43139. 26:35:18the next one. So let's get the
  43140. 26:35:20subcategory and run the query as well.
  43141. 26:35:23We don't have anything. So that means we
  43142. 26:35:25don't have unwanted spaces for the
  43143. 26:35:27subcategory. Let's go now and check the
  43144. 26:35:29last column. So I will just copy and
  43145. 26:35:31paste. Now let's get the maintenance and
  43146. 26:35:34let's go and execute. And as well, no
  43147. 26:35:36results. Perfect. We don't have any
  43148. 26:35:38unwanted spaces inside this table. So
  43149. 26:35:41now the next step is that we're going to
  43150. 26:35:42go and check the data standardizations
  43151. 26:35:45because all those columns has low
  43152. 26:35:47cardinality. So what we can do we can
  43153. 26:35:49say
  43154. 26:35:49select distinct let's get the cats
  43155. 26:35:53category from our table. I'll just copy
  43156. 26:35:56and paste it and check all values. So as
  43157. 26:35:58you can see we have the accessories,
  43158. 26:36:00bikes, clothing and components.
  43159. 26:36:02Everything looks perfect. We don't have
  43160. 26:36:04to change anything in this column. Let's
  43161. 26:36:06go and check the subcategory. And if you
  43162. 26:36:08scroll down, all values are friendly and
  43163. 26:36:11nice as well. Nothing to change here.
  43164. 26:36:14And let's go and check the last column,
  43165. 26:36:15the maintenance. Perfect. We have only
  43166. 26:36:18two values, yes and no. We don't have
  43167. 26:36:20any nulls. So my friends, that's means
  43168. 26:36:22this table has really nice data quality
  43169. 26:36:25and we don't have to clean up anything.
  43170. 26:36:27But still, we have to follow our
  43171. 26:36:29process. We have to go and load it from
  43172. 26:36:31the bronze to the silver even if we
  43173. 26:36:33didn't transform anything. So our job is
  43174. 26:36:35really easy. Here we're going to go and
  43175. 26:36:37say insert into silver dot ERP px and so
  43176. 26:36:42on. And we're going to go and define the
  43177. 26:36:44columns. So it's going to be the ID, the
  43178. 26:36:46category,
  43179. 26:36:48subcategory, maintenance. So that's it.
  43180. 26:36:50Let's go and insert the data. Now, as
  43181. 26:36:52usual, what we're going to do, we're
  43182. 26:36:53going to go and check the data. So
  43183. 26:36:56silver
  43184. 26:36:58ERP. Let's have a look. All right. So we
  43185. 26:37:01can see the ids are here, the
  43186. 26:37:02categories, the subcategories, the
  43187. 26:37:04maintenance and we have our meta column.
  43188. 26:37:07So everything is inserted correctly. All
  43189. 26:37:10right. So now I have all those queries
  43190. 26:37:12and the insert statements for all six
  43191. 26:37:14tables. And now what is important before
  43192. 26:37:17inserting any data, we have to make sure
  43193. 26:37:19that we are truncating and emptying the
  43194. 26:37:22table because if you run this query
  43195. 26:37:23twice, what's going to happen? You will
  43196. 26:37:25be inserting duplicates. So first
  43197. 26:37:27truncate the data and then do a full
  43198. 26:37:30load insert all data. So we're going to
  43199. 26:37:32have one step before it's like the
  43200. 26:37:34bronze layer. We're going to say
  43201. 26:37:35truncate table and then we will be
  43202. 26:37:37truncating the silver customer info and
  43203. 26:37:39only after that we have to go and insert
  43204. 26:37:42the data. And of course we can go and
  43205. 26:37:43give this nice information at the start.
  43206. 26:37:46So first we are truncating the table and
  43207. 26:37:48then inserting. So if I go and run the
  43208. 26:37:50whole thing. So let's go and do it. It
  43209. 26:37:52will be working. So if I can run it
  43210. 26:37:54again, we will not have any duplicates.
  43211. 26:37:56So we have to go and add this step
  43212. 26:37:58before each insert. So let's go and do
  43213. 26:38:00that. All right. So I'm done with all
  43214. 26:38:03tables. So now let's go and run
  43215. 26:38:06everything. So let's go and execute it.
  43216. 26:38:08And we can see in the messaging
  43217. 26:38:10everything working perfectly. So with
  43218. 26:38:12that we made all tables empty. And then
  43219. 26:38:13we inserted the
  43220. 26:38:18data. So perfect. With that we have a
  43221. 26:38:20nice script that loads the silver layer.
  43222. 26:38:23But of course like the front layer,
  43223. 26:38:25we're going to put everything in one
  43224. 26:38:26stored procedure. So let's go and do
  43225. 26:38:28that. We'll go to the beginning over
  43226. 26:38:30here and say create or alter procedure
  43227. 26:38:34and we're going to put it in the schema
  43228. 26:38:36silver and using the naming convention
  43229. 26:38:38load silver and we're going to go over
  43230. 26:38:40here and say begin and take the whole
  43231. 26:38:42code end it is long one and give it one
  43232. 26:38:45push with a tab and then at the end
  43233. 26:38:47we're going to say edge. Perfect. So we
  43234. 26:38:50have our stored procedure but we forgot
  43235. 26:38:52here the ass with that we will not have
  43236. 26:38:54any error. Let's go and execute it. So
  43237. 26:38:56the stored procedure is created. If you
  43238. 26:38:58go to the programmability and you will
  43239. 26:39:00find two procedures load bronze and load
  43240. 26:39:03silver. So now let's go and try it out.
  43241. 26:39:05All what you have to do is now only to
  43242. 26:39:07execute the silver load silver. So let's
  43243. 26:39:11execute the start procedure and with
  43244. 26:39:13that we will get the same results. This
  43245. 26:39:15third procedure now is responsible of
  43246. 26:39:18loading the whole silver layer. Now of
  43247. 26:39:20course the messaging here is not really
  43248. 26:39:23good because we have learned in the
  43249. 26:39:24bronze layer we can go and add many
  43250. 26:39:26stuff like handling the error doing nice
  43251. 26:39:29messaging catching the duration time. So
  43252. 26:39:32now your task is to pause the video take
  43253. 26:39:34this start procedure and go and
  43254. 26:39:36transform it to be very similar to the
  43255. 26:39:38bronze layer with the same messaging and
  43256. 26:39:41all the add-ons that we have added. So
  43257. 26:39:43pause the video now. I will do it as
  43258. 26:39:44well offline and I will see you
  43259. 26:39:49[Music]
  43260. 26:39:51soon. Okay. So I hope you are done and I
  43261. 26:39:54can show you the results. It's like the
  43262. 26:39:56bronze layer. We have defined at the
  43263. 26:39:57start few variables in order to catch
  43264. 26:40:00the duration. So we have the start time,
  43265. 26:40:02the end time, patch start time and patch
  43266. 26:40:04end time. And then we are printing a lot
  43267. 26:40:06of stuff in order to have like nice
  43268. 26:40:08messaging in the output. So at the start
  43269. 26:40:10we are saying loading the server layer
  43270. 26:40:12and then we start splitting by the
  43271. 26:40:14source system. So loading the CRM tables
  43272. 26:40:17and I'm going to show you only one table
  43273. 26:40:18for now. So we are setting the timer. So
  43274. 26:40:21we are saying start time get the date
  43275. 26:40:23and time informations to it. Then we are
  43276. 26:40:25doing the usual. We are truncating the
  43277. 26:40:27table and then we are inserting the new
  43278. 26:40:29informations after cleaning it up. And
  43279. 26:40:32we have this nice message. We will say
  43280. 26:40:34load duration where we are finding the
  43281. 26:40:36differences between the start time and
  43282. 26:40:38the end time using the function date
  43283. 26:40:40diff. And we want to show the result in
  43284. 26:40:42the seconds. So we are just printing how
  43285. 26:40:45long it took to load this table. And
  43286. 26:40:47we're going to go and repeat this
  43287. 26:40:48process for all the tables. And of
  43288. 26:40:50course we are putting everything in try
  43289. 26:40:52and catch. So the SQL going to go and
  43290. 26:40:55try to execute the try part. And if
  43291. 26:40:57there are any issues the SQL going to go
  43292. 26:41:00and execute the catch. And here we are
  43293. 26:41:02just printing few information like the
  43294. 26:41:04error message the error number and the
  43295. 26:41:06error states. And we are following
  43296. 26:41:07exactly the same standard at the bronze
  43297. 26:41:10layer. So let's go and execute the whole
  43298. 26:41:13thing. And with that we have updated the
  43299. 26:41:15definition of the third procedure. Let's
  43300. 26:41:17go now and execute it. So execute silver
  43301. 26:41:20dot load silver. So let's go and do
  43302. 26:41:23that. It went very fast like fewer than
  43303. 26:41:251 seconds again because we are working
  43304. 26:41:27on local machine loading the server
  43305. 26:41:29layer loading the CRM tables and we can
  43306. 26:41:32see this nice messaging. So it start
  43307. 26:41:34with truncating the table inserting the
  43308. 26:41:36data and we are getting the load
  43309. 26:41:38duration for this table and you will see
  43310. 26:41:40that everything is below 1 second and
  43311. 26:41:42that's because in real projects you will
  43312. 26:41:44get of course more than 1 second. So at
  43313. 26:41:47the end we have load duration of the
  43314. 26:41:49whole silver layer. And now I have one
  43315. 26:41:51more thing for you. Let's say that you
  43316. 26:41:53are changing the design of this store
  43317. 26:41:55procedure for the server layer. You are
  43318. 26:41:57adding different types of messaging or
  43319. 26:41:59maybe you're creating logs and so on. So
  43320. 26:42:01now all those new ideas and redesigns
  43321. 26:42:04that you are doing for the silver layer,
  43322. 26:42:05you have always to think about bringing
  43323. 26:42:08the same changes as well in the other
  43324. 26:42:10store procedure for the pros layer. So
  43325. 26:42:12always try to keep your codes following
  43326. 26:42:14the same standards. Don't have like one
  43327. 26:42:16idea in one store procedure and an old
  43328. 26:42:19idea in another one. Always try to
  43329. 26:42:21maintain those scripts and to keep them
  43330. 26:42:23all up to date following the same
  43331. 26:42:25standards. Otherwise, it can be really
  43332. 26:42:27hard for other developers to understand
  43333. 26:42:29the cause. I know that needs a lot of
  43334. 26:42:31work and commitments, but this is your
  43335. 26:42:33job to make everything following the
  43336. 26:42:35best practices and following the same
  43337. 26:42:37naming convention and standards that you
  43338. 26:42:39put for your projects. So guys, now we
  43339. 26:42:42have very nice two ETL scripts. One that
  43340. 26:42:45loads the bronze layer and another one
  43341. 26:42:47for the server layer. So now our data
  43342. 26:42:48warehouse is very simple. All what you
  43343. 26:42:50have to do is to run first the bronze
  43344. 26:42:53layer and with that we are taking all
  43345. 26:42:54the data from the CSV files from the
  43346. 26:42:57source and we put it inside our data
  43347. 26:42:59warehouse in the bronze layer and with
  43348. 26:43:01that we are refreshing the whole bronze
  43349. 26:43:03layer. Once it's done the next step is
  43350. 26:43:06to run the store procedure of the server
  43351. 26:43:08layer. So once you execute it you are
  43352. 26:43:10taking now all the data from the bronze
  43353. 26:43:12layer transforming it cleaning it up and
  43354. 26:43:15then loading it to the server layer. And
  43355. 26:43:18as you can see the concept is very
  43356. 26:43:19simple. We are just moving the data from
  43357. 26:43:21one layer another layer with different
  43358. 26:43:23tasks. All right guys, so as you can see
  43359. 26:43:25in the server layer we have done a lot
  43360. 26:43:27of data transformations and we have
  43361. 26:43:29covered all the types that we have in
  43362. 26:43:31the data cleansing. So we remove
  43363. 26:43:33duplicates, data filtering, handling
  43364. 26:43:35missing data, invalid data, unwanted
  43365. 26:43:37spaces, casting the data types and so
  43366. 26:43:39on. And as well we have derived new
  43367. 26:43:41columns, we have done data enrichment
  43368. 26:43:44and we have normalized a lot of data. So
  43369. 26:43:46now of course what we have not done yet
  43370. 26:43:48business rules and logic data
  43371. 26:43:50aggregations and data integration. This
  43372. 26:43:52is for the next layer. All right my
  43373. 26:43:54friends. So finally we are done cleaning
  43374. 26:43:56up the data and checking the quality of
  43375. 26:43:58our data. So we can go and close those
  43376. 26:44:01two steps. And now to the next step we
  43377. 26:44:03have to go and extend the data flow
  43378. 26:44:05diagram. So let's
  43379. 26:44:09go. Okay. So now let's go and extend our
  43380. 26:44:12data flow for the silver layer. So, what
  43381. 26:44:15I'm going to do, I'm just going to go
  43382. 26:44:16and copy the whole thing and put it side
  43383. 26:44:19by side to the bronze layer. And let's
  43384. 26:44:22call it silver layer. And the table name
  43385. 26:44:25is going to stay as before because we
  43386. 26:44:26have like one to one like the bronze
  43387. 26:44:29layer. But what we're going to do, we're
  43388. 26:44:30going to go and change the coloring. So,
  43389. 26:44:31I'm going to go and mark everything and
  43390. 26:44:33make it gray like silver. And of course,
  43391. 26:44:36what is very important is to make the
  43392. 26:44:38lineage. So, I'm going to go now from
  43393. 26:44:40the bronze and take an arrow and put it
  43394. 26:44:43to the silver table. And now with that
  43395. 26:44:45we have like a lineage between three
  43396. 26:44:47layers and you are checking this table
  43397. 26:44:48the customer info you can understand aha
  43398. 26:44:51this comes from the bronze layer from
  43399. 26:44:53the customer info and as well this comes
  43400. 26:44:55from the source system CRM so now we can
  43401. 26:44:58see the lineage between different layers
  43402. 26:45:01and without looking to any scripts and
  43403. 26:45:03so on in one picture you can understand
  43404. 26:45:05the whole projects so I don't have to
  43405. 26:45:07explain a lot of stuff by just looking
  43406. 26:45:09to this picture you can understand how
  43407. 26:45:11the data is flowing between sources is
  43408. 26:45:14bronze layer, silver layer, and to the
  43409. 26:45:16gold layer, of course, later. So, as you
  43410. 26:45:18can see, it looks really nice and clean.
  43411. 26:45:20All right. So, with that, we have
  43412. 26:45:21updated the data flow. Next, we're going
  43413. 26:45:24to go and commit our work in the G repo.
  43414. 26:45:26So, let's
  43415. 26:45:30go. Okay. So, now let's go and commit
  43416. 26:45:32our scripts. We're going to go to the
  43417. 26:45:34folder scripts. And here we have a
  43418. 26:45:36server layer. If you don't have it, of
  43419. 26:45:38course, you can go and create it. So,
  43420. 26:45:39first we're going to go and put the DDL
  43421. 26:45:41scripts for the server layer. So let's
  43422. 26:45:43go and I will paste the code over here.
  43423. 26:45:46And as usual, we have this commit as the
  43424. 26:45:48header explaining the purpose of this
  43425. 26:45:50script. So let's go and commit our work.
  43426. 26:45:53And we're going to do the same thing for
  43427. 26:45:55the store procedure that loads the
  43428. 26:45:57server layer. So I'm going to go over
  43429. 26:45:59here. I have already filed for that. So
  43430. 26:46:01let's go and paste that. So we have here
  43431. 26:46:04our stored procedures. And as usual at
  43432. 26:46:06the start, we have as well. So this
  43433. 26:46:08script is doing the ATL process where we
  43434. 26:46:10load the data from bronze into silver.
  43435. 26:46:13So the action is to truncate the table
  43436. 26:46:15first and then insert transformed cleans
  43437. 26:46:17data from bronze to silver. There are no
  43438. 26:46:20parameters at all. And this is how you
  43439. 26:46:22can use the source procedure. Okay. So
  43440. 26:46:24we're going to go and commit our work.
  43441. 26:46:27And now one more thing that we want to
  43442. 26:46:29commit in our project all those queries
  43443. 26:46:31that you have built to check the quality
  43444. 26:46:33of the server layer. So this time we
  43445. 26:46:35will not put it in the scripts. We're
  43446. 26:46:36going to go to the tests and here we're
  43447. 26:46:38going to go and make a new file called
  43448. 26:46:40quality checks silver and inside it
  43449. 26:46:42we're going to go and paste all the
  43450. 26:46:44queries that we have filled. I just here
  43451. 26:46:46reorganize them by the tables. So here
  43452. 26:46:49we can see all the checks that we have
  43453. 26:46:51done during the course and at the header
  43454. 26:46:54we have here nice comments. So here we
  43455. 26:46:56are just saying that this script is
  43456. 26:46:57going to check the quality of the server
  43457. 26:46:59layer and we are checking for nulls,
  43458. 26:47:01duplicates, unwanted spaces, invalid
  43459. 26:47:03date range and so on. So that each time
  43460. 26:47:06you come up with a new quality check,
  43461. 26:47:08I'm going to recommend you to share it
  43462. 26:47:09with the project and with other team in
  43463. 26:47:11order to make it part of multiple checks
  43464. 26:47:14that you do after running the ATL. So
  43465. 26:47:17that's it. I'm going to go and put those
  43466. 26:47:18checks in our repo and in case I come up
  43467. 26:47:22with new check, I'm going to go and
  43468. 26:47:23update it. Perfect. So now we have our
  43469. 26:47:25code in our repository. All right. So
  43470. 26:47:28with that, our code is saved and we are
  43471. 26:47:30done with the whole epic. So we have
  43472. 26:47:32built the silver layer. Now let's go and
  43473. 26:47:35minimize it. And now we come to my
  43474. 26:47:37favorite layer, the code layer. So we're
  43475. 26:47:39going to go and build it. The first step
  43476. 26:47:41as usual, we have to analyze. And this
  43477. 26:47:43time we're going to explore the business
  43478. 26:47:44objects. So let's
  43479. 26:47:48go. All right. So now we come to the big
  43480. 26:47:51question. How we going to build the gold
  43481. 26:47:52layer? As usual, we start with
  43482. 26:47:54analyzing. So now what we're going to do
  43483. 26:47:56here is to explore and understand what
  43484. 26:47:58are the main business objects that are
  43485. 26:48:00hidden inside our source system. So as
  43486. 26:48:02you can see we have two sources six
  43487. 26:48:04files and here we have to identify what
  43488. 26:48:06are the business objects. Once we have
  43489. 26:48:07this understanding then we can start
  43490. 26:48:09coding and here the main transformation
  43491. 26:48:11that we are doing is data integration.
  43492. 26:48:13And here usually I split it into three
  43493. 26:48:15steps. The first one we're going to go
  43494. 26:48:17and build those business objects that we
  43495. 26:48:19have identified. And after we have a
  43496. 26:48:21business objects we have to look at it
  43497. 26:48:23and decide what is the type of this
  43498. 26:48:25table. Is it a dimension? Is it a fact?
  43499. 26:48:28Or is it like maybe a flat table? So
  43500. 26:48:30what type of table that we have built
  43501. 26:48:32and the last step is of course we have
  43502. 26:48:34now to rename all the columns into
  43503. 26:48:36something friendly and easy to
  43504. 26:48:38understand so that our consumers don't
  43505. 26:48:40struggle with technical names. So once
  43506. 26:48:41we have all those steps what we're going
  43507. 26:48:43to do it's time to validate what we have
  43508. 26:48:44created. So what we have to do the new
  43509. 26:48:46data model that we have created it
  43510. 26:48:48should be connectable and we have to
  43511. 26:48:50check that the data integration is done
  43512. 26:48:52correctly and once everything is fine we
  43513. 26:48:54cannot skip the last step. we have to
  43514. 26:48:56document and as well commit our work in
  43515. 26:48:58the g. And here we will be introducing a
  43516. 26:49:00new type of documentations. So we're
  43517. 26:49:02going to have a diagram about the data
  43518. 26:49:04model. We're going to build a data
  43519. 26:49:06dictionary where we're going to describe
  43520. 26:49:07the data model. And of course we're
  43521. 26:49:09going to extend the data flow diagram.
  43522. 26:49:11So this is our process. Those are the
  43523. 26:49:13main steps that we will do in order to
  43524. 26:49:15build the code
  43525. 26:49:19layer. Okay. So what is exactly data
  43526. 26:49:22moduling? Usually the source system
  43527. 26:49:23going to deliver for you row data
  43528. 26:49:25unorganized messy not very useful in its
  43529. 26:49:29current states. But now the data
  43530. 26:49:31modeling is the process of taking this
  43531. 26:49:33row data and then organize it and
  43532. 26:49:35structure it in meaningful way. So what
  43533. 26:49:38we are doing we are putting the data in
  43534. 26:49:40new friendly and easy to understand
  43535. 26:49:43objects like customers, orders,
  43536. 26:49:45products. Each one of them is focused on
  43537. 26:49:47specific information and what is very
  43538. 26:49:49important is we're going to describe the
  43539. 26:49:51relationship between those objects. So
  43540. 26:49:54by connecting them using lines. So what
  43541. 26:49:56you have built on the right side we call
  43542. 26:49:58it logical data model. If you compare to
  43543. 26:50:00the left side you can see the data model
  43544. 26:50:02makes it really easy to understand our
  43545. 26:50:03data and the relationship the processes
  43546. 26:50:06behind them. Now in data modeling we
  43547. 26:50:07have three different stages or let's say
  43548. 26:50:09three different ways on how to draw a
  43549. 26:50:11data model. The first stage is the
  43550. 26:50:13conceptual data model. Here the focus is
  43551. 26:50:16only on the entity. So we have
  43552. 26:50:18customers, orders, products and we don't
  43553. 26:50:20go in details at all. So we don't
  43554. 26:50:22specify any columns or attributes inside
  43555. 26:50:24those boxes. We just want to focus what
  43556. 26:50:26are the entities that we have and as
  43557. 26:50:28well the relationship between them. So
  43558. 26:50:30the conceptual data model don't focus at
  43559. 26:50:33all on the details. It just gives the
  43560. 26:50:35big picture. So the second data model
  43561. 26:50:37that we can build is the logical data
  43562. 26:50:39model. And here we start specifying what
  43563. 26:50:41are the different columns that we can
  43564. 26:50:43find in each entity like we have the
  43565. 26:50:45customer ID the first name last name and
  43566. 26:50:48so on and we still draw the relationship
  43567. 26:50:50between those entities and as well we
  43568. 26:50:51make it clear which columns are the
  43569. 26:50:53primary key and so on. So as you can see
  43570. 26:50:55we have here more details but one thing
  43571. 26:50:57we don't describe a lot of details for
  43572. 26:50:59each column and we are not worry how
  43573. 26:51:01exactly we going to store those tables
  43574. 26:51:03in the database. The third and last
  43575. 26:51:05stage we have the physical data model.
  43576. 26:51:08This is where everything gets ready
  43577. 26:51:09before creating it in the database. So
  43578. 26:51:12here you have to add all the technical
  43579. 26:51:13details like adding for each column the
  43580. 26:51:16data types and the length of each data
  43581. 26:51:18type and many other database techniques
  43582. 26:51:21and details. So again if you look to the
  43583. 26:51:23conceptual data model it gives us the
  43584. 26:51:25big picture and in the logical data
  43585. 26:51:26model we dive into details of what data
  43586. 26:51:29we need and the physical layer model
  43587. 26:51:31prepares everything for the
  43588. 26:51:33implementation in the database. And to
  43589. 26:51:35be honest in my projects I only draw the
  43590. 26:51:37conceptual and the logical data model
  43591. 26:51:39because drawing and building the
  43592. 26:51:41physical data model needs a lot of
  43593. 26:51:43efforts and time and there are many
  43594. 26:51:45tools like in data bricks they
  43595. 26:51:46automatically generate those models. So
  43596. 26:51:49in this project what we're going to do
  43597. 26:51:50we're going to draw the logical data
  43598. 26:51:52model for the gold
  43599. 26:51:57layer. All right. It's now for analytics
  43600. 26:51:59and especially for data warehousing and
  43601. 26:52:01business intelligence. We need a special
  43602. 26:52:03data model that is optimized for
  43603. 26:52:05reporting and analytics and it should be
  43604. 26:52:08flexible, scalable and as well easy to
  43605. 26:52:10understand. And for that we have two
  43606. 26:52:12special data models. The first type of
  43607. 26:52:14data model we have the star schema. It
  43608. 26:52:16has a central fact table in the middle
  43609. 26:52:18and surrounded by dimensions. The fact
  43610. 26:52:20table contains transactions, events, and
  43611. 26:52:23the dimensions contains descriptive
  43612. 26:52:25informations. And the relationship
  43613. 26:52:26between the fact table in the middle and
  43614. 26:52:28the dimensions around it forms like a
  43615. 26:52:31star shape. And that's why we call it
  43616. 26:52:33star schema. And we have another data
  43617. 26:52:34model called snowflake schema. It looks
  43618. 26:52:37very similar to the star schema. So we
  43619. 26:52:39have again the fact in the middle and
  43620. 26:52:41surrounded by dimensions. But the big
  43621. 26:52:43difference is that we break the
  43622. 26:52:45dimensions into smaller subdimensions.
  43623. 26:52:48And the shape of this data model as you
  43624. 26:52:50are extending the dimensions it's going
  43625. 26:52:52to looks like a snowflake. So now if you
  43626. 26:52:54compare them side by side you can see
  43627. 26:52:55that the star schema looks easier right?
  43628. 26:52:58So it is usually easy to understand easy
  43629. 26:53:00to query it is really perfect for
  43630. 26:53:02analyzers but it has one issue with the
  43631. 26:53:05dimension might contain duplicates and
  43632. 26:53:07your dimensions get bigger with the
  43633. 26:53:09time. Now if you compare it to the
  43634. 26:53:10snowflake you can see the schema is more
  43635. 26:53:13complex. You saw you need a lot of
  43636. 26:53:15knowledge and efforts in order to query
  43637. 26:53:17something from the snowflake. But the
  43638. 26:53:19main advantage here comes with the
  43639. 26:53:20normalization as you are breaking those
  43640. 26:53:22redundancies in small tables. You can
  43641. 26:53:24optimize the storage. But to be honest,
  43642. 26:53:26who care about the storage? So for this
  43643. 26:53:28project, I have chose to use the star
  43644. 26:53:30schema because it is very commonly used.
  43645. 26:53:32Perfect for reporting like for example
  43646. 26:53:34if you're using PowerBI and we don't
  43647. 26:53:37have to worry about the storage. So
  43648. 26:53:38that's why we're going to adopt this
  43649. 26:53:40model to build our gold layer.
  43650. 26:53:46Okay. So now one more thing about those
  43651. 26:53:47data models is that they contain two
  43652. 26:53:50types of tables fact and dimensions. So
  43653. 26:53:52when I say this is a fact table or a
  43654. 26:53:54dimension table well the dimension
  43655. 26:53:56contains descriptive informations or
  43656. 26:53:58like categories that gives some context
  43657. 26:54:00to your data. For example a product info
  43658. 26:54:02you have product name, category,
  43659. 26:54:04subcategories and so on. This is like a
  43660. 26:54:06table that is describing the products
  43661. 26:54:09and this we call it dimension. But in
  43662. 26:54:11the other hand we have facts. They are
  43663. 26:54:13events like transactions. They contain
  43664. 26:54:15three important informations. First you
  43665. 26:54:18have multiple ids from multiple
  43666. 26:54:20dimensions. Then we have like date
  43667. 26:54:22informations like when the transaction
  43668. 26:54:24or the event did happen. And the third
  43669. 26:54:27type of information you're going to have
  43670. 26:54:28like measures and numbers. So if you see
  43671. 26:54:30those three types of data in one table,
  43672. 26:54:33then this is a fact. So if you have a
  43673. 26:54:35table that answers how much or how many,
  43674. 26:54:38then this is a fact. But if you have a
  43675. 26:54:40table that answers who, what, where,
  43676. 26:54:43then this is a dimension table. So this
  43677. 26:54:45is what dimension and fact
  43678. 26:54:50tables. All right my friends. So so far
  43679. 26:54:52in the bronze layer and in the silver
  43680. 26:54:54layer we didn't discuss anything about
  43681. 26:54:56the business. So the bronze and silver
  43682. 26:54:58were very technical. We are focusing on
  43683. 26:55:00data ingestion. We are focusing on
  43684. 26:55:02cleaning up the data quality of the
  43685. 26:55:04data. But still the tables are very
  43686. 26:55:06oriented to the source system. Now comes
  43687. 26:55:09the fun part in the god layer where
  43688. 26:55:11we're going to go and break the whole
  43689. 26:55:12data model of the sources. So we're
  43690. 26:55:14going to create something completely new
  43691. 26:55:16to our business that is easy to consume
  43692. 26:55:19for business reporting and analyzes. And
  43693. 26:55:22here it is very important to have a
  43694. 26:55:23clear understanding of the business and
  43695. 26:55:25the processes. And if you don't know it
  43696. 26:55:27already at this phase you have really to
  43697. 26:55:29invest time by meeting maybe process
  43698. 26:55:31experts, the domain experts in order to
  43699. 26:55:34have clear understanding what we are
  43700. 26:55:36talking about in the data. So now what
  43701. 26:55:38we're going to do, we're going to try to
  43702. 26:55:39detect what are the business objects
  43703. 26:55:41that are hidden in the source systems.
  43704. 26:55:44So now let's go and explore that. All
  43705. 26:55:46right. Now in order to build a new data
  43706. 26:55:48model, I have to understand first the
  43707. 26:55:50original data model. What are the main
  43708. 26:55:52business objects that we have? How
  43709. 26:55:53things are related to each others? And
  43710. 26:55:55this is very important process in
  43711. 26:55:57building a new model. So now what I
  43712. 26:55:59usually do, I start giving labels to all
  43713. 26:56:02those tables. So if you go to the shapes
  43714. 26:56:03over here, let's go and search for
  43715. 26:56:05label. And if we go to more icons, I'm
  43716. 26:56:08going to go and take this label over
  43717. 26:56:09here. So, drag and drop it. And then I'm
  43718. 26:56:11going to go and increase maybe the size
  43719. 26:56:13of the font. So, let's go with 20 and
  43720. 26:56:16bold. Just make it a little bit bigger.
  43721. 26:56:18So, now by looking to this data model,
  43722. 26:56:20we can see that we have product
  43723. 26:56:22informations in the CRM and as well in
  43724. 26:56:24the ARP. And then we have like customer
  43725. 26:56:26informations and transactional table.
  43726. 26:56:29So, now let's focus on the product. So,
  43727. 26:56:31the product information is over here. We
  43728. 26:56:33have here the current and the history
  43729. 26:56:35product informations and here we have
  43730. 26:56:37the categories that's belong to the
  43731. 26:56:39products. So in our data model we have
  43732. 26:56:41something called products. So let's go
  43733. 26:56:42and create this label. It's going to be
  43734. 26:56:44the product and let's go and give it a
  43735. 26:56:47color to the style. Let's pick for
  43736. 26:56:49example the red one. Now let's go and
  43737. 26:56:52move this label and put it beneath this
  43738. 26:56:54table over here. And with that I have
  43739. 26:56:56like a label saying this table belongs
  43740. 26:56:59to the objects called products. Now I'm
  43741. 26:57:01going to do the same thing for the other
  43742. 26:57:03table over here. So I'm going to go and
  43743. 26:57:05tag this table to the product as well.
  43744. 26:57:07So that I can see easily which tables
  43745. 26:57:09from the sources does has informations
  43746. 26:57:11about the product business object. All
  43747. 26:57:14right. Now moving on, we have here a
  43748. 26:57:15table called customer information. So we
  43749. 26:57:18have a lot of information about the
  43750. 26:57:19customer. We have as well in the ARP
  43751. 26:57:21customer information where we have the
  43752. 26:57:22birthday and the country. So those three
  43753. 26:57:25tables has to do with the object
  43754. 26:57:27customer. So that means we're going to
  43755. 26:57:28go and label it like that. So let's call
  43756. 26:57:30it customer and I'm going to go and pick
  43757. 26:57:33different color for that. Let's go with
  43758. 26:57:35the green. So I will tag this table like
  43759. 26:57:38this. And the same thing for the other
  43760. 26:57:40tables. So copy tag the second table and
  43761. 26:57:44the third table. Now it is very easily
  43762. 26:57:46for me to see which table to belong to
  43763. 26:57:49which business objects. And now we have
  43764. 26:57:51the final table over here and only one
  43765. 26:57:53table about the sales and orders. In the
  43766. 26:57:55arb we don't have any informations about
  43767. 26:57:57that. So this one going to be easy.
  43768. 26:57:59Let's call it sales. And let's move it
  43769. 26:58:03over here. And as well maybe change the
  43770. 26:58:05color of that to for example this color
  43771. 26:58:07over here. Now this step is very
  43772. 26:58:09important by building any data model in
  43773. 26:58:11the gold layer. It gives you a big
  43774. 26:58:13picture about the things that you are
  43775. 26:58:14going to module. So now the next step is
  43776. 26:58:16that we're going to go and build those
  43777. 26:58:18objects step by step. So let's start
  43778. 26:58:19with the first objects with our
  43779. 26:58:21customers. So here we have three tables
  43780. 26:58:23and we're going to start with the CRM.
  43781. 26:58:25So let's start with this table over
  43782. 26:58:26here. All right. So with that we know
  43783. 26:58:28what are our business objects and this
  43784. 26:58:30task is done and now in the next step
  43785. 26:58:32we're going to go back to scale and
  43786. 26:58:34start doing data integrations and
  43787. 26:58:36building completely new data model. So
  43788. 26:58:39let's go and do
  43789. 26:58:43that. Now let's have a quick look to the
  43790. 26:58:45good layer specifications. So this is
  43791. 26:58:47the final stage. We're going to provide
  43792. 26:58:49data to be consumed by reporting and
  43793. 26:58:51analytics. And this time we will not be
  43794. 26:58:53building tables. We will be using views.
  43795. 26:58:56So that means we will not be having like
  43796. 26:58:58stored procedure or any load process to
  43797. 26:59:00the code layer. All what we are doing is
  43798. 26:59:02only data transformation and the focus
  43799. 26:59:04of the data transformation going to be
  43800. 26:59:06data integration, aggregation, business
  43801. 26:59:08logic and so on. And this time we're
  43802. 26:59:10going to introduce a new data model. We
  43803. 26:59:12will be doing star schema. So those are
  43804. 26:59:15the specifications for the gold layer
  43805. 26:59:16and this is our scope. So this time we
  43806. 26:59:19make sure that we are selecting data
  43807. 26:59:21from the silver layer not from the
  43808. 26:59:23bronze because the bronze has bad data
  43809. 26:59:25quality and the silver is everything is
  43810. 26:59:27prepared and cleaned up. In order to
  43811. 26:59:29build the good layer going to be
  43812. 26:59:30targeting the server layer. So let's
  43813. 26:59:33start with select star from and we're
  43814. 26:59:36going to go to the silver CRM customer
  43815. 26:59:39info. So let's go and hit execute. And
  43816. 26:59:41now we're going to go and select the
  43817. 26:59:42columns that we need to be presented in
  43818. 26:59:45the go layer. So let's start selecting
  43819. 26:59:47the columns that we want. So we have the
  43820. 26:59:49ID, the key, the first
  43821. 26:59:55name. I will not go and get the metadata
  43822. 26:59:58information. This only belongs to the
  43823. 27:00:00silver. Perfect. The next step is that
  43824. 27:00:01I'm going to go and give this table an
  43825. 27:00:03alias. So let's go and call it CI. And
  43826. 27:00:06I'm going to make sure that we are
  43827. 27:00:07selecting from this alias because later
  43828. 27:00:10we're going to go and join this table
  43829. 27:00:12with other tables. So something like
  43830. 27:00:14this. So we're going to go with those
  43831. 27:00:15columns. Now let's move to the second
  43832. 27:00:17table. Let's go and get the birthday
  43833. 27:00:19information. So now we're going to jump
  43834. 27:00:20to the other system and we have to join
  43835. 27:00:22the data by the CID together with the
  43836. 27:00:25customer key. So now we have to go and
  43837. 27:00:27join the data with another table. And
  43838. 27:00:29here I try to avoid using the inner join
  43839. 27:00:32because if the other table doesn't have
  43840. 27:00:34all the information about the customers,
  43841. 27:00:36I might lose customers. So always start
  43842. 27:00:38with the master table and if you join it
  43843. 27:00:41with any other table in order to get
  43844. 27:00:43informations try always to avoid inner
  43845. 27:00:45join because the other source might not
  43846. 27:00:48have all the customers and if you do
  43847. 27:00:49inner join you might lose customers. So
  43848. 27:00:51I tend to start from the master table
  43849. 27:00:53and then everything else is about the
  43850. 27:00:56lift join. So I'm going to say lift join
  43851. 27:00:58silver ERP customer a12. So let's give
  43852. 27:01:01it the alias ca. And now we have to join
  43853. 27:01:04the tables. So it's going to be by CE
  43854. 27:01:06from the first table. It's going to be
  43855. 27:01:08the customer key equal to CA and we have
  43856. 27:01:12the CI ID. Now of course we're going to
  43857. 27:01:14get matching data because we checked the
  43858. 27:01:16server layer. But if we haven't prepared
  43859. 27:01:18the data in the server layer, we have to
  43860. 27:01:20do here preparation step in order to
  43861. 27:01:22join the tables. But we don't have to do
  43862. 27:01:23that because that was a pre-step in the
  43863. 27:01:26server layer. So now you can see the
  43864. 27:01:27systematic that we have in this bronze,
  43865. 27:01:30silver, gold. So now after joining the
  43866. 27:01:32tables we have to go and pick the
  43867. 27:01:33information that we need from the second
  43868. 27:01:35table which is the birth date. So B date
  43869. 27:01:38dates and as well from this table there
  43870. 27:01:40is another nice information it is the
  43871. 27:01:43gender information. So that's all what
  43872. 27:01:46we need from the second table. Let's go
  43873. 27:01:48and check the third table. So the third
  43874. 27:01:50table is about the location information
  43875. 27:01:52the countries and as well we connect the
  43876. 27:01:54tables by the CID with the key. So let's
  43877. 27:01:57go and do that. We're going to say as
  43878. 27:01:59well left join silver ERP location and
  43879. 27:02:03I'm going to give it the name LA and
  43880. 27:02:05then we have to join Y the keys the same
  43881. 27:02:07thing it's going to be CI customer key
  43882. 27:02:10equal to LA CI ID again we have prepared
  43883. 27:02:14those ids and keys in the server layer
  43884. 27:02:16so the join should be working now we
  43885. 27:02:18have to go and pick the data from the
  43886. 27:02:20second table so what do we have over
  43887. 27:02:22here we have the ID the country and the
  43888. 27:02:24metadata information so let's go and
  43889. 27:02:26just get the country Perfect. So now
  43890. 27:02:29with that we have joined all the three
  43891. 27:02:31tables and we have picked all the
  43892. 27:02:33columns that we want in this object. So
  43893. 27:02:35again by looking over here we have
  43894. 27:02:37joined this table with this one and this
  43895. 27:02:39one. So with that we have collected all
  43896. 27:02:41the customer informations that we have
  43897. 27:02:43from the two source systems. Okay. So
  43898. 27:02:46now let's go and query in order to make
  43899. 27:02:47sure that we have everything correct and
  43900. 27:02:49in order to understand that your joints
  43901. 27:02:51are correct you have to keep your eye in
  43902. 27:02:54those three columns. So if you are
  43903. 27:02:55seeing that you are getting data that
  43904. 27:02:58means you are doing the the joints
  43905. 27:03:00correctly but if you are seeing a lot of
  43906. 27:03:02nulls or no data at all that means your
  43907. 27:03:05joints are incorrect but now it looks
  43908. 27:03:07for me it is working and another check
  43909. 27:03:10that I do is that if your first table
  43910. 27:03:12has no duplicates what could happen is
  43911. 27:03:14that after doing multiple joins you
  43912. 27:03:16might now start getting duplicates
  43913. 27:03:18because the relationship between those
  43914. 27:03:20tables is not clear one to one you might
  43915. 27:03:23get like one to many relationship ship
  43916. 27:03:24or many to many relationships. So now
  43917. 27:03:26the check that I usually do at this
  43918. 27:03:28stage is that I have to make sure that I
  43919. 27:03:30don't have duplicates from their
  43920. 27:03:32results. So we don't have like multiple
  43921. 27:03:34rows for the same customer. So in order
  43922. 27:03:36to do that, we go and do a quick group
  43923. 27:03:39by. So we're going to group by the data
  43924. 27:03:41by the customer ID and then we do the
  43925. 27:03:44count from this subquery. So this is the
  43926. 27:03:48whole subquery and then after that we're
  43927. 27:03:51going to go and say group by the
  43928. 27:03:54customer ID and then we say having
  43929. 27:03:58count higher than one. So this query
  43930. 27:04:02actually try to find out whether we have
  43931. 27:04:04any duplicates in the primary key. So
  43932. 27:04:07let's go and execute it. We don't have
  43933. 27:04:09any duplicates and that means after
  43934. 27:04:11joining all those tables with the
  43935. 27:04:13customer info those tables didn't cause
  43936. 27:04:16any issues and didn't duplicate my data.
  43937. 27:04:18So this is very important check to make
  43938. 27:04:21sure that you are in the right way. All
  43939. 27:04:23right. So that means everything is fine
  43940. 27:04:25about the duplicates. We don't have to
  43941. 27:04:27worry about it. Now we have here an
  43942. 27:04:29integration issue. So let's go and
  43943. 27:04:30execute it again. And now if you look to
  43944. 27:04:32the data we have two sources for the
  43945. 27:04:34gender informations. one comes from the
  43946. 27:04:36CRM and another one come from the ERP.
  43947. 27:04:39So now the question is what we're going
  43948. 27:04:40to do with this? Well, we have to do
  43949. 27:04:42data integration. So let me show you how
  43950. 27:04:44I do it. First I go and have a new query
  43951. 27:04:47and then I'm going to go and remove all
  43952. 27:04:49other stuff and I'm going to leave only
  43953. 27:04:51those two informations and use it
  43954. 27:04:53distinct just to focus on the
  43955. 27:04:56integration and let's go and execute it
  43956. 27:04:58and maybe as well to do an order by. So
  43957. 27:05:00let's do one and two. Let's go and
  43958. 27:05:02execute it again. So now here we have
  43959. 27:05:04all the scenarios and we can see
  43960. 27:05:06sometimes there is a matching. So from
  43961. 27:05:08the first table we have female and the
  43962. 27:05:10other table we have as well female but
  43963. 27:05:12sometimes we have an issue like those
  43964. 27:05:13two tables are giving different
  43965. 27:05:15informations and the same thing over
  43966. 27:05:17here. So this is as well an issue
  43967. 27:05:18different informations. Another scenario
  43968. 27:05:20where we have a data from the first
  43969. 27:05:22table like here we have the female but
  43970. 27:05:24in the other table we have not
  43971. 27:05:26available. Well this is not a problem.
  43972. 27:05:28So we can get it from the first table
  43973. 27:05:30but we have as well the exact opposite
  43974. 27:05:32scenario where from the first table the
  43975. 27:05:34data is not available but it is
  43976. 27:05:36available from the second table. And now
  43977. 27:05:38here you might wonder why I'm getting a
  43978. 27:05:40null over here. We did handle all the
  43979. 27:05:42missing data in the silver layer and we
  43980. 27:05:44replace everything with not available.
  43981. 27:05:46So why we are still in getting a null?
  43982. 27:05:48This null doesn't come directly from the
  43983. 27:05:50tables. It just come because of joining
  43984. 27:05:53tables. So that means there are
  43985. 27:05:55customers in the CRM table that is not
  43986. 27:05:58available in the ARB table and if there
  43987. 27:06:01is like no match what going to happen we
  43988. 27:06:03will get a null from SQL. So this null
  43989. 27:06:06means there was no match and that's why
  43990. 27:06:08we are getting this null. It is not
  43991. 27:06:10coming from the content of the tables
  43992. 27:06:12and this is of course an issue. But now
  43993. 27:06:14the big issue what can happen for those
  43994. 27:06:16two scenarios here we have the data but
  43995. 27:06:19they are different. And here again we
  43996. 27:06:20have to ask the experts about it. What
  43997. 27:06:23is the master here? Is it the CRM system
  43998. 27:06:26or the ARP? And let's say from their
  43999. 27:06:28answer going to say the master data for
  44000. 27:06:30the customer information is the CRM. So
  44001. 27:06:33that means the CRM informations are more
  44002. 27:06:36accurate than the ERP information and
  44003. 27:06:39this is only about the customers of
  44004. 27:06:40course. So for this scenario where we
  44005. 27:06:42have female and male then the correct
  44006. 27:06:44information is the female from the first
  44007. 27:06:46source system. The same goes over here
  44008. 27:06:48and here we have like male and female
  44009. 27:06:50then the correct one is the male because
  44010. 27:06:53this source system is the master. Okay.
  44011. 27:06:55So now let's go and build this business
  44012. 27:06:57rule. We're going to start as usual with
  44013. 27:06:59the case win. So the first very
  44014. 27:07:01important rule is if we have a data in
  44015. 27:07:03the gender information from the CRM
  44016. 27:07:06system from the master then go and use
  44017. 27:07:08it. So we're going to go and check the
  44018. 27:07:10gender information from the CRM table.
  44019. 27:07:12So customer gender is not equal to not
  44020. 27:07:15available. So that means we have a value
  44021. 27:07:18male or female. Let me just have here a
  44022. 27:07:20comma like this. Then what's going to
  44023. 27:07:22happen? Go and use it. So we're going to
  44024. 27:07:24use the value from the master. CRM is
  44025. 27:07:28the master for gender info. Now
  44026. 27:07:32otherwise that means it is not available
  44027. 27:07:35from the CRM table. Then go and use and
  44028. 27:07:39grab the information from the second
  44029. 27:07:40table. So we're going to say CA gender.
  44030. 27:07:44But now we have to be careful with this
  44031. 27:07:46null over here. We have to convert it to
  44032. 27:07:47not available as well. So we're going to
  44033. 27:07:49use the
  44034. 27:07:50kis. So if this is a null then go and
  44035. 27:07:54use the not available like this. So
  44036. 27:07:57that's it. Let's have an end. And let me
  44037. 27:07:59just push this over here. So let's go
  44038. 27:08:01and call it new gen for now. Let's go
  44039. 27:08:04and execute it and let's go and check
  44040. 27:08:06the different scenarios. All those
  44041. 27:08:08values over here we have data from the
  44042. 27:08:11CRM system and this is as well
  44043. 27:08:13represented in the new column. But now
  44044. 27:08:15for the second part we don't have data
  44045. 27:08:18from the first system. So we are trying
  44046. 27:08:19to get it from the second system. So for
  44047. 27:08:22the first one is not available and then
  44048. 27:08:24we try to get it from the second source
  44049. 27:08:26system. So now we are activating the
  44050. 27:08:27else. Well it is null and with that the
  44051. 27:08:30kalis is activated and we are replacing
  44052. 27:08:32the null with not available. For the
  44053. 27:08:35second scenario as well, the first
  44054. 27:08:36search system don't have the gender
  44055. 27:08:39information. That's why we are grabbing
  44056. 27:08:40it from the second. So with that we have
  44057. 27:08:43a female. And then the third one the
  44058. 27:08:45same thing we don't have information but
  44059. 27:08:46we get it from the second source system.
  44060. 27:08:48We have the male and the last one it is
  44061. 27:08:50not available in both source systems.
  44062. 27:08:53That's why we are getting not available.
  44063. 27:08:55So with that as you can see we have a
  44064. 27:08:56perfect new column where we are
  44065. 27:08:58integrating two different source system
  44066. 27:09:00in one. And this is exactly what we call
  44067. 27:09:03data integration. This piece of
  44068. 27:09:05information, it is way better than the
  44069. 27:09:07source CRM and as well the source ARP.
  44070. 27:09:11It is more rich and has more
  44071. 27:09:13information. And this is exactly why we
  44072. 27:09:15try to get data from different source
  44073. 27:09:17system in order to get rich information
  44074. 27:09:19in the data warehouse. So with that we
  44075. 27:09:21have a nice logic and as you can see
  44076. 27:09:23it's way easier to separate it in
  44077. 27:09:25separate query in order first to build
  44078. 27:09:27the logic and then take it to the
  44079. 27:09:29original query. So what I'm going to do,
  44080. 27:09:31I'm just going to go and copy everything
  44081. 27:09:32from here and go back to our query. I'm
  44082. 27:09:35going to go and delete those
  44083. 27:09:36informations the gender and I will put
  44084. 27:09:39our new logic over here. So a comma and
  44085. 27:09:42let's go and execute. So with that we
  44086. 27:09:44have our new nice column. Now with that
  44087. 27:09:46we have very nice objects. We don't have
  44088. 27:09:48duplicates and we have integrated data
  44089. 27:09:50together. So we took three tables and we
  44090. 27:09:52put it in one object. Now the next step
  44091. 27:09:54is that we're going to go and give nice
  44092. 27:09:57friendly names. The rule in the gold
  44093. 27:09:59layer that to use friendly names and not
  44094. 27:10:01to follow the names that we get from the
  44095. 27:10:03source system and we have to make sure
  44096. 27:10:05that we are following the rules by the
  44097. 27:10:07naming conventions. So we are following
  44098. 27:10:09the snake case. So let's go and do it
  44099. 27:10:11step by step. For the first one let's go
  44100. 27:10:13and call it the customer ID. And then
  44101. 27:10:15the next one I will get rid of using
  44102. 27:10:18keys and so on. I'm going to go and call
  44103. 27:10:19it customer number because those are
  44104. 27:10:22customer numbers. Then for the next one,
  44105. 27:10:25we're going to call it first name
  44106. 27:10:28without using any prefixes. And the next
  44107. 27:10:31one last name and we have here marital
  44108. 27:10:35status. So I will be using the exact
  44109. 27:10:38name but without the prefix. And here we
  44110. 27:10:41just going to call it gender. And this
  44111. 27:10:42one we're going to call it career date.
  44112. 27:10:46And this one birth date. And the last
  44113. 27:10:49one going to be the country. So let's go
  44114. 27:10:52and execute it. Now as you can see the
  44115. 27:10:54names are really friendly. So we have
  44116. 27:10:56customer ID, customer numbers, first
  44117. 27:10:58name, last name, material status,
  44118. 27:11:00gender. So as you can see the names are
  44119. 27:11:02really nice and really easy to
  44120. 27:11:04understand. Now the next step I'm going
  44121. 27:11:06to think about the order of those
  44122. 27:11:07columns. So the first two it makes sense
  44123. 27:11:09to have it together. The first name,
  44124. 27:11:11last name, then I think the country is
  44125. 27:11:13very important information. So I'm going
  44126. 27:11:14to go and get it from here and put it
  44127. 27:11:16exactly after the last name is just
  44128. 27:11:19nicer. So let's go and execute it again.
  44129. 27:11:21So the first name, last name, country.
  44130. 27:11:23It's always nice to group up relevant
  44131. 27:11:25columns together, right? So we have here
  44132. 27:11:27the status of the gender and so on. And
  44133. 27:11:29then we have the career date and the
  44134. 27:11:30birth date. I think I'm going to go and
  44135. 27:11:32switch the birth date with the career
  44136. 27:11:34date. It's more important than the
  44137. 27:11:36career dates like this. And here not
  44138. 27:11:38forget the comma. So execute again. So
  44139. 27:11:41it looks wonderful. Now comes a very
  44140. 27:11:43important decision about these objects.
  44141. 27:11:45Is it a fact table or a dimension? Well,
  44142. 27:11:48as we learned, dimensions hold
  44143. 27:11:50descriptive informations about an
  44144. 27:11:52object. And as you can see, we have here
  44145. 27:11:54a descriptions about the customers. So
  44146. 27:11:56all those columns are describing the
  44147. 27:11:59customer information. And we don't have
  44148. 27:12:00here like transactions and events. And
  44149. 27:12:03we don't have like measures and so on.
  44150. 27:12:04So we cannot say this object is a fact.
  44151. 27:12:07It is clearly a dimension. So that's why
  44152. 27:12:10we're going to go and call this object
  44153. 27:12:12the dimension customer. Now there is one
  44154. 27:12:14thing that if you are creating a new
  44155. 27:12:16dimension you need always a primary key
  44156. 27:12:18for the dimension. Of course we can go
  44157. 27:12:20over here and depend on the primary key
  44158. 27:12:22that we get from the source system but
  44159. 27:12:24sometimes you can have like dimensions
  44160. 27:12:26where you don't have like a primary key
  44161. 27:12:28that you can count on. So what we have
  44162. 27:12:30to do is to go and generate a new
  44163. 27:12:33primary key in the data warehouse. And
  44164. 27:12:35those primary keys we call it surrogate
  44165. 27:12:37keys. Srogate keys are system generated
  44166. 27:12:40unique identifier that is assigned to
  44167. 27:12:42each records to make the record unique.
  44168. 27:12:45It is not a business key. It has no
  44169. 27:12:47meaning and no one in the business knows
  44170. 27:12:50about it. We only use it in order to
  44171. 27:12:52connect our data model. And in this way
  44172. 27:12:54we have more control on how to connect
  44173. 27:12:56our data model and we don't have to
  44174. 27:12:58depend always on the source system. And
  44175. 27:13:01there are different ways on how to
  44176. 27:13:02generate surrogate keys like defining it
  44177. 27:13:05in the DDL or maybe using the window
  44178. 27:13:07function row number in this data
  44179. 27:13:09warehouse. I'm going to go with a simple
  44180. 27:13:11solution where we're going to go and use
  44181. 27:13:12the window function. So now in order to
  44182. 27:13:15generate a surrogate key for this
  44183. 27:13:17dimension what we're going to do it is
  44184. 27:13:19very simple. So we're going to say row
  44185. 27:13:21number over and here we have to order by
  44186. 27:13:25something. You can order by the create
  44187. 27:13:27date or the customer ID or the customer
  44188. 27:13:30number. whatever you want but in this
  44189. 27:13:32example I'm going to go and order by the
  44190. 27:13:34customer ID. So we have to follow the
  44191. 27:13:37naming convention that all surrogate
  44192. 27:13:39keys with a key at the end as a suffix.
  44193. 27:13:41So now let's go and query those
  44194. 27:13:43informations. And as you can see at the
  44195. 27:13:45start we have a customer key and this is
  44196. 27:13:47a sequence. We don't have here of course
  44197. 27:13:49any duplicates. And now this target key
  44198. 27:13:52is generated in the data warehouse and
  44199. 27:13:54we're going to use this key in order to
  44200. 27:13:56connect the data model. So now with that
  44201. 27:13:58our query is ready and the last step is
  44202. 27:14:01that we're going to go and create the
  44203. 27:14:03object and as we decided all the objects
  44204. 27:14:05in the gold layer going to be virtual
  44205. 27:14:07one. So that means we're going to go and
  44206. 27:14:09create a view. So we're going to say
  44207. 27:14:11create view gold dot dim. So follow the
  44208. 27:14:15naming convention stand for the
  44209. 27:14:17dimension and we're going to have the
  44210. 27:14:18customers and then after that we have
  44211. 27:14:20ass. So with that everything is ready.
  44212. 27:14:23Let's go and execute it. It was
  44213. 27:14:25successful. Let's go to the views now
  44214. 27:14:27and you can see our first objects. So we
  44215. 27:14:30have the dimension customers in the gold
  44216. 27:14:32layer. Now as you know me in the next
  44217. 27:14:34step that we're going to go and check
  44218. 27:14:36the quality of this new objects. So
  44219. 27:14:38let's go and have a new query. So select
  44220. 27:14:41star from our view temp customers. And
  44221. 27:14:45now we have to make sure that everything
  44222. 27:14:47in the right position like this. And now
  44223. 27:14:49we can do different checks like the
  44224. 27:14:51uniqueness and so on. But I'm worried
  44225. 27:14:54about the gender information. So let's
  44226. 27:14:56go and have a distinct of all values. So
  44227. 27:14:59as you can see it is working perfectly.
  44228. 27:15:00We have only female, male and not
  44229. 27:15:03available. So that's it with that. We
  44230. 27:15:05have our first new
  44231. 27:15:10dimension. Okay friends. So now let's go
  44232. 27:15:12and build the second object. We have the
  44233. 27:15:15products. So as you can see product
  44234. 27:15:17information is available in both source
  44235. 27:15:19systems. As usual, we're going to start
  44236. 27:15:21with the CRM informations and then we're
  44237. 27:15:23going to go and join it with the other
  44238. 27:15:24table in order to get the category
  44239. 27:15:26informations. So those are the columns
  44240. 27:15:28that we want from this table. Now we
  44241. 27:15:30come here to a big decision about this
  44242. 27:15:33objects. This object contains historical
  44243. 27:15:35informations and as well the current
  44244. 27:15:37informations. Now of course depend on
  44245. 27:15:38the requirement whether you have to do
  44246. 27:15:40analyszis on the historical
  44247. 27:15:42informations. But if you don't have such
  44248. 27:15:43a requirements we can go and stay with
  44249. 27:15:46only the current informations of the
  44250. 27:15:48products. So we don't have to include
  44251. 27:15:49all the history in the objects and it is
  44252. 27:15:51anyway as we learned from the model over
  44253. 27:15:53here we are not using the primary key we
  44254. 27:15:56are using the product key. So now what
  44255. 27:15:58we have to do is to filter out the
  44256. 27:16:00historical data and to stay only with
  44257. 27:16:02the current data. So we're going to have
  44258. 27:16:04here a wear condition. And now in order
  44259. 27:16:06to select the current data what we're
  44260. 27:16:08going to do we're going to go and target
  44261. 27:16:10the end dates. If the end date is null
  44262. 27:16:12that means it is a current data. Let's
  44263. 27:16:14take this example over here. So you can
  44264. 27:16:16see here we have three records for the
  44265. 27:16:18same product key and for the first two
  44266. 27:16:21records we have here an information in
  44267. 27:16:23the end dates because it is historical
  44268. 27:16:25informations but the last record over
  44269. 27:16:28here we have it as a null and that's
  44270. 27:16:29because this is the current information
  44271. 27:16:32it is open and it's not closed yet. So
  44272. 27:16:34in order to select only the current
  44273. 27:16:36informations it is very simple we can
  44274. 27:16:38say brd in dates is null. So if you go
  44275. 27:16:42now and execute it, you will get only
  44276. 27:16:44the current products. You will not have
  44277. 27:16:46any history. And of course we can go and
  44278. 27:16:48add comment to it. Filter out all
  44279. 27:16:51historical data. And this means of
  44280. 27:16:54course we don't need the end date in our
  44281. 27:16:56selection of course because it is always
  44282. 27:16:58a null. So with that we have only the
  44283. 27:17:01current data. Now the next step is that
  44284. 27:17:03we have to go and join it with the
  44285. 27:17:05product categories from the ERP. And
  44286. 27:17:07we're going to use here the ID. So as
  44287. 27:17:10usual the master information is the CRM
  44288. 27:17:13and everything else going to be
  44289. 27:17:14secondary. That's why I use the lift
  44290. 27:17:17join just to make sure I'm not losing
  44291. 27:17:19I'm not filtering any data because if
  44292. 27:17:21there is no match then we lose data. So
  44293. 27:17:24lift join silver ERP and the category.
  44294. 27:17:27So let's call it PC. And now what we're
  44295. 27:17:30going to do we're going to go and join
  44296. 27:17:31it using the key. So en from the CRM we
  44297. 27:17:35have the category ID equal to PC ID. And
  44298. 27:17:39now we have to go and pick columns from
  44299. 27:17:40the second table. So it's going to be
  44300. 27:17:43the PC. We have the category very
  44301. 27:17:45important PC. We have the
  44302. 27:17:48subcategory and we can go and get the
  44303. 27:17:50maintenance. So something like this.
  44304. 27:17:53Let's go and query. And with that we
  44305. 27:17:55have all those columns comes from the
  44306. 27:17:58first table and those three comes from
  44307. 27:18:00the second. So with that we have
  44308. 27:18:01collected all the product informations
  44309. 27:18:04from the two source systems. Now the
  44310. 27:18:06next step is we have to go and check the
  44311. 27:18:08quality of these results. And of course
  44312. 27:18:10what is very important is to check the
  44313. 27:18:13uniqueness. So what we're going to do
  44314. 27:18:14we're going to go and have the following
  44315. 27:18:16query. I want to make sure that the
  44316. 27:18:19product key is
  44317. 27:18:21unique because we're going to use it
  44318. 27:18:23later in order to join the table with
  44319. 27:18:25the sales. So
  44320. 27:18:27from and then we have to have group by
  44321. 27:18:30product key and we're going to say
  44322. 27:18:32having
  44323. 27:18:33counts higher than one. So let's go and
  44324. 27:18:37check. Perfect. We don't have any
  44325. 27:18:38duplicates. The second table didn't
  44326. 27:18:41cause any duplicates for our join. And
  44327. 27:18:43as well this means we don't have
  44328. 27:18:45historical data and each product is only
  44329. 27:18:47one records and we don't have any
  44330. 27:18:49duplicates. So I'm really happy about
  44331. 27:18:52that. So let's go and query again. Now,
  44332. 27:18:54of course, the next step, do we have
  44333. 27:18:56anything to integrate together? Do we
  44334. 27:18:58have the same information twice? Well,
  44335. 27:19:00we don't have that. The next step is
  44336. 27:19:02that we're going to go and group up the
  44337. 27:19:04relevant informations together. So, I'm
  44338. 27:19:06going to say the product ID, then the
  44339. 27:19:09product key, and the product name are
  44340. 27:19:11together. So, all those three
  44341. 27:19:13informations are together. And after
  44342. 27:19:15that, we can put all the category
  44343. 27:19:17informations together. So, we're going
  44344. 27:19:18to have the category ID, the category
  44345. 27:19:21itself, the subcategory. Let me just
  44346. 27:19:23query and see the results. So we have
  44347. 27:19:25the product ID key name and then we have
  44348. 27:19:28the category ID name and the subcategory
  44349. 27:19:31and then maybe as well to put the
  44350. 27:19:33maintenance after the subcategory like
  44351. 27:19:36this and I think the product cost and
  44352. 27:19:38the line can start could stay at the
  44353. 27:19:40end. So let me just check. So those
  44354. 27:19:42three four informations about the
  44355. 27:19:44category and then we have the cost line
  44356. 27:19:46and the start date. I'm really happy
  44357. 27:19:48with that. The next step we're going to
  44358. 27:19:49go and give nice names, friendly names
  44359. 27:19:52for those columns. So let's start with
  44360. 27:19:54the first one. This is the product ID.
  44361. 27:19:57The next one going to be the product
  44362. 27:19:59number. We need the key for the
  44363. 27:20:01surrogate key later. And then we have
  44364. 27:20:04the product name. And after that we have
  44365. 27:20:07the category ID and the category. And
  44366. 27:20:11this is the subcategory. And then the
  44367. 27:20:14next one going to stay as it is. I don't
  44368. 27:20:16have to rename it. The next one going to
  44369. 27:20:18be the cost and the product line and the
  44370. 27:20:22last one going to be the start stage. So
  44371. 27:20:25let's go and execute it. Now we can see
  44372. 27:20:27very nicely in the output all those
  44373. 27:20:29friendly names for the columns and it
  44374. 27:20:32looks way nicer than before. I don't
  44375. 27:20:34have even to describe those informations
  44376. 27:20:36the name describe it. So perfect. Now
  44377. 27:20:38the next big decision is what do we have
  44378. 27:20:40here? Do we have a fact or dimension?
  44379. 27:20:42What do you think? Well, as you can see
  44380. 27:20:44here again, we have a lot of
  44381. 27:20:46descriptions about the products. So all
  44382. 27:20:48those informations are describing the
  44383. 27:20:51business object products. We don't have
  44384. 27:20:53like here transactions, events, a lot of
  44385. 27:20:56different keys and ids. So we don't have
  44386. 27:20:58really here facts. We have a dimension.
  44387. 27:21:01Each row is exactly describing one
  44388. 27:21:03object, describing one product. That's
  44389. 27:21:06why this is a dimension. Okay. So now
  44390. 27:21:08since this is a dimension, we have to go
  44391. 27:21:10and create a primary key for it. Well,
  44392. 27:21:12actually the surrogate key and as we
  44393. 27:21:14have done it for the customers, we're
  44394. 27:21:16going to go and use the window function
  44395. 27:21:18row number in order to generate it over
  44396. 27:21:21and then we have to sort the data. I
  44397. 27:21:22will go with the start date. So let's go
  44398. 27:21:25with the start dates and as well the
  44399. 27:21:28product key and we're going to give it a
  44400. 27:21:31name products key like this. So let's go
  44401. 27:21:35and execute it. With that, we have now
  44402. 27:21:37generated a primary key for each product
  44403. 27:21:40and we're going to be using it in order
  44404. 27:21:42to connect our data model. All right.
  44405. 27:21:44Now, the next step with that, we're
  44406. 27:21:45going to go and build the view. So,
  44407. 27:21:47we're going to say create view. We're
  44408. 27:21:50going to say gold and dimension products
  44409. 27:21:53and then us. So, let's go and create our
  44410. 27:21:56object. And now, if you go and refresh
  44411. 27:21:58the views, you will see our second
  44412. 27:22:00object, the second dimension. So, we
  44413. 27:22:02have here in the gold layer the
  44414. 27:22:04dimension products. And as usual, we're
  44415. 27:22:06going to go and have a look to this view
  44416. 27:22:09just to make sure that everything is
  44417. 27:22:10fine. So dem products. So let's execute
  44418. 27:22:14it. And by looking to the data
  44419. 27:22:16everything looks nice. So with that we
  44420. 27:22:18have now two
  44421. 27:22:23dimensions. All right friends. So with
  44422. 27:22:25that we have covered a lot of stuff. So
  44423. 27:22:27we have covered the customers and the
  44424. 27:22:29products and we are left with only one
  44425. 27:22:31table where we have the transactions the
  44426. 27:22:33sales and for the sales information we
  44427. 27:22:36have only data from the CRM. We don't
  44428. 27:22:37have anything from the ERP. So let's go
  44429. 27:22:39and build it. Okay. So now I have all
  44430. 27:22:41those informations and now of course we
  44431. 27:22:43have only one table. We don't have to do
  44432. 27:22:45any integrations and so on. And now we
  44433. 27:22:47have to answer the big question. Do we
  44434. 27:22:48have here a dimension or a fact? Well by
  44435. 27:22:51looking to those details we can see
  44436. 27:22:53transactions. We can see events. We have
  44437. 27:22:55a lot of dates, informations. We have as
  44438. 27:22:58well a lot of measures and metrics and
  44439. 27:23:00as well we have a lot of ids. So it is
  44440. 27:23:03connecting multiple dimensions. And this
  44441. 27:23:05is exactly a perfect setup for effect.
  44442. 27:23:08So we're going to go and use those
  44443. 27:23:09informations as a facts. And of course
  44444. 27:23:11as we learned a fact is connecting
  44445. 27:23:13multiple dimensions. We have to present
  44446. 27:23:16in this fact the surrogate keys that
  44447. 27:23:18comes from the dimensions. So those two
  44448. 27:23:20informations the product key and the
  44449. 27:23:23customer ID those informations comes
  44450. 27:23:25from the source system and as we learned
  44451. 27:23:27we want to connect our data model using
  44452. 27:23:29the surrogate keys. So what we're going
  44453. 27:23:31to do we're going to replace those two
  44454. 27:23:32informations with the surrogate keys
  44455. 27:23:34that we have generated and in order to
  44456. 27:23:36do that we have to go and join now the
  44457. 27:23:39two dimensions in order to get the
  44458. 27:23:42surrogate key and we call this process
  44459. 27:23:44of course data lookup. So we are joining
  44460. 27:23:46the tables in order only to get one
  44461. 27:23:48information. So let's go and do that. We
  44462. 27:23:50will go with a lift join of course not
  44463. 27:23:52to lose any transaction. So first we're
  44464. 27:23:55going to go and join it with the product
  44465. 27:23:56key. Now of course in the silver layer
  44466. 27:23:58we don't have any surrogate keys. We
  44467. 27:24:01have it in the gold layer. So that means
  44468. 27:24:03for the fact table we're going to be
  44469. 27:24:05joining the silver layer together with
  44470. 27:24:07the gold layer. So, gold dots and then
  44471. 27:24:09the dimension products and I'm going to
  44472. 27:24:12just call it PR. And we're going to join
  44473. 27:24:15the SD using the product key together
  44474. 27:24:18with the product
  44475. 27:24:20number from the dimension. And now the
  44476. 27:24:23only information that we need from the
  44477. 27:24:25dimension is the key, the surrogate key.
  44478. 27:24:28So, we're going to go over here and say
  44479. 27:24:30product key. And what I'm going to do,
  44480. 27:24:32I'm going to go and remove this
  44481. 27:24:34information from here because we don't
  44482. 27:24:36need it. We don't need the original
  44483. 27:24:37product key from the source system. We
  44484. 27:24:39need the surrogate key that we have
  44485. 27:24:41generated in our own in this data
  44486. 27:24:42warehouse. So the same thing going to
  44487. 27:24:44happen as well for the customer. So gold
  44488. 27:24:48dimension customer again we are doing
  44489. 27:24:51here a lookup in order to get the
  44490. 27:24:53information on SD. So we are joining
  44491. 27:24:56using this ID over here equal to the
  44492. 27:25:01customer ID because this is a customer
  44493. 27:25:03ID. And what we're going to do the same
  44494. 27:25:06thing we need the surrogate key the
  44495. 27:25:09customer key and we're going to delete
  44496. 27:25:11the ID because we don't need it. Now we
  44497. 27:25:12have the surrogate key. So now let's go
  44498. 27:25:14and execute it. And now with that we
  44499. 27:25:17have in our fact table the two keys from
  44500. 27:25:19the dimensions. And now this can help us
  44501. 27:25:21to connect the data model to connect the
  44502. 27:25:24facts with the dimensions. So this is
  44503. 27:25:26very necessary step building the fact
  44504. 27:25:28table. You have to put the surrogate
  44505. 27:25:30keys from the dimensions in the facts.
  44506. 27:25:32So that was actually the hardest part
  44507. 27:25:34building the facts. Now the next step
  44508. 27:25:36all what you have to do is to go and
  44509. 27:25:37give friendly names. So we're going to
  44510. 27:25:39go over here and say order number. Then
  44511. 27:25:42the surrogate keys are already friendly.
  44512. 27:25:44So we're going to go over here and say
  44513. 27:25:46this is the order date. And the next one
  44514. 27:25:49going to be shipping date. And then the
  44515. 27:25:53next one due age and the sales going to
  44516. 27:25:56be I'm going to say sales
  44517. 27:25:59amount the
  44518. 27:26:01quantity and the final one is the price.
  44519. 27:26:05So now let's go and execute it and look
  44520. 27:26:07to the results. So now as you can see
  44521. 27:26:09the columns looks very friendly and now
  44522. 27:26:11about the order of the columns we use
  44523. 27:26:13the following schema. So first in the
  44524. 27:26:15fact table we have all the surrogate
  44525. 27:26:17keys from the dimensions. Then second we
  44526. 27:26:19have all the dates and at the end you
  44527. 27:26:22group up all the measures and the
  44528. 27:26:24metrics at the end of the fact. So
  44529. 27:26:26that's it for the query for the facts.
  44530. 27:26:28Now we can go and build it. So we're
  44531. 27:26:30going to say
  44532. 27:26:31create view gold in the gold layer and
  44533. 27:26:35this time we're going to use the fact
  44534. 27:26:37underscore and we're going to go and
  44535. 27:26:38call it sales and then don't forget
  44536. 27:26:40about the ass. So that's it. Let's go
  44537. 27:26:42and create it. Perfect. Now we can see
  44538. 27:26:45the fact. So with that we have three
  44539. 27:26:47objects in the go there. We have two
  44540. 27:26:49dimensions and one facts. And now of
  44541. 27:26:51course the next step with that we're
  44542. 27:26:52going to go and check the quality of the
  44543. 27:26:55view. So let's have a simple
  44544. 27:26:58select fact sales. So let's execute it.
  44545. 27:27:02Now by checking the result you can see
  44546. 27:27:03it is exactly like the result from the
  44547. 27:27:06query and everything looks nice. Okay.
  44548. 27:27:08So now one more trick that I usually do
  44549. 27:27:10after building effect is try to connect
  44550. 27:27:13the whole data model in order to find
  44551. 27:27:14any issues. So let's go and do that. We
  44552. 27:27:16will do just simple lift join with the
  44553. 27:27:19dimensions. So gold dimension customers
  44554. 27:27:23see and we will use the
  44555. 27:27:28keys and then we're going to say where
  44556. 27:27:31customer key is null. So there is no
  44557. 27:27:33matching. So let's go and execute it.
  44558. 27:27:36And with that as you can see in the
  44559. 27:27:37results we are not getting anything that
  44560. 27:27:39means everything is matching perfectly
  44561. 27:27:42and we can do as well the same thing
  44562. 27:27:44with the products. So left join called
  44563. 27:27:48then products p on product key and then
  44564. 27:27:53we connect it with the fact product key
  44565. 27:27:56and then we going go and check the
  44566. 27:27:58product key from the dimension like
  44567. 27:28:00this. So we are checking whether we can
  44568. 27:28:02connect the fact together with the
  44569. 27:28:04dimension products. Let's go and check
  44570. 27:28:06and as you can see as well we are not
  44571. 27:28:08getting anything and this is all right.
  44572. 27:28:09So with that we have now SQL codes that
  44573. 27:28:12is tested and as well creating the gold
  44574. 27:28:15layer. Now in the next step as you know
  44575. 27:28:17in our requirements we have to make
  44576. 27:28:19clear documentations for the end users
  44577. 27:28:21in order to use our data model. So let's
  44578. 27:28:23go and draw a data model of the star
  44579. 27:28:28schema. So let's go and draw our data
  44580. 27:28:31model. Let's go and search for a table.
  44581. 27:28:34And now what I'm going to do, I'm going
  44582. 27:28:35to go and take this one where I can say
  44583. 27:28:37what is the primary key and what is the
  44584. 27:28:40foreign key. And I'm going to go and
  44585. 27:28:41change a little bit the design. So it's
  44586. 27:28:43going to be rounded. And let's say I'm
  44587. 27:28:45going to go and change to this color.
  44588. 27:28:46And maybe go to the size, make it 16.
  44589. 27:28:49And then I'm going to go and select all
  44590. 27:28:51the columns and make it as well 16 just
  44591. 27:28:54to increase the size. And then go to our
  44592. 27:28:57range and we can go and increase it 39.
  44593. 27:29:00So now let's go and zoom in a little bit
  44594. 27:29:02for the first table. Let's go and call
  44595. 27:29:04it gold dimension customers and make it
  44596. 27:29:08a little bit bigger like this. And now
  44597. 27:29:10we're going to go and define here the
  44598. 27:29:11primary key. It is the customer key. And
  44599. 27:29:14what else we're going to do? We're going
  44600. 27:29:15to go and list all the columns in the
  44601. 27:29:16dimension. It is a little bit annoying
  44602. 27:29:18but the result is going to be awesome.
  44603. 27:29:19So what do we have? The customer ID. We
  44604. 27:29:21have the customer number and then we
  44605. 27:29:25have the first name. Now in case you
  44606. 27:29:28want a new rows so you can hold control
  44607. 27:29:31and enter and you can go and add the
  44608. 27:29:33other columns. So now pause the video
  44609. 27:29:35and then go and create the two
  44610. 27:29:36dimensions the customers and the
  44611. 27:29:38products and add all the columns that
  44612. 27:29:40you have built in the
  44613. 27:29:43[Music]
  44614. 27:29:45view. Welcome back. So now I have those
  44615. 27:29:48two dimensions. The third one going to
  44616. 27:29:50be the fact table. Now for the fact
  44617. 27:29:52table I'm going to go with different
  44618. 27:29:54color. for example, the blue and I'm
  44619. 27:29:56going to go and put it in the middle.
  44620. 27:29:58Something like this. So, we're going to
  44621. 27:29:59say gold fact sales and here for that we
  44622. 27:30:04don't have primary key. So, we're going
  44623. 27:30:05to go and delete it. And I have to go
  44624. 27:30:07and add all the columns of the facts.
  44625. 27:30:09So, order number, products key, customer
  44626. 27:30:13key. Okay. All right. Perfect. Now, what
  44627. 27:30:15we can do, we can go and add the foreign
  44628. 27:30:17key information. So, the product key is
  44629. 27:30:19a foreign key for the products. So,
  44630. 27:30:21we're going to say FK1. And the customer
  44631. 27:30:23key going to be the foreign key for the
  44632. 27:30:25customers. So FK2 and of course you can
  44633. 27:30:27go and increase the spacing for that.
  44634. 27:30:30Okay. So now after we have the tables
  44635. 27:30:31the next step in data modeling is to go
  44636. 27:30:34and describe the relationship between
  44637. 27:30:35these tables. This is of course very
  44638. 27:30:37important for reporting and analytics in
  44639. 27:30:39order to understand how I'm going to go
  44640. 27:30:41and use the data model. And we have
  44641. 27:30:43different types of relationships. We
  44642. 27:30:44have one to one, one to many. And in
  44643. 27:30:46star schema data model the relationship
  44644. 27:30:48between the dimension and the fact is
  44645. 27:30:51one to many. And that's because in the
  44646. 27:30:52table customers we have for a specific
  44647. 27:30:55customer only one record describing the
  44648. 27:30:57customer but in the fact table the
  44649. 27:30:59customer might exist in multiple records
  44650. 27:31:01and that's because customers can order
  44651. 27:31:04multiple times. So that's why in fact it
  44652. 27:31:06is many and in the dimension side it is
  44653. 27:31:09one. Now in order to see all those
  44654. 27:31:10relationships we're going to go to the
  44655. 27:31:12menu to the left side and as you can see
  44656. 27:31:13we have here entity relations and now we
  44657. 27:31:16have different types of arrows. So for
  44658. 27:31:18example we have zero to many, one to
  44659. 27:31:20many, one to one and many different
  44660. 27:31:22types of relations. So now which one we
  44661. 27:31:24going to take? We're going to go and
  44662. 27:31:26pick this one. So it says one mandatory.
  44663. 27:31:28So that means the customer must exist in
  44664. 27:31:31the dimension table. Too many but it is
  44665. 27:31:33optional. So here we have three
  44666. 27:31:34scenarios. The customer didn't order
  44667. 27:31:36anything or the customer did order only
  44668. 27:31:38once or the customer did order many
  44669. 27:31:41things. So that's why in the fact table
  44670. 27:31:43it is optional. So we're going to take
  44671. 27:31:45this one and place it over here. So
  44672. 27:31:47we're going to go and connect this part
  44673. 27:31:50to the customer dimension and the many
  44674. 27:31:52parts to the facts. Well actually we
  44675. 27:31:55have to do it on the customers. So with
  44676. 27:31:57that we are describing the relationship
  44677. 27:31:59between the dimensions and fact with one
  44678. 27:32:01to many. One is mandatory for the
  44679. 27:32:03customer dimension and many is optional
  44680. 27:32:06to the facts. So we have the same story
  44681. 27:32:07as well for the products. So the many
  44682. 27:32:10part to the facts and the one goes to
  44683. 27:32:14the products. So it's going to look like
  44684. 27:32:15this. Each time you are connecting new
  44685. 27:32:17dimension to the fact table, it is
  44686. 27:32:19usually one to many relationship. So you
  44687. 27:32:22can go and add anything you want to this
  44688. 27:32:24model like for example a text like
  44689. 27:32:26explaining something. For example, if
  44690. 27:32:27you have some complicated calculations
  44691. 27:32:29and so on, you can go and write this
  44692. 27:32:31information over here. So for example,
  44693. 27:32:33we can say over here sales calculation,
  44694. 27:32:36we can make it a little bit smaller. So
  44695. 27:32:38let's go with 18. So we can go and write
  44696. 27:32:41here the formula for that. So sales
  44697. 27:32:43equal quantity multiplied with the price
  44698. 27:32:47and make this little bit bigger. So it
  44699. 27:32:50is really nice info that we can add it
  44700. 27:32:53to the data model and even we can go and
  44701. 27:32:55link it to the column. So we can go and
  44702. 27:32:57take this arrow for example put it like
  44703. 27:32:59this and link it to the column and with
  44704. 27:33:02that you have as well nice explanation
  44705. 27:33:04about the business rule or the
  44706. 27:33:05calculation. So you can go and add any
  44707. 27:33:07descriptions that you want to the data
  44708. 27:33:09model. Just to make it clear for anyone
  44709. 27:33:11that is using your data model. So with
  44710. 27:33:13that you don't have only like three
  44711. 27:33:15tables in the database. You have as well
  44712. 27:33:17like some kind of documentations and
  44713. 27:33:19explanation. In one click we can see how
  44714. 27:33:21the data model is built and how you can
  44715. 27:33:23connect the tables together. It is
  44716. 27:33:26amazing really for all users of your
  44717. 27:33:27data model. All right. So now with that
  44718. 27:33:29we have really nice data model. And now
  44719. 27:33:32in the next step we're going to go and
  44720. 27:33:33create quickly a data catalog.
  44721. 27:33:39All right, great. So with that we have a
  44722. 27:33:41data model and we can say we have
  44723. 27:33:42something called a data products and we
  44724. 27:33:44will be sharing this data product with
  44725. 27:33:47different types of users and there is
  44726. 27:33:48something that every data products
  44727. 27:33:51absolutely needs and that is the data
  44728. 27:33:53catalog. It is a document that can
  44729. 27:33:55describe everything about your data
  44730. 27:33:57model. columns, the tables, maybe the
  44731. 27:34:00relationship between the tables as well.
  44732. 27:34:02And with that, you make your data
  44733. 27:34:03product clear for everyone. And it's
  44734. 27:34:05going to be for them way easier to
  44735. 27:34:06derive more insights and reports from
  44736. 27:34:09your data product. And what is the most
  44737. 27:34:11important one? It is time-saving because
  44738. 27:34:14if you don't do that, what's going to
  44739. 27:34:15happen? Each consumer, each user of your
  44740. 27:34:17data product will keep asking you the
  44741. 27:34:19same questions about what do you mean
  44742. 27:34:21with this column? What is this table?
  44743. 27:34:23How to connect the table A with the
  44744. 27:34:24table P? and you will keep repeating
  44745. 27:34:26yourself and explaining stuff. So
  44746. 27:34:28instead of that you prepare a data
  44747. 27:34:30catalog, a data model and you deliver
  44748. 27:34:32everything together to the users and
  44749. 27:34:34with that you are saving a lot of time
  44750. 27:34:36and stress. I know it is annoying to
  44751. 27:34:38create a data catalog but it is
  44752. 27:34:40investments and best practices. So now
  44753. 27:34:42let's go and create one. Okay. So now in
  44754. 27:34:44order to do that I have created a new
  44755. 27:34:45file called data catalog in the folder
  44756. 27:34:48documents. And here what we're going to
  44757. 27:34:49do is very straightforward. We're going
  44758. 27:34:50to make a section for each table in the
  44759. 27:34:52code layer. So for example we have here
  44760. 27:34:54the table dimension customers. What you
  44761. 27:34:56have to do first is to describe this
  44762. 27:34:58table. So we are saying it stores
  44763. 27:35:00details about the customers with the
  44764. 27:35:02demographics and geographics data. So
  44765. 27:35:04you give a short description for the
  44766. 27:35:06table and then after that you're going
  44767. 27:35:07to go and list all your columns inside
  44768. 27:35:09this table and maybe as well the data
  44769. 27:35:11type. But what is way important is the
  44770. 27:35:13description for each column. So you give
  44771. 27:35:15a very short description like for
  44772. 27:35:17example here the gender of the customer.
  44773. 27:35:19And now one of the best practices of
  44774. 27:35:21describing a column is to give examples
  44775. 27:35:23because you can understand quickly the
  44776. 27:35:25purpose of the columns by just seeing an
  44777. 27:35:27example. Right? So here we are saying we
  44778. 27:35:29can find inside the male, female and not
  44779. 27:35:32available. So with that the consumer of
  44780. 27:35:33your table can immediately understand uh
  44781. 27:35:35it will not be an M or an F. It's going
  44782. 27:35:38to be a full friendly value without
  44783. 27:35:40having them to go and query the content
  44784. 27:35:41of the table. They can understand
  44785. 27:35:43quickly the purpose of that column. So
  44786. 27:35:45with that we have a full description for
  44787. 27:35:46all the columns of our dimension. The
  44788. 27:35:49same thing we're going to do for the
  44789. 27:35:50products. So again, a description for
  44790. 27:35:52the table and as well a description for
  44791. 27:35:54each column and the same thing for the
  44792. 27:35:56facts. So that's it. With that you have
  44793. 27:35:58like a data catalog for your data
  44794. 27:36:00products at the code layer. And with
  44795. 27:36:02that the business user or the data
  44796. 27:36:04analyst have better and clear
  44797. 27:36:05understanding of the content of your
  44798. 27:36:07code layer. All right my friends. So
  44799. 27:36:09that's all for the data catalog. In the
  44800. 27:36:11next step we're going to go back to DO
  44801. 27:36:13where we're going to finalize the data
  44802. 27:36:15flow diagram. So let's go.
  44803. 27:36:21Okay. So now we're going to go and
  44804. 27:36:22extend our data flow diagram, but this
  44805. 27:36:25time for the gold layer. So now let's go
  44806. 27:36:27and copy the whole thing from the silver
  44807. 27:36:29layer and put it over here side by side.
  44808. 27:36:31And of course we're going to go and
  44809. 27:36:33change the coloring to the gold. And now
  44810. 27:36:35we're going to go and rename stuff. So
  44811. 27:36:38this is the gold layer. But now of
  44812. 27:36:40course we cannot leave those tables like
  44813. 27:36:42this. We have completely new data model.
  44814. 27:36:44So what do we have over here? We have
  44815. 27:36:46the fact sales, we have dimension
  44816. 27:36:50customers, and as well we have dimension
  44817. 27:36:53products. So now what I'm going to do,
  44818. 27:36:55I'm going to go and remove all those
  44819. 27:36:56stuff. We have only three tables. And
  44820. 27:36:58let's go and put those three tables
  44821. 27:37:00somewhere here in the center. So now
  44822. 27:37:02what you have to do is to go and start
  44823. 27:37:03connecting those stuff. I'm going to go
  44824. 27:37:05with this arrow over here, direct
  44825. 27:37:07connection, and start connecting stuff.
  44826. 27:37:10So the sales details goes to the fact
  44827. 27:37:12table. Maybe put the fact table over
  44828. 27:37:14here. And then we have the dimension
  44829. 27:37:16customer. This comes from the CRM
  44830. 27:37:19customer info. And we have two tables
  44831. 27:37:22from the ERP. It comes from this table
  44832. 27:37:24as well. And the location from the ERP.
  44833. 27:37:27Now the same thing goes for the
  44834. 27:37:30products. It comes from the product info
  44835. 27:37:32and comes from the categories from the
  44836. 27:37:35ERP. Now, as you can see here, we have
  44837. 27:37:37cross arrows. So what you can do, we can
  44838. 27:37:38go and select everything and we can say
  44839. 27:37:40line jumps with a gap. And this makes it
  44840. 27:37:43a little bit like better in the visual
  44841. 27:37:45for the arrows. So now for example if
  44842. 27:37:47someone asks you where the data come
  44843. 27:37:49from for the dimension products you can
  44844. 27:37:51open this diagram and tell them okay
  44845. 27:37:53this comes from the server layer. We
  44846. 27:37:55have like two tables. The product info
  44847. 27:37:57from the CRM and as well the categories
  44848. 27:38:00from the ERP and those several tables
  44849. 27:38:02comes from the bronze layer and you can
  44850. 27:38:04see the product info comes from the CRM
  44851. 27:38:06and the category comes from the ERP. So
  44852. 27:38:09it is very simple. We have just created
  44853. 27:38:11a full data lineage for our data
  44854. 27:38:12warehouse from the sources into the
  44855. 27:38:15different layers in our data warehouse
  44856. 27:38:16and data lineage is this really amazing
  44857. 27:38:18documentation that can help not only
  44858. 27:38:20your users but as well the developers.
  44859. 27:38:22All right. So with that we have very
  44860. 27:38:23nice data flow diagram and a data
  44861. 27:38:25lineage. All right. So we have completed
  44862. 27:38:27the data flow. It's really feel like
  44863. 27:38:29progress like achievements as we are
  44864. 27:38:31clicking through all those tasks. And
  44865. 27:38:33now we come to the last task in building
  44866. 27:38:35the data warehouse where we're going to
  44867. 27:38:37go and commit our work in the get
  44868. 27:38:42repo. Okay. So now let's put our scripts
  44869. 27:38:44in the project. So we're going to go to
  44870. 27:38:46the scripts over here. We have here
  44871. 27:38:48bronze silver but we don't have a gold.
  44872. 27:38:49So let's go and create a new file. We're
  44873. 27:38:51going to have gold/ and then we're going
  44874. 27:38:53to say ddl gold.sql. So now we're going
  44875. 27:38:56to go and paste our views. So we have
  44876. 27:38:59here our three views. And as usual at
  44877. 27:39:01the start we can describe the purpose of
  44878. 27:39:03the views. So we are saying create gold
  44879. 27:39:05views. This script can go and create
  44880. 27:39:07views for the code layer and the code
  44881. 27:39:09layer represent the final dimension and
  44882. 27:39:11fact tables. The star schema each view
  44883. 27:39:13perform transformations and combination
  44884. 27:39:15data from the server layer to produce
  44885. 27:39:17business ready data sets and those views
  44886. 27:39:19can be used for analytics and reporting.
  44887. 27:39:21So that's it. Let's go and commit it.
  44888. 27:39:24Okay. So with that as you can see we
  44889. 27:39:26have the bronze the silver. So we have
  44890. 27:39:28all our ETLs and scripts in the
  44891. 27:39:31repository. And now as well for the code
  44892. 27:39:33layer, we're going to go and add all
  44893. 27:39:35those quality checks that we have used
  44894. 27:39:37in order to validate the dimensions and
  44895. 27:39:39facts. So we're going to go to the test
  44896. 27:39:41over here and we're going to go and
  44897. 27:39:42create a new file. It's going to be
  44898. 27:39:44quality checks gold and the file type is
  44899. 27:39:47SQL. So now let's go and paste our
  44900. 27:39:50quality checks. So we have the check for
  44901. 27:39:51the fact, the two dimensions and as well
  44902. 27:39:54an explanation about the script. So we
  44903. 27:39:56are validating the integrity and the
  44904. 27:39:58accuracy of the go layer. And here we
  44905. 27:40:00are checking the uniqueness of the
  44906. 27:40:01surrogate keys and whether we are able
  44907. 27:40:03to connect the data model. So let's put
  44908. 27:40:05that as well in our git and commit the
  44909. 27:40:08changes. And in case we come up with a
  44910. 27:40:09new quality checks, we're going to go
  44911. 27:40:11and add it to our script here. So those
  44912. 27:40:13checks are really important if you are
  44913. 27:40:15modifying the ATLs or you want to make
  44914. 27:40:17sure that after each those script should
  44915. 27:40:19run and so on. It is like a quality gate
  44916. 27:40:22to make sure that everything is fine in
  44917. 27:40:24the gold layer. Perfect. So now we have
  44918. 27:40:26our code in our repository. Okay
  44919. 27:40:28friends. So now what you have to do is
  44920. 27:40:30to go and finalize the get repo. So for
  44921. 27:40:32example all the documentations that we
  44922. 27:40:34have created during the projects we can
  44923. 27:40:37go and upload them in the docs. So for
  44924. 27:40:38example you can see here the data
  44925. 27:40:40architecture the data flow data
  44926. 27:40:42integration data model and so on. So
  44927. 27:40:44that each time you edit those pages you
  44928. 27:40:46can commit your work and you have like a
  44929. 27:40:48version of that. And another thing that
  44930. 27:40:50you can do is that you go to the readme
  44931. 27:40:53like for example over here I have added
  44932. 27:40:54the project overview some important
  44933. 27:40:56links and as well the data architecture
  44934. 27:40:59and a little description of the
  44935. 27:41:00architecture of course and of course
  44936. 27:41:02don't forget to add few words about
  44937. 27:41:04yourself and important profiles in the
  44938. 27:41:06different social medias. All right my
  44939. 27:41:08friends. So with that we have committed
  44940. 27:41:09our work and as well closed the last
  44941. 27:41:12epic building the god layer and with
  44942. 27:41:14that we have completed all the phases of
  44943. 27:41:17building a data warehouse. Everything is
  44944. 27:41:19100% and this feels really nice. All
  44945. 27:41:22right my friends. So with that we have
  44946. 27:41:23covered the first type of SQL projects
  44947. 27:41:26that data warehousing projects. This is
  44948. 27:41:28usually a very complex project that you
  44949. 27:41:30can get involved in a company and this
  44950. 27:41:32is really amazing project if you are
  44951. 27:41:33planning to be a data engineer. But of
  44952. 27:41:35course, if you are a data analyst, you
  44953. 27:41:37might end up as well building
  44954. 27:41:38warehouses. So now we have everything
  44955. 27:41:40prepared for the second type of projects
  44956. 27:41:42in SQL. We will deep dive now into the
  44957. 27:41:44exploratory data analyzers. So let's
  44958. 27:41:50go. And now here we're going to cover
  44959. 27:41:52the second type of projects where we're
  44960. 27:41:54going to use our basic SQL skills in
  44961. 27:41:56order to do something called data
  44962. 27:41:58profiling where we're going to try to
  44963. 27:41:59understand all the aspects of our data
  44964. 27:42:02sets using simple aggregations like the
  44965. 27:42:04sum, average, count and as well we will
  44966. 27:42:06be using techniques like some
  44967. 27:42:08[Music]
  44968. 27:42:11queries. All right my friends. So the
  44969. 27:42:13first step in any data project is that
  44970. 27:42:15we need data sets. If you have done the
  44971. 27:42:17previous project where we have built the
  44972. 27:42:19SQL data warehouse, then you have
  44973. 27:42:21everything the data and the database. So
  44974. 27:42:23you don't have to worry about it. But if
  44975. 27:42:25you skip that, which I don't recommend,
  44976. 27:42:27I still have prepared for you the files
  44977. 27:42:29and the database. So let's get the data
  44978. 27:42:31and create our database. All right. So
  44979. 27:42:32now if you go to the link in the
  44980. 27:42:34description, we're going to go to the
  44981. 27:42:35downloads. And of course, you can
  44982. 27:42:37subscribe to my newsletter. And then
  44983. 27:42:39here we have the SQL course materials.
  44984. 27:42:41And here we have a link for data
  44985. 27:42:42analytics projects. Let's go to the
  44986. 27:42:44link. And now here you have some
  44987. 27:42:45important links like downloading the
  44988. 27:42:47server the management studio where we're
  44989. 27:42:49going to write our SQLs and as well
  44990. 27:42:51there is a link to the g repository and
  44991. 27:42:53as well what is very important is to
  44992. 27:42:55download all the project files. So click
  44993. 27:42:57on that and download all the files. Now
  44994. 27:42:59extract the file and put it somewhere
  44995. 27:43:01safe at your PC and now inside it you
  44996. 27:43:03can find all the scripts and the data
  44997. 27:43:04sets. Now there is like three ways on
  44998. 27:43:06how to create the database in SQL
  44999. 27:43:08server. So the first one is by executing
  45000. 27:43:11scripts. If you go to the scripts over
  45001. 27:43:12here, the first one we have a file
  45002. 27:43:14called init database. Just go inside it
  45003. 27:43:17and copy the whole thing and then let's
  45004. 27:43:19go to SQL server. Now make a new query
  45005. 27:43:22and make sure you switch to the master
  45006. 27:43:25database and then paste the whole code.
  45007. 27:43:27So now what you are doing here is we are
  45008. 27:43:29creating a new database. We are creating
  45009. 27:43:31a schema and then three very important
  45010. 27:43:34tables that we're going to use in our
  45011. 27:43:36data analyzes. Now there is like only
  45012. 27:43:38one thing that you have to change in
  45013. 27:43:39this script and that is the path of the
  45014. 27:43:42files. And once you have done that just
  45015. 27:43:44go and execute the whole script. And now
  45016. 27:43:47as you can see everything is done and
  45017. 27:43:48there is like data inserted. Now if you
  45018. 27:43:50go to the left side to the database and
  45019. 27:43:52refresh you can find a new database
  45020. 27:43:55called data warehouse analytics. And if
  45021. 27:43:57you go inside the tables you will find
  45022. 27:44:00our three tables customer products and
  45023. 27:44:02sales. So this is one way on how to
  45024. 27:44:04create the database. The second methods
  45025. 27:44:06is to go to the databases over here.
  45026. 27:44:08Right click on it and say new database.
  45027. 27:44:11And for example, let's call it data
  45028. 27:44:13warehouse analytics. I'm going to call
  45029. 27:44:15it two because I have already one. And
  45030. 27:44:17then click okay. And with that you have
  45031. 27:44:19a new database. So what we're going to
  45032. 27:44:21do now, we're going to right click on it
  45033. 27:44:23and then go to tasks and then import
  45034. 27:44:26flat file. And now what we're going to
  45035. 27:44:27do, we're going to go and import the CSV
  45036. 27:44:30files to our new database. So we can go
  45037. 27:44:32next and then you have to go and locate
  45038. 27:44:34your files. I have them somewhere over
  45039. 27:44:37here. So data set CSV files and we have
  45040. 27:44:40to focus on the gold tables. So I'm
  45041. 27:44:43going to go and select this one and then
  45042. 27:44:44next. Now I'm just getting an overview
  45043. 27:44:46of my data. So next. Now just to make
  45044. 27:44:49sure that you are not getting any error,
  45045. 27:44:51I'm going to go and allow nulls and
  45046. 27:44:53that's all. So next and finish. So
  45047. 27:44:56perfect. The data has been inserted. Now
  45048. 27:44:58let's go to our database tables. And as
  45049. 27:45:01you can see, we have here our new table.
  45050. 27:45:03So you have to go and repeat this three
  45051. 27:45:05times in order to import the data. Well,
  45052. 27:45:07you can use this method if the first
  45053. 27:45:09method didn't work. But I really
  45054. 27:45:10recommend you to use the script in order
  45055. 27:45:12to create the database. The third way is
  45056. 27:45:14to go and restore the database itself.
  45057. 27:45:17Now how we're going to do it? We're
  45058. 27:45:18going to go again to the data sets and
  45059. 27:45:20as you can see we have here a database
  45060. 27:45:22backup. So as you can see we have here a
  45061. 27:45:24PAK file. So now what you have to do is
  45062. 27:45:26to go and copy that and then we're going
  45063. 27:45:28to go to the database location. So it
  45064. 27:45:30really depend where you have installed
  45065. 27:45:32the SQL server. So currently I have it
  45066. 27:45:34here program files Microsoft SQL server
  45067. 27:45:36and then the express MSSQL backup and
  45068. 27:45:40you have to place the file over here. So
  45069. 27:45:42I have it here data warehouse analytics
  45070. 27:45:44backup. And now all what you have to do
  45071. 27:45:45is to right click on the database and
  45072. 27:45:47then say restore database and then we're
  45073. 27:45:50going to go to the device three points
  45074. 27:45:52and we're going to say add. And now you
  45075. 27:45:54can see our database data warehouse
  45076. 27:45:56analytics. Once we say okay and then
  45077. 27:45:58okay and now since I have it already I
  45078. 27:46:01will get an error but once I click okay
  45079. 27:46:03the whole database can be restored
  45080. 27:46:05without running any scripts. So those
  45081. 27:46:07are the three ways on how to create the
  45082. 27:46:10database of the projects and if you have
  45083. 27:46:11built with me the data warehouse
  45084. 27:46:13projects before you don't have to do it
  45085. 27:46:14because we have built that together. So
  45086. 27:46:17pause the video and get the data for the
  45087. 27:46:23projects. All right my friends. So we're
  45088. 27:46:25going to start with a secret, a little
  45089. 27:46:27trick that I usually do by analyzing any
  45090. 27:46:30data sets. So let's start with little
  45091. 27:46:31coffee before we start. H this is really
  45092. 27:46:35hot. Okay. So the secret says as I'm
  45093. 27:46:37looking to any data sets in any
  45094. 27:46:39projects, I see the data always divided
  45095. 27:46:41between dimensions and measures.
  45096. 27:46:45What truth? You take the blue pill, you
  45097. 27:46:48take the red pill. All I'm offering is
  45098. 27:46:51the truth. Nothing more.
  45099. 27:46:54If you see your data like me as
  45100. 27:46:55dimensions and measures, you can
  45101. 27:46:58generate like endless amount of insights
  45102. 27:47:01from any projects from any data sets and
  45103. 27:47:03you will find me through the projects
  45104. 27:47:05that I'm always speaking about measures
  45105. 27:47:07and dimensions. So I'm going to show you
  45106. 27:47:09how I usually do it. So now usually by
  45107. 27:47:11looking to any data sets in any
  45108. 27:47:12projects. So you have like multiple
  45109. 27:47:14columns and rows here I see the data
  45110. 27:47:16always splitted into two categories
  45111. 27:47:18either a dimension or a measure. And now
  45112. 27:47:21of course the question is here is my
  45113. 27:47:23column a dimension or a measure? Well in
  45114. 27:47:26order to assign it to one of those
  45115. 27:47:27categories you have to ask the first
  45116. 27:47:30question is it a numeric value? If it's
  45117. 27:47:32not so you have like string or date or
  45118. 27:47:35any other data type then it is a
  45119. 27:47:36dimension and if it is yes in numeric
  45120. 27:47:39then you have to ask the second question
  45121. 27:47:42does it make sense to aggregate it. So
  45122. 27:47:44if the answer for both questions is yes,
  45123. 27:47:46it is numeric and it makes sense to
  45124. 27:47:49aggregate it then it is a measure
  45125. 27:47:51otherwise it is a dimension. Now let's
  45126. 27:47:53practice and have some examples. So now
  45127. 27:47:55by looking to the values of the column
  45128. 27:47:57category you can see all the values are
  45129. 27:47:59characters. So it is not numeric that
  45130. 27:48:02means this column is a dimension. So it
  45131. 27:48:04is very simple. Let's take another
  45132. 27:48:06column. We have the sales amount. So now
  45133. 27:48:08as you can see the values are numeric
  45134. 27:48:09and as well it makes sense to aggregate
  45135. 27:48:12those values. we can get the total sales
  45136. 27:48:14or the average sales and so on. So it
  45137. 27:48:16fulfill both of the conditions. It is
  45138. 27:48:18numeric and it makes sense to aggregate
  45139. 27:48:20it. That's why we say sales is a
  45140. 27:48:22measure. Now if you're checking the
  45141. 27:48:24values of the product name, you can see
  45142. 27:48:26that all of them are characters and
  45143. 27:48:28names. So it is not numeric. That means
  45144. 27:48:30the product is a dimension. Moving on to
  45145. 27:48:32the next one, we have the quantity. The
  45146. 27:48:34values are numeric and as well it makes
  45147. 27:48:36sense to aggregate it. Can summarize all
  45148. 27:48:38those values to have the total quantity.
  45149. 27:48:40So quantity is a measure. Now if you're
  45150. 27:48:42looking to the values of the birth dates
  45151. 27:48:44you can see this is a date information
  45152. 27:48:46it is not numeric so that means it is a
  45153. 27:48:49dimension right but if you calculate the
  45154. 27:48:51age from the birth dates age of the
  45155. 27:48:54customer going to be in numeric and it
  45156. 27:48:56makes sense to aggregate it for example
  45157. 27:48:58finding the average age of customers. So
  45158. 27:49:01if we derive a numeric value from a
  45159. 27:49:04dimension then we can use it as a
  45160. 27:49:06measure. So age is measure and now we
  45161. 27:49:08come to something really tricky. This is
  45162. 27:49:10the ID. So for example if you are
  45163. 27:49:12checking the customer ID you can see all
  45164. 27:49:14those values are numeric. So the first
  45165. 27:49:17condition is fulfilled. Now the very
  45166. 27:49:19important question does it make sense to
  45167. 27:49:21aggregate the ids? Well those ids are
  45168. 27:49:24unique identifier for a customer and if
  45169. 27:49:26you find like the average of that it is
  45170. 27:49:28not like helpful right I cannot think of
  45171. 27:49:31one use case of aggregating the customer
  45172. 27:49:34ID like having the average of all those
  45173. 27:49:36ids or summarizing the ids. So it makes
  45174. 27:49:39no sense to aggregate it. That's why we
  45175. 27:49:42can consider the ID of a customer as a
  45176. 27:49:44dimension not as a measure. So as you
  45177. 27:49:46can see it is very simple. If it is
  45178. 27:49:48numeric and it makes sense to aggregate
  45179. 27:49:50then it is measure otherwise it is a
  45180. 27:49:52dimension. And this is the foundations
  45181. 27:49:55of any data analytics. If you see your
  45182. 27:49:57data as dimensions and measures you can
  45183. 27:50:00generate a lot of use cases and insights
  45184. 27:50:03from your data sets. Now I totally
  45185. 27:50:05understand if you are still confused
  45186. 27:50:06about dimensions and measures and you
  45187. 27:50:08might be asking why do I need measures
  45188. 27:50:10and dimensions. Well if you are doing
  45189. 27:50:12any type of data analysis or you are
  45190. 27:50:14exploring any data sets you will be end
  45191. 27:50:16up always like grouping up the data by
  45192. 27:50:18something like you are grouping the data
  45193. 27:50:20by countries or grouping the data by for
  45194. 27:50:22example products or categories. So we
  45195. 27:50:25need dimensions to group up our data and
  45196. 27:50:28in the other sides you will be asking
  45197. 27:50:30questions like how much how many what is
  45198. 27:50:32the total of something. So you always
  45199. 27:50:34need to aggregate or calculate something
  45200. 27:50:36right and for that you need the measure.
  45201. 27:50:38So we need the measures in order to
  45202. 27:50:40answer the question how many and how
  45203. 27:50:42much and we need the dimensions in order
  45204. 27:50:44to group up the data by something. So
  45205. 27:50:47that's why almost in any type of data
  45206. 27:50:49analyzes you need dimensions and
  45207. 27:50:51measures and this going to be more clear
  45208. 27:50:53as we progress in the projects. All
  45209. 27:50:54right. So now I'm going to walk you
  45210. 27:50:56through the project road map and I have
  45211. 27:50:58split that into six steps. So we're
  45212. 27:51:00going to do different types of
  45213. 27:51:01explorations like the database
  45214. 27:51:03dimensions, measures, dates and we're
  45215. 27:51:05going to do some basics analyszis like
  45216. 27:51:07the magnitude and the ranking. So let's
  45217. 27:51:09start with the first step in our
  45218. 27:51:10projects. We're going to do database
  45219. 27:51:16exploration. So let's say that you have
  45220. 27:51:18joined a team and you got an access to a
  45221. 27:51:20database. The first thing that I usually
  45222. 27:51:22do is that I explore the structure of
  45223. 27:51:24the database just to have basic
  45224. 27:51:26understandings about the database
  45225. 27:51:28tables, the views, columns. Are we
  45226. 27:51:30talking about like 10 tables, hundreds
  45227. 27:51:32of tables? So it is just a few queries
  45228. 27:51:35in order to say hello to the database.
  45229. 27:51:37So now let's go to SQL and explore the
  45230. 27:51:39database of our projects. So now how we
  45231. 27:51:41going to do it? Either you go to the
  45232. 27:51:43left side over here and start clicking
  45233. 27:51:44the objects of your database and explore
  45234. 27:51:47the tables, views, columns and so on. Or
  45235. 27:51:49a better way that I usually do it that I
  45236. 27:51:51explore the database using a query. So
  45237. 27:51:53what we can do, we can go and select
  45238. 27:51:55data from the system tables because the
  45239. 27:51:58database stores metadata informations
  45240. 27:52:01about our tables and objects. So we're
  45241. 27:52:03going to target an information schema.
  45242. 27:52:06This is an internal schema in the
  45243. 27:52:07database where we have like multiple
  45244. 27:52:09tables and views to explore the metadata
  45245. 27:52:12and the structure of our database. So
  45246. 27:52:14for example, we can go with the tables.
  45247. 27:52:16So let's go and create it. And with that
  45248. 27:52:19you have a list of tables and with that
  45249. 27:52:22you can see multiple informations like a
  45250. 27:52:24catalog, the schema and the table names
  45251. 27:52:27and you can see over here the object
  45252. 27:52:28type whether it is a table or a view. If
  45253. 27:52:31you done the data warehouse project with
  45254. 27:52:32me then you will find a lot of tables.
  45255. 27:52:35But if you are just doing the data
  45256. 27:52:37analyzes you will see only those three
  45257. 27:52:40tables. So customers, products and
  45258. 27:52:42sales. So with that we can see in our
  45259. 27:52:44database there are like around 15 tables
  45260. 27:52:47or three tables. Now in the output you
  45261. 27:52:49can see the database name the schema and
  45262. 27:52:52a list of all tables and of course don't
  45263. 27:52:54forget that you are using the database
  45264. 27:52:57that we created. So with that we have a
  45265. 27:52:59nice quick list with all tables inside
  45266. 27:53:01our database. Now the next step we can
  45267. 27:53:03go and drill down and check what are the
  45268. 27:53:05columns that we have inside our
  45269. 27:53:07database. And for that we can as well
  45270. 27:53:08target the same schema. So select star
  45271. 27:53:11from information schema and it is very
  45272. 27:53:14simple. So we're going to go to the
  45273. 27:53:15table columns. So let's go and execute
  45274. 27:53:18it. And now we will see a lot of
  45275. 27:53:20informations over here. So we can see in
  45276. 27:53:22our database we have around 101 columns.
  45277. 27:53:26So that we can see all the columns
  45278. 27:53:28available in our database. And what I
  45279. 27:53:30usually do with that I go and select the
  45280. 27:53:33columns only for specific table. So we
  45281. 27:53:35can say where are table name
  45282. 27:53:38equal let's get for example the
  45283. 27:53:40dimension customers. So let's query the
  45284. 27:53:43whole thing and with that we can see we
  45285. 27:53:46have 10 columns inside this dimension
  45286. 27:53:48and this is how the columns are sorted
  45287. 27:53:50inside our table or view and we can see
  45288. 27:53:52all the metadata informations about each
  45289. 27:53:55column. So now as you can see we are now
  45290. 27:53:57exploring the structure of our database
  45291. 27:54:00and this is really helpful to get an
  45292. 27:54:02overview of the database and the
  45293. 27:54:03projects. Are we talking about like 20
  45294. 27:54:06tables or hundreds of tables? And we can
  45295. 27:54:08quickly see the naming of the columns,
  45296. 27:54:10the tables. This is really important to
  45297. 27:54:13get a feeling about the projects and
  45298. 27:54:15sets the foundations for exploring the
  45299. 27:54:18data inside those tables. All right
  45300. 27:54:20friends, so with that we have done the
  45301. 27:54:21first step. We have explored the
  45302. 27:54:23database structure and now we can start
  45303. 27:54:25diving into the actual data. The first
  45304. 27:54:27thing that we can explore is the
  45305. 27:54:29dimensions.
  45306. 27:54:34Okay. So what we going to do with the
  45307. 27:54:35dimension exploration? All what we have
  45308. 27:54:36to do is to go and identify the unique
  45309. 27:54:39values of each dimension that we have
  45310. 27:54:41inside our database. This can help us to
  45311. 27:54:43understand what are the categories,
  45312. 27:54:45which countries, what are the product
  45313. 27:54:47types that we have inside our database
  45314. 27:54:49and we have a very simple formula for
  45315. 27:54:51that. So all what you need is the SQL
  45316. 27:54:53keyword distinct together with any
  45317. 27:54:55dimension in your data set like distinct
  45318. 27:54:57country, distinct category. So for
  45319. 27:54:59example if you are checking any column
  45320. 27:55:00that is dimension you can see a lot of
  45321. 27:55:02values and repeating stuff but now once
  45322. 27:55:04you say distinct column what going to
  45323. 27:55:06happen you will get a list of all unique
  45324. 27:55:08values and with that you can understand
  45325. 27:55:10quickly I have three different types so
  45326. 27:55:12I have a bc and this as well going to
  45327. 27:55:14help you to understand the granularity
  45328. 27:55:16of your dimension does the dimension has
  45329. 27:55:19like three values or 100 value so it is
  45330. 27:55:21very simple let's go and analyze our
  45331. 27:55:23dimensions okay so now let's explore the
  45332. 27:55:25dimension values inside our database so
  45333. 27:55:27let's start with the first table the
  45334. 27:55:29customers and if you check those columns
  45335. 27:55:31we have to find an interesting dimension
  45336. 27:55:33like for example the country. So now
  45337. 27:55:34what we can do we can go and explore all
  45338. 27:55:36the countries our customers come from.
  45339. 27:55:39So let's go and do that. It is very
  45340. 27:55:41simple. Select distinct and then we have
  45341. 27:55:43our column the dimension country from
  45342. 27:55:45our table customers. So let's go and
  45343. 27:55:48execute it. And with that we can see in
  45344. 27:55:50the result we have six countries. This
  45345. 27:55:52is really nice in order to understand
  45346. 27:55:54the geographical spread. So we have
  45347. 27:55:56customers for our business that comes
  45348. 27:55:58from six different countries. Germany,
  45349. 27:56:00United States, France, Canada and so on.
  45350. 27:56:02So now with that we have like the first
  45351. 27:56:04little insights about our business. Now
  45352. 27:56:06let's jump to another table the
  45353. 27:56:08products. So what we have to do is to
  45354. 27:56:10explore all the categories inside our
  45355. 27:56:12business the major divisions. So we're
  45356. 27:56:14going to say select distinct category
  45357. 27:56:17from our table products. So let's go and
  45358. 27:56:20execute it. Now in the output you can
  45359. 27:56:22see we have four categories. We have the
  45360. 27:56:24accessories, bikes, clothing and
  45361. 27:56:26components. This is like giving us an
  45362. 27:56:28overview of the product range. What are
  45363. 27:56:30the major divisions inside our business?
  45364. 27:56:33Now the next one I'm digging deeper in
  45365. 27:56:35this information. So not only I want to
  45366. 27:56:37see the categories, I would like as well
  45367. 27:56:39to see the
  45368. 27:56:40subcategories. I'm not starting a new
  45369. 27:56:42query because there is of course
  45370. 27:56:44relationship between the category and
  45371. 27:56:45the subcategory. Let's go now and
  45372. 27:56:47execute it. Now you can see in the
  45373. 27:56:48output our categories are now splitted
  45374. 27:56:51into more specific groups. So for
  45375. 27:56:54example the bikes over here we have
  45376. 27:56:56mountain bikes, road bikes and so on. So
  45377. 27:56:58as you can see the subcategories has
  45378. 27:57:00more details about the products than the
  45379. 27:57:03category. And now in order to get the
  45380. 27:57:05full picture we going to bring now the
  45381. 27:57:07product name. So with that we're going
  45382. 27:57:10to get a big picture in one shot. So now
  45383. 27:57:13you can see the whole hierarchy of our
  45384. 27:57:15products. And of course it is more
  45385. 27:57:17interesting if you go and sort the data
  45386. 27:57:19by those three informations. So let me
  45387. 27:57:22just execute it again. So now if you go
  45388. 27:57:23and explore our data for example we have
  45389. 27:57:25here the category accessories and we
  45390. 27:57:27have a subcategory inside it called
  45391. 27:57:29lights. And in this subcategory we have
  45392. 27:57:31three different products. And if you
  45393. 27:57:33scroll to the end of our table you can
  45394. 27:57:35see that we have around
  45395. 27:57:37295 products. So you can see the
  45396. 27:57:40granularity of the product name is
  45397. 27:57:42different than the category and the
  45398. 27:57:43subcategory. And all those three
  45399. 27:57:45informations are related to each others.
  45400. 27:57:47So now as you can see after exploring
  45401. 27:57:49those dimensions we have now better
  45402. 27:57:51understanding on how the data is
  45403. 27:57:54organized and this can help us by the
  45404. 27:57:55analyzes if you are aggregating by the
  45405. 27:57:58category you will get only four rows. If
  45406. 27:58:00you are aggregating by the products you
  45407. 27:58:02will get hundreds of rows. So this is
  45408. 27:58:04how we explore the dimensions of our
  45409. 27:58:07database. Okay. So now with that we have
  45410. 27:58:09a clear picture about the dimensions
  45411. 27:58:10inside our data sets. And now in the
  45412. 27:58:12next step we're going to deep dive into
  45413. 27:58:13one special type of dimensions. We have
  45414. 27:58:16the dates. So we're going to explore the
  45415. 27:58:18date
  45416. 27:58:21columns. Okay. So now what we going to
  45417. 27:58:23do with the date exploration? We're
  45418. 27:58:25going to go and explore the boundaries
  45419. 27:58:27of the dates that we have in the data
  45420. 27:58:29sets. What is the earliest and the
  45421. 27:58:31latest dates in my data? We're going to
  45422. 27:58:33understand the time span. Do we have in
  45423. 27:58:35our business 2 years or like 10 years?
  45424. 27:58:38And this is of course very important to
  45425. 27:58:40understand in order later to make
  45426. 27:58:41different types of time analyzes. Now
  45427. 27:58:44the formula for that is very simple. All
  45428. 27:58:46what we need is the min and max
  45429. 27:58:48functions in order to get the earliest
  45430. 27:58:50and the latest dates. And of course
  45431. 27:58:51we're going to apply that on date
  45432. 27:58:53columns, date dimensions. So for
  45433. 27:58:55example, we're going to have like min
  45434. 27:58:56order date, max create date, min birth
  45435. 27:58:59date. So any date that you have in your
  45436. 27:59:01data set. And here if you look to any
  45437. 27:59:02date column inside your data, you will
  45438. 27:59:04find multiple values. But what is
  45439. 27:59:06interesting is to understand what is the
  45440. 27:59:08earliest date like here for example 2018
  45441. 27:59:11and what is the latest date for example
  45442. 27:59:142028 and with that we can understand aha
  45443. 27:59:17we have like time span of 10 years using
  45444. 27:59:20the date diff function. So now let's go
  45445. 27:59:22and apply our new formula on our date
  45446. 27:59:24columns. All right. So now let's search
  45447. 27:59:26for date informations inside our
  45448. 27:59:28database. And usually you're going to
  45449. 27:59:30find a lot in the facts. So let's go to
  45450. 27:59:32the fact cells. And here we have like
  45451. 27:59:33multiple dates. the order date, shipping
  45452. 27:59:35date and due dates. Now let's go and
  45453. 27:59:37explore the boundaries of the order
  45454. 27:59:39date. So we have the following task.
  45455. 27:59:40Find the date of the first and last
  45456. 27:59:43order. So how we going to do that? We're
  45457. 27:59:45going to say select and we are targeting
  45458. 27:59:47the order date from our table sales. So
  45459. 27:59:51let's go and execute it. And now we can
  45460. 27:59:53see we have a lot of values inside our
  45461. 27:59:56database. So now in order to find the
  45462. 27:59:58first dates, what we're going to do,
  45463. 27:59:59we're going to go and use the function
  45464. 28:00:01min in order to get the minimum order
  45465. 28:00:04dates. So we're going to go and call it
  45466. 28:00:06first order dates. So let's go and
  45467. 28:00:09execute it. So now we can see the date
  45468. 28:00:11of the first order. It is in December
  45469. 28:00:132010. Now let's go and find the date of
  45470. 28:00:16the last order. So we're going to have
  45471. 28:00:18this time the max order date. Uh let's
  45472. 28:00:22go and call it last order date. So let's
  45473. 28:00:26go and explore now the other boundary
  45474. 28:00:28and with that we can see in January 2014
  45475. 28:00:31it is the date of the last order in our
  45476. 28:00:34system. So with that we have explored
  45477. 28:00:36the boundaries of the order dates the
  45478. 28:00:38first and the last and of course we can
  45479. 28:00:40now understand very quickly that we have
  45480. 28:00:43four years of sales inside our business
  45481. 28:00:45but we can go and calculate it. So now
  45482. 28:00:47the task says how many years of sales
  45483. 28:00:49are available. Now in order to find the
  45484. 28:00:52years between those two dates, we have
  45485. 28:00:54another scale function. It's called date
  45486. 28:00:56diff. And now we have to go and subtract
  45487. 28:00:58two dates. Now this function need three
  45488. 28:01:00arguments. The first one you have to
  45489. 28:01:02specify whether it is a year, month and
  45490. 28:01:04day. And we start with the smallest
  45491. 28:01:06date. So it's going to be the min order
  45492. 28:01:09dates. And then the last argument is
  45493. 28:01:11going to be the latest or the highest
  45494. 28:01:13date. And it's going to be the max order
  45495. 28:01:15dates. And we can go and call it order
  45496. 28:01:18range in years. Okay. So let's go and
  45497. 28:01:21execute it. And with that you can see in
  45498. 28:01:23the output we have four years. Of course
  45499. 28:01:25if you want to go and check the months
  45500. 28:01:27you can go over here and say month and
  45501. 28:01:29execute. So between those two dates we
  45502. 28:01:31have 37 months. And of course now we
  45503. 28:01:34have to go and rename it. So with that
  45504. 28:01:36we have explored the dimension order
  45505. 28:01:39dates. But what is more interesting is
  45506. 28:01:41to check the customers and here we have
  45507. 28:01:44the birth date. So now what we can do,
  45508. 28:01:46we can go and find the youngest and the
  45509. 28:01:49oldest customer. So let's go and do
  45510. 28:01:51that. We're going to say select
  45511. 28:01:53minates and with that we are getting the
  45512. 28:01:56oldest birth date and we will get now
  45513. 28:01:59the max birth date and with that we will
  45514. 28:02:02get the youngest birth date from our
  45515. 28:02:06table customers. So let's go and explore
  45516. 28:02:09that. Now we can see the birth date of
  45517. 28:02:11the oldest customer. I hope he or she is
  45518. 28:02:14still alive. So it is more than 100
  45519. 28:02:16years and the youngest customer is
  45520. 28:02:19around like 40 years. So we don't have
  45521. 28:02:22really young customers inside our
  45522. 28:02:23business. And of course if you don't
  45523. 28:02:25want to see the birth dates, you want to
  45524. 28:02:27see the age, what you have to do is
  45525. 28:02:29actually very simple. You're going to
  45526. 28:02:30use as well diff and we want the year
  45527. 28:02:33and then we're going to say min birth
  45528. 28:02:36date with the current date and time. And
  45529. 28:02:39for that we have a function called get a
  45530. 28:02:41date and we're going to call it oldest
  45531. 28:02:44age. So if you go ahead and execute this
  45532. 28:02:47one over here you can see the age of the
  45533. 28:02:49oldest customer it is 109. Of course you
  45534. 28:02:52can do the same thing for the youngest.
  45535. 28:02:54If you just replace this with max and
  45536. 28:02:57here we have the youngest age. So let's
  45537. 28:03:00go and execute it. It is 39. So my
  45538. 28:03:03friends this is how we explore the
  45539. 28:03:05boundaries of a date and by finding the
  45540. 28:03:08first date and the last date and the
  45541. 28:03:10years between them we are having now
  45542. 28:03:12more understanding of the time span of
  45543. 28:03:14our business and that's going to help us
  45544. 28:03:16later by making different type of
  45545. 28:03:18complex analyzers. So this is how we
  45546. 28:03:20explore the dates. All right. So with
  45547. 28:03:22that we have now a clear picture about
  45548. 28:03:24the scope of our projects and the date
  45549. 28:03:26range inside our data sets. Now in the
  45550. 28:03:28next step, we're going to go and explore
  45551. 28:03:30the second type of data, the
  45552. 28:03:35measures. All right. So now what is
  45553. 28:03:37exactly exploring the measures? What
  45554. 28:03:39we're going to do is to calculate and
  45555. 28:03:41find out the key metrics of our
  45556. 28:03:44business, the big numbers, the highest
  45557. 28:03:46level of aggregations of our data. And
  45558. 28:03:48the formula for that is very simple.
  45559. 28:03:50We're going to go and use the aggregate
  45560. 28:03:52functions in SQL like the sum, average,
  45561. 28:03:55count for any measure inside our data
  45562. 28:03:57sets. So for example, we're going to
  45563. 28:03:59find the total sales by summarizing the
  45564. 28:04:01sales value, finding the average price,
  45565. 28:04:04finding the sum of quantity in order to
  45566. 28:04:06have a big number about all sold items.
  45567. 28:04:09So always an aggregate function together
  45568. 28:04:11with a measure. So for example, if you
  45569. 28:04:12have a column where you have a lot of
  45570. 28:04:14values and you go and summarize all
  45571. 28:04:16those values, you will get for example
  45572. 28:04:18240. So this is a key metric. This is
  45573. 28:04:21the highest level of aggregations and
  45574. 28:04:23the value is not splitted at all. So for
  45575. 28:04:25example, we say this is the total
  45576. 28:04:27revenue of our business. And this is
  45577. 28:04:29exactly what we mean by exploring the
  45578. 28:04:31measures. We will get those big numbers.
  45579. 28:04:33So now let's go and apply those
  45580. 28:04:34aggregate functions to the measures that
  45581. 28:04:36we have inside our data set. Okay. So
  45582. 28:04:38now we're going to go and spotlight on
  45583. 28:04:40the big numbers that matters the most of
  45584. 28:04:42our business. So now based on those
  45585. 28:04:44three tables, I have collected here the
  45586. 28:04:47following questions. So let's go and
  45587. 28:04:48solve them one by one. The first one is
  45588. 28:04:50find the total sales. So we're going to
  45589. 28:04:53go and summarize by using the sum
  45590. 28:04:55function for the sales amount as total
  45591. 28:04:59sales from our table fact sales. So
  45592. 28:05:03let's go and execute it. So this is the
  45593. 28:05:06total amount of sales in our business.
  45594. 28:05:08It is around 29 millions. So this is the
  45595. 28:05:12business total revenue. Now we can go to
  45596. 28:05:14the second one. It says show how many
  45597. 28:05:17items are sold. So this time we need
  45598. 28:05:19another column but from the same table
  45599. 28:05:22from the fact sales. So the question is
  45600. 28:05:24how many items that means we want the
  45601. 28:05:26quantity and we're going to stay with
  45602. 28:05:28the same function. So we are summarizing
  45603. 28:05:30all the values of the quantity and we
  45604. 28:05:32can call it total quantity. Let's go and
  45605. 28:05:36explore that. So we can see our business
  45606. 28:05:38did sold around 60,000 items and these
  45607. 28:05:4260,000 items did generate around 30
  45608. 28:05:44million. So let's keep going. The next
  45609. 28:05:46question, find the average selling
  45610. 28:05:48price. So that means we are targeting
  45611. 28:05:50the same table. And here we have the
  45612. 28:05:52price informations. So we're going to
  45613. 28:05:54say the price. This time the aggregate
  45614. 28:05:56function going to be the average. And
  45615. 28:05:57we're going to call it average price. So
  45616. 28:06:00let's go and execute it. So the average
  45617. 28:06:02price in our business is 486. So that
  45618. 28:06:05means our business is selling like
  45619. 28:06:07expensive items. Now let's go to the
  45620. 28:06:09next question. It says find the total
  45621. 28:06:12number of orders. And for that we're
  45622. 28:06:14going to go and use the function count
  45623. 28:06:16and we can count the order numbers. So
  45624. 28:06:20order number total orders let's go and
  45625. 28:06:24execute it. So it says we have 60,000
  45626. 28:06:27orders. And now as you are working with
  45627. 28:06:28the count function what I usually do I
  45628. 28:06:31try to count the same thing but using a
  45629. 28:06:34distinct. So distinct order number. So,
  45630. 28:06:37what I'm trying to do here is first
  45631. 28:06:40eliminate any duplicates in the order
  45632. 28:06:42number and then count it. I don't want
  45633. 28:06:44to count the same order twice inside our
  45634. 28:06:47sales. So, let's go and execute that.
  45635. 28:06:50Now, as you can see, we have only 27,000
  45636. 28:06:53orders out of 60,000. So, that means the
  45637. 28:06:57same order is repeating in our database.
  45638. 28:07:00Let's have actually a look. So, select
  45639. 28:07:02star from our table and let's go and
  45640. 28:07:06have a look. Now as you can see from the
  45641. 28:07:07first order over here you can see the
  45642. 28:07:09same order is repeated three times and
  45643. 28:07:12that's because this customer did order
  45644. 28:07:14three things in the same order. So now
  45645. 28:07:17of course what is the definition of
  45646. 28:07:19order? Usually the whole thing is one
  45647. 28:07:21order. That's why in order to get an
  45648. 28:07:23accurate number of orders you have to go
  45649. 28:07:25and use a distinct in order to eliminate
  45650. 28:07:28first all duplicates and then count how
  45651. 28:07:30many orders we have. So in this scenario
  45652. 28:07:32I'm going to say in our business we have
  45653. 28:07:34around 27,000 orders. So that's why it
  45654. 28:07:37is little bit tricky using the count
  45655. 28:07:39function. Always try to compare the
  45656. 28:07:41numbers before and after using distinct.
  45657. 28:07:44So let's keep going to the next one. It
  45658. 28:07:46says find the total number of products.
  45659. 28:07:48So it is very simple. We're going to say
  45660. 28:07:50select count and we're going to say
  45661. 28:07:52product key as total products from the
  45662. 28:07:57table gold products. So let's go and
  45663. 28:08:00execute it. So as you can see we have
  45664. 28:08:02295 and if you go and make it distinct
  45665. 28:08:06just to check you will get the same
  45666. 28:08:09number. So that means there is no
  45667. 28:08:10duplicates and of course you can go and
  45668. 28:08:12count the product name instead. The
  45669. 28:08:14names of the product is unique. So
  45670. 28:08:15that's why we are as well getting the
  45671. 28:08:18same numbers. So that's it. Let's
  45672. 28:08:20continue find the total number of
  45673. 28:08:22customers. So the same thing select
  45674. 28:08:25count and you can go with a customer key
  45675. 28:08:27for example from called a dimension
  45676. 28:08:30customers and I'm going to call it as
  45677. 28:08:33total customers. So let's go and execute
  45678. 28:08:36it. So we can see in our system we have
  45679. 28:08:3818,000 registered customers. Now the
  45680. 28:08:41next one it says find the total number
  45681. 28:08:43of customers that has placed an order.
  45682. 28:08:45So that means having a customer inside
  45683. 28:08:48our database doesn't mean that this
  45684. 28:08:50customer did already placed an order.
  45685. 28:08:52Maybe we have customer that just
  45686. 28:08:54registered and didn't order anything. So
  45687. 28:08:56what we're going to do, we're going to
  45688. 28:08:57take the same query, but instead of
  45689. 28:08:59targeting the customers table, we're
  45690. 28:09:01going to target our fact the sales. So
  45691. 28:09:04let's go and execute it. So now, as you
  45692. 28:09:06can see, we are getting 16,000, which
  45693. 28:09:08makes no sense because one customer
  45694. 28:09:10might order multiple stuff. So what
  45695. 28:09:12we're going to do, we're going to say
  45696. 28:09:14distinct and let's query it again. So
  45697. 28:09:16now it is more correct. We are getting
  45698. 28:09:18around 18,000 customers. Now we can go
  45699. 28:09:21and compare them one by one. So as you
  45700. 28:09:23can see we are getting the same numbers.
  45701. 28:09:25So that means all our registered
  45702. 28:09:26customers did already placed an order
  45703. 28:09:29because the numbers are matching. So it
  45704. 28:09:31is very simple. We are just using an
  45705. 28:09:33aggregate functions and that we are
  45706. 28:09:35getting those key values. But what I
  45707. 28:09:37usually do is that I collect all those
  45708. 28:09:39measures in one query in order to have
  45709. 28:09:41an overview of all key numbers in our
  45710. 28:09:44business. So instead of me querying each
  45711. 28:09:46one of them individually, I combine them
  45712. 28:09:49in one go. So now what we're going to
  45713. 28:09:50do, we're going to generate a report
  45714. 28:09:52that shows all key metrics of our
  45715. 28:09:54business. So how I usually do it, I'm
  45716. 28:09:56going to go and get the first query for
  45717. 28:09:57the total sales and put it over here.
  45718. 28:09:59And now I'm going to build only two
  45719. 28:10:01columns. The first one is the name of
  45720. 28:10:03the measure and the second one is the
  45721. 28:10:05value of the measure. So let me show you
  45722. 28:10:07what I mean. Now this one over here, I
  45723. 28:10:09will not call it total sales. I'm going
  45724. 28:10:11to make it like generic. So I'm going to
  45725. 28:10:13say measure value. And before it we're
  45726. 28:10:16going to make another column from a
  45727. 28:10:18static string value is the total sales
  45728. 28:10:21and we're going to call it measure name
  45729. 28:10:23like this. So let's go and just execute
  45730. 28:10:26this one over here. So the measure is
  45731. 28:10:28total sales. So it is not anymore like
  45732. 28:10:31the column name. It is now a value in
  45733. 28:10:33the output and the measure value is like
  45734. 28:10:35around 30 millions. Now what I'm going
  45735. 28:10:37to do I'm going to go and add another
  45736. 28:10:39measure as a second row. And in order to
  45737. 28:10:41do that, we're going to use the union
  45738. 28:10:43all and then copy the whole thing over
  45739. 28:10:45here and say total quantity and we're
  45740. 28:10:48going to change the measure to quantity.
  45741. 28:10:51So now let's select both of them and
  45742. 28:10:53query. And now as you can see we have
  45743. 28:10:55now the two big numbers in one query. So
  45744. 28:10:58the total sales and the total quantity.
  45745. 28:11:00So now what we can do we can go and
  45746. 28:11:01collect all those big numbers and
  45747. 28:11:03measures and put it in one query. So
  45748. 28:11:06with that we have the average price, the
  45749. 28:11:07total number of orders, product,
  45750. 28:11:09customers and as well you can go and
  45751. 28:11:11target different tables because SQL
  45752. 28:11:13cares here only about the number of
  45753. 28:11:15columns and the data type of columns
  45754. 28:11:17must be matching. So now let's go and
  45755. 28:11:20query this and now in single query we
  45756. 28:11:23can see the big numbers the key metrics
  45757. 28:11:26of our business. We can see the total
  45758. 28:11:28sales, total quantity, average price and
  45759. 28:11:30so on. This is a super report where you
  45760. 28:11:32can generate it for any business where
  45761. 28:11:34you have in one go the full big picture
  45762. 28:11:37about the business. So this is how I
  45763. 28:11:39generally do if I'm exploring a new
  45764. 28:11:40database. I put all those big numbers
  45765. 28:11:43and measures in one query to have better
  45766. 28:11:46understanding about the business. All
  45767. 28:11:47right my friends. So with that we have
  45768. 28:11:49now a clear understanding about the
  45769. 28:11:51dimensions and as well the measures of
  45770. 28:11:53our data sets. Now in the next step
  45771. 28:11:55we're going to go and start combining
  45772. 28:11:57stuff together in order to generate
  45773. 28:11:58insights. And we're going to focus now
  45774. 28:12:00in a very basic analyszis. It is the
  45775. 28:12:02magnitude
  45776. 28:12:07analyzis. Okay. So now what is exactly a
  45777. 28:12:09magnitude analyszis? It's all about
  45778. 28:12:11comparing the measure values across
  45779. 28:12:13different categories and dimensions. And
  45780. 28:12:15this can help us of course to understand
  45781. 28:12:17the importance of different categories.
  45782. 28:12:20Now the formula for that going to be
  45783. 28:12:21interesting. So now this time we will be
  45784. 28:12:23mixing stuff together. So first we have
  45785. 28:12:25to go and aggregate a specific measure
  45786. 28:12:27and then we say by dimension. We need
  45787. 28:12:30here the dimension in order to split the
  45788. 28:12:32measure. It sounds complicated but it is
  45789. 28:12:34very simple and basics. So for example
  45790. 28:12:36we can say the total sales by country,
  45791. 28:12:39the total quantity by category, the
  45792. 28:12:41average price by products, the total
  45793. 28:12:44orders by customer and if you follow
  45794. 28:12:46this formula you will be generating
  45795. 28:12:48endless amount of insights by just
  45796. 28:12:50combining any measure with any
  45797. 28:12:51dimension. You can call it it is a new
  45798. 28:12:53insight. So it's going to look like like
  45799. 28:12:55this. If you have one measure that is
  45800. 28:12:57like for example 600 and if you put now
  45801. 28:12:59this measure together with dimension
  45802. 28:13:01what's going to happen this 600 is going
  45803. 28:13:03to be splitted by the dimension values.
  45804. 28:13:05So A going to have like 200, B going to
  45805. 28:13:07have 300 and C 100. And now with that we
  45806. 28:13:10can go and compare those categories
  45807. 28:13:12right. So we can see now that category B
  45808. 28:13:15has the highest measure and the C has
  45809. 28:13:17the lowest. And this help us to compare
  45810. 28:13:19the values of the measure. what is the
  45811. 28:13:20best category and what is the worst
  45812. 28:13:22category. So this is very basics
  45813. 28:13:24analyszis. So let's go and apply this
  45814. 28:13:26formula on our data sets. Okay. So now
  45815. 28:13:29let's go and break all our measures by
  45816. 28:13:31dimensions. So here I have prepared few
  45817. 28:13:33interesting examples where first we're
  45818. 28:13:35going to break the total number of
  45819. 28:13:37customers. As we learned we have 18,000
  45820. 28:13:39by the countries. So the measure is
  45821. 28:13:42total customers and the dimension going
  45822. 28:13:44to be the countries. So let's go and
  45823. 28:13:45write the query for that. So we're going
  45824. 28:13:47to select. So the first thing that we're
  45825. 28:13:48going to go and add is the dimension. So
  45826. 28:13:50it's going to be the country. And then
  45827. 28:13:52we need the measure. It's going to be
  45828. 28:13:54the count of the customer key. So this
  45829. 28:13:58will give us the total customers. And we
  45830. 28:14:01need to select our table. So it's going
  45831. 28:14:03to be the dimension customers. And of
  45832. 28:14:05course we have to go and group up the
  45833. 28:14:07data by the countries. So group up
  45834. 28:14:10country. So let's go and execute it. And
  45835. 28:14:13with that you see again the list of
  45836. 28:14:15countries. So we have our six countries
  45837. 28:14:18and then the total customers for each
  45838. 28:14:20country. So that we can see the
  45839. 28:14:22distribution of customers by the
  45840. 28:14:24country. But what we usually do is that
  45841. 28:14:26we go and sort the data by the measure
  45842. 28:14:28the total customers like this. And we're
  45843. 28:14:31going to sort it by descending. So with
  45844. 28:14:33that we will get first the countries
  45845. 28:14:35with the highest customers. So let's go
  45846. 28:14:38and execute it. So now we can see in the
  45847. 28:14:40results the highest number of customers
  45848. 28:14:42come from United States then Australia,
  45849. 28:14:44United Kingdom
  45850. 28:14:46337 customers without the country
  45851. 28:14:50informations it is not available. So
  45852. 28:14:52that's it right it is very simple. So
  45853. 28:14:54with that we have splitted the total
  45854. 28:14:56number of customers by a dimension the
  45855. 28:14:58country. Now of course we can go and
  45856. 28:15:00split the data by different type of
  45857. 28:15:02dimension. So for the next one we are
  45858. 28:15:04saying find the total customers by
  45859. 28:15:07gender. So here's the same thing. We
  45860. 28:15:08have the same measure that to other
  45861. 28:15:10customers but we are splitting the data
  45862. 28:15:12by different type of dimension. So just
  45863. 28:15:14copy and paste and now instead of
  45864. 28:15:16countries we just going to switch it to
  45865. 28:15:18gender and over here and that's it. So
  45866. 28:15:21let's go and execute. So now as you can
  45867. 28:15:23see the granularity of the gender over
  45868. 28:15:26here is different than the countries. We
  45869. 28:15:27have here only three values and we can
  45870. 28:15:30see it is almost splitted evenly between
  45871. 28:15:32male customers and female customers. And
  45872. 28:15:34of course this going to help us to
  45873. 28:15:36understand the demography of our
  45874. 28:15:38customers. And as you can see it was
  45875. 28:15:40very simple. We just switch the
  45876. 28:15:42dimension. So you can go and split as
  45877. 28:15:44well by the marital status and so on.
  45878. 28:15:46Now let's go and split the total
  45879. 28:15:49products by the category. Well actually
  45880. 28:15:51the query is going to be very simple as
  45881. 28:15:53well. So select and here we're going to
  45882. 28:15:54have the same aggregate function the
  45883. 28:15:56count products key as total
  45884. 28:16:00products from our table gold dimension
  45885. 28:16:04products and then we're going to group
  45886. 28:16:05up by the dimension the category and
  45887. 28:16:08we're going to order by as well the same
  45888. 28:16:10thing total products distinct from the
  45889. 28:16:13highest to the lowest. So let's go and
  45890. 28:16:15execute it. And with that we can see how
  45891. 28:16:17many products do we have in each of
  45892. 28:16:19those categories. And we can see the
  45893. 28:16:21biggest category the components and
  45894. 28:16:23after that the pikes. And this is
  45895. 28:16:25interesting that we have seven products
  45896. 28:16:27where we have nulls where they don't
  45897. 28:16:29belong to any category. This is really
  45898. 28:16:31nice. Let's go to the next one. What do
  45899. 28:16:33we have over here? What is the average
  45900. 28:16:36costs in each category? So this is like
  45901. 28:16:38different style of question but at the
  45902. 28:16:40ends we're going to have the same thing.
  45903. 28:16:41We have over here the average costs.
  45904. 28:16:43This is the measure and the category is
  45905. 28:16:46our dimension. It's like we are saying
  45906. 28:16:48find average costs by category. So what
  45907. 28:16:51we're going to do, we're going to go and
  45908. 28:16:52copy the same query and the dimension is
  45909. 28:16:54the same. So the categories but the
  45910. 28:16:57measure is different. We are not talking
  45911. 28:16:59about the total products. We are going
  45912. 28:17:00to say average and here we're going to
  45913. 28:17:02have the column costs and let's go and
  45914. 28:17:04rename it average costs. So that's it as
  45915. 28:17:07well for the order by we have to use the
  45916. 28:17:10new measure. So let's go and execute it.
  45917. 28:17:12So now we can see the most expensive
  45918. 28:17:14category is the bikes costs a lot
  45919. 28:17:17compared to the accessories of course.
  45920. 28:17:19So you can see the accessories is only
  45921. 28:17:2113 and the bikes is 900. So this is as
  45922. 28:17:24well gives us insights about how
  45923. 28:17:26expensive each category is and as you
  45924. 28:17:28can see it is always the same templates.
  45925. 28:17:31We are splitting specific measure by a
  45926. 28:17:33dimension. So let's keep going to the
  45927. 28:17:35next one. It says what is the total
  45928. 28:17:38revenue generated for each category. So
  45929. 28:17:40again here the question is find the
  45930. 28:17:43total revenue by category. So the total
  45931. 28:17:46revenue here is the measure and the
  45932. 28:17:48category again is the dimension. So now
  45933. 28:17:50the total revenue comes from the fact
  45934. 28:17:52and the category comes this time from
  45935. 28:17:54the dimension. So that means we have to
  45936. 28:17:56go and join tables right. So how we
  45937. 28:17:58going to do it? Let's go and start with
  45938. 28:17:59the select star from and I would like
  45939. 28:18:02always to start from the fact table. So
  45940. 28:18:05fact sales f and then we're going to go
  45941. 28:18:07and join it with the dimension and
  45942. 28:18:09usually I go with the left join in order
  45943. 28:18:10to not lose anything because if you use
  45944. 28:18:13an inner join you might lose in the fact
  45945. 28:18:15few orders and few sales I don't want
  45946. 28:18:17that. So lift join with the dimension
  45947. 28:18:20this one going to be the products and
  45948. 28:18:22the key for that going to be very simple
  45949. 28:18:24going to be the product key and the same
  45950. 28:18:26thing for the facts. So with that we
  45951. 28:18:28join the fact table with the dimension.
  45952. 28:18:30So now we have to go and pick what do we
  45953. 28:18:32need? We need from the fact the sales
  45954. 28:18:34right. So sales amount and we need from
  45955. 28:18:37the products the category and we want to
  45956. 28:18:40group up the data by the category. So so
  45957. 28:18:43this part is done. What is missing is of
  45958. 28:18:46course the aggregations. So we are
  45959. 28:18:48aggregating actually the sales. So sum
  45960. 28:18:51sales and we can call it total revenue.
  45961. 28:18:54So like this. And of course we can go
  45962. 28:18:57and order the data by the total revenue
  45963. 28:18:59by our measure and distinct from highest
  45964. 28:19:02to the lowest. So as you can see it is
  45965. 28:19:03exactly like the previous one. But here
  45966. 28:19:05the data doesn't come from only one
  45967. 28:19:07table. Here it comes from two tables. So
  45968. 28:19:09the measure come from the facts and the
  45969. 28:19:11dimension come from the dimension
  45970. 28:19:13products. And this is classic right? The
  45971. 28:19:15dimension has all those descriptions and
  45972. 28:19:18details about the products like the
  45973. 28:19:20categories. And the fact table has all
  45974. 28:19:22those measures and dates that we use in
  45975. 28:19:25order to calculate our measures. So
  45976. 28:19:27that's it. Let's go and execute it. Now,
  45977. 28:19:29as you can see in the output, the
  45978. 28:19:31category bikes is bringing the most of
  45979. 28:19:33revenue. So here it's like in millions
  45980. 28:19:3628 millions of sales and the accessories
  45981. 28:19:39and the closing is not really bringing a
  45982. 28:19:41lot of like revenue. Both of them are
  45983. 28:19:43below like 1 million. So with that you
  45984. 28:19:45can understand our business is making a
  45985. 28:19:47lot of money selling bikes, right? So my
  45986. 28:19:50friends as we are exploring the data we
  45987. 28:19:52are understanding more and more about
  45988. 28:19:54our business right so let's keep going
  45989. 28:19:56to the next one we have here the
  45990. 28:19:57question what is the total revenue
  45991. 28:19:59generated by each customer so now we
  45992. 28:20:01want to find out the top spender right
  45993. 28:20:04select star and as well we start from
  45994. 28:20:06the fact table and this time we're going
  45995. 28:20:10to lift join it with the customers right
  45996. 28:20:12so the dimension customers and we're
  45997. 28:20:15going to go join the data so we're going
  45998. 28:20:17to use the customer key for the join And
  45999. 28:20:19what we're going to do, we're going to
  46000. 28:20:20go and get maybe the customer key. And
  46001. 28:20:23let's go and get as well the first name,
  46002. 28:20:25maybe few details about the customer and
  46003. 28:20:28as well the last name. So those are the
  46004. 28:20:30columns that we want from the customers.
  46005. 28:20:32And now what do we need? We need the
  46006. 28:20:34aggregation. So it's going to be the
  46007. 28:20:35same thing. Sales amount as total
  46008. 28:20:38revenue. And we have to go and group up
  46009. 28:20:41the data by all those three
  46010. 28:20:43informations. So we're going to go and
  46011. 28:20:45copy paste. And at the end as usual,
  46012. 28:20:47we're going to order by the measure
  46013. 28:20:49total revenue descending. So that's it.
  46014. 28:20:52It is exactly like previous one but with
  46015. 28:20:54different dimensions. So let's go and
  46016. 28:20:56query it. And now we get a full list of
  46017. 28:20:59all our customers, the 18,000s. And we
  46018. 28:21:02can see the total revenue for each
  46019. 28:21:04customer. So we can see Nicole and
  46020. 28:21:06Caitlyn, they are our top spenders and
  46021. 28:21:09the most royal customers that generated
  46022. 28:21:12sales and revenue for our business. This
  46023. 28:21:14is really cool. Right now let's go to
  46024. 28:21:16the next one. It says what is the
  46025. 28:21:18distribution of sold items across
  46026. 28:21:21countries. It is like finding the total
  46027. 28:21:23quantity by countries. So it is very
  46028. 28:21:26simple. I'm going to go and take the
  46029. 28:21:27same query because countries comes from
  46030. 28:21:29the dimension customers and the sold
  46031. 28:21:32items the quantity come from the sales.
  46032. 28:21:34So we are doing the same joints but with
  46033. 28:21:36different dimensions and measures. So
  46034. 28:21:38what do we need from the customers is
  46035. 28:21:40only the country and the measure going
  46036. 28:21:42to be the quantity. And here we're going
  46037. 28:21:44to go and say total sold items and we
  46038. 28:21:47have to change the group by to the
  46039. 28:21:50countries and sorting the data by the
  46040. 28:21:52new measure. That's it. And with that we
  46041. 28:21:54are generating new reports by just
  46042. 28:21:57changing the dimensions and measures. So
  46043. 28:21:59again this is very interesting to
  46044. 28:22:00understand which country is generating
  46045. 28:22:02like good business for us. So my friends
  46046. 28:22:04as you might already noticed if in the
  46047. 28:22:06dimension we have like small number of
  46048. 28:22:09unique values like in the countries we
  46049. 28:22:11have here only seven values in the
  46050. 28:22:12gender we have only three we call those
  46051. 28:22:14dimensions low cardality dimensions
  46052. 28:22:17because we have low number of values
  46053. 28:22:19inside it and in the result we will get
  46054. 28:22:21only here for example seven rows but if
  46055. 28:22:23our dimension is high cardality like by
  46056. 28:22:27the customers we have 18,000 unique
  46057. 28:22:30customers then our measure going to be
  46058. 28:22:32splitted by those 18,000 and in the
  46059. 28:22:35results we will get exactly the same
  46060. 28:22:37number of customers. So the number of
  46061. 28:22:39rows and results really depends on the
  46062. 28:22:41cardality of the dimension. So as you
  46063. 28:22:43can see we can generate a lot of
  46064. 28:22:45different reports by only following this
  46065. 28:22:47formula dividing the measure by a
  46066. 28:22:49dimension. So we just generated eight
  46067. 28:22:52different insights and reports by only
  46068. 28:22:54few measures and dimensions. So now what
  46069. 28:22:56you can do you can pause the video and
  46070. 28:22:57try different dimensions and measures in
  46071. 28:23:00order to have more insights about our
  46072. 28:23:02business. Okay. So as you can see this
  46073. 28:23:04is the basics analyszis that we can do
  46074. 28:23:06in any data set or any domain where we
  46075. 28:23:08are aggregating a measure by dimension.
  46076. 28:23:10Now in the next and last step in our
  46077. 28:23:12projects we will be doing ranking
  46078. 28:23:18analyszis. Okay. So what is ranking
  46079. 28:23:20analyszis? It is very basic. We're going
  46080. 28:23:22to go and order the value of our
  46081. 28:23:24dimension based on a measure in order to
  46082. 28:23:27identify the top performers and as well
  46083. 28:23:29the bottom performers. And the formula
  46084. 28:23:31for that is going to be the following.
  46085. 28:23:33So this time we're going to be ranking
  46086. 28:23:34the dimensions by an aggregated measure.
  46087. 28:23:37So for example, we're going to rank the
  46088. 28:23:38countries by the total sale or we're
  46089. 28:23:40going to find the top five products by
  46090. 28:23:42the sold item, the quantity or the
  46091. 28:23:45bottom three customers by total orders.
  46092. 28:23:47So it's like the magnitude analyzes.
  46093. 28:23:49We're going to have like an ordered list
  46094. 28:23:51of dimensions value. For example, from
  46095. 28:23:53the highest to the lowest in order to
  46096. 28:23:55identify quickly the top performers. And
  46097. 28:23:57of course we can go and filter the data
  46098. 28:23:59by saying I would like to have only the
  46099. 28:24:00top two categories. And with that you
  46100. 28:24:03are removing all other dimensions that
  46101. 28:24:05are not on the top two. And in SQL we
  46102. 28:24:07can use for that the keyword top or we
  46103. 28:24:10can use the ranking window functions
  46104. 28:24:12like rank, dense rank, row number and so
  46105. 28:24:15on. So let's go and apply our formula in
  46106. 28:24:17order to rank our data set. Okay. So now
  46107. 28:24:20let's check our data. We're going to
  46108. 28:24:22start with the first question. Which
  46109. 28:24:23five products generate the highest
  46110. 28:24:25revenue? So we are searching for the
  46111. 28:24:27best performing products in our
  46112. 28:24:29business. So of course the first
  46113. 28:24:30question what is the dimension and
  46114. 28:24:32measure that we have in this question.
  46115. 28:24:34Well the revenue that means we need the
  46116. 28:24:36sales from the facts and the products
  46117. 28:24:38that means we need the dimension
  46118. 28:24:40products. Now in order to write this
  46119. 28:24:41query it's going to be very simple. So
  46120. 28:24:43we can use as well the group by I will
  46121. 28:24:45not write it from the scratch. So I'm
  46122. 28:24:47just going to take this query over here
  46123. 28:24:49where we aggregated the total sales by
  46124. 28:24:51the category. Now what I have to do is
  46125. 28:24:53just to change the dimension. So instead
  46126. 28:24:56of the category we need the product name
  46127. 28:24:59and we are aggregating now the data by
  46128. 28:25:01the product name because we need the top
  46129. 28:25:03five products right. So the revenue is
  46130. 28:25:06the sales amount and with that we have
  46131. 28:25:08like almost everything is ready. So
  46132. 28:25:09let's go and execute it. And now we can
  46133. 28:25:11see we have a list of all products in
  46134. 28:25:13our business and as well we can see the
  46135. 28:25:16total revenue. But the task says here we
  46136. 28:25:18need the top five. So we don't need all
  46137. 28:25:21the products from our database. We have
  46138. 28:25:23to go and select only this subset. Now
  46139. 28:25:25in order to do that in SQL server, it's
  46140. 28:25:27very simple. We're going to go over here
  46141. 28:25:28and say top five and SQL going to go and
  46142. 28:25:31return only the first five rows from the
  46143. 28:25:34results. So let's go and execute it. And
  46144. 28:25:36as you can see now in the results, we
  46145. 28:25:38have only five products with the highest
  46146. 28:25:40sales. And that's it. With that, we have
  46147. 28:25:42solved the task and we can see the top
  46148. 28:25:44five products and all of them are pikes.
  46149. 28:25:47Now let's go and check the other sides.
  46150. 28:25:49We want to find the five worst
  46151. 28:25:51performing products by the same measure,
  46152. 28:25:53the sales. And this is very simple. So
  46153. 28:25:56what we're going to do, we're going to
  46154. 28:25:57go and take the same query over here.
  46155. 28:25:59And now what we're going to do, we're
  46156. 28:26:00going to go and sort the data from the
  46157. 28:26:02lowest to the highest. So instead of
  46158. 28:26:05descending, we're going to remove it.
  46159. 28:26:07And with that, SQL going to use the
  46160. 28:26:09ascending. So let's go and execute it.
  46161. 28:26:11And with that, as you can see, we are
  46162. 28:26:13getting the worst five performing
  46163. 28:26:15products by just sorting the data
  46164. 28:26:17differently. So it is very simple right
  46165. 28:26:19and with that we can see our five best
  46166. 28:26:21sellers and the five worst sellers. And
  46167. 28:26:24now what we can do we can go and just
  46168. 28:26:25change the dimension and generate
  46169. 28:26:28different reports like instead of the
  46170. 28:26:29product name let's go and check the
  46171. 28:26:31subcategories what are the best
  46172. 28:26:33subcategories of our data. So I just
  46173. 28:26:35change the dimension let's go and query.
  46174. 28:26:37So with that we can see the best
  46175. 28:26:39subcategories we have in our business
  46176. 28:26:41and the same thing if you want to go and
  46177. 28:26:42check the worst performing
  46178. 28:26:44subcategories. So generating reports is
  46179. 28:26:46very simple and now my friends in SQL
  46180. 28:26:48there is like two ways on how to create
  46181. 28:26:50ranking. We have a simple one where we
  46182. 28:26:53are using the group by clouds together
  46183. 28:26:55with the keyword top. But if you are
  46184. 28:26:57generating a reports where it's things
  46185. 28:26:59are more complex and you need more
  46186. 28:27:01flexibility, you should use the window
  46187. 28:27:03functions. So let me show you how I can
  46188. 28:27:05solve this task using the window
  46189. 28:27:07function. So now I'm going to go and
  46190. 28:27:08take almost the same query. Let's put it
  46191. 28:27:11over here. I'm going to get rid of the
  46192. 28:27:13top five. And let's see, we are still
  46193. 28:27:15speaking about the products name as well
  46194. 28:27:18with a group I. But now what we're going
  46195. 28:27:20to do, we're going to go and generate a
  46196. 28:27:21rank. So we can go and use for example
  46197. 28:27:23the row number. And in scale there's
  46198. 28:27:25like different types of window functions
  46199. 28:27:27for ranking. One of them is the row
  46200. 28:27:29number or the rank and then we're going
  46201. 28:27:31to say over. Now we're going to go and
  46202. 28:27:33sort the data. It's like we have done in
  46203. 28:27:35the previous one. We have to sort the
  46204. 28:27:37data by the total revenue and the total
  46205. 28:27:39revenue is the sum of sales and
  46206. 28:27:41descending and we're going to call this
  46207. 28:27:43rank products. So let's go and execute
  46208. 28:27:47it. Now as you can see we have created a
  46209. 28:27:49new column where we have like a rank. So
  46210. 28:27:52we have for each products like one rank
  46211. 28:27:55until the last
  46212. 28:27:56products 130. So now what we are
  46213. 28:27:59interested is to go and select the top
  46214. 28:28:01five. Right now in order to do that we
  46215. 28:28:04need a second step. That's why we're
  46216. 28:28:05going to go and use the subquery. So
  46217. 28:28:07we're going to say select star from and
  46218. 28:28:09then we're going to put the whole thing
  46219. 28:28:11in a subquery something like that. And
  46220. 28:28:14all what you have to do is to use the
  46221. 28:28:16new flag that we have created in order
  46222. 28:28:18to filter the data. So we're going to
  46223. 28:28:20say where the rank products is smaller
  46224. 28:28:22or equal to five. And with that we
  46225. 28:28:25should get only the top five products.
  46226. 28:28:28So let's go and execute it. And as you
  46227. 28:28:30can see we are getting the same results.
  46228. 28:28:32Now, of course, with the window
  46229. 28:28:33function, it is more complicated than
  46230. 28:28:35the first one. But with the window
  46231. 28:28:36function, we get more flexibility on
  46232. 28:28:38selecting more columns or adding more
  46233. 28:28:41different types of aggregations and
  46234. 28:28:42details on the query. And as well, we
  46235. 28:28:44can go and use different types of
  46236. 28:28:46ranking functions that handles the tice
  46237. 28:28:49differently. So, if the task is very
  46238. 28:28:51simple like this, I'm going to go with
  46239. 28:28:53the simple group pie. But if you are
  46240. 28:28:55generating like complex reports, I'm
  46241. 28:28:57going to go with the window function. So
  46242. 28:28:59now what you can do, you can go and rank
  46243. 28:29:00the data by different dimensions and
  46244. 28:29:02measures. For example, find the top 10
  46245. 28:29:04customers who have generated the highest
  46246. 28:29:06revenue. And as well, you can go and
  46247. 28:29:08find the three customers with the fewest
  46248. 28:29:11orders placed. So again, we can go and
  46249. 28:29:14reuse the previous queries that we have
  46250. 28:29:16generated. So this query generates the
  46251. 28:29:18customers and their total sales. And all
  46252. 28:29:20what you have to do is to say top 10 and
  46253. 28:29:23then rerun the query. And with that, we
  46254. 28:29:25are getting the top 10 customers. and
  46255. 28:29:27about the lowest three customers. All
  46256. 28:29:30what we have to do is to go and replace
  46257. 28:29:32the measure. So we are counting the
  46258. 28:29:36unique number of orders. So we're going
  46259. 28:29:39to say total orders and as well go
  46260. 28:29:42change the order by not descending
  46261. 28:29:44ascending. And we need the top three. So
  46262. 28:29:47let's go and execute it. So we can see
  46263. 28:29:50the three customers that did order only
  46264. 28:29:52once and they are the three customers
  46265. 28:29:54with the fewest orders. So as you can
  46266. 28:29:56see by just switching the dimensions and
  46267. 28:29:58measures we are generating completely
  46268. 28:30:00new important insights and as you can
  46269. 28:30:02see as we are exploring the data we are
  46270. 28:30:04understanding what are the best products
  46271. 28:30:06what are the top customers that are
  46272. 28:30:08usually very important for reporting.
  46273. 28:30:11All right my friends so with that we
  46274. 28:30:12have covered the last step in our
  46275. 28:30:15projects how to rank our data and with
  46276. 28:30:17that we have covered all the steps of
  46277. 28:30:19the project road map. We have done a lot
  46278. 28:30:21of explorations for the database,
  46279. 28:30:22dimensions, measures. We have combined
  46280. 28:30:25the dimensions and measures in order to
  46281. 28:30:27do magnitude and ranking analyszis.
  46282. 28:30:29Okay, my friends. So that's all about
  46283. 28:30:31the EDA projects. And now in the next
  46284. 28:30:33one, we will do the last type of
  46285. 28:30:35projects, the advanced data analytics.
  46286. 28:30:37So let's
  46287. 28:30:42go. And now the type that we're going to
  46288. 28:30:44cover is advanced analytics projects
  46289. 28:30:46using SQL where we're going to write
  46290. 28:30:48complex SQL queries to answer real
  46291. 28:30:50business questions. So we're going to
  46292. 28:30:52use the advanced window functions, the
  46293. 28:30:54CTE subqueries and we're going to go and
  46294. 28:30:56script two big queries in order to
  46295. 28:30:59generate two reports. So with this type
  46296. 28:31:01of project, you will learn how to solve
  46297. 28:31:03real business questions using advanced
  46298. 28:31:05techniques. All right. So for this
  46299. 28:31:06project as well, we have a road map
  46300. 28:31:08where we're going to progress through
  46301. 28:31:10different type of steps and analyzes. So
  46302. 28:31:12we're going to do many stuff like change
  46303. 28:31:13over time, cumulative analyszis,
  46304. 28:31:15performance, data segmentations and at
  46305. 28:31:18the end reporting and all using SQL. So
  46306. 28:31:20let's start with the first step in the
  46307. 28:31:21road map. We going to analyze the change
  46308. 28:31:24over time. So let's
  46309. 28:31:28go. Okay. So now what is change over
  46310. 28:31:31time? It is a technique in order to
  46311. 28:31:33analyze how a measure evolves over the
  46312. 28:31:35time. And this is very important in
  46313. 28:31:37order to track the trends and as well to
  46314. 28:31:40identify seasonality of your data. And
  46315. 28:31:42the formula for that is very simple.
  46316. 28:31:44We're going to go and aggregate a
  46317. 28:31:45measure but this time based on a date
  46318. 28:31:48dimension. For example, the total sales
  46319. 28:31:50by a year, the average cost by the
  46320. 28:31:53month. So if you combine any aggregated
  46321. 28:31:55measure together with a date column or
  46322. 28:31:57dimension, then all what you are doing
  46323. 28:31:59is you are analyzing the change over
  46324. 28:32:01time. So for example, we're going to go
  46325. 28:32:03and break our measure this time for
  46326. 28:32:04example by the years. And with that we
  46327. 28:32:06can track immediately how our business
  46328. 28:32:09is doing over the time over the years.
  46329. 28:32:11So for example, we can see here the best
  46330. 28:32:13year was 2024 and then we have really
  46331. 28:32:15hard decline in our business in 2025 and
  46332. 28:32:18then slightly it's going up in 2026. So
  46333. 28:32:21with that we can quickly analyze the
  46334. 28:32:23trends of our business. So now let's go
  46335. 28:32:25and check the trends and the changes
  46336. 28:32:27over time in our business. Okay. So now
  46337. 28:32:29let's analyze the trends and changes
  46338. 28:32:31over time in our data and in order to do
  46339. 28:32:33this kind of analyzes usually we target
  46340. 28:32:36the fact table because there usually we
  46341. 28:32:38have our measures and as well dates. So
  46342. 28:32:40we have the order date, shipping date
  46343. 28:32:42and due date. Now what we can do we can
  46344. 28:32:44go and analyze there the sales
  46345. 28:32:46performance over time. So as we learned
  46346. 28:32:48all what we need is a metric and a date.
  46347. 28:32:51Let's go for example and select the
  46348. 28:32:54order date and as well one of those
  46349. 28:32:56measures sales amount from our fact
  46350. 28:33:00table. So let's go and query it. And we
  46351. 28:33:04can go and order the data by the order
  46352. 28:33:06dates ascending. So let's go and
  46353. 28:33:09execute. And as you can see we have
  46354. 28:33:11nulls in our data. What we can do? We
  46355. 28:33:13can go and filter those data out. We
  46356. 28:33:15don't need it. So we're going to say
  46357. 28:33:17where order date is not null. So let's
  46358. 28:33:19go and execute it again. All right. So
  46359. 28:33:22that we don't have those orders. Now, as
  46360. 28:33:24you can see, we have sales over time,
  46361. 28:33:26right? We have a date and we have a
  46362. 28:33:28measure. So this looks really good. But
  46363. 28:33:31now what we're going to do, we're going
  46364. 28:33:31to go and aggregate the data by the
  46365. 28:33:33sales amount. So let's go and say sum.
  46366. 28:33:37And we're going to call it total sales.
  46367. 28:33:39And then we group up the data by the
  46368. 28:33:42order dates. So let's go and execute it.
  46369. 28:33:45And with that, as you can see, for each
  46370. 28:33:47day, we have the total sales. So now the
  46371. 28:33:49granularity of our data is the day and
  46372. 28:33:52we can say of course now we are
  46373. 28:33:54analyzing the sales over time but
  46374. 28:33:56usually we don't aggregate the data on
  46375. 28:33:58the day level we want to have higher
  46376. 28:34:00aggregations for example let's go to the
  46377. 28:34:02years and now in order to change the
  46378. 28:34:05dimension date here from a day to a year
  46379. 28:34:07we have to use date functions and there
  46380. 28:34:10are a lot of date functions in order to
  46381. 28:34:12extract that date part and now in order
  46382. 28:34:14just to get the year we have a quick
  46383. 28:34:16function called year and it going to
  46384. 28:34:18convert convert our date to year. So
  46385. 28:34:21let's call it order year and of course
  46386. 28:34:23we have to go and group up the data by
  46387. 28:34:26the year and as well sort it by the
  46388. 28:34:28year. So let's go and execute. Now we
  46389. 28:34:30are at the year level and we have only
  46390. 28:34:33five years. So that means we have
  46391. 28:34:35changed the aggregation from the day to
  46392. 28:34:37year and now it is very easily to
  46393. 28:34:39analyze the performance of our business
  46394. 28:34:42over the years. So the first year was
  46395. 28:34:44the lowest and you can see 2013 is the
  46396. 28:34:47best year in our business and then it is
  46397. 28:34:50declined massively in 2014. And of
  46398. 28:34:53course we can go and add more measures
  46399. 28:34:55to our data not only the total sales.
  46400. 28:34:57For example, let's go and calculate the
  46401. 28:34:59total number of customers. So we can say
  46402. 28:35:02count distinct customer key as total
  46403. 28:35:06customers. So let's go and execute it.
  46404. 28:35:09And with that we can check are we
  46405. 28:35:10gaining like customers over the time if
  46406. 28:35:13there are any trends that we can see and
  46407. 28:35:15we can go and keep extending stuff like
  46408. 28:35:17we can go and add the total number of
  46409. 28:35:19quantities. So summarize quantity as
  46410. 28:35:23total quantity. So let's go and execute
  46411. 28:35:26and with that we have really nice
  46412. 28:35:27picture in order to understand is the
  46413. 28:35:30revenue increasing or decreasing over
  46414. 28:35:32the time what is the best year the worst
  46415. 28:35:35year are we gaining customers over time
  46416. 28:35:37if there any like trends that we can
  46417. 28:35:39spot now by looking to the result you
  46418. 28:35:41can see this gives us highlevel
  46419. 28:35:43long-term view of your data and of
  46420. 28:35:45course it helps for strategic decisions
  46421. 28:35:48and now what we can do we can go and
  46422. 28:35:50drill down to the months so we can go
  46423. 28:35:52and aggregate the data by the month
  46424. 28:35:54regardless list the years in order to
  46425. 28:35:56give us an idea how each month is
  46426. 28:35:58performing on average. So all what we
  46427. 28:36:00have to do is to switch the function
  46428. 28:36:02from year to a month like this. And of
  46429. 28:36:04course for the group by and the order by
  46430. 28:36:06let's go and execute and of course in
  46431. 28:36:09the output we will get all the months
  46432. 28:36:11and guess what which month is the best
  46433. 28:36:13for sales is of course December because
  46434. 28:36:16you have all those Christmas and stuff
  46435. 28:36:18and the worst months as you can see is
  46436. 28:36:20February. So with that we are
  46437. 28:36:22understanding the seasonality of our
  46438. 28:36:24business and the trends patterns of our
  46439. 28:36:26business. And as you are not including
  46440. 28:36:28the year in our analyzes you are
  46441. 28:36:30aggregating all the data from all years.
  46442. 28:36:33Now what we can do we can make it more
  46443. 28:36:35specific for each year where you go and
  46444. 28:36:37add the year informations to our query.
  46445. 28:36:40So we can have both a year and months.
  46446. 28:36:42Let me just change this to a month. And
  46447. 28:36:45of course we have to go and add it to
  46448. 28:36:47the group by and the order by. So let's
  46449. 28:36:50go and execute and with that we are
  46450. 28:36:51aggregating the data of a month of
  46451. 28:36:53specific year. So now we have all the
  46452. 28:36:55months of all years and now if you want
  46453. 28:36:58to focus on only one year what you can
  46454. 28:37:00do you can go and filter the data by the
  46455. 28:37:02order year and with that you can see how
  46456. 28:37:04the data is evolving over time. Now of
  46457. 28:37:06course in SQL we can go and format the
  46458. 28:37:08date differently. So instead of using
  46459. 28:37:11the year and the month in separate
  46460. 28:37:13columns what we can do we can use the
  46461. 28:37:15date trunk function. So instead of here
  46462. 28:37:17we're going to say date trunk and if you
  46463. 28:37:19want the granularity of your date at the
  46464. 28:37:21month level we're going to say month and
  46465. 28:37:23then the date and with that you will get
  46466. 28:37:27both the year and the date and let's
  46467. 28:37:30call it order date like this. So let's
  46468. 28:37:32go and execute. Now in the output we
  46469. 28:37:34will get exactly the same result as
  46470. 28:37:36before but instead of having like two
  46471. 28:37:38columns for the year and the month we
  46472. 28:37:40have everything in one and because we
  46473. 28:37:42saved the month that means it's still
  46474. 28:37:44going to go and remove all the days. So
  46475. 28:37:46as you can see it always starts with the
  46476. 28:37:48one. So the first day of the month and
  46477. 28:37:50with that you will get one row for each
  46478. 28:37:53month for each year. And if you want to
  46479. 28:37:55change that quickly to a year just you
  46480. 28:37:57go and change the date parts to a year
  46481. 28:38:00and you will get the granularity of the
  46482. 28:38:01year. Now if you don't like this format
  46483. 28:38:03and you would like to have your specific
  46484. 28:38:05format what you can do you can go and
  46485. 28:38:08use the format function. So format the
  46486. 28:38:11first argument is going to be the date
  46487. 28:38:13and then you go and do your format that
  46488. 28:38:15you want. So for example it start with
  46489. 28:38:17the years and let's say I would like to
  46490. 28:38:19have the abbreviation of the month name.
  46491. 28:38:22So something like this and of course
  46492. 28:38:24group by and order by. So let's go and
  46493. 28:38:27execute it. And with that we got our
  46494. 28:38:29format the year minus then the
  46495. 28:38:31abbreviation of the month. But you have
  46496. 28:38:32to be careful which function you are
  46497. 28:38:34using because the format you will get in
  46498. 28:38:36the output a string. And as you can see
  46499. 28:38:38you cannot sort it correctly. So the
  46500. 28:38:41data here is sorted by the year but not
  46501. 28:38:43by the month. But if you are using date
  46502. 28:38:45trunk you can see the data is correctly
  46503. 28:38:48sorted. So if we switch it to a month it
  46504. 28:38:51will be as well. Okay. So everything is
  46505. 28:38:53sorted correctly because the output here
  46506. 28:38:55is a date and SQL going to sort the date
  46507. 28:38:58correctly. It is not string. And if you
  46508. 28:39:00are using the year and the month the
  46509. 28:39:02output here going to be an integer and
  46510. 28:39:05sorting an integer is not a problem. So
  46511. 28:39:07of course you can go and pick the one
  46512. 28:39:08that you like. So that's it. Let's go
  46513. 28:39:11and execute it. And now you can go and
  46514. 28:39:13keep analyzing by finding another date
  46515. 28:39:15in our data set and another measure. So
  46516. 28:39:18as you can see it is very simple. Okay.
  46517. 28:39:20So that's all about how to analyze the
  46518. 28:39:22trends and the change over time. Now in
  46519. 28:39:24the next step we're going to do some
  46520. 28:39:25kind of advanced aggregations by doing
  46521. 28:39:27cumulative
  46522. 28:39:32analyszis. Okay. So what is cumulative
  46523. 28:39:34analyszis? It is aggregating the data
  46524. 28:39:37progressively over the time and this is
  46525. 28:39:39very important technique in order to
  46526. 28:39:41understand how our business is growing
  46527. 28:39:44over the time. So how our business is
  46528. 28:39:46progressing over the time whether it is
  46529. 28:39:48growing or declining it is very
  46530. 28:39:50interesting analyszis. So the formula
  46531. 28:39:52going to be very similar to the changes
  46532. 28:39:54over time but instead of having a simple
  46533. 28:39:56aggregations on the measure we're going
  46534. 28:39:57to aggregate our measure but this time
  46535. 28:39:59cumulative. So we are like adding stuff
  46536. 28:40:01on top of each others and the data again
  46537. 28:40:03can split it by the date dimension cuz
  46538. 28:40:06we want to track the progress over the
  46539. 28:40:08time. For example, we can find the
  46540. 28:40:10running total of sales or the moving
  46541. 28:40:12average of sales by a month. So now
  46542. 28:40:15let's have again our simple example
  46543. 28:40:16where our sales is splitted by the
  46544. 28:40:18years. Now this is the classic change
  46545. 28:40:20over time. But in order now to make it
  46546. 28:40:22cumulative what can happen? We're going
  46547. 28:40:24to take the measure and add to it. For
  46548. 28:40:26example, 2024 we have 300. And now for
  46549. 28:40:292025, we're going to add the 300
  46550. 28:40:31together with the 100 in order to make
  46551. 28:40:34it cumulative. So for 2025, we're going
  46552. 28:40:36to have 400. And the same thing for
  46553. 28:40:382026, we're going to go and add the 400
  46554. 28:40:41together with the 200. And with that, we
  46555. 28:40:43will get 600. So as you can see, we are
  46556. 28:40:45keep adding the values in order to
  46557. 28:40:47generate something called cumulative
  46558. 28:40:49value. Now for this type of analysis, we
  46559. 28:40:51use in SQL the aggregate window
  46560. 28:40:53functions. in order to find out the
  46561. 28:40:55cumulative values. So now let's go and
  46562. 28:40:57apply our formula in order to find
  46563. 28:40:59whether our business is growing or
  46564. 28:41:01declining. So let's go. Okay, so now we
  46565. 28:41:02have to analyze the following. We're
  46566. 28:41:04going to calculate the total sales for
  46567. 28:41:06each month and as well the running total
  46568. 28:41:08of sales over time in order to analyze
  46569. 28:41:10the trends. So let's see how we're going
  46570. 28:41:12to do that. Let's start with the easy
  46571. 28:41:14stuff where we're going to calculate the
  46572. 28:41:15total sales for each month. So we are
  46573. 28:41:17calculating the changes over time and we
  46574. 28:41:18have already done that. So all what we
  46575. 28:41:20need is a date and a measure. Our date
  46576. 28:41:22going to be the order date and the
  46577. 28:41:24measure going to be the sales amount
  46578. 28:41:26from our fact
  46579. 28:41:27table. So let's query this. And now we
  46580. 28:41:30want to find the total sales for each
  46581. 28:41:32month. That means we're going to change
  46582. 28:41:33the granularity of the order date from a
  46583. 28:41:35day to a month. And I usually like using
  46584. 28:41:38the date rank for this kind of tasks.
  46585. 28:41:40And the granularity going to be the
  46586. 28:41:42month. So this is the order
  46587. 28:41:44dates. And now for the sales we're going
  46588. 28:41:47to use aggregate function sum sales as
  46589. 28:41:49total sales. And of course we have to go
  46590. 28:41:52and group up the data by the
  46591. 28:41:54date. So let's go and execute it. So as
  46592. 28:41:59you can see we have now the total sales
  46593. 28:42:00for each month. And don't forget to get
  46594. 28:42:03rid of the nulls. So where we can say
  46595. 28:42:05where order date is not null. Now it
  46596. 28:42:09looks better. We don't have nulls. And
  46597. 28:42:10of course we can go and order the data
  46598. 28:42:12by our date. Now our measure is just
  46599. 28:42:15aggregated for each month individually.
  46600. 28:42:17Right? But we don't want that. We want
  46601. 28:42:19to have like a running total. So we'd
  46602. 28:42:22like to have like commumulative metric.
  46603. 28:42:24In order to do that, we have to use
  46604. 28:42:26window function. So let's go and do
  46605. 28:42:27that. We will use a subquery for that.
  46606. 28:42:30In order just to make it simple. So what
  46607. 28:42:32we need? We need the order date and
  46608. 28:42:34let's say the total sales and here we
  46609. 28:42:36have to have our window
  46610. 28:42:39function. Then we're going to put the
  46611. 28:42:41rest in a subquery. And of course we can
  46612. 28:42:44go and get rid of the order by because
  46613. 28:42:46anyway our data going to be sorted using
  46614. 28:42:48the window function. So now let's start
  46615. 28:42:49writing our window function. We will
  46616. 28:42:52have the sum of total sales. So we want
  46617. 28:42:56to summarize those new values. And we're
  46618. 28:42:58going to build a window function like
  46619. 28:43:00this over. We don't have to go and
  46620. 28:43:01partition anything. So we can go
  46621. 28:43:03immediately and say order by our new
  46622. 28:43:06order date that we have calculated. And
  46623. 28:43:08we want it to be ascending. So actually
  46624. 28:43:10that's it. So as running total sales. So
  46625. 28:43:15let's try that out. Now if you look to
  46626. 28:43:16the result you can see that all those
  46627. 28:43:19values are cumulative and it is working
  46628. 28:43:21like this. The first total sales is
  46629. 28:43:23equal to the total sales because
  46630. 28:43:25previously we don't have anything. Now
  46631. 28:43:27for the next row what going to happen is
  46632. 28:43:29going to go and add this value to the
  46633. 28:43:32previous one. And with that we get the
  46634. 28:43:34running total value. Now moving on to
  46635. 28:43:36the third row is going to go and add all
  46636. 28:43:38those three values together. And of
  46637. 28:43:40course this going to give us the running
  46638. 28:43:42total for this month and so on. So as
  46639. 28:43:44SQL is moving through the window it is
  46640. 28:43:48always adding the current value to all
  46641. 28:43:50previous values. And this is because of
  46642. 28:43:52the default frame of the window. The
  46643. 28:43:54frame going to be between the unbounded
  46644. 28:43:57preceding and the current row. So that
  46645. 28:43:59means for example if we are at this row
  46646. 28:44:01over here current total sales for this
  46647. 28:44:03month is this one and the unbounded
  46648. 28:44:05preceding is all the values before this
  46649. 28:44:08month. So that means we are getting all
  46650. 28:44:10the previous values together with the
  46651. 28:44:12current value and with that we will get
  46652. 28:44:15the effect of the running total sales.
  46653. 28:44:17And now of course as you can see it is
  46654. 28:44:19going through all the years. Right now
  46655. 28:44:22we can go and limit the running total
  46656. 28:44:24for only one year. So for each new year
  46657. 28:44:27it has to reset and start from the
  46658. 28:44:29scratch. So that means we are
  46659. 28:44:30partitioning the data. For each year we
  46660. 28:44:33would like to have partition. For the
  46661. 28:44:34first year, it's going to be 2010. It is
  46662. 28:44:36one row. And for the 2011, we're going
  46663. 28:44:39to get the whole partition over here.
  46664. 28:44:41So, in order to partition our window,
  46665. 28:44:43it's very simple. We're going to go and
  46666. 28:44:44say partition by the order date. That's
  46667. 28:44:49it. Let's go and execute it. Now, let's
  46668. 28:44:51go and check for the first partition for
  46669. 28:44:532010. You can see the running total is
  46670. 28:44:55the same as the first month. But since
  46671. 28:44:57we have only one month, that's it for
  46672. 28:44:59this year. Now, as we go to the next
  46673. 28:45:01year, as you can see, it resets. So you
  46674. 28:45:04can see the running total sales for
  46675. 28:45:062011. It is exactly as January. It is
  46676. 28:45:09not adding up now the value of the
  46677. 28:45:11current value with the previous one
  46678. 28:45:13because the previous one is outside of
  46679. 28:45:15the window. So as you can see we are
  46680. 28:45:17getting running total for the whole year
  46681. 28:45:19and once we hit a new year it is going
  46682. 28:45:22to reset. So it is working and this is
  46683. 28:45:24how you can create cumulative values in
  46684. 28:45:26SQL. And of course if you would like to
  46685. 28:45:28change the granularity of our data it is
  46686. 28:45:30very simple. All what you have to do is
  46687. 28:45:32to go over here and say instead of month
  46688. 28:45:34we're going to make it as a year. And of
  46689. 28:45:36course don't forget to change as well
  46690. 28:45:38the group by. So let's go ahead and
  46691. 28:45:40execute. And with that we are creating
  46692. 28:45:42cumulative values for each year. But of
  46693. 28:45:45course it makes no sense to partition by
  46694. 28:45:47the years. Let's go and remove it and
  46695. 28:45:50execute it again. And with that you are
  46696. 28:45:52creating the running total sales the
  46697. 28:45:54cumulative metric over the years. So as
  46698. 28:45:56you can see it is very simple. Now we
  46699. 28:45:58can go and add like another measure and
  46700. 28:46:01another aggregation like for example
  46701. 28:46:03instead of finding the running total we
  46702. 28:46:05can find the moving average. So let's
  46703. 28:46:07for example go and get the moving
  46704. 28:46:09average of the price. So first we have
  46705. 28:46:12to calculate the average of the price as
  46706. 28:46:15average price. And now what we have to
  46707. 28:46:16do is to go and make another window
  46708. 28:46:19function over here where we are saying
  46709. 28:46:22average the average price and we're
  46710. 28:46:25going to go and call it moving
  46711. 28:46:27average. That's it. So let's go and
  46712. 28:46:30execute it. And with that you are
  46713. 28:46:32getting the moving average price of our
  46714. 28:46:34sales. All right. So now you might still
  46715. 28:46:36asking what is really different between
  46716. 28:46:38using a normal aggregation and
  46717. 28:46:40cumulative aggregation. Well, we usually
  46718. 28:46:43use normal aggregations in order to
  46719. 28:46:45check the performance of each individual
  46720. 28:46:47row. Like if I want to see how each year
  46721. 28:46:49is performing, I'm going to go and do a
  46722. 28:46:51normal aggregation. But if you want to
  46723. 28:46:53see a progression and you want to
  46724. 28:46:55understand how your business is growing,
  46725. 28:46:57you have to go and use cumulative
  46726. 28:46:59aggregations because you can see easily
  46727. 28:47:01here the progress of your business over
  46728. 28:47:04the years. So there is like a difference
  46729. 28:47:06between using cumulative value and
  46730. 28:47:08normal aggregation. All right. So with
  46731. 28:47:10that you have done with the cumulative
  46732. 28:47:12analyszis and you have learned all
  46733. 28:47:14different types of aggregations. Now the
  46734. 28:47:16next step in our road map we're going to
  46735. 28:47:18do performance
  46736. 28:47:22analyszis. Okay. So what is performance
  46737. 28:47:24analyszis? It is the process of
  46738. 28:47:26comparing the current value with a
  46739. 28:47:29target value to compare the performance
  46740. 28:47:31of specific category and this can help
  46741. 28:47:33us in order to measure the success to
  46742. 28:47:35compare the performance. So the formula
  46743. 28:47:37for that is very simple. We're going to
  46744. 28:47:39find the difference between the current
  46745. 28:47:41measure and the target measure by
  46746. 28:47:43subtracting them. Like for example, we
  46747. 28:47:44can go and compare the current sale with
  46748. 28:47:46the average sale or the current year
  46749. 28:47:49sales with the previous year sales or
  46750. 28:47:51the current sales with the lowest sales
  46751. 28:47:54or maybe the highest sales. So as you
  46752. 28:47:56can see we are always comparing the
  46753. 28:47:57current measure together with a target
  46754. 28:48:00with something else. So for example, we
  46755. 28:48:01have here again a measure that is
  46756. 28:48:02splitted by three categories. So those
  46757. 28:48:04values are the current values. Now if
  46758. 28:48:07you have a target like for example the
  46759. 28:48:08average. Now as you can see for each row
  46760. 28:48:10we have like the 200. Now what we can do
  46761. 28:48:12once we have those two things in one row
  46762. 28:48:14we can go and simply subtract them. So
  46763. 28:48:16for the A the current value is exactly
  46764. 28:48:19equal to the average. Both of them is
  46765. 28:48:20200 and the difference between them is
  46766. 28:48:23zero. So this product is performing as
  46767. 28:48:25an average. Now for the next one we have
  46768. 28:48:27300 and the target is 200. So the
  46769. 28:48:29differences between them is 100. That
  46770. 28:48:31means this category is performing very
  46771. 28:48:34well. So this is a good performer. Now
  46772. 28:48:36for the last one we will get minus 100.
  46773. 28:48:38So that means it is below the average.
  46774. 28:48:41So it is not performing very well. And
  46775. 28:48:43for this type of analysis we usually use
  46776. 28:48:45window functions like the aggregate
  46777. 28:48:46window functions, the sum, average, max,
  46778. 28:48:49min or the value window functions like
  46779. 28:48:51lead and lag. So now let's go back to
  46780. 28:48:53SQL and apply this formula in order to
  46781. 28:48:56measure the performance of our business.
  46782. 28:48:58So let's go. All right my friends. So
  46783. 28:48:59now we have the following task. analyze
  46784. 28:49:01the yearly performance of products by
  46785. 28:49:04comparing their sales to both the
  46786. 28:49:06average sales performance of the
  46787. 28:49:08products and the previous year sales.
  46788. 28:49:10Okay, this sounds a little bit
  46789. 28:49:12complicated and serious. Let's have some
  46790. 28:49:13coffee before we
  46791. 28:49:15start. Okay, so what do we have over
  46792. 28:49:18here? So it is talking about the yearly
  46793. 28:49:20performance of products. So that means
  46794. 28:49:23we need the order date as a dimension
  46795. 28:49:25and as well the product and the measure
  46796. 28:49:27that is used over here is the sales. So
  46797. 28:49:30let's do it step by step. So we need
  46798. 28:49:32things from our fact table. So fact
  46799. 28:49:35sales and we need the product. So I'm
  46800. 28:49:37going to go and get it from the
  46801. 28:49:39dimension product in order to have a
  46802. 28:49:41nice name. So we have to join the data
  46803. 28:49:44by the product key and I'm going to go
  46804. 28:49:47and change the alias to P. So product
  46805. 28:49:51key. Okay. So with that we have our two
  46806. 28:49:53tables. Now let's go and select our
  46807. 28:49:54columns. So we need the order date. We
  46808. 28:49:57need the product name and we need our
  46809. 28:50:00measure. So it's going to be the sales
  46810. 28:50:02amount. All right. So now let's go and
  46811. 28:50:04query those informations. Now we have to
  46812. 28:50:06analyze the yearly performance. That
  46813. 28:50:08means we don't need the day. The
  46814. 28:50:10granularity is the years. So that's why
  46815. 28:50:12let's go and convert it using year
  46816. 28:50:15function. And we're going to call it
  46817. 28:50:17order year. And of course we have to go
  46818. 28:50:19and aggregate then the sales. And I'm
  46819. 28:50:21going to call it current sales. And of
  46820. 28:50:24course we have to group up the data by
  46821. 28:50:26the date, the year and as well by the
  46822. 28:50:30product name. So that's it. Let's go and
  46823. 28:50:34execute it. And of course I'm going to
  46824. 28:50:35go and get rid of all those nulls. So
  46825. 28:50:38where order date is not null. All right.
  46826. 28:50:42So with that we have solved the first
  46827. 28:50:44part. So we have the yearly performance
  46828. 28:50:46of the product. Now in the task we have
  46829. 28:50:49to compare this value the current sales
  46830. 28:50:51to the average sales performance of the
  46831. 28:50:54products. So that means we need the
  46832. 28:50:55average and as well the previous year
  46833. 28:50:58sales. So that means we have to compare
  46834. 28:51:00each value to the previous year for the
  46835. 28:51:02same product of course. So that means
  46836. 28:51:04things are getting a little bit more
  46837. 28:51:06complicated and with that we need the
  46838. 28:51:08help of the window functions. Let's do
  46839. 28:51:09it one by one. Let's focus on the
  46840. 28:51:11average sales. So now what we're going
  46841. 28:51:13to do based on those values based on
  46842. 28:51:15this results we will do a new
  46843. 28:51:17calculations and aggregations. And now
  46844. 28:51:19in order to do that either we use a
  46845. 28:51:22subquery or a city. I'm going to go with
  46846. 28:51:24a city because it looks nicer. So with
  46847. 28:51:27yearly product sales this is the new
  46848. 28:51:30name that we are giving for this
  46849. 28:51:32results. And now what we're going to do
  46850. 28:51:34we're going to build queries on top of
  46851. 28:51:35these results. So first of all I will
  46852. 28:51:38just select everything from this table.
  46853. 28:51:40yearly product sales just to test. So it
  46854. 28:51:42is working. Now I'm selecting data from
  46855. 28:51:45our city. So now the next step I'm going
  46856. 28:51:47to go and list all the columns that I
  46857. 28:51:49want in my results. So the order date,
  46858. 28:51:52the product
  46859. 28:51:53name, the current sales. This is just
  46860. 28:51:57nicer in order to have control on which
  46861. 28:51:59columns you want to present at the end
  46862. 28:52:01results. Now the next step, I'm going to
  46863. 28:52:02go and order the data by first the
  46864. 28:52:05product
  46865. 28:52:06name and then the order year. And with
  46866. 28:52:09that we can have better understanding of
  46867. 28:52:11the results. So we can see this product
  46868. 28:52:13has three years of sales and those are
  46869. 28:52:15the current sales for each year. So now
  46870. 28:52:17we have to go and calculate the average
  46871. 28:52:20of those three sales. So in order to do
  46872. 28:52:22that we're going to use the
  46873. 28:52:24average current sales over we have to
  46874. 28:52:29decide now how to partition the data.
  46875. 28:52:31Since we are focusing on the products we
  46876. 28:52:33have to partition the results by the
  46877. 28:52:35product name. So we're going to say
  46878. 28:52:36partition
  46879. 28:52:37by product name and we don't have to
  46880. 28:52:40sort the data because we are using the
  46881. 28:52:42average. So it doesn't matter how the
  46882. 28:52:44data is sorted. So let's call it average
  46883. 28:52:47sales. So let's go ahead and execute it.
  46884. 28:52:49And now if you are looking to the
  46885. 28:52:51results for this product the average
  46886. 28:52:53sales of all those three values is
  46887. 28:52:5513,000. So now as you can see for each
  46888. 28:52:58row we have the current sales and side
  46889. 28:53:01by side with the average sales and the
  46890. 28:53:03same thing for the next product as well.
  46891. 28:53:05So now since we have both of the
  46892. 28:53:07informations on the same row current
  46893. 28:53:09sales and the average the change the
  46894. 28:53:11difference between the current value and
  46895. 28:53:14the average value. So all what we have
  46896. 28:53:15to do is to go and subtract right. So
  46897. 28:53:17we're going to say the current sales
  46898. 28:53:20subtracted by the average sales and
  46899. 28:53:23we're going to call
  46900. 28:53:24it the difference in average. So let's
  46901. 28:53:28go and execute it. And now as you can
  46902. 28:53:30see we are getting now the comparison.
  46903. 28:53:32we have the differences between the
  46904. 28:53:34current and the average and of course
  46905. 28:53:36what I like to do is to make a flag or
  46906. 28:53:38like indicator whether we are above the
  46907. 28:53:41average below the average or at the
  46908. 28:53:42average so in order to do that we're
  46909. 28:53:44going to go and use the case when
  46910. 28:53:46statement so if the difference is higher
  46911. 28:53:50than zero then we are above the average
  46912. 28:53:53right above average oh let's have an
  46913. 28:53:55abbreviation for that and if we are
  46914. 28:53:58below zero that means we are below the
  46915. 28:54:00average right so below
  46916. 28:54:03then below average and if it is exactly
  46917. 28:54:06zero else then it is average. So that's
  46918. 28:54:10it. Let's end it and I'm going to call
  46919. 28:54:12it average change. So let's go and
  46920. 28:54:16execute it. Now if you focus again on
  46921. 28:54:18one of the products you can see the
  46922. 28:54:20current sales of this product in 2012 it
  46923. 28:54:23is below the average. It is really low.
  46924. 28:54:25And for the next year for 2013 it is
  46925. 28:54:29above the average. It was really nice
  46926. 28:54:31year for these products and the last
  46927. 28:54:33year 2014 it was again below the
  46928. 28:54:35average. So with that we have really
  46929. 28:54:37nice flag in order to see quickly
  46930. 28:54:39whether we are above or below the
  46931. 28:54:41average and it is interesting to see
  46932. 28:54:43whether we have zeros. So yeah sometimes
  46933. 28:54:46it is exactly like the average and here
  46934. 28:54:48we have like a zero. It's not below or
  46935. 28:54:50above. So with that we are comparing the
  46936. 28:54:53performance of the sales of each
  46937. 28:54:55products with the average. And as you
  46938. 28:54:57can see it is really simple. Yeah. using
  46939. 28:54:59the window functions. So let's go and
  46940. 28:55:01check again our task. We have compared
  46941. 28:55:03the current sales to the average sales
  46942. 28:55:05performance. Now we have to compare it
  46943. 28:55:07as well with the previous year sales. So
  46944. 28:55:10let's go back to our example over here.
  46945. 28:55:12This time we have to compare the current
  46946. 28:55:14sales not with the average but with the
  46947. 28:55:17previous year. So we don't have to write
  46948. 28:55:19like another CTE or query. We can
  46949. 28:55:21continue with the same results. So now
  46950. 28:55:23all what you have to do is to access the
  46951. 28:55:26previous year. And in order to do that,
  46952. 28:55:27we have amazing window function called
  46953. 28:55:30lag. So let's do it step by step. So now
  46954. 28:55:32we're going to go and create a new
  46955. 28:55:33column that's called lag. I want to
  46956. 28:55:36access the previous value of what the
  46957. 28:55:38current sales, right? So current sales
  46958. 28:55:42and
  46959. 28:55:42over we still have to partition the data
  46960. 28:55:45by the product name because we focus on
  46961. 28:55:47the products. So partition by product
  46962. 28:55:50name. But now in order to access the
  46963. 28:55:53previous value that means we have to
  46964. 28:55:55sort the data and we're going to sort it
  46965. 28:55:57by the years. We need the previous year.
  46966. 28:55:59So we're going to say order by order
  46967. 28:56:02year and we're going to sort it
  46968. 28:56:03ascending from the lowest to the
  46969. 28:56:05highest. So we're going to leave it like
  46970. 28:56:06this. And with that this window function
  46971. 28:56:08going to give us the previous year sales
  46972. 28:56:11of the products. So I'm just going to
  46973. 28:56:13call it previous year sales like this.
  46974. 28:56:15And I think here we have something
  46975. 28:56:17wrong. Okay. So let's go a and execute
  46976. 28:56:19it and let's go and focus on one of
  46977. 28:56:21those products. So now for the first
  46978. 28:56:22year of this product, the previous year
  46979. 28:56:25was null, right? So we don't have any
  46980. 28:56:27data from the previous year. But for the
  46981. 28:56:292013, we have a previous year of 2012.
  46982. 28:56:32So that's why now we are getting the
  46983. 28:56:35previous value of the sales based on the
  46984. 28:56:37years. And the same thing for the last
  46985. 28:56:39year over here. You can see we are
  46986. 28:56:41getting the previous sales. So it is
  46987. 28:56:43working. And for the next window, same
  46988. 28:56:45thing for the first year. we will get
  46989. 28:56:47null and the previous sales we will get
  46990. 28:56:49it from the previous year. So with that
  46991. 28:56:51we have now the previous sales and if
  46992. 28:56:53you check this over here we have in the
  46993. 28:56:56same row now the current sales of the
  46994. 28:56:58current year and as well the sales of
  46995. 28:57:01the previous year. Now what we have to
  46996. 28:57:03do the same thing we have to go and
  46997. 28:57:05subtract those two informations in order
  46998. 28:57:07to compare them. Right? So we're going
  46999. 28:57:09to go and do the same thing. So we will
  47000. 28:57:11get the current sales minus the whole
  47001. 28:57:14thing the whole window function and
  47002. 28:57:16we're going to call it previous year. So
  47003. 28:57:19difference of the previous year and with
  47004. 28:57:21that we are calculating the differences
  47005. 28:57:23between them. So for this year for this
  47006. 28:57:25product as you can see the difference
  47007. 28:57:27here is really big between the current
  47008. 28:57:29sales and the previous year. Now of
  47009. 28:57:31course what we can do we can go and make
  47010. 28:57:32as well a flag or an indicator. I'm
  47011. 28:57:35going to go and copy the whole thing
  47012. 28:57:37from the previous average but we have to
  47013. 28:57:39go and get the right function this and
  47014. 28:57:42the same over here and now it is not
  47015. 28:57:44above or below the average I'm going to
  47016. 28:57:46say it is increasing or decreasing right
  47017. 28:57:49so increase or decrease and we're going
  47018. 28:57:52to call it previous year change and
  47019. 28:57:54instead of average we can say no change
  47020. 28:57:57so let's go and execute it and I'm
  47021. 28:58:00having here an extra comma let's go and
  47022. 28:58:02execute it so again let's go and focus
  47023. 28:58:05of one of those products. For the first
  47024. 28:58:07year of this product, there is no change
  47025. 28:58:09because there is no previous year. For
  47026. 28:58:11the next year of this product, we have
  47027. 28:58:13an increase, right? Because the current
  47028. 28:58:15sales is way higher than the previous
  47029. 28:58:18year. And now by going to the last year
  47030. 28:58:19of this product, we have a decrease
  47031. 28:58:21because the current sales is less than
  47032. 28:58:24the previous year. So my friends, we
  47033. 28:58:26call this type of analyszis year over
  47034. 28:58:30year analyszis. And if you want to
  47035. 28:58:32calculate the month over month analyzes,
  47036. 28:58:34it's very simple. All what you have to
  47037. 28:58:36do is to go and change the function from
  47038. 28:58:38year to a month and with that you are
  47039. 28:58:40extracting the month part. And the
  47040. 28:58:42difference between analyzing the months
  47041. 28:58:44and years is of course the scope.
  47042. 28:58:46Year-over-year is good for long-term
  47043. 28:58:49trends analyzes where on the other hand
  47044. 28:58:51the month over month it is shortterm
  47045. 28:58:53trends analyzes. You are just focusing
  47046. 28:58:56on the seasonality of your data. So this
  47047. 28:58:58is how we analyze the performance of our
  47048. 28:59:01business by comparing the current
  47049. 28:59:03measure with a target measure and you
  47050. 28:59:05can go and use different dimensions and
  47051. 28:59:07stuff. So instead of the sales you can
  47052. 28:59:09check the quantity instead of products
  47053. 28:59:11you can check the customers and you can
  47054. 28:59:13go and compare the current information
  47055. 28:59:15not only with the average or the
  47056. 28:59:17previous year you can compare it with
  47057. 28:59:19the lowest sales and the highest sales
  47058. 28:59:21and it can open the door for many
  47059. 28:59:23different insights. But we are always
  47060. 28:59:25using the same methods using the window
  47061. 28:59:28functions. We compare the current value
  47062. 28:59:30with another value in our data sets. So
  47063. 28:59:33this is how we do performance
  47064. 28:59:34comparison. All right. So that you have
  47065. 28:59:36learned how to analyze the performance
  47066. 28:59:38of our business. Now in the next step
  47067. 28:59:40we're going to do partto-hole analyszis.
  47068. 28:59:43So let's
  47069. 28:59:46go. Okay. So now what is exactly part to
  47070. 28:59:49whole analyszis? Well, we use it in
  47071. 28:59:51order to find out the proportion of a
  47072. 28:59:53part relative to the whole. Well, here
  47073. 28:59:55we're going to analyze how an individual
  47074. 28:59:57category is contributing to the overall
  47075. 29:00:00in order to understand what is the most
  47076. 29:00:03impacting category to the overall
  47077. 29:00:05business. So now for the formula, it is
  47078. 29:00:07very simple. You have to go and pick one
  47079. 29:00:09of your measures divided by the total of
  47080. 29:00:12the measure and then multiply it by 100
  47081. 29:00:14in order to find the percentage by a
  47082. 29:00:16specific dimension. Like for example, if
  47083. 29:00:18you take the sales, so you divide the
  47084. 29:00:20sales by the total sales, multiplied by
  47085. 29:00:23100 by the category or if you take the
  47086. 29:00:25quantity divided by the total quantity
  47087. 29:00:28and then find the percentage by a
  47088. 29:00:30country. So for example, again we have
  47089. 29:00:31our measure splitted by categories. But
  47090. 29:00:33now instead of having this number, what
  47091. 29:00:35we're going to do, we're going to
  47092. 29:00:36calculate the percentage. So for the
  47093. 29:00:38first one, we're going to take the 200
  47094. 29:00:40divided by 600 multiply it by 100. So
  47095. 29:00:43we're going to get the percentage 33. So
  47096. 29:00:45once we do that for the all categories,
  47097. 29:00:47it's going to be now very easy to see
  47098. 29:00:49that the category P it is contributing
  47099. 29:00:51to the overall number by 50%. Which
  47100. 29:00:54makes it of course a top performer. So
  47101. 29:00:56you can visual in your head as like a
  47102. 29:00:58pie chart and you can see how each part
  47103. 29:01:01is contributing to the whole pie chart
  47104. 29:01:03and with that it can help us to
  47105. 29:01:04understand the importance of each
  47106. 29:01:06category to our business. So now let's
  47107. 29:01:08go and apply this formula to our
  47108. 29:01:10measures in order to understand the
  47109. 29:01:12importance of our categories. So let's
  47110. 29:01:14go. Okay. So now let's do part hole
  47111. 29:01:16analyszis. All what we need one
  47112. 29:01:17dimension and one measure. So for
  47113. 29:01:19example we have the following task. It
  47114. 29:01:21is very simple. Which categories
  47115. 29:01:22contribute the most to the overall
  47116. 29:01:25sales. So now let's go and do it step by
  47117. 29:01:27step. So first we're going to go and
  47118. 29:01:29collect the informations. So we need the
  47119. 29:01:31category. We need the sales amount and
  47120. 29:01:34those informations come as usual from
  47121. 29:01:37the fact sales and from our dimension
  47122. 29:01:41the product. Right? So we have quickly
  47123. 29:01:44to go and connect them using the product
  47124. 29:01:47key. Okay. So that's all what we need
  47125. 29:01:50for our query. So let's go and select.
  47126. 29:01:52So we have here the categories and the
  47127. 29:01:54sales amount. So now the first thing we
  47128. 29:01:56have to calculate the total sales for
  47129. 29:01:58each category. So let's go and do that.
  47130. 29:02:00It is very simple. So sum total sales
  47131. 29:02:04and we are grouping up the data by the
  47132. 29:02:07category. So this is basics. Right now
  47133. 29:02:09we have the total sales for each of
  47134. 29:02:11those categories. Now in order to
  47135. 29:02:13calculate the percentage we need two
  47136. 29:02:14measures the total sales for each
  47137. 29:02:16category and we have it here already and
  47138. 29:02:19as well side by side we need the total
  47139. 29:02:21sales across all categories. So the big
  47140. 29:02:24number without any dimension but now as
  47141. 29:02:26you look to the result you can see the
  47142. 29:02:28granularity here is that category. Now
  47143. 29:02:31we need the total sales again by
  47144. 29:02:33different granularity. And in order to
  47145. 29:02:35mix those stuff together we use the
  47146. 29:02:37window functions. So now how we going to
  47147. 29:02:39do it? either you go over here and start
  47148. 29:02:41writing your window function. And of
  47149. 29:02:42course, you can do it together with the
  47150. 29:02:44group by or you can do it as a second
  47151. 29:02:46step in your query using either a CTE or
  47152. 29:02:49a subquery. So I'm going to go with the
  47153. 29:02:51CTE just to make it clear. So category
  47154. 29:02:55sales like this. So now let's start
  47155. 29:02:58again selecting the same information. So
  47156. 29:03:00category total sales from our table
  47157. 29:03:03category or CTE sales. So let's go and
  47158. 29:03:07execute it. So now we have the same
  47159. 29:03:09results and now we're going to go and
  47160. 29:03:10build our window function like this. So
  47161. 29:03:12we're going to say the sum we want to
  47162. 29:03:14aggregate all those values right to get
  47163. 29:03:16the total sales over the whole data
  47164. 29:03:19sets. So we're going to say sum total
  47165. 29:03:21sales. And now in order to get the big
  47166. 29:03:24number we're going to say over and
  47167. 29:03:26inside it we will not define anything
  47168. 29:03:28because we don't want to partition the
  47169. 29:03:30data. We don't want to introduce any
  47170. 29:03:32dimension. We just want the big number.
  47171. 29:03:34And with that we will get the overall
  47172. 29:03:38sales. So let's go and execute it. Now
  47173. 29:03:41as you can see this is the total sales
  47174. 29:03:43by the category. So the total sales is
  47175. 29:03:46splitted by the categories. And this is
  47176. 29:03:48the overall sales of all orders of
  47177. 29:03:51everything the highest number. Now since
  47178. 29:03:53we have them side by side what we can do
  47179. 29:03:55we can very easily calculate the path to
  47180. 29:03:58whole or the percentage. So let's start
  47181. 29:04:01doing that. We need the total sales and
  47182. 29:04:03we want to go and divide it by the
  47183. 29:04:05overall sales. So we're going to take
  47184. 29:04:07our window function and put it over
  47185. 29:04:08here. So let's go and multiply it now
  47186. 29:04:11with 100. I'm going to go and call it
  47187. 29:04:14percentage of total. So let's go and
  47188. 29:04:18execute it. Now as you can see we are
  47189. 29:04:19getting zeros and that's because the
  47190. 29:04:21total sales is not float. So what we
  47191. 29:04:24have to do is to go and cast it to
  47192. 29:04:25something like a decimal. So floats like
  47193. 29:04:29this. So let's go and reexecute it. And
  47194. 29:04:31now, as you can see, we are getting now
  47195. 29:04:32the percentages, but we have a lot of
  47196. 29:04:35numbers after the comma. So, we're going
  47197. 29:04:37to go and round the numbers now. So,
  47198. 29:04:39let's go to the start round and then go
  47199. 29:04:42to the end, comma, and let's have like
  47200. 29:04:44two decimals. So, let's go and execute
  47201. 29:04:47it again. Now, looks perfect. Now, what
  47202. 29:04:49we can do, we can go and add like a
  47203. 29:04:51percentage. And with that, we are
  47204. 29:04:52converting the whole thing to a string.
  47205. 29:04:54So, we're going to do concatenation. So,
  47206. 29:04:56concat at the start and go to the end.
  47207. 29:05:00And let's add the percentage character.
  47208. 29:05:02And as well we can go and order the data
  47209. 29:05:05by the total sales descending. So let's
  47210. 29:05:09go and execute it. So now by looking to
  47211. 29:05:11the result you can see the category
  47212. 29:05:13bikes is dominating. So it is
  47213. 29:05:15overwhelming top performing the
  47214. 29:05:17categories. It is making 69% of the
  47215. 29:05:21total sales of our business. So this
  47216. 29:05:23means my friends most of the business
  47217. 29:05:25revenue comes from the bikes. And as you
  47218. 29:05:28can see the accessories and clothing
  47219. 29:05:30they are really minor contributors to
  47220. 29:05:32our business which is not really good
  47221. 29:05:35and this is actually dangerous thing. If
  47222. 29:05:37you have like one category dominating
  47223. 29:05:39your whole business you are over relying
  47224. 29:05:41on only one category in your business
  47225. 29:05:43and if this fails this category then the
  47226. 29:05:46whole business is going to fail. So by
  47227. 29:05:48looking to this either the business has
  47228. 29:05:49to decide removing all those products by
  47229. 29:05:52those two categories or to focus more on
  47230. 29:05:56bringing more revenue for the products
  47231. 29:05:58that are inside those two categories. So
  47232. 29:06:00as you can see guys those insights are
  47233. 29:06:03really amazing for the business and
  47234. 29:06:04helps the managers and the decision
  47235. 29:06:06makers to understand what is going on
  47236. 29:06:08quickly and make very critical
  47237. 29:06:11decisions. And now you can see as well
  47238. 29:06:12from the results perfectly why the part
  47239. 29:06:15to whole analyszis is very important
  47240. 29:06:17because by just looking to those numbers
  47241. 29:06:19it's going to be really hard to
  47242. 29:06:20understand the importance of the
  47243. 29:06:23categories. But seeing the data as a
  47244. 29:06:25percentage how each category is
  47245. 29:06:27contributing to the whole sales of the
  47246. 29:06:29business makes it easier to understand
  47247. 29:06:32which category is underperforming or top
  47248. 29:06:35performing. And now you have a very
  47249. 29:06:36simple formula where you can go and
  47250. 29:06:38change the metrics. For example, instead
  47251. 29:06:40of total sales, you can go and change
  47252. 29:06:42the aggregations to total number of
  47253. 29:06:44orders or the total number of customers.
  47254. 29:06:47So you can go and bring any type of
  47255. 29:06:49measures and bring it to this analyszis
  47256. 29:06:51and you're going to generate completely
  47257. 29:06:53new view for the decision makers in
  47258. 29:06:56order to develop a new strategy for the
  47259. 29:06:58business. It was very interesting. Now
  47260. 29:06:59in the next step, we're going to do my
  47261. 29:07:01favorite topic where we're going to
  47262. 29:07:03start doing data segmentations using
  47263. 29:07:04SQL. So let's go.
  47264. 29:07:10Okay. So now what is data segmentations?
  47265. 29:07:12What we're going to do here is we're
  47266. 29:07:13going to go and group up the data based
  47267. 29:07:15on specific range. So that means we're
  47268. 29:07:17going to go and create a new categories
  47269. 29:07:19and then go and aggregate the data based
  47270. 29:07:21on the new category. And the formula for
  47271. 29:07:23that going to be very interesting. So
  47272. 29:07:25it's going to be this time we're going
  47273. 29:07:26to have a measure by a measure not by
  47274. 29:07:29dimension. So you have to go and pick
  47275. 29:07:31two different measures and convert one
  47276. 29:07:33of those measures to a range or to a
  47277. 29:07:35group and then aggregate the data by
  47278. 29:07:36this measure. So for example, we're
  47279. 29:07:38going to go and calculate the total
  47280. 29:07:40number of products by the sales range or
  47281. 29:07:43the total number of customers by the age
  47282. 29:07:45group. So as you can see we have two
  47283. 29:07:46measures and we are trying to combine
  47284. 29:07:48them together in order to create new
  47285. 29:07:50insights. Let's have the following
  47286. 29:07:51example. So here for example we have
  47287. 29:07:53like two measures and now the first step
  47288. 29:07:55is that we're going to take one of those
  47289. 29:07:56measures and convert it to a dimension.
  47290. 29:07:59converted to a category. For example,
  47291. 29:08:01we're going to say if the values are
  47292. 29:08:03like equal or below 100, it will be
  47293. 29:08:05converted to a category called low. And
  47294. 29:08:08between 100 and 200, it's going to be
  47295. 29:08:10assigned to a new category called
  47296. 29:08:12medium. And everything above 200, it's
  47297. 29:08:15going to be large. So, as you can see
  47298. 29:08:16what we are doing, we are taking one
  47299. 29:08:18measure and based on the range of this
  47300. 29:08:20measure, we are building a new
  47301. 29:08:22categories, new dimension. And now the
  47302. 29:08:24final step is the easiest one. We're
  47303. 29:08:26going to go and aggregate another
  47304. 29:08:27measure based on the new category. So
  47305. 29:08:29we're going to have seven for low, six
  47306. 29:08:31for medium, and 15 for large. So with
  47307. 29:08:33that, as you can see, we are creating
  47308. 29:08:35new categories or segments based on a
  47309. 29:08:37measure. And then we are aggregating
  47310. 29:08:39another measure based of this new
  47311. 29:08:42segments. And in SQL, in order to create
  47312. 29:08:44those new categories and segments, we
  47313. 29:08:46use the amazing case when statements
  47314. 29:08:49because it's going to help us to define
  47315. 29:08:50the rules and based on the range, it's
  47316. 29:08:52going to go and create a new category
  47317. 29:08:54and labels. So now let's go and apply
  47318. 29:08:56this formula on our data set in order to
  47319. 29:08:59segment our data. So let's go. Okay. So
  47320. 29:09:01now let's go and segment our data and
  47321. 29:09:03all what we need is two measures. So now
  47322. 29:09:05we have the following task and it says
  47323. 29:09:07segment products into cost ranges and
  47324. 29:09:10count how many products fall into each
  47325. 29:09:12segment. So now by looking to this task
  47326. 29:09:14we have two measures. First the costs
  47327. 29:09:16and as well the second one is the total
  47328. 29:09:19number of products. And of course we
  47329. 29:09:21have to go and segment one of those two
  47330. 29:09:22measures. And in this task we are
  47331. 29:09:24segmenting the costs. So we have to
  47332. 29:09:27focus now on taking this measure and
  47333. 29:09:29convert it to a dimension. So now all
  47334. 29:09:31those informations are available in the
  47335. 29:09:33table products. So now let's go and
  47336. 29:09:35select few columns. We're going to get
  47337. 29:09:36the product key and let's get the
  47338. 29:09:40product name and the costs. That's all
  47339. 29:09:43what we need. So let's execute it. Now
  47340. 29:09:45as you can see this is our measure the
  47341. 29:09:47costs. Now we have to go and convert
  47342. 29:09:49this measure to dimension. And in order
  47343. 29:09:52to do that, we use the case win
  47344. 29:09:54statements. We always use the case win
  47345. 29:09:56statement in order to create new
  47346. 29:09:57categories. So let's go and do that.
  47347. 29:10:00Case win. Let's start with the first
  47348. 29:10:01range. Let's say it is below 100. So all
  47349. 29:10:04the costs that are below 100. We're
  47350. 29:10:07going to label it with a new value. It's
  47351. 29:10:09going to be below 100. So now let's go
  47352. 29:10:12to the next range. We are saying when
  47353. 29:10:14costs now between 100 and 500. So all
  47354. 29:10:19costs between this range. They will get
  47355. 29:10:21the label 100 and 500. So this is very
  47356. 29:10:25simple. Let's go and get another range.
  47357. 29:10:27For example, between 500 and 1,000. Then
  47358. 29:10:33it's going to get a label between 500
  47359. 29:10:35and 1,000. And now it depend how many
  47360. 29:10:37categories and segments you want to
  47361. 29:10:39create. Each row of this case when each
  47362. 29:10:42condition will be creating like a new
  47363. 29:10:44value for your dimension. So I'm going
  47364. 29:10:46to stop with that. I'm going to say at
  47365. 29:10:47the end else. So if the cost is not
  47366. 29:10:49fulfilling any of those, it's going to
  47367. 29:10:51be above 1,000. Right? So that's it.
  47368. 29:10:55Let's give it a name. It's going to be
  47369. 29:10:57cost range. So now let's go and execute
  47370. 29:10:59it. Now let's go and check the result.
  47371. 29:11:02For example, the cost here is zero. It
  47372. 29:11:03is below 100, which is correct. This
  47373. 29:11:06value is above 1,000. This is between
  47374. 29:11:08500 and 1,000. And this is between 100
  47375. 29:11:11and 500. So everything looks correct.
  47376. 29:11:14Nice. So with that we are done with the
  47377. 29:11:16first step where we have converted one
  47378. 29:11:18measure into a dimension. So with that
  47379. 29:11:20we have now our segments. The next step
  47380. 29:11:23with that we're going to go and
  47381. 29:11:25aggregate the data based on this a new
  47382. 29:11:27dimension. So either you do it in one go
  47383. 29:11:29or what I usually do I put everything in
  47384. 29:11:31one city or a subquery and I'm going to
  47385. 29:11:34call it products
  47386. 29:11:36segments as based on this results I'm
  47387. 29:11:40going to go and aggregate the data. So
  47388. 29:11:41this is my temporary results and now
  47389. 29:11:44we're going to go and just aggregate the
  47390. 29:11:45data like this. So let's get first our
  47391. 29:11:47dimension cost range and then we need
  47392. 29:11:50our measure. So it's going to be count
  47393. 29:11:52product
  47394. 29:11:53key as total products from our city. It
  47395. 29:11:58was the product segments and then group
  47396. 29:12:01by our new dimension. That's it. It's
  47397. 29:12:04very simple. Let's go and execute it
  47398. 29:12:06now. Now you can see in the output we
  47399. 29:12:08have our segmented measure and we can
  47400. 29:12:10see the total numbers in each of those
  47401. 29:12:13segment and range and of course we can
  47402. 29:12:14go and order the data by our aggregation
  47403. 29:12:17the total products. Let's go and execute
  47404. 29:12:19it maybe descending. So now as you can
  47405. 29:12:21see we have a lot of products that are
  47406. 29:12:24not costing a lot. It is below 100.
  47407. 29:12:26After that between 100 500 and the
  47408. 29:12:29lowest number of products is in the
  47409. 29:12:32range that is above 1,000. So we don't
  47410. 29:12:34have a lot of products that are costing
  47411. 29:12:36a lot and that's because maybe we have a
  47412. 29:12:38lot of accessories in the business. So
  47413. 29:12:40my friends this is very powerful. If
  47414. 29:12:42your dimensions in the data set is not
  47415. 29:12:45enough to create insights you can take
  47416. 29:12:47one of your measures convert it to a
  47417. 29:12:49dimension using case win and then
  47418. 29:12:51aggregate your other measures based on
  47419. 29:12:54this new dimension. So we are deriving
  47420. 29:12:56new informations and as I told you by
  47421. 29:12:58just following this concept measures and
  47422. 29:13:00dimensions you can generate endless
  47423. 29:13:03amount of reports even if your business
  47424. 29:13:05or your data set is small. Okay my
  47425. 29:13:08friends so now let's go and segment
  47426. 29:13:09something else. So this time it's going
  47427. 29:13:11to be a little bit more complicated. So
  47428. 29:13:13we have the following task and it says
  47429. 29:13:15group customers into three segments
  47430. 29:13:17based on their spending behavior. So we
  47431. 29:13:19have the VIB customers. They are the
  47432. 29:13:21customers with at least 12 months of
  47433. 29:13:24history and spending more than 5,000.
  47434. 29:13:27And the second category we have the
  47435. 29:13:29regular customers. They have at least as
  47436. 29:13:31well 12 months of history but they spend
  47437. 29:13:34like less than 5,000. And the last
  47438. 29:13:36category we have the new customers.
  47439. 29:13:38Their lifespan is less than 12 months.
  47440. 29:13:41And we have to find the total number of
  47441. 29:13:42customers by each group. So now here we
  47442. 29:13:44have a lot of measures and stuff. So the
  47443. 29:13:46first one is the total number of
  47444. 29:13:48customers. This is going to be the final
  47445. 29:13:50aggregation that we're going to do. But
  47446. 29:13:52what is interesting, we're going to
  47447. 29:13:53build the segments and this time is
  47448. 29:13:55based on different columns. So first it
  47449. 29:13:58is based on a measure the total number
  47450. 29:14:00of months for each customer and as well
  47451. 29:14:03the total spending, the total number of
  47452. 29:14:05sales. So we have the sales, we have the
  47453. 29:14:08total number of months and as well the
  47454. 29:14:10total number of customers. So now we're
  47455. 29:14:11going to do it step by step. Don't you
  47456. 29:14:13worry about it. So now what I usually
  47457. 29:14:14do, I start collecting all the data that
  47458. 29:14:16I need. So what do we need? We need a
  47459. 29:14:19customer key. In order to do the
  47460. 29:14:21aggregation for the total number of
  47461. 29:14:22customers, we need as well the sales
  47462. 29:14:24amount right for the spending. And now
  47463. 29:14:27in order to calculate those number of
  47464. 29:14:29months, we need a date. And for that, we
  47465. 29:14:32have to calculate the lifespan of a
  47466. 29:14:34customer. And usually we create it using
  47467. 29:14:36the order date. I'm going to show you
  47468. 29:14:38how we're going to do it. So we need the
  47469. 29:14:39order date. And of course, we have to
  47470. 29:14:41select our table. So let's start with
  47471. 29:14:43the fact table. So fact sales and we're
  47472. 29:14:46going to join it with the
  47473. 29:14:48customers. So our dimension customers
  47474. 29:14:51and the key for that it is the customer
  47475. 29:14:54key as well for the customers. And here
  47476. 29:14:56we have to specify which column come
  47477. 29:14:58from which table. So the first one from
  47478. 29:15:00the customers, the sales from the fact
  47479. 29:15:02and the order date from the fact as
  47480. 29:15:04well. So now let's go and execute. Now
  47481. 29:15:07we can see we have our customers, the
  47482. 29:15:09sales and the order dates. So now the
  47483. 29:15:11sales going to help us in order to
  47484. 29:15:12specify the range of spending. But now
  47485. 29:15:15what is interesting we have to calculate
  47486. 29:15:17the lifespan. So now in order to get the
  47487. 29:15:19lifespan we have to find out the first
  47488. 29:15:21order and the last order of each
  47489. 29:15:24customer. So how many months is between
  47490. 29:15:26the first order and the last order. So
  47491. 29:15:28in order to do that we need the min
  47492. 29:15:31function for the order dates. So this is
  47493. 29:15:34the first order and the max in order to
  47494. 29:15:37get the last order. Right.
  47495. 29:15:41And since we are using min and max, we
  47496. 29:15:43have to go and group up the data. And we
  47497. 29:15:45need to do that anyway in order to get
  47498. 29:15:47the total spending. So for the sales
  47499. 29:15:50amount, we're going to have the sum in
  47500. 29:15:52order to have the total spend total
  47501. 29:15:56spending. And we don't need the order
  47502. 29:15:58age. And the dimension where we're going
  47503. 29:15:59to group up the data is by the customer
  47504. 29:16:02key. So let's go and execute it. So now
  47505. 29:16:04in the results we have a list of all our
  47506. 29:16:06customers and as well the total spending
  47507. 29:16:09for each customer and we have the first
  47508. 29:16:11order date and the last order dates. Now
  47509. 29:16:13in order to calculate how many months
  47510. 29:16:16between the first order and the last
  47511. 29:16:18order we can go and use the function
  47512. 29:16:20date diff in order to get a new measure.
  47513. 29:16:23So let's go and do that date diff. And
  47514. 29:16:25now since we need the number of months
  47515. 29:16:27we're going to use the month and then
  47516. 29:16:29the second argument going to be the
  47517. 29:16:31first order. So order date and the
  47518. 29:16:35second one going to be the latest. So
  47519. 29:16:36max order date and we're going to call
  47520. 29:16:39this lifpan. So let's go and query and
  47521. 29:16:43let's have a look to our results. You
  47522. 29:16:45can see for this customer 712 between
  47523. 29:16:48the first order and the last order we
  47524. 29:16:50have 11 muscles and for this customer
  47525. 29:16:53over here we have zero because the first
  47526. 29:16:55order and the last order is in the same
  47527. 29:16:57month and maybe there is only one order.
  47528. 29:16:59So with that we have the lifespan and as
  47529. 29:17:01you can see guys we have derived a new
  47530. 29:17:04measure from the dimension order age in
  47531. 29:17:07order later to derive from this new
  47532. 29:17:09measure a new dimension the segments. So
  47533. 29:17:12we are converting a dimension to a
  47534. 29:17:14measure and then from a measure to a new
  47535. 29:17:16dimension and this is usually what we do
  47536. 29:17:18in analyzes and in SQL. So now do we
  47537. 29:17:21have all the informations for the logic?
  47538. 29:17:23So we have the lifespan. So we have the
  47539. 29:17:25total number of monsters, we have the
  47540. 29:17:27total spending and I think we are ready
  47541. 29:17:29to start building our segments. So now
  47542. 29:17:31what we're going to do, we're going to
  47543. 29:17:32create the segments based on these
  47544. 29:17:34results that we have prepared. So this
  47545. 29:17:36result is the intermediate result before
  47546. 29:17:38the final one. Now either you're going
  47547. 29:17:40to put it in a CTE or subquery. Well, I
  47548. 29:17:43usually go and use the CTE. It is nicer.
  47549. 29:17:47So with customer
  47550. 29:17:49spending and I'm going to put the whole
  47551. 29:17:52thing in ECT and we can start writing a
  47552. 29:17:54new query from the scratch based on the
  47553. 29:17:56inter results. So let's go and select
  47554. 29:17:58again the customer key. I'm going to get
  47555. 29:18:01the total spending and the lifpan. So we
  47556. 29:18:05don't actually need the first and the
  47557. 29:18:07last order and we're going to get all
  47558. 29:18:09those informations from our new city. So
  47559. 29:18:12let's go and execute. And now let's
  47560. 29:18:14start building the segments. And as
  47561. 29:18:16usual, we're going to go and use the
  47562. 29:18:17case win statements. It is just amazing
  47563. 29:18:20statements in order to derive and build
  47564. 29:18:23new columns. So now what do we have for
  47565. 29:18:25the first category? So they are the
  47566. 29:18:27customers over 12 months and spending
  47567. 29:18:29more than 5,000. So now we're going to
  47568. 29:18:31say if the laugh span is higher than 12
  47569. 29:18:35and the total spending is higher than
  47570. 29:18:395,000 then we have our VIB customers. So
  47571. 29:18:44this is the first label. Let's go to the
  47572. 29:18:47second one. If the lifespan as well I
  47573. 29:18:49think more than 12. So let's go and
  47574. 29:18:51check. Well, it is at least 12. I have
  47575. 29:18:53here mistake. So it's going to be larger
  47576. 29:18:56or equal. So now it is more correct. So
  47577. 29:18:58the customers that has at least 12
  47578. 29:19:00months but they spend like 5,000 or
  47579. 29:19:02less. So that means it's going to stay
  47580. 29:19:04the same condition but the total
  47581. 29:19:06spending will be less or equal 5,000s
  47582. 29:19:11and they are the regular customers. So
  47583. 29:19:14they will get this label. Now if it is
  47584. 29:19:17not fulfilling those two conditions what
  47585. 29:19:19this means this means this is a new
  47586. 29:19:22customer right. So they will get this
  47587. 29:19:24label. Let's go and have an end and
  47588. 29:19:26let's call it customer segments. So
  47589. 29:19:30let's go and execute it. Now let's have
  47590. 29:19:32a look for this customer 712. So the
  47591. 29:19:35total spending is less than 5,000. So
  47592. 29:19:38this customer is not a VIB and as well
  47593. 29:19:41the lifespan is less than 12. So that
  47594. 29:19:44means for us it is a new customer. Now
  47595. 29:19:46the next one we have a VIB. So this
  47596. 29:19:49customer has a history at least 12
  47597. 29:19:51months. So we have here 16 months and as
  47598. 29:19:53well the total spending more than 5,000.
  47599. 29:19:56That's why this customer is a VIB. But
  47600. 29:19:58now let's go and search for a regular
  47601. 29:20:01customer
  47602. 29:20:032349. So this customer spent less than
  47603. 29:20:065,000. So we are fulfilling this
  47604. 29:20:08condition over here and as well this
  47605. 29:20:10customer has at least 12 months of
  47606. 29:20:13history that's why we have a regular. So
  47607. 29:20:15now as you can see we have derived a new
  47608. 29:20:18dimension from two measures the lifespan
  47609. 29:20:21and the total spending. Now of course
  47610. 29:20:23the last step what is going to be we
  47611. 29:20:25have to go and find the total number of
  47612. 29:20:27customers for each of those categories.
  47613. 29:20:29So now what we're going to do we're
  47614. 29:20:30going to remove all those stuff and
  47615. 29:20:32we're going to start with our new
  47616. 29:20:33dimension and then comes the aggregation
  47617. 29:20:36count customer key. So as total
  47618. 29:20:40customers and then we have to group up
  47619. 29:20:42the data by our new dimension. So this
  47620. 29:20:46going to be really annoying if I'm going
  47621. 29:20:47to take this here and put it in the
  47622. 29:20:49group I because this means each time I'm
  47623. 29:20:52changing the logic I have to take care
  47624. 29:20:54of that twice. One in the select
  47625. 29:20:56statement and the second one in the
  47626. 29:20:58group I. So now actually instead of that
  47627. 29:21:00what I'm going to do I changed my mind.
  47628. 29:21:02I'm going to still having the
  47629. 29:21:04aggregation in the second step. So we
  47630. 29:21:06need the customer key we have the
  47631. 29:21:08definition of our customer segments. And
  47632. 29:21:10now I'm going to go and use the subquery
  47633. 29:21:13where I put the aggregation as a second
  47634. 29:21:15step. So my friends that means this is
  47635. 29:21:18again a second intermediate results. You
  47636. 29:21:21can of course put it in a second city.
  47637. 29:21:23So that means this is the first
  47638. 29:21:25intermediate results where we have
  47639. 29:21:27created the lifespan and the total
  47640. 29:21:28spending and the second intermediate
  47641. 29:21:30result is creating the customer segments
  47642. 29:21:33and the third step and the last one is
  47643. 29:21:35by doing the final aggregation. So we're
  47644. 29:21:37going to do it like this. Select our
  47645. 29:21:40dimension customer segments. Then we're
  47646. 29:21:43going to go and count the customer key
  47647. 29:21:46from our sub query. So this is our
  47648. 29:21:49subquery and don't forget to group by
  47649. 29:21:52our dimension customer segments. I think
  47650. 29:21:54I have it wrong. All right. So this is
  47651. 29:21:56the subquery and this is the final step
  47652. 29:21:58where we are aggregating everything. I'm
  47653. 29:22:00going to go and order the data by the
  47654. 29:22:03total customers like this. So now let's
  47655. 29:22:07go and execute the whole thing. Well
  47656. 29:22:10descending not ascending. Okay. Okay. So
  47657. 29:22:12now we can see from our results the
  47658. 29:22:14highest number of our customers belong
  47659. 29:22:17to the category new. So we have 14,000
  47660. 29:22:20customers that are new in our business.
  47661. 29:22:22And then the second category we have the
  47662. 29:22:24regular customers. So we have around
  47663. 29:22:262,000 customers. And in VIB we have a
  47664. 29:22:29lot of VIB customers. So we have
  47665. 29:22:321,655 VIB customers in our business. So
  47666. 29:22:34with that my friends, we have done data
  47667. 29:22:36segmentation. It is amazing. We have
  47668. 29:22:38segmented our customers based on their
  47669. 29:22:41spending behavior and as you can see all
  47670. 29:22:43those informations are totally derived
  47671. 29:22:46from the our data and this help us to
  47672. 29:22:48have a deep understanding of the
  47673. 29:22:50behavior of our customers and of course
  47674. 29:22:52this can help as well making smart
  47675. 29:22:58decisions. All right my friends so with
  47676. 29:23:00that we have covered the five different
  47677. 29:23:02types of data analytics thus we can do
  47678. 29:23:05using SQL. Now what I usually do as the
  47679. 29:23:07last tip in my project is that I try to
  47680. 29:23:09collect all the different types of
  47681. 29:23:11explorations and analyzes that I have
  47682. 29:23:13done in my data sets so that I can put
  47683. 29:23:15everything in one for example view or
  47684. 29:23:17table and then offer it to other users
  47685. 29:23:20and with that it going to help the other
  47686. 29:23:21users or stakeholders to make a quick
  47687. 29:23:24analyszis for decision- making. So now
  47688. 29:23:26what we're going to do, we're going to
  47689. 29:23:26have like some kind of requirements
  47690. 29:23:28where we're going to bring a lot of
  47691. 29:23:29different analyzes in one big script in
  47692. 29:23:32order to have insights about one object
  47693. 29:23:34like for example the customers. So I'm
  47694. 29:23:36going to show you the requirement of
  47695. 29:23:38this reports and we're going to analyze
  47696. 29:23:39it and start writing the scripts. So
  47697. 29:23:41let's go. Okay friends. So now let's
  47698. 29:23:43create a customer report and here are
  47699. 29:23:45the requirements for the report. So now
  47700. 29:23:48we have like a general statement. It
  47701. 29:23:49says this report should consolidate key
  47702. 29:23:52customer metrics and behaviors. So it
  47703. 29:23:54says first we have to gather all the
  47704. 29:23:56details about the customers like names,
  47705. 29:23:59age, transaction details and then we
  47706. 29:24:01have to segment the customers into
  47707. 29:24:03categories VIB, regular and new and as
  47708. 29:24:05well by the age groups and we have to
  47709. 29:24:07provide as well aggregations like the
  47710. 29:24:10total order, total sales, quantity,
  47711. 29:24:12products and so on. And we have to
  47712. 29:24:14generate important KPIs like the
  47713. 29:24:16recency, the average order value, the
  47714. 29:24:19average monthly spends. So we have a lot
  47715. 29:24:22of things and we're going to do it step
  47716. 29:24:23by step. All right. Now I'm going to
  47717. 29:24:24take you step by step in the process of
  47718. 29:24:26building a complex query that I usually
  47719. 29:24:29use in order to build a report. Now the
  47720. 29:24:31first thing that I usually do is I start
  47721. 29:24:33selecting the data from the database and
  47722. 29:24:36I usually start with the fact table. So
  47723. 29:24:38this is my starting point and then
  47724. 29:24:39usually I join it with the dimensions
  47725. 29:24:41and here I use lift join and after that
  47726. 29:24:44I think about how to filter the data
  47727. 29:24:46because usually we don't need all the
  47728. 29:24:48data that is available in the database
  47729. 29:24:50and of course in the result I will not
  47730. 29:24:52be selecting all the columns. I'm going
  47731. 29:24:54to be selecting only the relevant
  47732. 29:24:55columns that I need for my reports. So
  47733. 29:24:58since we have like complex query we will
  47734. 29:25:00be dividing the process into multiple
  47735. 29:25:02steps and I usually call this step the
  47736. 29:25:04base data and this going to be the
  47737. 29:25:06foundation the scope for the next steps
  47738. 29:25:08and since we have like multiple steps
  47739. 29:25:10I'm going to put this in a CTE so we
  47740. 29:25:12have this as an intermediate results and
  47741. 29:25:14what we're going to do in this step as
  47742. 29:25:16well we're going to do few
  47743. 29:25:17transformations like maybe calculating
  47744. 29:25:19and deriving new columns maybe
  47745. 29:25:21formatting the date so some basic
  47746. 29:25:23transformations so now let's go and
  47747. 29:25:24build this results for our report so the
  47748. 29:25:27first step is retrieving the core
  47749. 29:25:29columns from the tables. So let's go and
  47750. 29:25:31do it together. So we need of course our
  47751. 29:25:33fact table facts and we need our
  47752. 29:25:38dimension gold customer and as usual
  47753. 29:25:40we're going to go and connect them. All
  47754. 29:25:42right. Okay. So this is the basic and
  47755. 29:25:45now what we're going to do we're going
  47756. 29:25:46to go and retrieve all the columns that
  47757. 29:25:48we need for our reports. So let's start
  47758. 29:25:50picking stuff. So order number let's get
  47759. 29:25:53the product key the order date sales
  47760. 29:25:58amount quantity and I think that's all
  47761. 29:26:01from the facts let's go and get few
  47762. 29:26:03informations from the customers so let's
  47763. 29:26:06get the customer key the customer number
  47764. 29:26:10the first name and as well the last name
  47765. 29:26:13and what else we can go and get the
  47766. 29:26:15birth dates because we have to create
  47767. 29:26:16the age groups so birth dates let's go
  47768. 29:26:20and query. So I think those are all the
  47769. 29:26:23columns that we need in order to do the
  47770. 29:26:25next steps. And now before we go and
  47771. 29:26:27proceed with the aggregations, what
  47772. 29:26:29we're going to do, we're going to think
  47773. 29:26:30about filtering the data. As I recall,
  47774. 29:26:32we have some orders where the order date
  47775. 29:26:34is null. So I'm going to go and remove
  47776. 29:26:37those stuff. So order date is not null.
  47777. 29:26:40So that means in the first query the
  47778. 29:26:42base query not only I'm selecting the
  47779. 29:26:44columns that I need for the reports also
  47780. 29:26:47I'm defining the scope of the data sets
  47781. 29:26:49by filtering the data. So you can as
  47782. 29:26:51well make the scope here only one year
  47783. 29:26:53or something. Now what else we can do is
  47784. 29:26:54to think about all those columns and
  47785. 29:26:56whether we can do any type of
  47786. 29:26:58transformations in order to prepare them
  47787. 29:27:00for the aggregations. Like for example
  47788. 29:27:02I'm going to go and say you know what
  47789. 29:27:03instead of first and last name I'm going
  47790. 29:27:05to put them together in one. So it's
  47791. 29:27:07going to be the customer name. It's
  47792. 29:27:08better than having like two columns. So,
  47793. 29:27:10let's go and do it. We're going to say
  47794. 29:27:12concat and then we're going to start
  47795. 29:27:14with the first name and we're going to
  47796. 29:27:16have a separator between them. You can
  47797. 29:27:18have like a minus or a white space like
  47798. 29:27:21this and after that the last name. So,
  47799. 29:27:24let's call it customer name. And we can
  47800. 29:27:27go and get rid of those two columns. So,
  47801. 29:27:29let's go and execute. And with that, you
  47802. 29:27:31have everything in one column. Now,
  47803. 29:27:32another thing that we can prepare that
  47804. 29:27:35we don't need the birth date. We
  47805. 29:27:37actually need for our reports the age
  47806. 29:27:39groups. So that means we have to go and
  47807. 29:27:41calculate the age. So let's go and
  47808. 29:27:43transform it. So date diff we want it in
  47809. 29:27:46years, the birth date and the current
  47810. 29:27:49date from system and we're going to call
  47811. 29:27:50it age. So let's execute again. Perfect.
  47812. 29:27:54So with that we have all the data that
  47813. 29:27:56we need for our reports. Let's go and
  47814. 29:27:58put everything in one city. So I'm going
  47815. 29:28:00to call it with query as and put
  47816. 29:28:03everything in this city. And I'm going
  47817. 29:28:05to go and put this comment over here
  47818. 29:28:08inside the city. Perfect. And now we're
  47819. 29:28:10going to go and write a query from the
  47820. 29:28:13scratch. Paste on our intermediate
  47821. 29:28:15results. So base is query. It's execute.
  47822. 29:28:18All right. So now by looking to our
  47823. 29:28:20report with that we have the important
  47824. 29:28:22columns. Right. So now in the next step
  47825. 29:28:24we're going to do aggregations on top of
  47826. 29:28:26these intermediate results. So here
  47827. 29:28:28we're going to do all the aggregations
  47828. 29:28:29that is needed for the report and we're
  47829. 29:28:31going to put everything again in CTE as
  47830. 29:28:34an intermediate results which makes
  47831. 29:28:36everything a modular and easy to read.
  47832. 29:28:38So now let's go and do the necessary
  47833. 29:28:40aggregations on the result that we have
  47834. 29:28:42previously prepared. So that's why this
  47835. 29:28:44is very important as a second step in
  47836. 29:28:47our report. Always tend to make a
  47837. 29:28:49separated CTE only for aggregations. So
  47838. 29:28:52let's go and do that. I'm going to go
  47839. 29:28:54and select again all the customer
  47840. 29:28:56informations like the customer key
  47841. 29:28:58number, age. So I'm just going to copy
  47842. 29:29:00and paste and put it over here. And we
  47843. 29:29:03just need the column
  47844. 29:29:05names. So the key number, name, and age.
  47845. 29:29:09Now after that, we're going to start
  47846. 29:29:10doing aggregations. So what do you want
  47847. 29:29:12to aggregate is first, for example, the
  47848. 29:29:14total number of orders. So we're going
  47849. 29:29:16to go and count distinct order
  47850. 29:29:19number as total orders. So this is one
  47851. 29:29:24aggregation. We can go and summarize all
  47852. 29:29:26those sales
  47853. 29:29:27amounts as
  47854. 29:29:30total sales and the quantities as well.
  47855. 29:29:33So sum quantity as total quantity and as
  47856. 29:29:38well we can go and count how many
  47857. 29:29:40products did our customer order. So the
  47858. 29:29:43products key as total
  47859. 29:29:47products. So what I'm doing now I'm just
  47860. 29:29:50looking to our intermediate results and
  47861. 29:29:51try to figure out what we can aggregate
  47862. 29:29:54for example it makes no sense to
  47863. 29:29:55aggregate for example the ages right so
  47864. 29:29:58from the order number we have total
  47865. 29:29:59orders total product sales amount
  47866. 29:30:01quantity and from the right side we
  47867. 29:30:03cannot aggregate anything and that's
  47868. 29:30:05because they are the details of the
  47869. 29:30:06customers but from the fact table we can
  47870. 29:30:09do a lot of aggregations so now what we
  47871. 29:30:10can do with the order date over here we
  47872. 29:30:12can for example find the last order
  47873. 29:30:15dates from our customer which is really
  47874. 29:30:17nice information. So we can say max
  47875. 29:30:20order date as last order and of course
  47876. 29:30:23we can go and calculate the lifespan and
  47877. 29:30:26that we're going to need it as you
  47878. 29:30:27remember in order to categorize our
  47879. 29:30:30customer. So I will just copy and paste
  47880. 29:30:32it from the previous query is the date
  47881. 29:30:34diff month between the first order from
  47882. 29:30:37the customer and the last order of the
  47883. 29:30:39customer. So and we call this lifespan.
  47884. 29:30:42Okay. So we derived two measures or
  47885. 29:30:44aggregations from the order date. Now I
  47886. 29:30:47think we have done everything possible
  47887. 29:30:49and what is missing of course is to have
  47888. 29:30:51a group by because we are doing
  47889. 29:30:53aggregations and we are grouping by the
  47890. 29:30:56customer details. So going to be
  47891. 29:30:58customer key, customer number, name and
  47892. 29:31:01age. So I think we have everything for
  47893. 29:31:03our aggregations. Let's go and execute
  47894. 29:31:06it. A list of all customers and we have
  47895. 29:31:09few details about the customers and now
  47896. 29:31:11we have a lot of measures. So the total
  47897. 29:31:13order, total sales, total quantity,
  47898. 29:31:15products, the last order and the
  47899. 29:31:17lifespan. And with that we have covered
  47900. 29:31:20this part over here where we have
  47901. 29:31:22provided aggregations on the customer
  47902. 29:31:24level. So we have the details and we
  47903. 29:31:27have the aggregations. All right. So
  47904. 29:31:28with that we have now all the
  47905. 29:31:30preparations that is required to build
  47906. 29:31:32the final results. So it really depend
  47907. 29:31:35on the scenario. If it's possible we can
  47908. 29:31:37take all the data from one city or if
  47909. 29:31:39it's needed we can get it from multiple
  47910. 29:31:41cities. But in our scenario, we're going
  47911. 29:31:42to take it from the second city, the
  47912. 29:31:44aggregations, and we're going to prepare
  47913. 29:31:46the final results. So here we're going
  47914. 29:31:48to bring everything together and we
  47915. 29:31:49might introduce final transformations
  47916. 29:31:52that is needed for the reports. So let's
  47917. 29:31:54go and write the query for the final
  47918. 29:31:56results. Now we can go and start
  47919. 29:31:58segmenting our customer and as well
  47920. 29:32:01creating the KPIs. So let's go to the
  47921. 29:32:03third step. I'm going to go and put this
  47922. 29:32:05in a CTE. So let's call it customer
  47923. 29:32:08aggregation.
  47924. 29:32:10And now based on these results, we will
  47925. 29:32:13write the final query. So I like always
  47926. 29:32:16to put a comment about the steps. So the
  47927. 29:32:18first city is the base query where we
  47928. 29:32:20just joined the data and prepared it.
  47929. 29:32:22And then the second query is for the
  47930. 29:32:24aggregations. And the final one is for
  47931. 29:32:26the final results. So let's go and start
  47932. 29:32:29writing our final query. We will start
  47933. 29:32:31with select. And I'm going to go and
  47934. 29:32:32list again all the customer
  47935. 29:32:34informations. So I'm going to go and get
  47936. 29:32:36again same things. We have the customer
  47937. 29:32:39key, customer number, name, age and so
  47938. 29:32:41on. And now after that we need to create
  47939. 29:32:43the age categories. And now after that
  47940. 29:32:46I'm going to go and get all those
  47941. 29:32:47measures as well from our query. But of
  47942. 29:32:50course without the calculations I just
  47943. 29:32:52need the names of
  47944. 29:32:56it. So with that we have everything from
  47945. 29:32:59our previous CTE. So the customer
  47946. 29:33:02aggregation. Okay. So let's just test
  47947. 29:33:05it. Now everything is working. So now
  47948. 29:33:06what we have to do? We have to create
  47949. 29:33:08few categories age category and as well
  47950. 29:33:10the segments of the customers right for
  47951. 29:33:12segmenting the customers we have already
  47952. 29:33:14done the query so I will just copy and
  47953. 29:33:16paste it from the previous analyszis it
  47954. 29:33:18looks like this if the lifespan is at
  47955. 29:33:20least like 12 months and the sales above
  47956. 29:33:235,000 then a less or equal 5,000 then
  47957. 29:33:26regular otherwise it is a new customer
  47958. 29:33:28so this is our first segment but the
  47959. 29:33:31second segment about the ages we're
  47960. 29:33:32going to go and build it now and again
  47961. 29:33:34how we going to do it when so if the age
  47962. 29:33:36for example example less than 20 then
  47963. 29:33:39the customer is under 20. Let's make
  47964. 29:33:42another range where we say if the
  47965. 29:33:44customer age is
  47966. 29:33:46between 20 and let's say
  47967. 29:33:4929 then we have the second range and we
  47968. 29:33:53can keep repeating the same thing for
  47969. 29:33:55the second one. It really depend how
  47970. 29:33:57many categories you want to build. So 30
  47971. 29:34:00and 39 I belong to this group. Now the
  47972. 29:34:04next one let's have the 40s as well
  47973. 29:34:06right so 40 49 same thing over here and
  47974. 29:34:11now else let's say 50 and above right
  47975. 29:34:14and above so let's go and end it as age
  47976. 29:34:19group I just want to sort it little bit
  47977. 29:34:22like this okay now it looks nice so with
  47978. 29:34:24that again we have turned a measure into
  47979. 29:34:27a dimension and let's go and execute it
  47980. 29:34:29now so now by checking the results we
  47981. 29:34:32have the details of the customers and
  47982. 29:34:33Now we have a new category. So as you
  47983. 29:34:36can see it is working. 54 it is above
  47984. 29:34:3950. This is in the range between 40 and
  47985. 29:34:4249. We have here 67 above 50. I believe
  47986. 29:34:45we don't have any customer that is below
  47987. 29:34:4820. Right? Or even between 20 and 30.
  47988. 29:34:50Okay. So with that we have created our
  47989. 29:34:53two categories and by looking to the
  47990. 29:34:56reports you see we can segment the
  47991. 29:34:58customers now into categories. The VIB,
  47992. 29:35:00regular, new and the age group. And with
  47993. 29:35:02that we have covered all those three
  47994. 29:35:04requirements and we come now to the last
  47995. 29:35:06requirements. We have to calculate the
  47996. 29:35:08following KPIs. Now the first one it is
  47997. 29:35:10an easy one. It is the recency. How many
  47998. 29:35:12months since the last order we have
  47999. 29:35:14calculated over here the last order for
  48000. 29:35:16the customer. It is this one. And now in
  48001. 29:35:19order to find the recency it is very
  48002. 29:35:20simple. So all we have to do is to take
  48003. 29:35:22this over here. I will just put it maybe
  48004. 29:35:24after the segmentation. And all what you
  48005. 29:35:26have to do is to use the date diff as
  48006. 29:35:28usual. So month is the last order date
  48007. 29:35:32and the get date. So as you can see we
  48008. 29:35:35are using this setup like in many
  48009. 29:35:37analyzes right we always find the
  48010. 29:35:39differences between a date from our data
  48011. 29:35:41sets and the current date and time and
  48012. 29:35:43with that we will get the recency. So
  48013. 29:35:47let's go and execute it. Now you can see
  48014. 29:35:48how many months since the last order of
  48015. 29:35:51the customer and of course you can go
  48016. 29:35:53and test it using the last order date.
  48017. 29:35:55And this is really important in order to
  48018. 29:35:56understand whether the customer is still
  48019. 29:35:58active or inactive. Okay, so this is for
  48020. 29:36:01the first easy KPI. Now let's go to the
  48021. 29:36:03second one. It says calculate the
  48022. 29:36:05average order value. So how we going to
  48023. 29:36:08do this? Let's go back over here. Now in
  48024. 29:36:10order to compute the average order
  48025. 29:36:12value, we have to divide the total sales
  48026. 29:36:15by the total orders. So how many revenue
  48027. 29:36:18did the customer generate? And we divide
  48028. 29:36:20it by the total number of orders and
  48029. 29:36:22after that we have to find the average.
  48030. 29:36:24So it is very simple. Let's go and write
  48031. 29:36:26that. We're going to go to the end of
  48032. 29:36:27our table where we're going to put our
  48033. 29:36:29KPI and I'm going to say here compute
  48034. 29:36:32average order value. So as a shortcut
  48035. 29:36:35AVO. So we say total sales divided by
  48036. 29:36:39total orders. And let's call it average
  48037. 29:36:42order value. So let's go and execute it.
  48038. 29:36:45And if you go to the last over here, you
  48039. 29:36:47can see the average order value of our
  48040. 29:36:50customers. But now if you are dividing
  48041. 29:36:51numbers together you have to be careful
  48042. 29:36:53that you are not dividing by zero
  48043. 29:36:55otherwise you will get an error. So
  48044. 29:36:56imagine that a customer has a zero
  48045. 29:36:58didn't order anything you might get an
  48046. 29:37:01error. In our scenario, we don't have
  48047. 29:37:02that because we are starting from the
  48048. 29:37:04order table or the fact table. But
  48049. 29:37:06still, I like to make sure this never
  48050. 29:37:08happens. And for that, I usually go and
  48051. 29:37:10use the case when statements. Very
  48052. 29:37:12simple one. If the total orders is equal
  48053. 29:37:14to zero, then make it zero. Otherwise,
  48054. 29:37:18do the calculation that we talked about.
  48055. 29:37:20So like this. And at the ends, we will
  48056. 29:37:23add an end. So that's it. And with that,
  48057. 29:37:26I make sure we will never divide by
  48058. 29:37:28zero. So that's it. It was simple,
  48059. 29:37:30right? Let's go to the last KBI the
  48060. 29:37:33average monthly spend. So how we will
  48061. 29:37:36calculate that
  48062. 29:37:38compute average monthly spend. So now
  48063. 29:37:42since we are speaking about the spending
  48064. 29:37:44that means we need the total sales.
  48065. 29:37:46Right? So how much sales did the
  48066. 29:37:48customer generate totally and then we
  48067. 29:37:51divide it by the number of months and
  48068. 29:37:53with that we will get the average
  48069. 29:37:55monthly spend. Right? So that means we
  48070. 29:37:57can divide the total sales by the
  48071. 29:38:00lifespan as we calculated it is the
  48072. 29:38:02period where the customer has been
  48073. 29:38:04active from the starts until the end.
  48074. 29:38:06Okay. So now let's do it step by step.
  48075. 29:38:08First we have to be careful that we are
  48076. 29:38:10not dividing by zero and I believe in
  48077. 29:38:12the lifespan we have zeros. So what
  48078. 29:38:14we're going to say as usual case when
  48079. 29:38:16lifespan is equal to zero then this time
  48080. 29:38:19we will not make it zero the customer
  48081. 29:38:21exist only for one month. So what we can
  48082. 29:38:23do we can get the total sales of the
  48083. 29:38:25customer and we don't have to divide it
  48084. 29:38:27by the month in order to find the
  48085. 29:38:29average because the average is equal to
  48086. 29:38:31the current total
  48087. 29:38:32sales. So with that we make sure we are
  48088. 29:38:35not dividing by zero otherwise we're
  48089. 29:38:37going to have our calculation. So total
  48090. 29:38:39sales divided by life span. So the total
  48091. 29:38:43sale divided by the months and with that
  48092. 29:38:45we will get the average monthly spend.
  48093. 29:38:47So and and ass and we're going to call
  48094. 29:38:50it average monthly spend. Perfect. So
  48095. 29:38:54let's go and try that out. Let's go to
  48096. 29:38:56the right side. And with that we have
  48097. 29:38:58our third KPI and we have the average
  48098. 29:39:01monthly spends. And with that guys, we
  48099. 29:39:03have now full reports about the
  48100. 29:39:06customers and we have covered all the
  48101. 29:39:08requirements. All right. So with that we
  48102. 29:39:09have the final results and we have
  48103. 29:39:11fulfilled the requirements. So what
  48104. 29:39:13we're going to do, we're going to take
  48105. 29:39:14the whole query and put it in the
  48106. 29:39:16database as a view. And once we have the
  48107. 29:39:18view, the report in the database, we can
  48108. 29:39:20share it with the others. Now the other
  48109. 29:39:22data analyst in the team can go and
  48110. 29:39:24maybe create a dashboard in order to
  48111. 29:39:26visual data using API tool like Tableau
  48112. 29:39:29or PowerBI. But in this scenario, the
  48113. 29:39:31user can go and connect your view the
  48114. 29:39:33last prepared data to the dashboard. And
  48115. 29:39:36with that the user can quickly generate
  48116. 29:39:38insights without doing a lot of steps in
  48117. 29:39:40order to prepare the data for the
  48118. 29:39:42visualizations. And of course the data
  48119. 29:39:44analyst can go and connect the
  48120. 29:39:45dimensions and facts. But having this
  48121. 29:39:47one solid view it's going to be like way
  48122. 29:39:50easier to consume. And of course the
  48123. 29:39:51data analyst can as well write a query
  48124. 29:39:54on top of your view in order to generate
  48125. 29:39:56a quick insights. So as you can see
  48126. 29:39:57using only SQL you are covering a lot of
  48127. 29:40:00complex steps in order to make the data
  48128. 29:40:03ready for reporting and analyzes and
  48129. 29:40:05this is what usually happened in real
  48130. 29:40:07projects. We're going to go and put the
  48131. 29:40:09query in the database so that the others
  48132. 29:40:12can use it. So what we're going to do
  48133. 29:40:14very simple create review and we're
  48134. 29:40:16going to put it in a good layer and
  48135. 29:40:17we're going to call it report customers
  48136. 29:40:20and then ask like this and let's go and
  48137. 29:40:23execute it. It is successful. Now if you
  48138. 29:40:25go to our database and check the views
  48139. 29:40:27you will find a new view called gold
  48140. 29:40:29report customers. Now all what you have
  48141. 29:40:31to do is to go and have a simple select.
  48142. 29:40:34So codes reports customers and you will
  48143. 29:40:38get an amazing report about the
  48144. 29:40:41customers. This kind of reporting it is
  48145. 29:40:43very important because you are giving a
  48146. 29:40:45full picture 360° view of all your
  48147. 29:40:48customers. So you have details,
  48148. 29:40:50categories, measures everything in one
  48149. 29:40:52go and it going to makes life easier.
  48150. 29:40:54Now for any user of this view to quickly
  48151. 29:40:56understand the data and generate maybe
  48152. 29:40:58insights based in this one view that can
  48153. 29:41:01helps of course your customers. So I
  48154. 29:41:02just want to show you now what this
  48155. 29:41:04means. If a user using your reports so
  48156. 29:41:06either in SQL or maybe they're going to
  48157. 29:41:08go and connect it to PowerBI or Tableau
  48158. 29:41:10they can generate immediately insights.
  48159. 29:41:12So for example, if they go and say count
  48160. 29:41:15customer number so as total customers
  48161. 29:41:19and then they're going to go and take
  48162. 29:41:21any dimension for example the age group.
  48163. 29:41:24So something like this and then group by
  48164. 29:41:27the age group. Put just put it here
  48165. 29:41:30first. And then they're going to go and
  48166. 29:41:31add any other measure. For example, the
  48167. 29:41:34total
  48168. 29:41:36sales and any other measure that you
  48169. 29:41:38have in this view and then execute and
  48170. 29:41:41quickly they can do analyszis on top of
  48171. 29:41:43your view without having them to go to
  48172. 29:41:45their fact and dimensions. So this is
  48173. 29:41:48like one extra prepared layer the data
  48174. 29:41:50model that you have built. And if you
  48175. 29:41:52don't want to group it by the ages, you
  48176. 29:41:54can go and have the customer segments
  48177. 29:41:56and it will be working. So quickly they
  48178. 29:41:58can analyze the new derived informations
  48179. 29:42:01that you have prepared in your reports.
  48180. 29:42:03So guys, this is amazing reports about
  48181. 29:42:06the
  48182. 29:42:11customers. And now what you're going to
  48183. 29:42:13do, you're going to go and prepare the
  48184. 29:42:15second report where you have to build
  48185. 29:42:17complete insights about the products of
  48186. 29:42:19the business. It is very similar to the
  48187. 29:42:22customers. So we want to generate a
  48188. 29:42:24report for the products. You have to
  48189. 29:42:26provide details like the product name,
  48190. 29:42:27category, subcategory and the costs. You
  48191. 29:42:30have to segment the products by the
  48192. 29:42:32revenue. So you can have categories like
  48193. 29:42:34high, medium and low. And then you have
  48194. 29:42:35to provide the basic aggregations at the
  48195. 29:42:38level of the products and then calculate
  48196. 29:42:40few KPIs. So as you can see it is very
  48197. 29:42:42similar to the customers. And now what
  48198. 29:42:44you have to do you have to pause the
  48199. 29:42:46video follow the same step at the
  48200. 29:42:48customers where we join the tables car
  48201. 29:42:50create aggregations and put everything
  48202. 29:42:52like in CTE and at the end once you are
  48203. 29:42:55done create the view where you have the
  48204. 29:42:57report about the products. So I'm going
  48205. 29:42:59to go now and do it offline and I will
  48206. 29:43:01see you
  48207. 29:43:02[Music]
  48208. 29:43:06soon. Okay my friends I hope you are
  48209. 29:43:08done with the reports. I'm going to show
  48210. 29:43:10you quickly how I've done it. So I've
  48211. 29:43:12just created a new view called report
  48212. 29:43:14products and then we start with the base
  48213. 29:43:16query where we have joined the fact
  48214. 29:43:18table with the dimension products and
  48215. 29:43:20collected all the columns that we need
  48216. 29:43:23for the reports and we put everything in
  48217. 29:43:25the first city. So this is the first
  48218. 29:43:27step and there was from my side no need
  48219. 29:43:30for any transformations over here. So we
  48220. 29:43:32go now to the second step and here we
  48221. 29:43:34have to put all the different types of
  48222. 29:43:36aggregations in one go. So we calculate
  48223. 29:43:38the lifespan, the last sales order,
  48224. 29:43:41total orders, total customers, sales
  48225. 29:43:43quantity and as well I have created the
  48226. 29:43:45average selling price of the products.
  48227. 29:43:48It is very simple. We are dividing the
  48228. 29:43:50sales amount by the quantity. So this is
  48229. 29:43:52the basic aggregations about the
  48230. 29:43:54products and finally we have the final
  48231. 29:43:56query. So we start with selecting the
  48232. 29:43:58basic informations about the products.
  48233. 29:44:00So we have the key, name, category and
  48234. 29:44:02then we have here the recency and we
  48235. 29:44:04have our new segments. This one is very
  48236. 29:44:07easy for the products. So we are saying
  48237. 29:44:08if the total sales is higher than 50,000
  48238. 29:44:11then this is a high performer and if
  48239. 29:44:14it's like between 50 and 10k then this
  48240. 29:44:16is a mid-range otherwise it is low
  48241. 29:44:19performer. So the segmentations of the
  48242. 29:44:21products is very simple and after that
  48243. 29:44:23we have like all our measures that we
  48244. 29:44:26aggregated in the CTE and now we come to
  48245. 29:44:28the two KBIS. It is very similar to the
  48246. 29:44:30customers. So the first one the average
  48247. 29:44:32order revenue it is simply dividing the
  48248. 29:44:34sales by the total orders and you have
  48249. 29:44:36to take care of the zeros of course and
  48250. 29:44:39the average monthly revenue we divide
  48251. 29:44:41the total sales by the lifespan of the
  48252. 29:44:43products and of course if the lifespan
  48253. 29:44:45is zero so it is only one month then it
  48254. 29:44:48is the total sales and with that you
  48255. 29:44:50generate the average monthly revenue. So
  48256. 29:44:52as you can see it is very similar to the
  48257. 29:44:54customers but still the focus here is
  48258. 29:44:56the products. Now of course we put this
  48259. 29:44:58query in view. So we have the report
  48260. 29:45:01products side by side by the report
  48261. 29:45:03customers and now we have really amazing
  48262. 29:45:06report about the products where we have
  48263. 29:45:07everything. So we have a lot of details
  48264. 29:45:09about the customers. We have as well a
  48265. 29:45:11dimension in order to segment our
  48266. 29:45:14products and we have a lot of measures
  48267. 29:45:16that are really important about each
  48268. 29:45:18products. So we have the total number of
  48269. 29:45:20orders sales, how many customers did
  48270. 29:45:22order the products, the average price,
  48271. 29:45:24the average revenue and the monthly
  48272. 29:45:26average revenue. And this gives you
  48273. 29:45:28really deep insights about each product
  48274. 29:45:30of your business. And of course, this is
  48275. 29:45:32very helpful in order to compare the
  48276. 29:45:34products, right? And now, of course,
  48277. 29:45:36this is core analyzis that you're going
  48278. 29:45:38to need it a lot in your business.
  48279. 29:45:39That's why we offer it as a view. So, I
  48280. 29:45:42think we have now two amazing reports
  48281. 29:45:44about our
  48282. 29:45:48data. All right, my friends. So, now
  48283. 29:45:50don't forget to put all your work in the
  48284. 29:45:52Git repository in order to share it with
  48285. 29:45:54others as a successful project. So as
  48286. 29:45:57usual we have the data sets,
  48287. 29:45:58documentations and as well the scripts
  48288. 29:46:00that you have done through this projects
  48289. 29:46:02and here I'm putting everything
  48290. 29:46:04together. So we have all the activity of
  48291. 29:46:06the exploration as well with the
  48292. 29:46:08advanced analyszis that we have done. So
  48293. 29:46:10we have the change over time, the
  48294. 29:46:12cumulative analyszis, performance, data
  48295. 29:46:14segmentations, part tool analyszis and
  48296. 29:46:16as well our two new reports. So I
  48297. 29:46:19recommend you if you haven't done that
  48298. 29:46:20yet go and create now a repository put
  48299. 29:46:23all your work there to make sure that
  48300. 29:46:25everyone can access and see your work
  48301. 29:46:26and my friends don't forget to add nice
  48302. 29:46:29commenting on your code and formatting
  48303. 29:46:31and styling your code should be perfect.
  48304. 29:46:34So if you haven't done that yet go and
  48305. 29:46:36do it now. All right my friends so with
  48306. 29:46:38that we have done the last step in our
  48307. 29:46:40road map. We have created two solid
  48308. 29:46:42reporting for our users. And with that,
  48309. 29:46:44we have completed all the steps of our
  48310. 29:46:46advanced analytics projects. And with
  48311. 29:46:48this project and the previous projects,
  48312. 29:46:49you can see now the full picture on how
  48313. 29:46:51to do data analytics on any data sets
  48314. 29:46:54using SQL. So starting by the first step
  48315. 29:46:57where we have explored the database and
  48316. 29:46:59end up having a very solid reports where
  48317. 29:47:02we have consolidated everything in one
  48318. 29:47:04view and with that we have now really
  48319. 29:47:05great understanding about the business,
  48320. 29:47:08about our data. And now what you can do,
  48321. 29:47:10you can go and grab any data sets in the
  48322. 29:47:12internet and you can go through all
  48323. 29:47:13these faces again and I promise you at
  48324. 29:47:16the end you will have a full picture and
  48325. 29:47:18understanding of the business and this
  48326. 29:47:20is what I exactly do in each project if
  48327. 29:47:22I want to understand any type of data
  48328. 29:47:24sets. All right my friends. So with that
  48329. 29:47:25we have covered the last type of SQL
  48330. 29:47:28projects the advanced data analytics.
  48331. 29:47:30And with that we have now three solid
  48332. 29:47:32projects using SQL and they are very
  48333. 29:47:35similar to real world projects in the
  48334. 29:47:36industry especially if you want to be a
  48335. 29:47:38data engineer or a data analyst. And my
  48336. 29:47:40friends we have covered the last chapter
  48337. 29:47:43in our course. So this is the advanced
  48338. 29:47:45level in SQL. And those are all the
  48339. 29:47:47chapters that I have designed for you to
  48340. 29:47:50take you from the basics to intermediate
  48341. 29:47:52and then to the advanced topics. My
  48342. 29:47:54friend, you made it. Congrats. You
  48343. 29:47:56should be really proud of yourself. And
  48344. 29:47:58now with that, I can say that I have
  48345. 29:47:59shared everything that I know about SQL
  48346. 29:48:02and you can now solve any complex task
  48347. 29:48:04using SQL like I do in my real projects.
  48348. 29:48:07And I hope that you have enjoyed the
  48349. 29:48:08journey. And if you do and you want me
  48350. 29:48:10to create more free courses like this,
  48351. 29:48:12make sure to support the channel by
  48352. 29:48:14subscribing, liking, and commenting.
  48353. 29:48:16This of course going to make the channel
  48354. 29:48:17grow, reach the others, and as well
  48355. 29:48:19motivates me to make more content like
  48356. 29:48:21this. So nothing left to say. Thank you
  48357. 29:48:24so much for watching and I will see you
  48358. 29:48:25in the next course.

About this transcript

This page contains the full transcript of SQL Full Course for Beginners (30 Hours) – From Zero to Hero by Data with Baraa, generated from the public captions YouTube serves with the video. The transcript has 363,984 words across 48,358 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.

What you can do with it

Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.

Free YouTube transcript tool

YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.