Thursday, October 24, 2013

Listagg and Row_number

1. Шаардлага №1

Listagg
Өмнөх бичлэг дээр байсан table-үүдийг ашиглаад бас өөр нэг шаардлагыг хэрэгжүүлж үзье. Энэ нь сурагчийн жагсаалтыг харуулангаа, түүний авч байсан дүнгүүдийг огнооны дарааллаар нь цувуулан харуулах юм.

Энд listagg хэмээх oracle-н үндсэн функцийг ашигласан байгаа. Энэ функцийн зориулалт нь угаасаа энэ юм. тодорхой талбараар груплээд, тэндээсээ өөр нэг талбарыг жагсаан харуулах. to_char ашигладаг нь ямар учиртай вэ гэвэл listagg нь
nvarchar2 төрлийн хувьсагчийн харуулахдаа дөрвөлжин дүрсүүд болгочихоод байдаг учраас ингэсэн юм.

Ингээд жишээ үр дүнг харцгаая

2. Шаардлага №2

Эндээс үүдээд, сурагчдын жагсаалт дээр хамгийн авсан дүнг нь хичээлийн нэр, огноотой нь харуулъя. (Өөр нэг жишээ гэвэл тухайн барааны анх худалдаж авсан дүн байж болно).

Listagg-г жаахан string manipulation-той холиод доорх query-г бичиж болно

Үр дүн нь


Сул тал
listagg маань varchar төрөл дээр ажилладаг учир, 4000-с дээш урттай текст бүтээх явцдаа алдаа заадаг сул талтай. Мэдээж том жижиг бүхий л бааз дээр ажиллах зүйл хийх шаардлагатай учир өөр арга хайж олъё.

Row_number

Дээрх сул талыг шийдэхийн тулд row_number() ашиглая. энэ функц нь result set-г нэг талбараар бүлэглэхдээ, тэр бүлэг доторх мөрүүдийг нь дугаарлаж өгдөг юм. Жишээ нь

Энэ query-ний үр дүн нь :

Шаардлага №2-ынхоо query-г дахиад бичье, энэ удаа row_number() ашиглаж:

Хамгийн дотор талд, дээр ашигласан query-ээ хийж өгөөд, тэндээсээ зөвхөн 1 гэсэн grade_order-той мөрүүдийг нь аваад тэрийгээ join-уудаар баяжуулаад өгөхөд л үрдүнгээ авч чадаж байна.
Энэний давуу тал нь, 4000 тэмдэгтийн алдаа гарахгүй, нэг сурагч хичнээ мянга дүн авсан ч болно, мөн group by ашиглахгүй, арай цэвэрхэн болсон байгаа. Сул тал нь гэвэл group by ашиглаагүй учраас, aggregate функц-ээ хамтад нь бичиж
болохгүй болж байгаа юм (Жишээ нь өмнө нь Listagg хийхдээ хамтад нь count() хийж болох байсан).

Нэгэнт л 4000 тэмдэгтийн алдаа Шаардлага №1-н query дээр гарах болохоор, мөн хүн тийм урт юмыг (нэг сурагч хэдэн мянган дүн авах боломжтой бол) хараад байх боломжгүй (эсвэл хүсэхгүй) учраас тэр query-ээ дахиад бичье, ингэхдээ, тухайн
сурагчийн эхний 10 дүнг л харуулдаг болгоё. Listagg болон Row_number-г хамтад нь ашиглаж.

10-р мөр дээр заавал case ашиглаад байх шаардлага байхгүй, доор нь WHERE GRADE_ORDER <= 10 гэж бичихэд л хангалттай. Гэвч бид хамтад нь нийт хэдэн дүн авсаныг нь бас харуулъя гэсэн болохоор ингэж хийлээ. Ингээд үр дүн нь :

Wednesday, October 16, 2013

SUM - CASE (Pivot like query)

1. Оршил

Ямар нэг систем хөгжүүлэх явцад (эсвэл жирийн нэг бааз дээр ажиллах явцад) гардаг шаардлагын нэг нь пивот маягийн үр дүнг харуулах query юм. Жишээ нь нийт сурагчдын ямар ямар дүнг хэдэн удаа авсан байна эсвэл барааны тухайн огноо хүртэлх үлдэгдэл болон эцсийн (нийт) үлдэгдэл гэх мэт. Яагаад пивот шиг гэж байна гэхээр, харахад пивот table шиг мөртлөө, багана нь static (өгөгдлөөс хамаарч өөрчлөгддөггүй) болохоор тэр.

Энэний шийдэл нь их энгийн бөгөөд, хувьдаа нэлээд их ашигладаг, мөн хүмүүс ч асуугаад байдаг болохоор нь нийтлэе гэж бодлоо

2. Өгөгдөл

Эхний жишээг шууд харуулах байдлаар шийдлээ үзүүлье. Тэгэхээр бидэнд student, journal, lesson гэсэн 3 table хэрэг болно. Эдгээр нь

3. Шийдэл

Энд хичээлийн нэр шаардлагагүй байсан болохоор, хичээлийн table-г ашигласангүй. Мөн заавал sub-query ашиглаад байх шаардлага ч байхгүй л дээ, гэхдээ яг бодогдсон үр дүн, нэмэлт мэдээлэл зэргийг тусад нь харахад амар байдаг болохоор ингэж ашиглаад сурчихсан юм.

Ингээд жишээ үр дүн нь :