# T-SQL BASIS

- "<i class="fa fa-book fa-fw"></i>T-SQL" "Transact-SQL". Đây là một extension của Structured Query Language (SQL) được sử dụng bởi Microsoft.
- Bên cạnh T-SQL chúng ta còn có SQL, PL-SQL (Oracle) .
- Trong nội dung bài hướng dẫn này ta sẽ dùng [Microsoft-SQL-server](https://docs.microsoft.com/en-us/sql/samples/adventureworks-install-configure?view=sql-server-ver15&tabs=ssms) làm công cụ.
- Data base sử dụng [AdventureWork2017 OLTP](https://docs.microsoft.com/en-us/sql/samples/adventureworks-install-configure?view=sql-server-ver15&tabs=ssms)
## Kiểu dữ liệu trong T-SQL
[tài liệu của Microsoft](https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-types-transact-sql?view=sql-server-ver15)
| Description | Data type | Storage | Max value |
| ------------------ | ------------------- | ------- | --------- |
| Số Nguyên | int | 4 bytes |2^32 -1 |
| | smallint | 2 bytes | 2^15 -1 |
| Số thực | float | 4-8 bytes | |
| | decimal(p,s) | 5-17 bytes |-10^38 +1 to 10^38 –1 |
| Tiền tệ | money | 8 bytes |-922,337,203,685,477.5808 to 922,337,203,685,477.5807 (-922,337,203,685,477.58 |
| Ngày giờ | datetime | 8 bytes | |
| Chuỗi | char | 1 bytes | 8,000 characters |
| | varchar | 2 bytes |8,000 characters |
| | nchar | 4 bytes |4,000 characters Unicode |
| | nvarchar | 4 bytes | 4,000 characters Unicode |
| Logic (true/false) | bit | 1 bit | 0 or 1 |
## Truy vấn đơn giản
### Select, from, where
```sql=
SELECT <columns>
FROM <table_name>
WHERE <conditios>
```
```Select *``` :lấy tất cả
```Select top 10 *``` : 10 dòng đầu tiên và tất cả columns
```Select distinct <columns_names>``` : chọn ra những giá trị độc lập của cột
:::info
:bulb: **Chú ý**:
Nếu lấy tất cả columns của bảng thì dùng ```<table_name>.*```
Các cột cách nhau bới dấu phẩy (,)
:::
> Logic chạy
>
> From -> Where -> Select.
>
> Từ bảng nào -> Điều kiện là gì -> Chọn ra những cột nào
#### Các phép so sánh trong mệnh đề WHERE
> '=' Phép so sánh bằng
> '>' Phép so sánh lớn hơn
> '>=' Phép so sánh lớn hơn hoặc bằng
> '<' Phép so sánh bé hơn
> '<=' Phép so sánh bé hơn hoặc bằng
> '<>', '!=' Phép so sánh khác (not equal to)
#### Các phép Logic trong mệnh đề WHERE
> ALL
> ANY
> AND
> OR
> BETWEEN
> IN
>EXISTS
>NOT
>LIKE
## order by
```SQL
SELECT <columns>
FROM <table_name>
WHERE <conditios>
ORDER BY <column_names> [ASC|DESC]
```
```SQL
ASC: sắp xếp tăng dần
DESC: sắp xếp giảm dần
```
## group by
```SQL
SELECT <columns>
FROM <table_name>
WHERE <conditions>
GROUP BY <column_names>
ORDER BY <column_names> [ASC|DESC]
```
> Mục đích chính của <span class="sqlkeywordcolor" style="color:mediumblue">GROUP BY</span> là để gom nhóm dữ liệu theo 1 tiêu chí. <b>Và từ đó thực hiện các phép tính </b> <span class="sqlkeywordcolor" style="color:mediumblue">SUM, COUNT, AVG,...</span>
## having
```SQL
SELECT <columns>
FROM <table_name>
WHERE <conditions>
GROUP BY <column_names>
HAVING <conditions>
ORDER BY <column_names> [ASC|DESC]
```
> Mục đích chính của <span class="sqlkeywordcolor" style="color:mediumblue">HAVING</span> là thực thi 1 điều kiện trong bảng đã được gom nhóm. Lưu ý là chỉ dùng <span class="sqlkeywordcolor" style="color:mediumblue">HAVING</span> khi có <span class="sqlkeywordcolor" style="color:mediumblue">GROUP BY</span>.<br>
Nó giống như <span class="sqlkeywordcolor" style="color:mediumblue">WHERE</span>. Nhưng <span class="sqlkeywordcolor" style="color:mediumblue">WHERE</span> dùng cho <span class="sqlkeywordcolor" style="color:mediumblue">SELECT</span> còn <span class="sqlkeywordcolor" style="color:mediumblue">HAVING</span> dùng cho <span class="sqlkeywordcolor" style="color:mediumblue">GROUP BY</span>
flow logic chạy

## Aggregate function: hàm kết hợp
- COUNT : đếm số lượng dòng dữ liệu
- AVG: tính trung bình
- MAX: tính giá trị lớn nhất
- SUM: tính tổng
:::info
:bulb: **Chú ý 1**:
```COUNT(1)``` VÀ ```COUNT(*)``` Đếm toàn bộ số lượng dòng của cả bảng. Kể cả các dòng NULL
```COUNT([COLUMN_NAME])``` Đếm các dòng có giá trị khác NULL trong 1 cột
:::
:::info
:bulb: **Chú ý 2**:
không dùng các hàm kết hợp trên với mệnh đề ```WHERE```
Các mệnh đề trên thường được kết hợp với ```GROUP BY, HAVING```
Nếu các hàm kết hợp dùng với ```SELECT``` và kết hợp các cột khác thì tên cột phải ược ```GROUP BY```
:::
VÍ DỤ:
TRANSACTION
| NAME | PRICE |
| ---- | ----- |
| A |1 |
| A |2 |
| A | 3 |
| B |4 |
| B |5 |
| C | 6 |
```SQL
SELECT SUM(PRICE) AS TOTAL_MONEY
FROM TRANSACTION
```
RESULT
| TOTAL_MONEY |
| -------- |
| 21 |
```SQL
SELECT NAME, SUM(PRICE) AS TOTAL_MONEY
FROM TRANSACTION
GROUP BY NAME
```
RESULT
| NAME | TOTAL_MONEY |
| ---- | ----- |
| A |6 |
| B |9 |
| C | 6 |
```SQL
SELECT NAME, SUM(PRICE) AS TOTAL_MONEY
FROM TRANSACTION
GROUP BY NAME
HAVING SUM(PRICE) > 6
```
RESULT
| NAME | TOTAL_MONEY |
| ---- | ----- |
| B |9 |
## Date time fucntion
- format-default: "yyyy/MM/dd"
- between [date1] and [date2]
- year(date): lấy năm
- month(date): lấy tháng
- day(Date): lấy ngày
- dateadd("đơn vị","bao nhiêu đơn vị", ngày bắt đầu tính)
vd:
dateadd(year, -1, '2013/05/01') -> 2012/05/01
dateadd(month, 1, '2013/05/01') -> 2013/06/01
# Exercise:
Với schema PRODUCTION CỦA dữ liệu AventureWork [digaram](https://i0.wp.com/improveandrepeat.com/wp-content/uploads/2018/12/AdvWorksOLTPSchemaVisio.png?ssl=1)
tất cả câu bên dưới đều dùng bảng [TransactionHistory]
1. Lấy 10 giao dịch có số lượng bán cao nhất từ bảng . Kết qủa được sắp xếp giảm dần theo số lượng
2. Lấy 10 ID sản phẩm có số lượng bán cao nhất từ bảng . Kết qủa được sắp xếp tăng dần theo số lượng
3. Với mỗiID sản phẩm cho biết số lượng bán ra theo từng tháng trong năm 2014
4. So sánh số lượng giao dịch giữa 2 năm 2013, 2014
5. Số lượng giao dịch trong ngày "20/11/2013"
6. Cho biết số lượng trung bình 1 giao dịch theo từng tháng trong năm 2014
7. cho biết ID sản phẩm có nhiều hơn 10 giao dịch trong tháng 5/2014