[{"data":1,"prerenderedAt":3151},["ShallowReactive",2],{"navigation_docs":3,"-tu-hoc-database-sql-server-cu-phap-co-ban":420,"-tu-hoc-database-sql-server-cu-phap-co-ban-surround":3146},[4,153],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":26},"Phỏng vấn .NET","i-lucide-briefcase","\u002Fphong-van","1.phong-van",[10,27,66,111,128],{"title":11,"icon":12,"path":13,"stem":14,"children":15,"page":26},"Tổng quan","i-lucide-compass","\u002Fphong-van\u002Ftong-quan","1.phong-van\u002F1.tong-quan",[16,21],{"title":17,"path":18,"stem":19,"icon":20},"Thị trường HCM","\u002Fphong-van\u002Ftong-quan\u002Fthi-truong","1.phong-van\u002F1.tong-quan\u002F1.thi-truong","i-lucide-trending-up",{"title":22,"path":23,"stem":24,"icon":25},"Lộ trình 7 ngày","\u002Fphong-van\u002Ftong-quan\u002Flo-trinh","1.phong-van\u002F1.tong-quan\u002F2.lo-trinh","i-lucide-calendar-days",false,{"title":22,"icon":25,"path":28,"stem":29,"children":30,"page":26},"\u002Fphong-van\u002Flo-trinh","1.phong-van\u002F2.lo-trinh",[31,36,41,46,51,56,61],{"title":32,"path":33,"stem":34,"icon":35},"Ngày 1 — C# cơ bản","\u002Fphong-van\u002Flo-trinh\u002Fngay-1-csharp-co-ban","1.phong-van\u002F2.lo-trinh\u002F1.ngay-1-csharp-co-ban","i-lucide-1",{"title":37,"path":38,"stem":39,"icon":40},"Ngày 2 — OOP và SOLID","\u002Fphong-van\u002Flo-trinh\u002Fngay-2-oop-solid","1.phong-van\u002F2.lo-trinh\u002F2.ngay-2-oop-solid","i-lucide-2",{"title":42,"path":43,"stem":44,"icon":45},"Ngày 3 — C# nâng cao","\u002Fphong-van\u002Flo-trinh\u002Fngay-3-csharp-nang-cao","1.phong-van\u002F2.lo-trinh\u002F3.ngay-3-csharp-nang-cao","i-lucide-3",{"title":47,"path":48,"stem":49,"icon":50},"Ngày 4 — Database và SQL","\u002Fphong-van\u002Flo-trinh\u002Fngay-4-database-sql","1.phong-van\u002F2.lo-trinh\u002F4.ngay-4-database-sql","i-lucide-4",{"title":52,"path":53,"stem":54,"icon":55},"Ngày 5 — ASP.NET Core và EF Core","\u002Fphong-van\u002Flo-trinh\u002Fngay-5-aspnet-efcore","1.phong-van\u002F2.lo-trinh\u002F5.ngay-5-aspnet-efcore","i-lucide-5",{"title":57,"path":58,"stem":59,"icon":60},"Ngày 6 — DSA coding","\u002Fphong-van\u002Flo-trinh\u002Fngay-6-dsa","1.phong-van\u002F2.lo-trinh\u002F6.ngay-6-dsa","i-lucide-6",{"title":62,"path":63,"stem":64,"icon":65},"Ngày 7 — Mock và HR","\u002Fphong-van\u002Flo-trinh\u002Fngay-7-mock-interview","1.phong-van\u002F2.lo-trinh\u002F7.ngay-7-mock-interview","i-lucide-7",{"title":67,"icon":68,"path":69,"stem":70,"children":71,"page":26},"Ngân hàng câu hỏi","i-lucide-database","\u002Fphong-van\u002Fngan-hang-cau-hoi","1.phong-van\u002F3.ngan-hang-cau-hoi",[72,77,82,87,92,97,102,107],{"title":73,"path":74,"stem":75,"icon":76},"C# (60+ câu)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fcsharp","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F1.csharp","i-lucide-hash",{"title":78,"path":79,"stem":80,"icon":81},"OOP và SOLID (40+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Foop","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F2.oop","i-lucide-shapes",{"title":83,"path":84,"stem":85,"icon":86},"SQL (40+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fsql","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F3.sql","i-lucide-database-zap",{"title":88,"path":89,"stem":90,"icon":91},"ASP.NET và EF (50+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Faspnet-ef","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F4.aspnet-ef","i-lucide-server",{"title":93,"path":94,"stem":95,"icon":96},"DSA và Coding (30+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fdsa-coding","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F5.dsa-coding","i-lucide-binary",{"title":98,"path":99,"stem":100,"icon":101},"HR và Soft skill (25+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fhr-behavior","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F6.hr-behavior","i-lucide-users",{"title":103,"path":104,"stem":105,"icon":106},"Design Pattern (55+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fdesign-pattern","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F7.design-pattern","i-lucide-puzzle",{"title":108,"path":109,"stem":110,"icon":91},"ASP.NET MVC và Web API","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Faspnet-mvc-webapi","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F8.aspnet-mvc-webapi",{"title":112,"itle":113,"icon":114,"path":115,"stem":116,"children":117,"page":26},"Tai Lieu","Tài liệu và Cheat sheet","i-lucide-book-marked","\u002Fphong-van\u002Ftai-lieu","1.phong-van\u002F4.tai-lieu",[118,123],{"title":119,"path":120,"stem":121,"icon":122},"Cheat Sheet","\u002Fphong-van\u002Ftai-lieu\u002Fcheatsheet","1.phong-van\u002F4.tai-lieu\u002F1.cheatsheet","i-lucide-clipboard-list",{"title":124,"path":125,"stem":126,"icon":127},"Nguồn tham khảo","\u002Fphong-van\u002Ftai-lieu\u002Fnguon","1.phong-van\u002F4.tai-lieu\u002F2.nguon","i-lucide-link",{"title":129,"icon":130,"path":131,"stem":132,"children":133,"page":26},"Phỏng vấn English","i-lucide-globe","\u002Fphong-van\u002Fenglish-interview","1.phong-van\u002F5.english-interview",[134,138,143,148],{"title":135,"path":136,"stem":137,"icon":130},"Tổng quan English","\u002Fphong-van\u002Fenglish-interview\u002Ftong-quan","1.phong-van\u002F5.english-interview\u002F1.tong-quan",{"title":139,"path":140,"stem":141,"icon":142},"Vocabulary","\u002Fphong-van\u002Fenglish-interview\u002Fvocabulary","1.phong-van\u002F5.english-interview\u002F2.vocabulary","i-lucide-book-a",{"title":144,"path":145,"stem":146,"icon":147},"Technical Q và A (EN)","\u002Fphong-van\u002Fenglish-interview\u002Ftechnical-en","1.phong-van\u002F5.english-interview\u002F3.technical-en","i-lucide-code",{"title":149,"path":150,"stem":151,"icon":152},"Behavioral (EN)","\u002Fphong-van\u002Fenglish-interview\u002Fbehavioral-en","1.phong-van\u002F5.english-interview\u002F4.behavioral-en","i-lucide-message-square-text",{"title":154,"icon":155,"path":156,"stem":157,"children":158},"Tự học","i-lucide-graduation-cap","\u002Ftu-hoc","2.tu-hoc",[159,161,287,310,333,357,384],{"title":154,"path":156,"stem":160,"icon":155},"2.tu-hoc\u002Findex",{"title":162,"icon":68,"path":163,"stem":164,"children":165},"Database","\u002Ftu-hoc\u002Fdatabase","2.tu-hoc\u002F1.database\u002Findex",[166,167,197,222,243,248],{"title":162,"path":163,"stem":164,"icon":68},{"title":168,"icon":91,"path":169,"stem":170,"children":171,"page":26},"SQL Server","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server","2.tu-hoc\u002F1.database\u002F2.sql-server",[172,177,182,187,192],{"title":173,"path":174,"stem":175,"icon":176},"1. Giới thiệu và Cài đặt","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F1.gioi-thieu-cai-dat","i-lucide-play-circle",{"title":178,"path":179,"stem":180,"icon":181},"2. Cú pháp cơ bản","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F2.cu-phap-co-ban","i-lucide-code-2",{"title":183,"path":184,"stem":185,"icon":186},"3. Truy vấn nâng cao","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F3.truy-van-nang-cao","i-lucide-git-merge",{"title":188,"path":189,"stem":190,"icon":191},"4. Đặc thù và Performance","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F4.dac-thu-performance","i-lucide-gauge",{"title":193,"path":194,"stem":195,"icon":196},"5. Q và A phỏng vấn","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F5.cau-hoi-phong-van","i-lucide-message-circle-question",{"title":198,"icon":199,"path":200,"stem":201,"children":202,"page":26},"PostgreSQL","i-simple-icons-postgresql","\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql","2.tu-hoc\u002F1.database\u002F3.postgresql",[203,206,209,212,215,218],{"title":173,"path":204,"stem":205,"icon":176},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F1.gioi-thieu-cai-dat",{"title":178,"path":207,"stem":208,"icon":181},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F2.cu-phap-co-ban",{"title":183,"path":210,"stem":211,"icon":186},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F3.truy-van-nang-cao",{"title":188,"path":213,"stem":214,"icon":191},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F4.dac-thu-performance",{"title":193,"path":216,"stem":217,"icon":196},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F5.cau-hoi-phong-van",{"title":219,"path":220,"stem":221,"icon":96},"6. Tích hợp C# và Postgres","\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Ftich-hop-csharp","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F6.tich-hop-csharp",{"title":223,"icon":224,"path":225,"stem":226,"children":227,"page":26},"MySQL","i-simple-icons-mysql","\u002Ftu-hoc\u002Fdatabase\u002Fmysql","2.tu-hoc\u002F1.database\u002F4.mysql",[228,231,234,237,240],{"title":173,"path":229,"stem":230,"icon":176},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F4.mysql\u002F1.gioi-thieu-cai-dat",{"title":178,"path":232,"stem":233,"icon":181},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F4.mysql\u002F2.cu-phap-co-ban",{"title":183,"path":235,"stem":236,"icon":186},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F4.mysql\u002F3.truy-van-nang-cao",{"title":188,"path":238,"stem":239,"icon":191},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F4.mysql\u002F4.dac-thu-performance",{"title":193,"path":241,"stem":242,"icon":196},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F4.mysql\u002F5.cau-hoi-phong-van",{"title":244,"path":245,"stem":246,"icon":247},"So sánh 3 RDBMS","\u002Ftu-hoc\u002Fdatabase\u002Fso-sanh","2.tu-hoc\u002F1.database\u002F5.so-sanh","i-lucide-columns-3",{"title":249,"path":250,"stem":251,"children":252,"icon":254},"Supabase (BaaS)","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase","2.tu-hoc\u002F1.database\u002F6.supabase\u002Findex",[253,255,259,264,269,274,278,283],{"title":249,"path":250,"stem":251,"icon":254},"i-simple-icons-supabase",{"title":256,"path":257,"stem":258,"icon":68},"1. Database","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fdatabase","2.tu-hoc\u002F1.database\u002F6.supabase\u002F1.database",{"title":260,"path":261,"stem":262,"icon":263},"2. Authentication","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fauthentication","2.tu-hoc\u002F1.database\u002F6.supabase\u002F2.authentication","i-lucide-key",{"title":265,"path":266,"stem":267,"icon":268},"3. Storage & Realtime","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fstorage-realtime","2.tu-hoc\u002F1.database\u002F6.supabase\u002F3.storage-realtime","i-lucide-zap",{"title":270,"path":271,"stem":272,"icon":273},"4. Edge Functions & AI","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Ffunctions-ai","2.tu-hoc\u002F1.database\u002F6.supabase\u002F4.functions-ai","i-lucide-brain",{"title":275,"path":276,"stem":277,"icon":181},"5. API & SDKs","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fapi-sdk","2.tu-hoc\u002F1.database\u002F6.supabase\u002F5.api-sdk",{"title":279,"path":280,"stem":281,"icon":282},"6. Platform & Deploy","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fplatform-deploy","2.tu-hoc\u002F1.database\u002F6.supabase\u002F6.platform-deploy","i-lucide-cloud",{"title":284,"path":285,"stem":286,"icon":196},"7. Interview & Q&A","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Finterview","2.tu-hoc\u002F1.database\u002F6.supabase\u002F7.interview",{"title":288,"icon":289,"path":290,"stem":291,"children":292},"TypeScript","i-simple-icons-typescript","\u002Ftu-hoc\u002Ftypescript","2.tu-hoc\u002F2.typescript\u002Findex",[293,294,297,301,306],{"title":288,"path":290,"stem":291,"icon":289},{"title":173,"path":295,"stem":296,"icon":176},"\u002Ftu-hoc\u002Ftypescript\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F2.typescript\u002F1.gioi-thieu-cai-dat",{"title":298,"path":299,"stem":300,"icon":81},"2. Type System","\u002Ftu-hoc\u002Ftypescript\u002Ftype-system","2.tu-hoc\u002F2.typescript\u002F2.type-system",{"title":302,"path":303,"stem":304,"icon":305},"3. Advanced types","\u002Ftu-hoc\u002Ftypescript\u002Fadvanced-types","2.tu-hoc\u002F2.typescript\u002F3.advanced-types","i-lucide-braces",{"title":307,"path":308,"stem":309,"icon":196},"4. Q và A phỏng vấn","\u002Ftu-hoc\u002Ftypescript\u002Fcau-hoi-phong-van","2.tu-hoc\u002F2.typescript\u002F4.cau-hoi-phong-van",{"title":311,"icon":81,"path":312,"stem":313,"children":314},"OOP","\u002Ftu-hoc\u002Foop","2.tu-hoc\u002F3.oop\u002Findex",[315,316,321,326,330],{"title":311,"path":312,"stem":313,"icon":81},{"title":317,"path":318,"stem":319,"icon":320},"1. Bốn tính chất","\u002Ftu-hoc\u002Foop\u002F4-tinh-chat","2.tu-hoc\u002F3.oop\u002F1.4-tinh-chat","i-lucide-circle-dot",{"title":322,"path":323,"stem":324,"icon":325},"2. SOLID","\u002Ftu-hoc\u002Foop\u002Fsolid","2.tu-hoc\u002F3.oop\u002F2.solid","i-lucide-shield",{"title":327,"path":328,"stem":329,"icon":106},"3. Design Pattern","\u002Ftu-hoc\u002Foop\u002Fdesign-pattern","2.tu-hoc\u002F3.oop\u002F3.design-pattern",{"title":307,"path":331,"stem":332,"icon":196},"\u002Ftu-hoc\u002Foop\u002Fcau-hoi-phong-van","2.tu-hoc\u002F3.oop\u002F4.cau-hoi-phong-van",{"title":334,"icon":305,"path":335,"stem":336,"children":337},"Generic","\u002Ftu-hoc\u002Fgeneric","2.tu-hoc\u002F4.generic\u002Findex",[338,339,344,349,354],{"title":334,"path":335,"stem":336,"icon":305},{"title":340,"path":341,"stem":342,"icon":343},"1. Khái niệm và cú pháp","\u002Ftu-hoc\u002Fgeneric\u002Fkhai-niem","2.tu-hoc\u002F4.generic\u002F1.khai-niem","i-lucide-book",{"title":345,"path":346,"stem":347,"icon":348},"2. Constraint và Variance","\u002Ftu-hoc\u002Fgeneric\u002Fconstraint-variance","2.tu-hoc\u002F4.generic\u002F2.constraint-variance","i-lucide-filter",{"title":350,"path":351,"stem":352,"icon":353},"3. C# vs TS","\u002Ftu-hoc\u002Fgeneric\u002Fso-sanh","2.tu-hoc\u002F4.generic\u002F3.so-sanh","i-lucide-git-compare",{"title":307,"path":355,"stem":356,"icon":196},"\u002Ftu-hoc\u002Fgeneric\u002Fcau-hoi-phong-van","2.tu-hoc\u002F4.generic\u002F4.cau-hoi-phong-van",{"title":358,"icon":359,"path":360,"stem":361,"children":362},"Nuxt 4","i-simple-icons-nuxt","\u002Ftu-hoc\u002Fnuxt-4","2.tu-hoc\u002F5.nuxt-4\u002Findex",[363,364,367,372,376,379],{"title":358,"path":360,"stem":361,"icon":359},{"title":173,"path":365,"stem":366,"icon":176},"\u002Ftu-hoc\u002Fnuxt-4\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F5.nuxt-4\u002F1.gioi-thieu-cai-dat",{"title":368,"path":369,"stem":370,"icon":371},"2. Routing và Rendering","\u002Ftu-hoc\u002Fnuxt-4\u002Frouting-rendering","2.tu-hoc\u002F5.nuxt-4\u002F2.routing-rendering","i-lucide-route",{"title":373,"path":374,"stem":375,"icon":91},"3. Data và Server","\u002Ftu-hoc\u002Fnuxt-4\u002Fdata-server","2.tu-hoc\u002F5.nuxt-4\u002F3.data-server",{"title":307,"path":377,"stem":378,"icon":196},"\u002Ftu-hoc\u002Fnuxt-4\u002Fcau-hoi-phong-van","2.tu-hoc\u002F5.nuxt-4\u002F4.cau-hoi-phong-van",{"title":380,"path":381,"stem":382,"icon":383},"5. Practical Todo App","\u002Ftu-hoc\u002Fnuxt-4\u002Fpractical-todo-app","2.tu-hoc\u002F5.nuxt-4\u002F5.practical-todo-app","i-lucide-check-square",{"title":385,"path":386,"stem":387,"children":388,"icon":390},"Tailwind CSS","\u002Ftu-hoc\u002Ftailwindcss","2.tu-hoc\u002F6.tailwindcss\u002Findex",[389,391,396,401,406,411,416],{"title":385,"path":386,"stem":387,"icon":390},"i-simple-icons-tailwindcss",{"title":392,"path":393,"stem":394,"icon":395},"1. Layout & Spacing","\u002Ftu-hoc\u002Ftailwindcss\u002Flayout-spacing","2.tu-hoc\u002F6.tailwindcss\u002F1.layout-spacing","i-lucide-layout",{"title":397,"path":398,"stem":399,"icon":400},"2. Typography & Colors","\u002Ftu-hoc\u002Ftailwindcss\u002Ftypography-colors","2.tu-hoc\u002F6.tailwindcss\u002F2.typography-colors","i-lucide-type",{"title":402,"path":403,"stem":404,"icon":405},"3. Interactive & Effects","\u002Ftu-hoc\u002Ftailwindcss\u002Finteractive-effects","2.tu-hoc\u002F6.tailwindcss\u002F3.interactive-effects","i-lucide-sparkles",{"title":407,"path":408,"stem":409,"icon":410},"4. Responsive & Dark Mode","\u002Ftu-hoc\u002Ftailwindcss\u002Fresponsive-darkmode","2.tu-hoc\u002F6.tailwindcss\u002F4.responsive-darkmode","i-lucide-monitor-smartphone",{"title":412,"path":413,"stem":414,"icon":415},"5. Customization & Theme","\u002Ftu-hoc\u002Ftailwindcss\u002Fcustomization","2.tu-hoc\u002F6.tailwindcss\u002F5.customization","i-lucide-settings-2",{"title":417,"path":418,"stem":419,"icon":181},"6. Practical Projects","\u002Ftu-hoc\u002Ftailwindcss\u002Fpractical-projects","2.tu-hoc\u002F6.tailwindcss\u002F6.practical-projects",{"id":421,"title":422,"body":423,"description":3139,"extension":3140,"links":3141,"meta":3142,"navigation":3143,"path":179,"seo":3144,"stem":180,"__hash__":3145},"docs\u002F2.tu-hoc\u002F1.database\u002F2.sql-server\u002F2.cu-phap-co-ban.md","Cú pháp T-SQL cơ bản",{"type":424,"value":425,"toc":3097},"minimark",[426,431,436,588,611,615,678,695,699,792,811,815,820,832,956,962,1010,1036,1074,1078,1095,1152,1157,1224,1260,1264,1268,1379,1383,1422,1457,1461,1476,1480,1483,1573,1586,1590,1662,1665,1719,1735,1738,1762,1766,1786,1898,1902,1962,1972,1976,2052,2091,2095,2099,2159,2163,2217,2221,2255,2265,2269,2276,2386,2414,2418,2548,2552,2556,2623,2627,2669,2697,2701,2708,2771,2807,2811,2815,2854,2868,2872,2897,2901,2945,2949,2993,2997,3036,3040,3075,3085,3093],[427,428,430],"h2",{"id":429},"_1-kiểu-dữ-liệu-thường-dùng","1. Kiểu dữ liệu thường dùng",[432,433,435],"h3",{"id":434},"numeric","Numeric",[437,438,439,458],"table",{},[440,441,442],"thead",{},[443,444,445,449,452,455],"tr",{},[446,447,448],"th",{},"Kiểu",[446,450,451],{},"Range",[446,453,454],{},"Storage",[446,456,457],{},"Khi nào dùng",[459,460,461,479,495,511,530,546,568],"tbody",{},[443,462,463,470,473,476],{},[464,465,466],"td",{},[467,468,469],"code",{},"BIT",[464,471,472],{},"0\u002F1\u002FNULL",[464,474,475],{},"1 byte (8 bits gom)",[464,477,478],{},"Boolean",[443,480,481,486,489,492],{},[464,482,483],{},[467,484,485],{},"TINYINT",[464,487,488],{},"0 → 255",[464,490,491],{},"1 byte",[464,493,494],{},"Status nhỏ",[443,496,497,502,505,508],{},[464,498,499],{},[467,500,501],{},"SMALLINT",[464,503,504],{},"-32K → 32K",[464,506,507],{},"2 bytes",[464,509,510],{},"Số nhỏ",[443,512,513,518,521,524],{},[464,514,515],{},[467,516,517],{},"INT",[464,519,520],{},"-2.1B → 2.1B",[464,522,523],{},"4 bytes",[464,525,526],{},[527,528,529],"strong",{},"Mặc định cho ID",[443,531,532,537,540,543],{},[464,533,534],{},[467,535,536],{},"BIGINT",[464,538,539],{},"-9.2 × 10¹⁸ → ...",[464,541,542],{},"8 bytes",[464,544,545],{},"ID cực lớn, timestamp Unix",[443,547,548,553,556,559],{},[464,549,550],{},[467,551,552],{},"DECIMAL(p, s)",[464,554,555],{},"Chính xác",[464,557,558],{},"5-17 bytes",[464,560,561,564,565],{},[527,562,563],{},"Tiền"," — ",[467,566,567],{},"DECIMAL(18, 2)",[443,569,570,579,582,585],{},[464,571,572,575,576],{},[467,573,574],{},"FLOAT"," \u002F ",[467,577,578],{},"REAL",[464,580,581],{},"Xấp xỉ",[464,583,584],{},"4 hoặc 8 bytes",[464,586,587],{},"Khoa học",[589,590,593,594,597,598,602,603,606,607,610],"callout",{"color":591,"icon":592},"warning","i-lucide-star","⭐ ",[527,595,596],{},"Câu hỏi phỏng vấn:"," ",[599,600,601],"em",{},"\"Khi lưu giá tiền, dùng FLOAT hay DECIMAL?\""," → ",[527,604,605],{},"DECIMAL",". FLOAT là số gần đúng (",[467,608,609],{},"0.1 + 0.2 = 0.30000000000000004","), gây sai sót khi tính tiền.",[432,612,614],{"id":613},"chuỗi","Chuỗi",[437,616,617,626],{},[440,618,619],{},[443,620,621,623],{},[446,622,448],{},[446,624,625],{},"Đặc điểm",[459,627,628,638,648,665],{},[443,629,630,635],{},[464,631,632],{},[467,633,634],{},"CHAR(n)",[464,636,637],{},"Cố định n ký tự, pad space. ASCII.",[443,639,640,645],{},[464,641,642],{},[467,643,644],{},"VARCHAR(n)",[464,646,647],{},"Biến đổi đến n. ASCII. Tốn ít space hơn CHAR khi data ngắn.",[443,649,650,659],{},[464,651,652,655,656],{},[467,653,654],{},"NCHAR(n)",", ",[467,657,658],{},"NVARCHAR(n)",[464,660,661,664],{},[527,662,663],{},"Unicode",", dùng cho tiếng Việt, Nhật, Trung.",[443,666,667,675],{},[464,668,669,655,672],{},[467,670,671],{},"VARCHAR(MAX)",[467,673,674],{},"NVARCHAR(MAX)",[464,676,677],{},"Tới 2GB. Cho bài viết, JSON.",[589,679,681,684,685,687,688,690,691,694],{"color":680,"icon":268},"info",[527,682,683],{},"Quy tắc thực dụng (2025):"," mặc định ",[467,686,658],{}," cho mọi text user-input. SQL Server 2019+ hỗ trợ UTF-8 collation, có thể dùng ",[467,689,644],{}," + UTF-8 cho tiết kiệm space — nhưng phức tạp, fresher nên cứ ",[467,692,693],{},"NVARCHAR",".",[432,696,698],{"id":697},"thời-gian","Thời gian",[437,700,701,713],{},[440,702,703],{},[443,704,705,707,709,711],{},[446,706,448],{},[446,708,451],{},[446,710,555],{},[446,712,454],{},[459,714,715,731,747,762,777],{},[443,716,717,722,725,728],{},[464,718,719],{},[467,720,721],{},"DATE",[464,723,724],{},"0001-01-01 → 9999-12-31",[464,726,727],{},"Ngày",[464,729,730],{},"3 bytes",[443,732,733,738,741,744],{},[464,734,735],{},[467,736,737],{},"TIME",[464,739,740],{},"00:00:00 → 23:59:59.9999999",[464,742,743],{},"100 ns",[464,745,746],{},"3-5 bytes",[443,748,749,754,757,760],{},[464,750,751],{},[467,752,753],{},"DATETIME",[464,755,756],{},"1753-01-01 → 9999-12-31",[464,758,759],{},"3.33 ms",[464,761,542],{},[443,763,764,769,772,774],{},[464,765,766],{},[467,767,768],{},"DATETIME2(7)",[464,770,771],{},"0001 → 9999",[464,773,743],{},[464,775,776],{},"6-8 bytes",[443,778,779,784,787,789],{},[464,780,781],{},[467,782,783],{},"DATETIMEOFFSET",[464,785,786],{},"Có timezone",[464,788,743],{},[464,790,791],{},"8-10 bytes",[589,793,593,796,799,800,805,806,808,809,694],{"color":794,"icon":795},"primary","i-lucide-info",[527,797,798],{},"Best practice 2025:"," dùng ",[527,801,802],{},[467,803,804],{},"DATETIME2"," thay cho ",[467,807,753],{}," cũ (range rộng hơn, precision cao hơn, cùng size 8 bytes). Cần timezone thì ",[467,810,783],{},[432,812,814],{"id":813},"kiểu-mới-sql-server-2025","Kiểu mới SQL Server 2025",[816,817,819],"h4",{"id":818},"vector-lưu-embedding-cho-aiml","VECTOR — Lưu embedding cho AI\u002FML",[821,822,823,824,827,828,831],"p",{},"SQL Server 2025 giới thiệu kiểu ",[467,825,826],{},"VECTOR"," native, cho phép lưu và tìm kiếm vector embedding ngay trong database — không cần extension như ",[467,829,830],{},"pgvector"," bên PostgreSQL.",[833,834,839],"pre",{"className":835,"code":836,"language":837,"meta":838,"style":838},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","-- Tạo bảng với cột VECTOR\nCREATE TABLE Products (\n    Id INT IDENTITY PRIMARY KEY,\n    Name NVARCHAR(200),\n    Description NVARCHAR(MAX),\n    Embedding VECTOR(1536)  -- 1536 dimensions cho OpenAI text-embedding-3-small\n);\n\n-- Insert vector\nINSERT INTO Products (Name, Embedding)\nVALUES (N'Laptop', '[0.123, -0.456, 0.789, ...]');\n\n-- Tính khoảng cách vector (cosine similarity)\nDECLARE @query_embedding VECTOR(1536) = '[0.111, -0.222, 0.333, ...]';\n\nSELECT TOP 5 Name,\n    VECTOR_DISTANCE('cosine', Embedding, @query_embedding) AS Similarity\nFROM Products\nORDER BY Similarity ASC;\n","sql","",[467,840,841,849,855,861,867,873,879,885,892,898,904,910,915,921,927,932,938,944,950],{"__ignoreMap":838},[842,843,846],"span",{"class":844,"line":845},"line",1,[842,847,848],{},"-- Tạo bảng với cột VECTOR\n",[842,850,852],{"class":844,"line":851},2,[842,853,854],{},"CREATE TABLE Products (\n",[842,856,858],{"class":844,"line":857},3,[842,859,860],{},"    Id INT IDENTITY PRIMARY KEY,\n",[842,862,864],{"class":844,"line":863},4,[842,865,866],{},"    Name NVARCHAR(200),\n",[842,868,870],{"class":844,"line":869},5,[842,871,872],{},"    Description NVARCHAR(MAX),\n",[842,874,876],{"class":844,"line":875},6,[842,877,878],{},"    Embedding VECTOR(1536)  -- 1536 dimensions cho OpenAI text-embedding-3-small\n",[842,880,882],{"class":844,"line":881},7,[842,883,884],{},");\n",[842,886,888],{"class":844,"line":887},8,[842,889,891],{"emptyLinePlaceholder":890},true,"\n",[842,893,895],{"class":844,"line":894},9,[842,896,897],{},"-- Insert vector\n",[842,899,901],{"class":844,"line":900},10,[842,902,903],{},"INSERT INTO Products (Name, Embedding)\n",[842,905,907],{"class":844,"line":906},11,[842,908,909],{},"VALUES (N'Laptop', '[0.123, -0.456, 0.789, ...]');\n",[842,911,913],{"class":844,"line":912},12,[842,914,891],{"emptyLinePlaceholder":890},[842,916,918],{"class":844,"line":917},13,[842,919,920],{},"-- Tính khoảng cách vector (cosine similarity)\n",[842,922,924],{"class":844,"line":923},14,[842,925,926],{},"DECLARE @query_embedding VECTOR(1536) = '[0.111, -0.222, 0.333, ...]';\n",[842,928,930],{"class":844,"line":929},15,[842,931,891],{"emptyLinePlaceholder":890},[842,933,935],{"class":844,"line":934},16,[842,936,937],{},"SELECT TOP 5 Name,\n",[842,939,941],{"class":844,"line":940},17,[842,942,943],{},"    VECTOR_DISTANCE('cosine', Embedding, @query_embedding) AS Similarity\n",[842,945,947],{"class":844,"line":946},18,[842,948,949],{},"FROM Products\n",[842,951,953],{"class":844,"line":952},19,[842,954,955],{},"ORDER BY Similarity ASC;\n",[821,957,958,961],{},[527,959,960],{},"DiskANN index cho vector search"," — SQL Server 2025 dùng thuật toán DiskANN (Microsoft Research) cho approximate nearest neighbor (ANN) search, nhanh hơn full scan hàng trăm lần trên dataset lớn:",[833,963,965],{"className":835,"code":964,"language":837,"meta":838,"style":838},"-- Tạo vector index với DiskANN\nCREATE VECTOR INDEX idx_products_embedding\nON Products (Embedding) WITH (DISTANCE_METRIC = 'cosine');\n\n-- Tìm kiếm vector với index\nDECLARE @query_embedding VECTOR(1536) = '[...]';\n\nSELECT TOP 10 * FROM Products\nORDER BY VECTOR_SEARCH(Embedding, @query_embedding, 10);\n",[467,966,967,972,977,982,986,991,996,1000,1005],{"__ignoreMap":838},[842,968,969],{"class":844,"line":845},[842,970,971],{},"-- Tạo vector index với DiskANN\n",[842,973,974],{"class":844,"line":851},[842,975,976],{},"CREATE VECTOR INDEX idx_products_embedding\n",[842,978,979],{"class":844,"line":857},[842,980,981],{},"ON Products (Embedding) WITH (DISTANCE_METRIC = 'cosine');\n",[842,983,984],{"class":844,"line":863},[842,985,891],{"emptyLinePlaceholder":890},[842,987,988],{"class":844,"line":869},[842,989,990],{},"-- Tìm kiếm vector với index\n",[842,992,993],{"class":844,"line":875},[842,994,995],{},"DECLARE @query_embedding VECTOR(1536) = '[...]';\n",[842,997,998],{"class":844,"line":881},[842,999,891],{"emptyLinePlaceholder":890},[842,1001,1002],{"class":844,"line":887},[842,1003,1004],{},"SELECT TOP 10 * FROM Products\n",[842,1006,1007],{"class":844,"line":894},[842,1008,1009],{},"ORDER BY VECTOR_SEARCH(Embedding, @query_embedding, 10);\n",[589,1011,1013,1016,1017,1020,1021,1024,1025,1028,1029,1028,1032,1035],{"color":591,"icon":1012},"i-lucide-alert-triangle",[527,1014,1015],{},"Hạn chế hiện tại (SQL Server 2025):"," Sau khi tạo ",[467,1018,1019],{},"VECTOR INDEX",", bảng trở thành ",[527,1022,1023],{},"read-only"," — không ",[467,1026,1027],{},"INSERT","\u002F",[467,1030,1031],{},"UPDATE",[467,1033,1034],{},"DELETE"," được. Microsoft dự kiến sẽ fix trong CU (Cumulative Update) tiếp theo. Khi thiết kế hệ thống, cần tách bảng embedding riêng hoặc chấp nhận rebuild index định kỳ.",[589,1037,1038,1045],{"color":591,"icon":592},[821,1039,593,1040,597,1042],{},[527,1041,596],{},[599,1043,1044],{},"\"Làm sao để tìm kiếm ngữ nghĩa (semantic search) trong SQL Server?\"",[1046,1047,1048,1056,1068],"ul",{},[1049,1050,1051,1052,1055],"li",{},"Trước 2025: dùng full-text search + ",[467,1053,1054],{},"FREETEXT",", hoặc tự tính cosine similarity bằng T-SQL (chậm, không scale).",[1049,1057,1058,1059,1061,1062,1061,1065,1067],{},"Từ 2025: dùng ",[467,1060,826],{}," + ",[467,1063,1064],{},"VECTOR_DISTANCE",[467,1066,1019],{}," (DiskANN) — nhanh, chính xác, native trong engine.",[1049,1069,1070,1071,694],{},"Pattern điển hình: App gọi OpenAI \u002F Azure OpenAI API để tạo embedding → lưu vào SQL Server → query bằng ",[467,1072,1073],{},"VECTOR_SEARCH",[816,1075,1077],{"id":1076},"json-kiểu-first-class","JSON — Kiểu first-class",[821,1079,1080,1081,1061,1083,1086,1087,1090,1091,1094],{},"Trước SQL Server 2025, JSON được lưu dưới dạng ",[467,1082,674],{},[467,1084,1085],{},"CHECK (ISJSON(col) = 1)",". Từ 2025, ",[467,1088,1089],{},"JSON"," là kiểu dữ liệu ",[527,1092,1093],{},"first-class",":",[833,1096,1098],{"className":835,"code":1097,"language":837,"meta":838,"style":838},"-- Tạo bảng với cột JSON native\nCREATE TABLE Orders (\n    Id INT IDENTITY PRIMARY KEY,\n    OrderData JSON,  -- first-class type, không còn là NVARCHAR nữa!\n    CreatedAt DATETIME2 DEFAULT GETDATE(),\n    INDEX idx_customer_id ON OrderData(json_path = '$.customer_id')\n);\n\n-- Insert JSON\nINSERT INTO Orders (OrderData)\nVALUES ('{\"customer_id\": 101, \"total\": 2500000, \"status\": \"pending\"}');\n",[467,1099,1100,1105,1110,1114,1119,1124,1129,1133,1137,1142,1147],{"__ignoreMap":838},[842,1101,1102],{"class":844,"line":845},[842,1103,1104],{},"-- Tạo bảng với cột JSON native\n",[842,1106,1107],{"class":844,"line":851},[842,1108,1109],{},"CREATE TABLE Orders (\n",[842,1111,1112],{"class":844,"line":857},[842,1113,860],{},[842,1115,1116],{"class":844,"line":863},[842,1117,1118],{},"    OrderData JSON,  -- first-class type, không còn là NVARCHAR nữa!\n",[842,1120,1121],{"class":844,"line":869},[842,1122,1123],{},"    CreatedAt DATETIME2 DEFAULT GETDATE(),\n",[842,1125,1126],{"class":844,"line":875},[842,1127,1128],{},"    INDEX idx_customer_id ON OrderData(json_path = '$.customer_id')\n",[842,1130,1131],{"class":844,"line":881},[842,1132,884],{},[842,1134,1135],{"class":844,"line":887},[842,1136,891],{"emptyLinePlaceholder":890},[842,1138,1139],{"class":844,"line":894},[842,1140,1141],{},"-- Insert JSON\n",[842,1143,1144],{"class":844,"line":900},[842,1145,1146],{},"INSERT INTO Orders (OrderData)\n",[842,1148,1149],{"class":844,"line":906},[842,1150,1151],{},"VALUES ('{\"customer_id\": 101, \"total\": 2500000, \"status\": \"pending\"}');\n",[821,1153,1154],{},[527,1155,1156],{},"Hàm JSON mới trong SQL Server 2025:",[833,1158,1160],{"className":835,"code":1159,"language":837,"meta":838,"style":838},"-- JSON_ARRAYAGG — aggregate thành JSON array\nSELECT JSON_ARRAYAGG(Name) FROM Products WHERE Category = N'Điện tử';\n-- Kết quả: [\"iPhone 15\", \"iPad Pro\", \"MacBook Air\"]\n\n-- JSON_OBJECTAGG — aggregate thành JSON object\nSELECT JSON_OBJECTAGG(Id: Name) FROM Products;\n-- Kết quả: {\"1\": \"iPhone 15\", \"2\": \"iPad Pro\", ...}\n\n-- JSON_CONTAINS — kiểm tra giá trị tồn tại trong JSON\nSELECT * FROM Orders WHERE JSON_CONTAINS(OrderData, 'completed', '$.status');\n\n-- Sửa JSON tại chỗ (in-place modification)\nUPDATE Orders SET OrderData.modify('append $.tags', '\"urgent\"');\n",[467,1161,1162,1167,1172,1177,1181,1186,1191,1196,1200,1205,1210,1214,1219],{"__ignoreMap":838},[842,1163,1164],{"class":844,"line":845},[842,1165,1166],{},"-- JSON_ARRAYAGG — aggregate thành JSON array\n",[842,1168,1169],{"class":844,"line":851},[842,1170,1171],{},"SELECT JSON_ARRAYAGG(Name) FROM Products WHERE Category = N'Điện tử';\n",[842,1173,1174],{"class":844,"line":857},[842,1175,1176],{},"-- Kết quả: [\"iPhone 15\", \"iPad Pro\", \"MacBook Air\"]\n",[842,1178,1179],{"class":844,"line":863},[842,1180,891],{"emptyLinePlaceholder":890},[842,1182,1183],{"class":844,"line":869},[842,1184,1185],{},"-- JSON_OBJECTAGG — aggregate thành JSON object\n",[842,1187,1188],{"class":844,"line":875},[842,1189,1190],{},"SELECT JSON_OBJECTAGG(Id: Name) FROM Products;\n",[842,1192,1193],{"class":844,"line":881},[842,1194,1195],{},"-- Kết quả: {\"1\": \"iPhone 15\", \"2\": \"iPad Pro\", ...}\n",[842,1197,1198],{"class":844,"line":887},[842,1199,891],{"emptyLinePlaceholder":890},[842,1201,1202],{"class":844,"line":894},[842,1203,1204],{},"-- JSON_CONTAINS — kiểm tra giá trị tồn tại trong JSON\n",[842,1206,1207],{"class":844,"line":900},[842,1208,1209],{},"SELECT * FROM Orders WHERE JSON_CONTAINS(OrderData, 'completed', '$.status');\n",[842,1211,1212],{"class":844,"line":906},[842,1213,891],{"emptyLinePlaceholder":890},[842,1215,1216],{"class":844,"line":912},[842,1217,1218],{},"-- Sửa JSON tại chỗ (in-place modification)\n",[842,1220,1221],{"class":844,"line":917},[842,1222,1223],{},"UPDATE Orders SET OrderData.modify('append $.tags', '\"urgent\"');\n",[589,1225,1226,1233],{"color":591,"icon":592},[821,1227,593,1228,597,1230],{},[527,1229,596],{},[599,1231,1232],{},"\"SQL Server có hỗ trợ JSON không? So với MongoDB thì thế nào?\"",[1046,1234,1235,1245,1254],{},[1049,1236,1237,1238,655,1241,1244],{},"SQL Server hỗ trợ JSON từ 2016 (",[467,1239,1240],{},"OPENJSON",[467,1242,1243],{},"FOR JSON","), nhưng lưu dưới dạng string.",[1049,1246,1247,1248,1250,1251,694],{},"Từ 2025: kiểu ",[467,1249,1089],{}," native — validate tự động, index trực tiếp trên json path, sửa in-place với ",[467,1252,1253],{},".modify()",[1049,1255,1256,1259],{},[527,1257,1258],{},"Khác MongoDB:"," SQL Server là relational-first có JSON capability. MongoDB là document-first. Dùng SQL Server JSON khi cần hybrid: schema cố định cho phần lớn data + flexible JSON cho phần metadata\u002Funstructured.",[427,1261,1263],{"id":1262},"_2-ddl-data-definition-language","2. DDL — Data Definition Language",[432,1265,1267],{"id":1266},"create-drop-alter-table","CREATE \u002F DROP \u002F ALTER TABLE",[833,1269,1271],{"className":835,"code":1270,"language":837,"meta":838,"style":838},"CREATE TABLE Products (\n    Id INT IDENTITY PRIMARY KEY,\n    Name NVARCHAR(200) NOT NULL,\n    Price DECIMAL(18, 2) NOT NULL CHECK (Price >= 0),\n    CategoryId INT NOT NULL,\n    CreatedAt DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),\n    IsActive BIT NOT NULL DEFAULT 1,\n    CONSTRAINT FK_Products_Category FOREIGN KEY (CategoryId)\n        REFERENCES Categories(Id) ON DELETE NO ACTION\n);\n\n-- Thêm cột\nALTER TABLE Products ADD Description NVARCHAR(MAX) NULL;\n\n-- Đổi kiểu\nALTER TABLE Products ALTER COLUMN Name NVARCHAR(300) NOT NULL;\n\n-- Drop cột\nALTER TABLE Products DROP COLUMN Description;\n\n-- Drop bảng (dropping cascading FK nếu cần xử lý trước)\nDROP TABLE IF EXISTS Products;\n",[467,1272,1273,1277,1281,1286,1291,1296,1301,1306,1311,1316,1320,1324,1329,1334,1338,1343,1348,1352,1357,1362,1367,1373],{"__ignoreMap":838},[842,1274,1275],{"class":844,"line":845},[842,1276,854],{},[842,1278,1279],{"class":844,"line":851},[842,1280,860],{},[842,1282,1283],{"class":844,"line":857},[842,1284,1285],{},"    Name NVARCHAR(200) NOT NULL,\n",[842,1287,1288],{"class":844,"line":863},[842,1289,1290],{},"    Price DECIMAL(18, 2) NOT NULL CHECK (Price >= 0),\n",[842,1292,1293],{"class":844,"line":869},[842,1294,1295],{},"    CategoryId INT NOT NULL,\n",[842,1297,1298],{"class":844,"line":875},[842,1299,1300],{},"    CreatedAt DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),\n",[842,1302,1303],{"class":844,"line":881},[842,1304,1305],{},"    IsActive BIT NOT NULL DEFAULT 1,\n",[842,1307,1308],{"class":844,"line":887},[842,1309,1310],{},"    CONSTRAINT FK_Products_Category FOREIGN KEY (CategoryId)\n",[842,1312,1313],{"class":844,"line":894},[842,1314,1315],{},"        REFERENCES Categories(Id) ON DELETE NO ACTION\n",[842,1317,1318],{"class":844,"line":900},[842,1319,884],{},[842,1321,1322],{"class":844,"line":906},[842,1323,891],{"emptyLinePlaceholder":890},[842,1325,1326],{"class":844,"line":912},[842,1327,1328],{},"-- Thêm cột\n",[842,1330,1331],{"class":844,"line":917},[842,1332,1333],{},"ALTER TABLE Products ADD Description NVARCHAR(MAX) NULL;\n",[842,1335,1336],{"class":844,"line":923},[842,1337,891],{"emptyLinePlaceholder":890},[842,1339,1340],{"class":844,"line":929},[842,1341,1342],{},"-- Đổi kiểu\n",[842,1344,1345],{"class":844,"line":934},[842,1346,1347],{},"ALTER TABLE Products ALTER COLUMN Name NVARCHAR(300) NOT NULL;\n",[842,1349,1350],{"class":844,"line":940},[842,1351,891],{"emptyLinePlaceholder":890},[842,1353,1354],{"class":844,"line":946},[842,1355,1356],{},"-- Drop cột\n",[842,1358,1359],{"class":844,"line":952},[842,1360,1361],{},"ALTER TABLE Products DROP COLUMN Description;\n",[842,1363,1365],{"class":844,"line":1364},20,[842,1366,891],{"emptyLinePlaceholder":890},[842,1368,1370],{"class":844,"line":1369},21,[842,1371,1372],{},"-- Drop bảng (dropping cascading FK nếu cần xử lý trước)\n",[842,1374,1376],{"class":844,"line":1375},22,[842,1377,1378],{},"DROP TABLE IF EXISTS Products;\n",[432,1380,1382],{"id":1381},"ràng-buộc-constraint","Ràng buộc (Constraint)",[833,1384,1386],{"className":835,"code":1385,"language":837,"meta":838,"style":838},"CREATE TABLE Users (\n    Id INT IDENTITY PRIMARY KEY,                       -- PRIMARY KEY\n    Email NVARCHAR(150) NOT NULL UNIQUE,               -- UNIQUE\n    Age INT CHECK (Age BETWEEN 0 AND 150),             -- CHECK\n    Status NVARCHAR(20) NOT NULL DEFAULT 'Active',     -- DEFAULT\n    CountryId INT NULL FOREIGN KEY REFERENCES Countries(Id) -- FK\n);\n",[467,1387,1388,1393,1398,1403,1408,1413,1418],{"__ignoreMap":838},[842,1389,1390],{"class":844,"line":845},[842,1391,1392],{},"CREATE TABLE Users (\n",[842,1394,1395],{"class":844,"line":851},[842,1396,1397],{},"    Id INT IDENTITY PRIMARY KEY,                       -- PRIMARY KEY\n",[842,1399,1400],{"class":844,"line":857},[842,1401,1402],{},"    Email NVARCHAR(150) NOT NULL UNIQUE,               -- UNIQUE\n",[842,1404,1405],{"class":844,"line":863},[842,1406,1407],{},"    Age INT CHECK (Age BETWEEN 0 AND 150),             -- CHECK\n",[842,1409,1410],{"class":844,"line":869},[842,1411,1412],{},"    Status NVARCHAR(20) NOT NULL DEFAULT 'Active',     -- DEFAULT\n",[842,1414,1415],{"class":844,"line":875},[842,1416,1417],{},"    CountryId INT NULL FOREIGN KEY REFERENCES Countries(Id) -- FK\n",[842,1419,1420],{"class":844,"line":881},[842,1421,884],{},[589,1423,1424,1431],{"color":591,"icon":592},[821,1425,593,1426,597,1428],{},[527,1427,596],{},[599,1429,1430],{},"\"Primary Key vs Unique Key khác gì?\"",[1046,1432,1433,1446],{},[1049,1434,1435,1436,655,1439,1442,1443,694],{},"PK: ",[527,1437,1438],{},"không null",[527,1440,1441],{},"1 cái \u002F bảng",", mặc định ",[527,1444,1445],{},"clustered index",[1049,1447,1448,1449,1452,1453,1456],{},"Unique: ",[527,1450,1451],{},"cho 1 null"," (SQL Server, khác chuẩn ANSI), ",[527,1454,1455],{},"nhiều cái \u002F bảng",", mặc định non-clustered.",[432,1458,1460],{"id":1459},"computed-column","Computed column",[833,1462,1464],{"className":835,"code":1463,"language":837,"meta":838,"style":838},"ALTER TABLE Products ADD\n    PriceWithTax AS (Price * 1.10) PERSISTED;     -- PERSISTED = lưu vật lý, index được\n",[467,1465,1466,1471],{"__ignoreMap":838},[842,1467,1468],{"class":844,"line":845},[842,1469,1470],{},"ALTER TABLE Products ADD\n",[842,1472,1473],{"class":844,"line":851},[842,1474,1475],{},"    PriceWithTax AS (Price * 1.10) PERSISTED;     -- PERSISTED = lưu vật lý, index được\n",[427,1477,1479],{"id":1478},"_3-dml-data-manipulation","3. DML — Data Manipulation",[432,1481,1027],{"id":1482},"insert",[833,1484,1486],{"className":835,"code":1485,"language":837,"meta":838,"style":838},"-- Single row\nINSERT INTO Products (Name, Price, CategoryId)\nVALUES (N'Bàn phím cơ', 2500000, 1);\n\n-- Multi-row\nINSERT INTO Products (Name, Price, CategoryId)\nVALUES\n    (N'Chuột Logitech', 1500000, 1),\n    (N'Tai nghe Sony',  3500000, 2);\n\n-- INSERT từ SELECT\nINSERT INTO ProductsBackup (Name, Price)\nSELECT Name, Price FROM Products WHERE IsActive = 1;\n\n-- Lấy ID vừa insert\nINSERT INTO Products (Name, Price, CategoryId)\nOUTPUT INSERTED.Id, INSERTED.Name\nVALUES (N'iPhone 15', 25000000, 3);\n",[467,1487,1488,1493,1498,1503,1507,1512,1516,1521,1526,1531,1535,1540,1545,1550,1554,1559,1563,1568],{"__ignoreMap":838},[842,1489,1490],{"class":844,"line":845},[842,1491,1492],{},"-- Single row\n",[842,1494,1495],{"class":844,"line":851},[842,1496,1497],{},"INSERT INTO Products (Name, Price, CategoryId)\n",[842,1499,1500],{"class":844,"line":857},[842,1501,1502],{},"VALUES (N'Bàn phím cơ', 2500000, 1);\n",[842,1504,1505],{"class":844,"line":863},[842,1506,891],{"emptyLinePlaceholder":890},[842,1508,1509],{"class":844,"line":869},[842,1510,1511],{},"-- Multi-row\n",[842,1513,1514],{"class":844,"line":875},[842,1515,1497],{},[842,1517,1518],{"class":844,"line":881},[842,1519,1520],{},"VALUES\n",[842,1522,1523],{"class":844,"line":887},[842,1524,1525],{},"    (N'Chuột Logitech', 1500000, 1),\n",[842,1527,1528],{"class":844,"line":894},[842,1529,1530],{},"    (N'Tai nghe Sony',  3500000, 2);\n",[842,1532,1533],{"class":844,"line":900},[842,1534,891],{"emptyLinePlaceholder":890},[842,1536,1537],{"class":844,"line":906},[842,1538,1539],{},"-- INSERT từ SELECT\n",[842,1541,1542],{"class":844,"line":912},[842,1543,1544],{},"INSERT INTO ProductsBackup (Name, Price)\n",[842,1546,1547],{"class":844,"line":917},[842,1548,1549],{},"SELECT Name, Price FROM Products WHERE IsActive = 1;\n",[842,1551,1552],{"class":844,"line":923},[842,1553,891],{"emptyLinePlaceholder":890},[842,1555,1556],{"class":844,"line":929},[842,1557,1558],{},"-- Lấy ID vừa insert\n",[842,1560,1561],{"class":844,"line":934},[842,1562,1497],{},[842,1564,1565],{"class":844,"line":940},[842,1566,1567],{},"OUTPUT INSERTED.Id, INSERTED.Name\n",[842,1569,1570],{"class":844,"line":946},[842,1571,1572],{},"VALUES (N'iPhone 15', 25000000, 3);\n",[589,1574,593,1575,1581,1582,1585],{"color":794,"icon":592},[527,1576,1577,1578],{},"Mệnh đề ",[467,1579,1580],{},"OUTPUT"," — đặc thù SQL Server, cực mạnh. Trả về row đã insert\u002Fupdate\u002Fdelete trong cùng statement. Tương đương ",[467,1583,1584],{},"RETURNING"," của Postgres.",[432,1587,1589],{"id":1588},"select","SELECT",[833,1591,1593],{"className":835,"code":1592,"language":837,"meta":838,"style":838},"-- Cơ bản\nSELECT Id, Name, Price FROM Products WHERE Price > 1000000 ORDER BY Price DESC;\n\n-- TOP + WITH TIES\nSELECT TOP 5 WITH TIES Name, Price\nFROM Products ORDER BY Price DESC;\n\n-- DISTINCT\nSELECT DISTINCT CategoryId FROM Products;\n\n-- Pagination (SQL Server 2012+)\nSELECT * FROM Products\nORDER BY Id\nOFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;\n",[467,1594,1595,1600,1605,1609,1614,1619,1624,1628,1633,1638,1642,1647,1652,1657],{"__ignoreMap":838},[842,1596,1597],{"class":844,"line":845},[842,1598,1599],{},"-- Cơ bản\n",[842,1601,1602],{"class":844,"line":851},[842,1603,1604],{},"SELECT Id, Name, Price FROM Products WHERE Price > 1000000 ORDER BY Price DESC;\n",[842,1606,1607],{"class":844,"line":857},[842,1608,891],{"emptyLinePlaceholder":890},[842,1610,1611],{"class":844,"line":863},[842,1612,1613],{},"-- TOP + WITH TIES\n",[842,1615,1616],{"class":844,"line":869},[842,1617,1618],{},"SELECT TOP 5 WITH TIES Name, Price\n",[842,1620,1621],{"class":844,"line":875},[842,1622,1623],{},"FROM Products ORDER BY Price DESC;\n",[842,1625,1626],{"class":844,"line":881},[842,1627,891],{"emptyLinePlaceholder":890},[842,1629,1630],{"class":844,"line":887},[842,1631,1632],{},"-- DISTINCT\n",[842,1634,1635],{"class":844,"line":894},[842,1636,1637],{},"SELECT DISTINCT CategoryId FROM Products;\n",[842,1639,1640],{"class":844,"line":900},[842,1641,891],{"emptyLinePlaceholder":890},[842,1643,1644],{"class":844,"line":906},[842,1645,1646],{},"-- Pagination (SQL Server 2012+)\n",[842,1648,1649],{"class":844,"line":912},[842,1650,1651],{},"SELECT * FROM Products\n",[842,1653,1654],{"class":844,"line":917},[842,1655,1656],{},"ORDER BY Id\n",[842,1658,1659],{"class":844,"line":923},[842,1660,1661],{},"OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;\n",[432,1663,1031],{"id":1664},"update",[833,1666,1668],{"className":835,"code":1667,"language":837,"meta":838,"style":838},"-- Update có WHERE\nUPDATE Products\nSET Price = Price * 1.1, UpdatedAt = SYSUTCDATETIME()\nWHERE CategoryId = 1;\n\n-- UPDATE từ JOIN (đặc thù SQL Server — Postgres\u002FMySQL syntax khác)\nUPDATE p\nSET p.CategoryName = c.Name\nFROM Products p\nJOIN Categories c ON c.Id = p.CategoryId;\n",[467,1669,1670,1675,1680,1685,1690,1694,1699,1704,1709,1714],{"__ignoreMap":838},[842,1671,1672],{"class":844,"line":845},[842,1673,1674],{},"-- Update có WHERE\n",[842,1676,1677],{"class":844,"line":851},[842,1678,1679],{},"UPDATE Products\n",[842,1681,1682],{"class":844,"line":857},[842,1683,1684],{},"SET Price = Price * 1.1, UpdatedAt = SYSUTCDATETIME()\n",[842,1686,1687],{"class":844,"line":863},[842,1688,1689],{},"WHERE CategoryId = 1;\n",[842,1691,1692],{"class":844,"line":869},[842,1693,891],{"emptyLinePlaceholder":890},[842,1695,1696],{"class":844,"line":875},[842,1697,1698],{},"-- UPDATE từ JOIN (đặc thù SQL Server — Postgres\u002FMySQL syntax khác)\n",[842,1700,1701],{"class":844,"line":881},[842,1702,1703],{},"UPDATE p\n",[842,1705,1706],{"class":844,"line":887},[842,1707,1708],{},"SET p.CategoryName = c.Name\n",[842,1710,1711],{"class":844,"line":894},[842,1712,1713],{},"FROM Products p\n",[842,1715,1716],{"class":844,"line":900},[842,1717,1718],{},"JOIN Categories c ON c.Id = p.CategoryId;\n",[589,1720,1723,1726,1727,1730,1731,1734],{"color":1721,"icon":1722},"error","i-lucide-alert-octagon",[527,1724,1725],{},"Lỗi fresher kinh điển:"," quên ",[467,1728,1729],{},"WHERE"," trong UPDATE\u002FDELETE → đè\u002Fxoá hết bảng. Trước khi chạy, ",[527,1732,1733],{},"luôn SELECT thử"," với cùng WHERE.",[432,1736,1034],{"id":1737},"delete",[833,1739,1741],{"className":835,"code":1740,"language":837,"meta":838,"style":838},"DELETE FROM Products WHERE IsActive = 0;\n\n-- TOP — xoá có giới hạn\nDELETE TOP (1000) FROM AuditLogs WHERE CreatedAt \u003C DATEADD(MONTH, -6, GETDATE());\n",[467,1742,1743,1748,1752,1757],{"__ignoreMap":838},[842,1744,1745],{"class":844,"line":845},[842,1746,1747],{},"DELETE FROM Products WHERE IsActive = 0;\n",[842,1749,1750],{"class":844,"line":851},[842,1751,891],{"emptyLinePlaceholder":890},[842,1753,1754],{"class":844,"line":857},[842,1755,1756],{},"-- TOP — xoá có giới hạn\n",[842,1758,1759],{"class":844,"line":863},[842,1760,1761],{},"DELETE TOP (1000) FROM AuditLogs WHERE CreatedAt \u003C DATEADD(MONTH, -6, GETDATE());\n",[432,1763,1765],{"id":1764},"truncate","TRUNCATE",[833,1767,1769],{"className":835,"code":1768,"language":837,"meta":838,"style":838},"TRUNCATE TABLE Logs;\n-- Nhanh hơn DELETE (không log từng row, deallocate page).\n-- KHÔNG dùng được nếu bảng được FK reference.\n",[467,1770,1771,1776,1781],{"__ignoreMap":838},[842,1772,1773],{"class":844,"line":845},[842,1774,1775],{},"TRUNCATE TABLE Logs;\n",[842,1777,1778],{"class":844,"line":851},[842,1779,1780],{},"-- Nhanh hơn DELETE (không log từng row, deallocate page).\n",[842,1782,1783],{"class":844,"line":857},[842,1784,1785],{},"-- KHÔNG dùng được nếu bảng được FK reference.\n",[589,1787,1788,1793],{"color":591,"icon":592},[821,1789,593,1790],{},[527,1791,1792],{},"DELETE vs TRUNCATE vs DROP:",[437,1794,1795,1808],{},[440,1796,1797],{},[443,1798,1799,1801,1803,1805],{},[446,1800],{},[446,1802,1034],{},[446,1804,1765],{},[446,1806,1807],{},"DROP",[459,1809,1810,1823,1835,1847,1859,1873,1886],{},[443,1811,1812,1815,1818,1821],{},[464,1813,1814],{},"Loại",[464,1816,1817],{},"DML",[464,1819,1820],{},"DDL",[464,1822,1820],{},[443,1824,1825,1827,1830,1833],{},[464,1826,1729],{},[464,1828,1829],{},"✅",[464,1831,1832],{},"❌",[464,1834,1832],{},[443,1836,1837,1840,1842,1844],{},[464,1838,1839],{},"Reset IDENTITY",[464,1841,1832],{},[464,1843,1829],{},[464,1845,1846],{},"N\u002FA",[443,1848,1849,1852,1855,1857],{},[464,1850,1851],{},"Trigger",[464,1853,1854],{},"✅ chạy",[464,1856,1832],{},[464,1858,1846],{},[443,1860,1861,1864,1867,1870],{},[464,1862,1863],{},"Tốc độ",[464,1865,1866],{},"Chậm",[464,1868,1869],{},"Nhanh",[464,1871,1872],{},"Nhanh nhất",[443,1874,1875,1878,1881,1883],{},[464,1876,1877],{},"Bảng sau khi chạy",[464,1879,1880],{},"✅ còn",[464,1882,1880],{},[464,1884,1885],{},"❌ mất",[443,1887,1888,1891,1893,1896],{},[464,1889,1890],{},"Rollback trong tx",[464,1892,1829],{},[464,1894,1895],{},"✅ (SQL Server!)",[464,1897,1829],{},[432,1899,1901],{"id":1900},"merge-upsert-atomic","MERGE — Upsert atomic",[833,1903,1905],{"className":835,"code":1904,"language":837,"meta":838,"style":838},"MERGE INTO Products AS target\nUSING (VALUES\n    (N'iPhone 15', 25000000, 3),\n    (N'iPad Pro',  20000000, 3)\n) AS src (Name, Price, CategoryId)\nON target.Name = src.Name\nWHEN MATCHED THEN\n    UPDATE SET Price = src.Price\nWHEN NOT MATCHED THEN\n    INSERT (Name, Price, CategoryId) VALUES (src.Name, src.Price, src.CategoryId)\nOUTPUT $action, INSERTED.Id, INSERTED.Name;\n",[467,1906,1907,1912,1917,1922,1927,1932,1937,1942,1947,1952,1957],{"__ignoreMap":838},[842,1908,1909],{"class":844,"line":845},[842,1910,1911],{},"MERGE INTO Products AS target\n",[842,1913,1914],{"class":844,"line":851},[842,1915,1916],{},"USING (VALUES\n",[842,1918,1919],{"class":844,"line":857},[842,1920,1921],{},"    (N'iPhone 15', 25000000, 3),\n",[842,1923,1924],{"class":844,"line":863},[842,1925,1926],{},"    (N'iPad Pro',  20000000, 3)\n",[842,1928,1929],{"class":844,"line":869},[842,1930,1931],{},") AS src (Name, Price, CategoryId)\n",[842,1933,1934],{"class":844,"line":875},[842,1935,1936],{},"ON target.Name = src.Name\n",[842,1938,1939],{"class":844,"line":881},[842,1940,1941],{},"WHEN MATCHED THEN\n",[842,1943,1944],{"class":844,"line":887},[842,1945,1946],{},"    UPDATE SET Price = src.Price\n",[842,1948,1949],{"class":844,"line":894},[842,1950,1951],{},"WHEN NOT MATCHED THEN\n",[842,1953,1954],{"class":844,"line":900},[842,1955,1956],{},"    INSERT (Name, Price, CategoryId) VALUES (src.Name, src.Price, src.CategoryId)\n",[842,1958,1959],{"class":844,"line":906},[842,1960,1961],{},"OUTPUT $action, INSERTED.Id, INSERTED.Name;\n",[589,1963,1964,1967,1968,1971],{"color":591,"icon":1012},[527,1965,1966],{},"Tranh cãi MERGE:"," historically có bug edge case. Nhiều DBA khuyên dùng tổ hợp ",[467,1969,1970],{},"IF EXISTS \u002F UPDATE \u002F INSERT"," thay vì MERGE. SQL Server 2022+ đã fix nhiều, nhưng kỹ thì test kỹ.",[427,1973,1975],{"id":1974},"_4-null-handling","4. NULL handling",[833,1977,1979],{"className":835,"code":1978,"language":837,"meta":838,"style":838},"-- NULL không bằng gì, kể cả NULL khác\nSELECT NULL = NULL;       -- không trả TRUE, trả UNKNOWN (NULL)\n\n-- Phải dùng IS NULL \u002F IS NOT NULL\nSELECT * FROM Users WHERE Email IS NULL;\nSELECT * FROM Users WHERE Email IS NOT NULL;\n\n-- ISNULL \u002F COALESCE — trả giá trị thay thế\nSELECT Name, ISNULL(Email, 'no-email') AS Email FROM Users;\n\n-- COALESCE chuẩn ANSI, nhận nhiều argument\nSELECT Name, COALESCE(MobilePhone, HomePhone, 'no-phone') AS Phone FROM Users;\n\n-- NULLIF — trả NULL nếu 2 giá trị bằng nhau (tránh chia 0)\nSELECT a \u002F NULLIF(b, 0) AS Result FROM Calc;\n",[467,1980,1981,1986,1991,1995,2000,2005,2010,2014,2019,2024,2028,2033,2038,2042,2047],{"__ignoreMap":838},[842,1982,1983],{"class":844,"line":845},[842,1984,1985],{},"-- NULL không bằng gì, kể cả NULL khác\n",[842,1987,1988],{"class":844,"line":851},[842,1989,1990],{},"SELECT NULL = NULL;       -- không trả TRUE, trả UNKNOWN (NULL)\n",[842,1992,1993],{"class":844,"line":857},[842,1994,891],{"emptyLinePlaceholder":890},[842,1996,1997],{"class":844,"line":863},[842,1998,1999],{},"-- Phải dùng IS NULL \u002F IS NOT NULL\n",[842,2001,2002],{"class":844,"line":869},[842,2003,2004],{},"SELECT * FROM Users WHERE Email IS NULL;\n",[842,2006,2007],{"class":844,"line":875},[842,2008,2009],{},"SELECT * FROM Users WHERE Email IS NOT NULL;\n",[842,2011,2012],{"class":844,"line":881},[842,2013,891],{"emptyLinePlaceholder":890},[842,2015,2016],{"class":844,"line":887},[842,2017,2018],{},"-- ISNULL \u002F COALESCE — trả giá trị thay thế\n",[842,2020,2021],{"class":844,"line":894},[842,2022,2023],{},"SELECT Name, ISNULL(Email, 'no-email') AS Email FROM Users;\n",[842,2025,2026],{"class":844,"line":900},[842,2027,891],{"emptyLinePlaceholder":890},[842,2029,2030],{"class":844,"line":906},[842,2031,2032],{},"-- COALESCE chuẩn ANSI, nhận nhiều argument\n",[842,2034,2035],{"class":844,"line":912},[842,2036,2037],{},"SELECT Name, COALESCE(MobilePhone, HomePhone, 'no-phone') AS Phone FROM Users;\n",[842,2039,2040],{"class":844,"line":917},[842,2041,891],{"emptyLinePlaceholder":890},[842,2043,2044],{"class":844,"line":923},[842,2045,2046],{},"-- NULLIF — trả NULL nếu 2 giá trị bằng nhau (tránh chia 0)\n",[842,2048,2049],{"class":844,"line":929},[842,2050,2051],{},"SELECT a \u002F NULLIF(b, 0) AS Result FROM Calc;\n",[589,2053,2054,2070],{"color":591,"icon":592},[821,2055,593,2056,597,2059],{},[527,2057,2058],{},"Câu hỏi PV:",[599,2060,2061,2062,2065,2066,2069],{},"\"",[467,2063,2064],{},"COUNT(*)"," vs ",[467,2067,2068],{},"COUNT(col)"," khác gì?\"",[1046,2071,2072,2077,2085],{},[1049,2073,2074,2076],{},[467,2075,2064],{}," đếm tất cả row.",[1049,2078,2079,2081,2082,694],{},[467,2080,2068],{}," đếm row ",[527,2083,2084],{},"có col IS NOT NULL",[1049,2086,2087,2090],{},[467,2088,2089],{},"COUNT(DISTINCT col)"," đếm distinct non-null.",[427,2092,2094],{"id":2093},"_5-function-thường-dùng","5. Function thường dùng",[432,2096,2098],{"id":2097},"string","String",[833,2100,2102],{"className":835,"code":2101,"language":837,"meta":838,"style":838},"SELECT\n    LEN(N'Hello'),                       -- 5\n    LOWER(N'ABC'), UPPER(N'abc'),\n    LEFT(N'Hello', 3),                   -- 'Hel'\n    RIGHT(N'Hello', 2),                  -- 'lo'\n    SUBSTRING(N'Hello', 2, 3),           -- 'ell'\n    LTRIM(N'  abc  '), RTRIM(N'  abc  '), TRIM(N'  abc  '),\n    REPLACE(N'abc', 'b', 'X'),           -- 'aXc'\n    CONCAT(N'Hello', ' ', N'World'),\n    STRING_AGG(Name, ', ')               -- aggregate, gộp string\n        WITHIN GROUP (ORDER BY Name);\n",[467,2103,2104,2109,2114,2119,2124,2129,2134,2139,2144,2149,2154],{"__ignoreMap":838},[842,2105,2106],{"class":844,"line":845},[842,2107,2108],{},"SELECT\n",[842,2110,2111],{"class":844,"line":851},[842,2112,2113],{},"    LEN(N'Hello'),                       -- 5\n",[842,2115,2116],{"class":844,"line":857},[842,2117,2118],{},"    LOWER(N'ABC'), UPPER(N'abc'),\n",[842,2120,2121],{"class":844,"line":863},[842,2122,2123],{},"    LEFT(N'Hello', 3),                   -- 'Hel'\n",[842,2125,2126],{"class":844,"line":869},[842,2127,2128],{},"    RIGHT(N'Hello', 2),                  -- 'lo'\n",[842,2130,2131],{"class":844,"line":875},[842,2132,2133],{},"    SUBSTRING(N'Hello', 2, 3),           -- 'ell'\n",[842,2135,2136],{"class":844,"line":881},[842,2137,2138],{},"    LTRIM(N'  abc  '), RTRIM(N'  abc  '), TRIM(N'  abc  '),\n",[842,2140,2141],{"class":844,"line":887},[842,2142,2143],{},"    REPLACE(N'abc', 'b', 'X'),           -- 'aXc'\n",[842,2145,2146],{"class":844,"line":894},[842,2147,2148],{},"    CONCAT(N'Hello', ' ', N'World'),\n",[842,2150,2151],{"class":844,"line":900},[842,2152,2153],{},"    STRING_AGG(Name, ', ')               -- aggregate, gộp string\n",[842,2155,2156],{"class":844,"line":906},[842,2157,2158],{},"        WITHIN GROUP (ORDER BY Name);\n",[432,2160,2162],{"id":2161},"date","Date",[833,2164,2166],{"className":835,"code":2165,"language":837,"meta":838,"style":838},"SELECT\n    SYSUTCDATETIME(),                    -- UTC, DATETIME2 — KHUYẾN NGHỊ\n    GETUTCDATE(),                        -- UTC, DATETIME\n    GETDATE(),                           -- Local server time\n    DATEADD(DAY, 7, GETDATE()),          -- +7 ngày\n    DATEDIFF(DAY, '2026-01-01', GETDATE()),  -- số ngày giữa\n    DATEPART(YEAR, GETDATE()),           -- 2026\n    YEAR(GETDATE()), MONTH(GETDATE()), DAY(GETDATE()),\n    FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm'),  -- chậm hơn CONVERT, đẹp hơn\n    EOMONTH(GETDATE());                  -- last day of month\n",[467,2167,2168,2172,2177,2182,2187,2192,2197,2202,2207,2212],{"__ignoreMap":838},[842,2169,2170],{"class":844,"line":845},[842,2171,2108],{},[842,2173,2174],{"class":844,"line":851},[842,2175,2176],{},"    SYSUTCDATETIME(),                    -- UTC, DATETIME2 — KHUYẾN NGHỊ\n",[842,2178,2179],{"class":844,"line":857},[842,2180,2181],{},"    GETUTCDATE(),                        -- UTC, DATETIME\n",[842,2183,2184],{"class":844,"line":863},[842,2185,2186],{},"    GETDATE(),                           -- Local server time\n",[842,2188,2189],{"class":844,"line":869},[842,2190,2191],{},"    DATEADD(DAY, 7, GETDATE()),          -- +7 ngày\n",[842,2193,2194],{"class":844,"line":875},[842,2195,2196],{},"    DATEDIFF(DAY, '2026-01-01', GETDATE()),  -- số ngày giữa\n",[842,2198,2199],{"class":844,"line":881},[842,2200,2201],{},"    DATEPART(YEAR, GETDATE()),           -- 2026\n",[842,2203,2204],{"class":844,"line":887},[842,2205,2206],{},"    YEAR(GETDATE()), MONTH(GETDATE()), DAY(GETDATE()),\n",[842,2208,2209],{"class":844,"line":894},[842,2210,2211],{},"    FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm'),  -- chậm hơn CONVERT, đẹp hơn\n",[842,2213,2214],{"class":844,"line":900},[842,2215,2216],{},"    EOMONTH(GETDATE());                  -- last day of month\n",[432,2218,2220],{"id":2219},"conversion","Conversion",[833,2222,2224],{"className":835,"code":2223,"language":837,"meta":838,"style":838},"SELECT\n    CAST('123' AS INT),                  -- 123\n    CONVERT(INT, '123'),                 -- 123\n    TRY_CAST('abc' AS INT),              -- NULL (không throw)\n    TRY_CONVERT(DATE, '2026-13-99'),     -- NULL (không throw)\n    PARSE('2,500.00' AS DECIMAL(18, 2) USING 'en-US');\n",[467,2225,2226,2230,2235,2240,2245,2250],{"__ignoreMap":838},[842,2227,2228],{"class":844,"line":845},[842,2229,2108],{},[842,2231,2232],{"class":844,"line":851},[842,2233,2234],{},"    CAST('123' AS INT),                  -- 123\n",[842,2236,2237],{"class":844,"line":857},[842,2238,2239],{},"    CONVERT(INT, '123'),                 -- 123\n",[842,2241,2242],{"class":844,"line":863},[842,2243,2244],{},"    TRY_CAST('abc' AS INT),              -- NULL (không throw)\n",[842,2246,2247],{"class":844,"line":869},[842,2248,2249],{},"    TRY_CONVERT(DATE, '2026-13-99'),     -- NULL (không throw)\n",[842,2251,2252],{"class":844,"line":875},[842,2253,2254],{},"    PARSE('2,500.00' AS DECIMAL(18, 2) USING 'en-US');\n",[589,2256,593,2257,2260,2261,2264],{"color":794,"icon":592},[527,2258,2259],{},"TRY_CAST \u002F TRY_CONVERT"," dùng khi dữ liệu nguồn có thể lỗi format. Trả ",[467,2262,2263],{},"NULL"," thay vì raise error → tránh vỡ batch.",[432,2266,2268],{"id":2267},"regex-sql-server-2025","RegEx (SQL Server 2025)",[821,2270,2271,2272,2275],{},"SQL Server 2025 bổ sung native RegEx functions — trước đây chỉ có ",[467,2273,2274],{},"LIKE"," với pattern hạn chế, muốn RegEx phải dùng CLR integration:",[833,2277,2279],{"className":835,"code":2278,"language":837,"meta":838,"style":838},"-- Kiểm tra pattern trong WHERE\nSELECT * FROM Users\nWHERE REGEXP_LIKE(Email, '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$');\n\n-- Trích xuất substring theo pattern\nSELECT REGEXP_SUBSTR(ContactInfo, '\\d{3}-\\d{3}-\\d{4}') AS Phone FROM Contacts;\n\n-- Thay thế theo pattern\nSELECT REGEXP_REPLACE(SSN, '(\\d{3})-(\\d{2})-(\\d{4})', '***-**-$3') AS MaskedSSN\nFROM Users;\n\n-- Đếm số lần khớp pattern\nSELECT REGEXP_COUNT(SqlText, '\\b(SELECT|INSERT|UPDATE|DELETE)\\b', 'i') AS DMLCount\nFROM AuditLogs;\n\n-- Tách chuỗi thành bảng (nhiều delimiter)\nSELECT * FROM REGEXP_SPLIT_TO_TABLE('a,b;c|d', '[,;|]');\n-- Kết quả: 4 rows — 'a', 'b', 'c', 'd'\n\n-- CHECK constraint với RegEx\nALTER TABLE Users ADD CONSTRAINT ck_email\nCHECK (REGEXP_LIKE(Email, '^.+@.+\\..+$'));\n",[467,2280,2281,2286,2291,2296,2300,2305,2310,2314,2319,2324,2329,2333,2338,2343,2348,2352,2357,2362,2367,2371,2376,2381],{"__ignoreMap":838},[842,2282,2283],{"class":844,"line":845},[842,2284,2285],{},"-- Kiểm tra pattern trong WHERE\n",[842,2287,2288],{"class":844,"line":851},[842,2289,2290],{},"SELECT * FROM Users\n",[842,2292,2293],{"class":844,"line":857},[842,2294,2295],{},"WHERE REGEXP_LIKE(Email, '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$');\n",[842,2297,2298],{"class":844,"line":863},[842,2299,891],{"emptyLinePlaceholder":890},[842,2301,2302],{"class":844,"line":869},[842,2303,2304],{},"-- Trích xuất substring theo pattern\n",[842,2306,2307],{"class":844,"line":875},[842,2308,2309],{},"SELECT REGEXP_SUBSTR(ContactInfo, '\\d{3}-\\d{3}-\\d{4}') AS Phone FROM Contacts;\n",[842,2311,2312],{"class":844,"line":881},[842,2313,891],{"emptyLinePlaceholder":890},[842,2315,2316],{"class":844,"line":887},[842,2317,2318],{},"-- Thay thế theo pattern\n",[842,2320,2321],{"class":844,"line":894},[842,2322,2323],{},"SELECT REGEXP_REPLACE(SSN, '(\\d{3})-(\\d{2})-(\\d{4})', '***-**-$3') AS MaskedSSN\n",[842,2325,2326],{"class":844,"line":900},[842,2327,2328],{},"FROM Users;\n",[842,2330,2331],{"class":844,"line":906},[842,2332,891],{"emptyLinePlaceholder":890},[842,2334,2335],{"class":844,"line":912},[842,2336,2337],{},"-- Đếm số lần khớp pattern\n",[842,2339,2340],{"class":844,"line":917},[842,2341,2342],{},"SELECT REGEXP_COUNT(SqlText, '\\b(SELECT|INSERT|UPDATE|DELETE)\\b', 'i') AS DMLCount\n",[842,2344,2345],{"class":844,"line":923},[842,2346,2347],{},"FROM AuditLogs;\n",[842,2349,2350],{"class":844,"line":929},[842,2351,891],{"emptyLinePlaceholder":890},[842,2353,2354],{"class":844,"line":934},[842,2355,2356],{},"-- Tách chuỗi thành bảng (nhiều delimiter)\n",[842,2358,2359],{"class":844,"line":940},[842,2360,2361],{},"SELECT * FROM REGEXP_SPLIT_TO_TABLE('a,b;c|d', '[,;|]');\n",[842,2363,2364],{"class":844,"line":946},[842,2365,2366],{},"-- Kết quả: 4 rows — 'a', 'b', 'c', 'd'\n",[842,2368,2369],{"class":844,"line":952},[842,2370,891],{"emptyLinePlaceholder":890},[842,2372,2373],{"class":844,"line":1364},[842,2374,2375],{},"-- CHECK constraint với RegEx\n",[842,2377,2378],{"class":844,"line":1369},[842,2379,2380],{},"ALTER TABLE Users ADD CONSTRAINT ck_email\n",[842,2382,2383],{"class":844,"line":1375},[842,2384,2385],{},"CHECK (REGEXP_LIKE(Email, '^.+@.+\\..+$'));\n",[589,2387,2388,2395],{"color":794,"icon":592},[821,2389,593,2390,597,2392],{},[527,2391,596],{},[599,2393,2394],{},"\"Làm sao validate email trong SQL Server?\"",[1046,2396,2397,2404,2411],{},[1049,2398,2399,2400,2403],{},"Trước 2025: ",[467,2401,2402],{},"CHECK (Email LIKE '%_@__%.__%')"," — sơ sài, dễ bỏ sót edge case.",[1049,2405,2406,2407,2410],{},"Từ 2025: ",[467,2408,2409],{},"CHECK (REGEXP_LIKE(Email, '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'))"," — chuẩn RFC 5322 simplified.",[1049,2412,2413],{},"Lưu ý: validation hoàn chỉnh nên làm ở tầng application. RegEx trong DB là lớp bảo vệ cuối cùng, tránh data bẩn lọt vào.",[427,2415,2417],{"id":2416},"_6-variable-control-flow-trong-t-sql","6. Variable & control flow trong T-SQL",[833,2419,2421],{"className":835,"code":2420,"language":837,"meta":838,"style":838},"DECLARE @Name NVARCHAR(50) = N'Alice';\nDECLARE @Age INT;\nSET @Age = 25;\n\nIF @Age >= 18\n    PRINT N'Adult';\nELSE\n    PRINT N'Minor';\n\n-- WHILE\nDECLARE @i INT = 0;\nWHILE @i \u003C 5\nBEGIN\n    PRINT @i;\n    SET @i += 1;\nEND\n\n-- CASE — dùng cả trong SELECT\nSELECT Name,\n    CASE\n        WHEN Price \u003C 1000000 THEN N'Cheap'\n        WHEN Price \u003C 10000000 THEN N'Medium'\n        ELSE N'Premium'\n    END AS Tier\nFROM Products;\n",[467,2422,2423,2428,2433,2438,2442,2447,2452,2457,2462,2466,2471,2476,2481,2486,2491,2496,2501,2505,2510,2515,2520,2525,2530,2536,2542],{"__ignoreMap":838},[842,2424,2425],{"class":844,"line":845},[842,2426,2427],{},"DECLARE @Name NVARCHAR(50) = N'Alice';\n",[842,2429,2430],{"class":844,"line":851},[842,2431,2432],{},"DECLARE @Age INT;\n",[842,2434,2435],{"class":844,"line":857},[842,2436,2437],{},"SET @Age = 25;\n",[842,2439,2440],{"class":844,"line":863},[842,2441,891],{"emptyLinePlaceholder":890},[842,2443,2444],{"class":844,"line":869},[842,2445,2446],{},"IF @Age >= 18\n",[842,2448,2449],{"class":844,"line":875},[842,2450,2451],{},"    PRINT N'Adult';\n",[842,2453,2454],{"class":844,"line":881},[842,2455,2456],{},"ELSE\n",[842,2458,2459],{"class":844,"line":887},[842,2460,2461],{},"    PRINT N'Minor';\n",[842,2463,2464],{"class":844,"line":894},[842,2465,891],{"emptyLinePlaceholder":890},[842,2467,2468],{"class":844,"line":900},[842,2469,2470],{},"-- WHILE\n",[842,2472,2473],{"class":844,"line":906},[842,2474,2475],{},"DECLARE @i INT = 0;\n",[842,2477,2478],{"class":844,"line":912},[842,2479,2480],{},"WHILE @i \u003C 5\n",[842,2482,2483],{"class":844,"line":917},[842,2484,2485],{},"BEGIN\n",[842,2487,2488],{"class":844,"line":923},[842,2489,2490],{},"    PRINT @i;\n",[842,2492,2493],{"class":844,"line":929},[842,2494,2495],{},"    SET @i += 1;\n",[842,2497,2498],{"class":844,"line":934},[842,2499,2500],{},"END\n",[842,2502,2503],{"class":844,"line":940},[842,2504,891],{"emptyLinePlaceholder":890},[842,2506,2507],{"class":844,"line":946},[842,2508,2509],{},"-- CASE — dùng cả trong SELECT\n",[842,2511,2512],{"class":844,"line":952},[842,2513,2514],{},"SELECT Name,\n",[842,2516,2517],{"class":844,"line":1364},[842,2518,2519],{},"    CASE\n",[842,2521,2522],{"class":844,"line":1369},[842,2523,2524],{},"        WHEN Price \u003C 1000000 THEN N'Cheap'\n",[842,2526,2527],{"class":844,"line":1375},[842,2528,2529],{},"        WHEN Price \u003C 10000000 THEN N'Medium'\n",[842,2531,2533],{"class":844,"line":2532},23,[842,2534,2535],{},"        ELSE N'Premium'\n",[842,2537,2539],{"class":844,"line":2538},24,[842,2540,2541],{},"    END AS Tier\n",[842,2543,2545],{"class":844,"line":2544},25,[842,2546,2547],{},"FROM Products;\n",[427,2549,2551],{"id":2550},"_7-stored-procedure-user-defined-function","7. Stored procedure & user-defined function",[432,2553,2555],{"id":2554},"stored-procedure","Stored Procedure",[833,2557,2559],{"className":835,"code":2558,"language":837,"meta":838,"style":838},"CREATE OR ALTER PROCEDURE GetUsersByCity\n    @City NVARCHAR(50),\n    @MinAge INT = 18\nAS\nBEGIN\n    SET NOCOUNT ON;\n    SELECT Id, Name, Age\n    FROM Users\n    WHERE City = @City AND Age >= @MinAge;\nEND\nGO\n\nEXEC GetUsersByCity @City = N'HCM', @MinAge = 21;\n",[467,2560,2561,2566,2571,2576,2581,2585,2590,2595,2600,2605,2609,2614,2618],{"__ignoreMap":838},[842,2562,2563],{"class":844,"line":845},[842,2564,2565],{},"CREATE OR ALTER PROCEDURE GetUsersByCity\n",[842,2567,2568],{"class":844,"line":851},[842,2569,2570],{},"    @City NVARCHAR(50),\n",[842,2572,2573],{"class":844,"line":857},[842,2574,2575],{},"    @MinAge INT = 18\n",[842,2577,2578],{"class":844,"line":863},[842,2579,2580],{},"AS\n",[842,2582,2583],{"class":844,"line":869},[842,2584,2485],{},[842,2586,2587],{"class":844,"line":875},[842,2588,2589],{},"    SET NOCOUNT ON;\n",[842,2591,2592],{"class":844,"line":881},[842,2593,2594],{},"    SELECT Id, Name, Age\n",[842,2596,2597],{"class":844,"line":887},[842,2598,2599],{},"    FROM Users\n",[842,2601,2602],{"class":844,"line":894},[842,2603,2604],{},"    WHERE City = @City AND Age >= @MinAge;\n",[842,2606,2607],{"class":844,"line":900},[842,2608,2500],{},[842,2610,2611],{"class":844,"line":906},[842,2612,2613],{},"GO\n",[842,2615,2616],{"class":844,"line":912},[842,2617,891],{"emptyLinePlaceholder":890},[842,2619,2620],{"class":844,"line":917},[842,2621,2622],{},"EXEC GetUsersByCity @City = N'HCM', @MinAge = 21;\n",[432,2624,2626],{"id":2625},"scalar-function","Scalar function",[833,2628,2630],{"className":835,"code":2629,"language":837,"meta":838,"style":838},"CREATE OR ALTER FUNCTION fn_FullName(@First NVARCHAR(50), @Last NVARCHAR(50))\nRETURNS NVARCHAR(101)\nAS BEGIN\n    RETURN CONCAT(@First, ' ', @Last);\nEND\nGO\n\nSELECT dbo.fn_FullName(FirstName, LastName) FROM Users;\n",[467,2631,2632,2637,2642,2647,2652,2656,2660,2664],{"__ignoreMap":838},[842,2633,2634],{"class":844,"line":845},[842,2635,2636],{},"CREATE OR ALTER FUNCTION fn_FullName(@First NVARCHAR(50), @Last NVARCHAR(50))\n",[842,2638,2639],{"class":844,"line":851},[842,2640,2641],{},"RETURNS NVARCHAR(101)\n",[842,2643,2644],{"class":844,"line":857},[842,2645,2646],{},"AS BEGIN\n",[842,2648,2649],{"class":844,"line":863},[842,2650,2651],{},"    RETURN CONCAT(@First, ' ', @Last);\n",[842,2653,2654],{"class":844,"line":869},[842,2655,2500],{},[842,2657,2658],{"class":844,"line":875},[842,2659,2613],{},[842,2661,2662],{"class":844,"line":881},[842,2663,891],{"emptyLinePlaceholder":890},[842,2665,2666],{"class":844,"line":887},[842,2667,2668],{},"SELECT dbo.fn_FullName(FirstName, LastName) FROM Users;\n",[589,2670,2671,2677],{"color":591,"icon":1012},[821,2672,2673,2676],{},[527,2674,2675],{},"Tránh scalar UDF trong SELECT lớn"," — gây row-by-row execution, chậm. Dùng inline table-valued function (iTVF) thay:",[833,2678,2680],{"className":835,"code":2679,"language":837,"meta":838,"style":838},"CREATE FUNCTION fn_FullNameTbl(@First NVARCHAR(50), @Last NVARCHAR(50))\nRETURNS TABLE\nAS RETURN (SELECT CONCAT(@First, ' ', @Last) AS FullName);\n",[467,2681,2682,2687,2692],{"__ignoreMap":838},[842,2683,2684],{"class":844,"line":845},[842,2685,2686],{},"CREATE FUNCTION fn_FullNameTbl(@First NVARCHAR(50), @Last NVARCHAR(50))\n",[842,2688,2689],{"class":844,"line":851},[842,2690,2691],{},"RETURNS TABLE\n",[842,2693,2694],{"class":844,"line":857},[842,2695,2696],{},"AS RETURN (SELECT CONCAT(@First, ' ', @Last) AS FullName);\n",[427,2698,2700],{"id":2699},"_8-sp_invoke_external_rest_endpoint-gọi-api-từ-t-sql","8. sp_invoke_external_rest_endpoint — Gọi API từ T-SQL",[821,2702,2703,2704,2707],{},"SQL Server 2025 cho phép gọi HTTP REST API trực tiếp từ T-SQL thông qua stored procedure hệ thống ",[467,2705,2706],{},"sp_invoke_external_rest_endpoint",". Đây là tính năng cực mạnh để tích hợp AI\u002FML và external service ngay trong database:",[833,2709,2711],{"className":835,"code":2710,"language":837,"meta":838,"style":838},"-- Gọi OpenAI API để tạo embedding ngay trong T-SQL\nDECLARE @response NVARCHAR(MAX);\n\nEXEC sp_invoke_external_rest_endpoint\n    @url = 'https:\u002F\u002Fapi.openai.com\u002Fv1\u002Fembeddings',\n    @method = 'POST',\n    @headers = '{\"Content-Type\": \"application\u002Fjson\", \"Authorization\": \"Bearer \u003Cyour-api-key>\"}',\n    @payload = '{\"model\": \"text-embedding-3-small\", \"input\": \"describe this product\"}',\n    @response = @response OUTPUT;\n\n-- Parse response để lấy embedding\nSELECT JSON_VALUE(@response, '$.data[0].embedding') AS Embedding;\n",[467,2712,2713,2718,2723,2727,2732,2737,2742,2747,2752,2757,2761,2766],{"__ignoreMap":838},[842,2714,2715],{"class":844,"line":845},[842,2716,2717],{},"-- Gọi OpenAI API để tạo embedding ngay trong T-SQL\n",[842,2719,2720],{"class":844,"line":851},[842,2721,2722],{},"DECLARE @response NVARCHAR(MAX);\n",[842,2724,2725],{"class":844,"line":857},[842,2726,891],{"emptyLinePlaceholder":890},[842,2728,2729],{"class":844,"line":863},[842,2730,2731],{},"EXEC sp_invoke_external_rest_endpoint\n",[842,2733,2734],{"class":844,"line":869},[842,2735,2736],{},"    @url = 'https:\u002F\u002Fapi.openai.com\u002Fv1\u002Fembeddings',\n",[842,2738,2739],{"class":844,"line":875},[842,2740,2741],{},"    @method = 'POST',\n",[842,2743,2744],{"class":844,"line":881},[842,2745,2746],{},"    @headers = '{\"Content-Type\": \"application\u002Fjson\", \"Authorization\": \"Bearer \u003Cyour-api-key>\"}',\n",[842,2748,2749],{"class":844,"line":887},[842,2750,2751],{},"    @payload = '{\"model\": \"text-embedding-3-small\", \"input\": \"describe this product\"}',\n",[842,2753,2754],{"class":844,"line":894},[842,2755,2756],{},"    @response = @response OUTPUT;\n",[842,2758,2759],{"class":844,"line":900},[842,2760,891],{"emptyLinePlaceholder":890},[842,2762,2763],{"class":844,"line":906},[842,2764,2765],{},"-- Parse response để lấy embedding\n",[842,2767,2768],{"class":844,"line":912},[842,2769,2770],{},"SELECT JSON_VALUE(@response, '$.data[0].embedding') AS Embedding;\n",[589,2772,2773,2780],{"color":591,"icon":592},[821,2774,593,2775,597,2777],{},[527,2776,596],{},[599,2778,2779],{},"\"Làm sao tích hợp AI vào SQL Server?\"",[1046,2781,2782,2797],{},[1049,2783,2784,2787,2788,2790,2791,2793,2794,2796],{},[527,2785,2786],{},"Pattern RAG đơn giản (2025):"," Dùng ",[467,2789,2706],{}," gọi OpenAI \u002F Azure OpenAI để tạo embedding → lưu vào cột ",[467,2792,826],{}," → query bằng ",[467,2795,1073],{}," + DiskANN index. Toàn bộ pipeline chạy trong T-SQL, không cần code C# \u002F Python trung gian.",[1049,2798,2799,2802,2803,2806],{},[527,2800,2801],{},"Lưu ý bảo mật:"," API key không nên hardcode trong script. Dùng ",[467,2804,2805],{},"DATABASE SCOPED CREDENTIAL"," hoặc Azure Key Vault để quản lý secret.",[427,2808,2810],{"id":2809},"_9-các-tính-năng-t-sql-mới-khác-2022","9. Các tính năng T-SQL mới khác (2022+)",[432,2812,2814],{"id":2813},"greatest-least-sql-server-2022","GREATEST \u002F LEAST (SQL Server 2022+)",[833,2816,2818],{"className":835,"code":2817,"language":837,"meta":838,"style":838},"-- Trả về giá trị lớn nhất \u002F nhỏ nhất trong danh sách\nSELECT GREATEST(10, 25, 7, 42) AS MaxValue;   -- 42\nSELECT LEAST(10, 25, 7, 42) AS MinValue;      -- 7\n\n-- Ứng dụng: lấy ngày gần nhất trong nhiều cột\nSELECT Id, GREATEST(CreatedAt, UpdatedAt, DeletedAt) AS LastActivity\nFROM AuditLog;\n",[467,2819,2820,2825,2830,2835,2839,2844,2849],{"__ignoreMap":838},[842,2821,2822],{"class":844,"line":845},[842,2823,2824],{},"-- Trả về giá trị lớn nhất \u002F nhỏ nhất trong danh sách\n",[842,2826,2827],{"class":844,"line":851},[842,2828,2829],{},"SELECT GREATEST(10, 25, 7, 42) AS MaxValue;   -- 42\n",[842,2831,2832],{"class":844,"line":857},[842,2833,2834],{},"SELECT LEAST(10, 25, 7, 42) AS MinValue;      -- 7\n",[842,2836,2837],{"class":844,"line":863},[842,2838,891],{"emptyLinePlaceholder":890},[842,2840,2841],{"class":844,"line":869},[842,2842,2843],{},"-- Ứng dụng: lấy ngày gần nhất trong nhiều cột\n",[842,2845,2846],{"class":844,"line":875},[842,2847,2848],{},"SELECT Id, GREATEST(CreatedAt, UpdatedAt, DeletedAt) AS LastActivity\n",[842,2850,2851],{"class":844,"line":881},[842,2852,2853],{},"FROM AuditLog;\n",[589,2855,2856,2857,2860,2861,1028,2864,2867],{"color":794,"icon":795},"Trước đây phải dùng ",[467,2858,2859],{},"CASE WHEN a > b THEN a ELSE b END"," lồng nhau nhiều tầng — ",[467,2862,2863],{},"GREATEST",[467,2865,2866],{},"LEAST"," gọn và dễ đọc hơn nhiều.",[432,2869,2871],{"id":2870},"string_split-với-vị-trí-sql-server-2022","STRING_SPLIT với vị trí (SQL Server 2022+)",[833,2873,2875],{"className":835,"code":2874,"language":837,"meta":838,"style":838},"-- Tham số thứ 3 (enable_ordinal = 1) để có thêm cột ordinal\nSELECT value, ordinal\nFROM STRING_SPLIT('apple,banana,cherry', ',', 1);\n-- Kết quả: (apple, 1), (banana, 2), (cherry, 3)\n",[467,2876,2877,2882,2887,2892],{"__ignoreMap":838},[842,2878,2879],{"class":844,"line":845},[842,2880,2881],{},"-- Tham số thứ 3 (enable_ordinal = 1) để có thêm cột ordinal\n",[842,2883,2884],{"class":844,"line":851},[842,2885,2886],{},"SELECT value, ordinal\n",[842,2888,2889],{"class":844,"line":857},[842,2890,2891],{},"FROM STRING_SPLIT('apple,banana,cherry', ',', 1);\n",[842,2893,2894],{"class":844,"line":863},[842,2895,2896],{},"-- Kết quả: (apple, 1), (banana, 2), (cherry, 3)\n",[432,2898,2900],{"id":2899},"date_bucket-sql-server-2022","DATE_BUCKET (SQL Server 2022+)",[833,2902,2904],{"className":835,"code":2903,"language":837,"meta":838,"style":838},"-- Gom nhóm theo khoảng thời gian cố định\nSELECT\n    DATE_BUCKET(MINUTE, 15, CreatedAt) AS Bucket,\n    COUNT(*) AS OrderCount\nFROM Orders\nGROUP BY DATE_BUCKET(MINUTE, 15, CreatedAt)\nORDER BY Bucket;\n-- Gom mỗi 15 phút: 08:00, 08:15, 08:30, 08:45, ...\n",[467,2905,2906,2911,2915,2920,2925,2930,2935,2940],{"__ignoreMap":838},[842,2907,2908],{"class":844,"line":845},[842,2909,2910],{},"-- Gom nhóm theo khoảng thời gian cố định\n",[842,2912,2913],{"class":844,"line":851},[842,2914,2108],{},[842,2916,2917],{"class":844,"line":857},[842,2918,2919],{},"    DATE_BUCKET(MINUTE, 15, CreatedAt) AS Bucket,\n",[842,2921,2922],{"class":844,"line":863},[842,2923,2924],{},"    COUNT(*) AS OrderCount\n",[842,2926,2927],{"class":844,"line":869},[842,2928,2929],{},"FROM Orders\n",[842,2931,2932],{"class":844,"line":875},[842,2933,2934],{},"GROUP BY DATE_BUCKET(MINUTE, 15, CreatedAt)\n",[842,2936,2937],{"class":844,"line":881},[842,2938,2939],{},"ORDER BY Bucket;\n",[842,2941,2942],{"class":844,"line":887},[842,2943,2944],{},"-- Gom mỗi 15 phút: 08:00, 08:15, 08:30, 08:45, ...\n",[432,2946,2948],{"id":2947},"generate_series-sql-server-2022","GENERATE_SERIES (SQL Server 2022+)",[833,2950,2952],{"className":835,"code":2951,"language":837,"meta":838,"style":838},"-- Sinh chuỗi số liên tiếp\nSELECT value FROM GENERATE_SERIES(1, 10);\n-- 1, 2, 3, ..., 10\n\n-- Ứng dụng: sinh calendar table\nSELECT DATEADD(DAY, value, '2026-01-01') AS CalendarDate\nFROM GENERATE_SERIES(0, 364);\n-- 365 ngày của năm 2026\n",[467,2953,2954,2959,2964,2969,2973,2978,2983,2988],{"__ignoreMap":838},[842,2955,2956],{"class":844,"line":845},[842,2957,2958],{},"-- Sinh chuỗi số liên tiếp\n",[842,2960,2961],{"class":844,"line":851},[842,2962,2963],{},"SELECT value FROM GENERATE_SERIES(1, 10);\n",[842,2965,2966],{"class":844,"line":857},[842,2967,2968],{},"-- 1, 2, 3, ..., 10\n",[842,2970,2971],{"class":844,"line":863},[842,2972,891],{"emptyLinePlaceholder":890},[842,2974,2975],{"class":844,"line":869},[842,2976,2977],{},"-- Ứng dụng: sinh calendar table\n",[842,2979,2980],{"class":844,"line":875},[842,2981,2982],{},"SELECT DATEADD(DAY, value, '2026-01-01') AS CalendarDate\n",[842,2984,2985],{"class":844,"line":881},[842,2986,2987],{},"FROM GENERATE_SERIES(0, 364);\n",[842,2989,2990],{"class":844,"line":887},[842,2991,2992],{},"-- 365 ngày của năm 2026\n",[432,2994,2996],{"id":2995},"window-clause-sql-server-2022","WINDOW clause (SQL Server 2022+)",[833,2998,3000],{"className":835,"code":2999,"language":837,"meta":838,"style":838},"-- Định nghĩa window một lần, dùng nhiều lần — tránh lặp code\nSELECT Name, Category, Price,\n    ROW_NUMBER() OVER w AS RowNum,\n    AVG(Price) OVER w AS AvgByCategory,\n    RANK() OVER w AS RankByPrice\nFROM Products\nWINDOW w AS (PARTITION BY Category ORDER BY Price DESC);\n",[467,3001,3002,3007,3012,3017,3022,3027,3031],{"__ignoreMap":838},[842,3003,3004],{"class":844,"line":845},[842,3005,3006],{},"-- Định nghĩa window một lần, dùng nhiều lần — tránh lặp code\n",[842,3008,3009],{"class":844,"line":851},[842,3010,3011],{},"SELECT Name, Category, Price,\n",[842,3013,3014],{"class":844,"line":857},[842,3015,3016],{},"    ROW_NUMBER() OVER w AS RowNum,\n",[842,3018,3019],{"class":844,"line":863},[842,3020,3021],{},"    AVG(Price) OVER w AS AvgByCategory,\n",[842,3023,3024],{"class":844,"line":869},[842,3025,3026],{},"    RANK() OVER w AS RankByPrice\n",[842,3028,3029],{"class":844,"line":875},[842,3030,949],{},[842,3032,3033],{"class":844,"line":881},[842,3034,3035],{},"WINDOW w AS (PARTITION BY Category ORDER BY Price DESC);\n",[432,3037,3039],{"id":3038},"first_value-last_value-với-ignore-nulls","FIRST_VALUE \u002F LAST_VALUE với IGNORE NULLS",[833,3041,3043],{"className":835,"code":3042,"language":837,"meta":838,"style":838},"-- Bỏ qua NULL khi lấy giá trị đầu\u002Fcuối trong window\nSELECT Id, SensorReading,\n    LAST_VALUE(SensorReading) IGNORE NULLS OVER (\n        ORDER BY Id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING\n    ) AS LastNonNullReading\nFROM SensorData;\n",[467,3044,3045,3050,3055,3060,3065,3070],{"__ignoreMap":838},[842,3046,3047],{"class":844,"line":845},[842,3048,3049],{},"-- Bỏ qua NULL khi lấy giá trị đầu\u002Fcuối trong window\n",[842,3051,3052],{"class":844,"line":851},[842,3053,3054],{},"SELECT Id, SensorReading,\n",[842,3056,3057],{"class":844,"line":857},[842,3058,3059],{},"    LAST_VALUE(SensorReading) IGNORE NULLS OVER (\n",[842,3061,3062],{"class":844,"line":863},[842,3063,3064],{},"        ORDER BY Id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING\n",[842,3066,3067],{"class":844,"line":869},[842,3068,3069],{},"    ) AS LastNonNullReading\n",[842,3071,3072],{"class":844,"line":875},[842,3073,3074],{},"FROM SensorData;\n",[589,3076,3077,3080,3081,3084],{"color":794,"icon":795},[467,3078,3079],{},"IGNORE NULLS"," cực hữu ích cho bài toán ",[527,3082,3083],{},"fill-down",": điền giá trị gần nhất không null vào các row null trong time-series data — trước đây phải viết subquery hoặc cursor phức tạp.",[589,3086,3088,3089],{"color":794,"icon":3087},"i-lucide-arrow-right","Tiếp theo: ",[3090,3091,3092],"a",{"href":184},"Truy vấn nâng cao — JOIN, subquery, window, CTE, transaction",[3094,3095,3096],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":838,"searchDepth":851,"depth":851,"links":3098},[3099,3105,3110,3118,3119,3125,3126,3130,3131],{"id":429,"depth":851,"text":430,"children":3100},[3101,3102,3103,3104],{"id":434,"depth":857,"text":435},{"id":613,"depth":857,"text":614},{"id":697,"depth":857,"text":698},{"id":813,"depth":857,"text":814},{"id":1262,"depth":851,"text":1263,"children":3106},[3107,3108,3109],{"id":1266,"depth":857,"text":1267},{"id":1381,"depth":857,"text":1382},{"id":1459,"depth":857,"text":1460},{"id":1478,"depth":851,"text":1479,"children":3111},[3112,3113,3114,3115,3116,3117],{"id":1482,"depth":857,"text":1027},{"id":1588,"depth":857,"text":1589},{"id":1664,"depth":857,"text":1031},{"id":1737,"depth":857,"text":1034},{"id":1764,"depth":857,"text":1765},{"id":1900,"depth":857,"text":1901},{"id":1974,"depth":851,"text":1975},{"id":2093,"depth":851,"text":2094,"children":3120},[3121,3122,3123,3124],{"id":2097,"depth":857,"text":2098},{"id":2161,"depth":857,"text":2162},{"id":2219,"depth":857,"text":2220},{"id":2267,"depth":857,"text":2268},{"id":2416,"depth":851,"text":2417},{"id":2550,"depth":851,"text":2551,"children":3127},[3128,3129],{"id":2554,"depth":857,"text":2555},{"id":2625,"depth":857,"text":2626},{"id":2699,"depth":851,"text":2700},{"id":2809,"depth":851,"text":2810,"children":3132},[3133,3134,3135,3136,3137,3138],{"id":2813,"depth":857,"text":2814},{"id":2870,"depth":857,"text":2871},{"id":2899,"depth":857,"text":2900},{"id":2947,"depth":857,"text":2948},{"id":2995,"depth":857,"text":2996},{"id":3038,"depth":857,"text":3039},"DDL, DML, kiểu dữ liệu, NULL handling, ràng buộc — nền tảng T-SQL cho SQL Server 2025.","md",null,{},{"title":178,"icon":181},{"title":422,"description":3139},"EuHf6OSHbx27isfZ-i-oIHRYblAa023UbYc6ouYi5f4",[3147,3149],{"title":173,"path":174,"stem":175,"description":3148,"icon":176,"children":-1},"SQL Server 2025 (17.x) — RDBMS của Microsoft với native vector + JSON + RegEx + Copilot. Hướng dẫn cài đặt bằng Docker, SSMS, Azure Data Studio.",{"title":183,"path":184,"stem":185,"description":3150,"icon":186,"children":-1},"JOIN, subquery, set operation, CTE recursive, window function, transaction, isolation level — gốc cho SQL Server.",1783490364015]