กระทู้เก่าบอร์ด อ.สุภาพ ไชยา
512 1
URL.หัวข้อ /
URL
Crosstab Query ใน MySQL และ PostgreSQL
คงไม่ปฏิเสธนะครับว่า Crosstab query ใน Access ช่วยงานเราได้มาก
แล้วถ้าจะปรับไปใช้ MySQL หรือ Postgres แล้วจะมี Crosstab ให้ด้วยหรือเปล่าครับ
ลองเข้าไปดูที่ http://www.mysql.com/articles/wizard/page3.html นะครับ เขาสอนการทำ Crosstab ใน MySQL ไว้ให้ศึกษากัน
ผมเลยนำมาประยุกต์ใช้กับกระทู้ต่างๆ ในเว็บบอร์ดนี้ โดยดูว่าแต่ละกระทู้ผมได้ตอบไปกี่ครั้ง โดยเลือกคุณ ac เปรียบเทียบด้วย แล้วแสดงจำนวนคำตอบทั้งหมดของแต่ละกระทู้ด้วย (ผมต้องลองกับกระทู้ที่ 1 - 30 เท่านั้นเพื่อให้เห็นภาพสั้นๆ)
MySQL Crosstab query:
mysql> select qnumber as "Question No.", sum(if(aname='สุภาพ',1,0)) as S, sum(if(aname='ac',1,0)) as A, count(*) as Total from answer where qnumber <30 group by qnumber;
+--------------+------+------+-------+
| Question No. | S | A | Total |
+--------------+------+------+-------+
| 1 | 2 | 0 | 2 |
| 3 | 1 | 0 | 1 |
| 4 | 1 | 0 | 1 |
| 8 | 1 | 0 | 1 |
| 10 | 1 | 0 | 2 |
| 11 | 1 | 0 | 2 |
| 13 | 0 | 0 | 1 |
| 14 | 1 | 0 | 1 |
| 18 | 1 | 0 | 1 |
| 19 | 2 | 0 | 2 |
| 20 | 1 | 0 | 1 |
| 22 | 2 | 0 | 3 |
| 23 | 1 | 0 | 1 |
| 26 | 1 | 0 | 3 |
| 27 | 1 | 0 | 1 |
| 28 | 1 | 0 | 1 |
| 29 | 3 | 0 | 6 |
+--------------+------+------+-------+
17 rows in set (0.00 sec)
Postgres:
ผมลองประยุกต์ใช้กับ Postgres โดยเข้าไปค้นในเว็บ เจอที่
http://www.phpfreaks.com/postgresqlmanual/page/functions-conditional.html
เป็นการใช้ Case โดยมีโครงสร้างดังนี้
Case When เงื่อนไข1 Then ผลลัพธ์
Case When เงื่อนไข2 Then ผลลัพธ์
...
Else ผลลัพธ์
End
แล้วลองนำมาประยุกต์ใช้ดังนี้
mydb=# select qnumber as "Question No.", sum(case when aname='สุภาพ' then 1 else 0 end) as "Supap", sum(case when aname='ac' then 1 else 0 end) as "Ac", count(*) as "Total" from answer where qnumber <30 group by qnumber;
Question No. | Supap | Ac | Total
--------------+-------+----+-------
1 | 2 | 0 | 2
3 | 1 | 0 | 1
4 | 1 | 0 | 1
8 | 1 | 0 | 1
10 | 1 | 0 | 2
11 | 1 | 0 | 2
13 | 0 | 0 | 1
14 | 1 | 0 | 1
18 | 1 | 0 | 1
19 | 2 | 0 | 2
20 | 1 | 0 | 1
22 | 2 | 0 | 3
23 | 1 | 0 | 1
26 | 1 | 0 | 3
27 | 1 | 0 | 1
28 | 1 | 0 | 1
29 | 3 | 0 | 6
(17 rows)
ถ้าไม่อยากที่จะพิมพ์ SQL ยาวๆ อย่างนี้ ก็สร้างเป็น View ได้
CREATE VIEW ชื่อวิว AS sql statement
จากตัวอย่างข้างล่างผมสร้าง View ชื่อ crosstab
mydb=# create view crosstab --how to use crosstab in Postgres
mydb-# as select qnumber as "Question No.", sum(case when aname='สุภาพ' then 1 else 0 end) as "Supap", sum(case when aname='ac' then 1 else 0 end) as "Ac", count(*) as "Total" from answer where qnumber <30 group by qnumber;
CREATE
(--how to use crosstab in Postgres คือ comment)
ลองดูวิวที่ได้สร้างขึ้นดังนี้
mydb=# select * from crosstab;
Question No. | Supap | Ac | Total
--------------+-------+----+-------
1 | 2 | 0 | 2
3 | 1 | 0 | 1
4 | 1 | 0 | 1
8 | 1 | 0 | 1
10 | 1 | 0 | 2
11 | 1 | 0 | 2
13 | 0 | 0 | 1
14 | 1 | 0 | 1
18 | 1 | 0 | 1
19 | 2 | 0 | 2
20 | 1 | 0 | 1
22 | 2 | 0 | 3
23 | 1 | 0 | 1
26 | 1 | 0 | 3
27 | 1 | 0 | 1
28 | 1 | 0 | 1
29 | 3 | 0 | 6
(17 rows)
ถ้าจะดูโครงสร้างของ View ที่ได้สร้างขึ้น ให้ใช้
\d ชื่อวิวเป้าหมาย
mydb=# \d crosstab
View "crosstab"
Column | Type | Modifiers
--------------+---------+-----------
Question No. | integer |
Supap | bigint |
Ac | bigint |
Total | bigint |
View definition: SELECT answer.qnumber AS "Question No.", sum(CASE WHEN (answer.
aname = 'สุภาพ'::"varchar") THEN 1 ELSE 0 END) AS "Supap", sum(CASE WHEN (answer
.aname = 'ac'::"varchar") THEN 1 ELSE 0 END) AS "Ac", count(*) AS "Total" FROM answer WHERE (answer.qnumber < 30) GROUP BY answer.qnumber;
ลองประยุกต์ใช้ดูนะครับ
แล้วถ้าจะปรับไปใช้ MySQL หรือ Postgres แล้วจะมี Crosstab ให้ด้วยหรือเปล่าครับ
ลองเข้าไปดูที่ http://www.mysql.com/articles/wizard/page3.html นะครับ เขาสอนการทำ Crosstab ใน MySQL ไว้ให้ศึกษากัน
ผมเลยนำมาประยุกต์ใช้กับกระทู้ต่างๆ ในเว็บบอร์ดนี้ โดยดูว่าแต่ละกระทู้ผมได้ตอบไปกี่ครั้ง โดยเลือกคุณ ac เปรียบเทียบด้วย แล้วแสดงจำนวนคำตอบทั้งหมดของแต่ละกระทู้ด้วย (ผมต้องลองกับกระทู้ที่ 1 - 30 เท่านั้นเพื่อให้เห็นภาพสั้นๆ)
MySQL Crosstab query:
mysql> select qnumber as "Question No.", sum(if(aname='สุภาพ',1,0)) as S, sum(if(aname='ac',1,0)) as A, count(*) as Total from answer where qnumber <30 group by qnumber;
+--------------+------+------+-------+
| Question No. | S | A | Total |
+--------------+------+------+-------+
| 1 | 2 | 0 | 2 |
| 3 | 1 | 0 | 1 |
| 4 | 1 | 0 | 1 |
| 8 | 1 | 0 | 1 |
| 10 | 1 | 0 | 2 |
| 11 | 1 | 0 | 2 |
| 13 | 0 | 0 | 1 |
| 14 | 1 | 0 | 1 |
| 18 | 1 | 0 | 1 |
| 19 | 2 | 0 | 2 |
| 20 | 1 | 0 | 1 |
| 22 | 2 | 0 | 3 |
| 23 | 1 | 0 | 1 |
| 26 | 1 | 0 | 3 |
| 27 | 1 | 0 | 1 |
| 28 | 1 | 0 | 1 |
| 29 | 3 | 0 | 6 |
+--------------+------+------+-------+
17 rows in set (0.00 sec)
Postgres:
ผมลองประยุกต์ใช้กับ Postgres โดยเข้าไปค้นในเว็บ เจอที่
http://www.phpfreaks.com/postgresqlmanual/page/functions-conditional.html
เป็นการใช้ Case โดยมีโครงสร้างดังนี้
Case When เงื่อนไข1 Then ผลลัพธ์
Case When เงื่อนไข2 Then ผลลัพธ์
...
Else ผลลัพธ์
End
แล้วลองนำมาประยุกต์ใช้ดังนี้
mydb=# select qnumber as "Question No.", sum(case when aname='สุภาพ' then 1 else 0 end) as "Supap", sum(case when aname='ac' then 1 else 0 end) as "Ac", count(*) as "Total" from answer where qnumber <30 group by qnumber;
Question No. | Supap | Ac | Total
--------------+-------+----+-------
1 | 2 | 0 | 2
3 | 1 | 0 | 1
4 | 1 | 0 | 1
8 | 1 | 0 | 1
10 | 1 | 0 | 2
11 | 1 | 0 | 2
13 | 0 | 0 | 1
14 | 1 | 0 | 1
18 | 1 | 0 | 1
19 | 2 | 0 | 2
20 | 1 | 0 | 1
22 | 2 | 0 | 3
23 | 1 | 0 | 1
26 | 1 | 0 | 3
27 | 1 | 0 | 1
28 | 1 | 0 | 1
29 | 3 | 0 | 6
(17 rows)
ถ้าไม่อยากที่จะพิมพ์ SQL ยาวๆ อย่างนี้ ก็สร้างเป็น View ได้
CREATE VIEW ชื่อวิว AS sql statement
จากตัวอย่างข้างล่างผมสร้าง View ชื่อ crosstab
mydb=# create view crosstab --how to use crosstab in Postgres
mydb-# as select qnumber as "Question No.", sum(case when aname='สุภาพ' then 1 else 0 end) as "Supap", sum(case when aname='ac' then 1 else 0 end) as "Ac", count(*) as "Total" from answer where qnumber <30 group by qnumber;
CREATE
(--how to use crosstab in Postgres คือ comment)
ลองดูวิวที่ได้สร้างขึ้นดังนี้
mydb=# select * from crosstab;
Question No. | Supap | Ac | Total
--------------+-------+----+-------
1 | 2 | 0 | 2
3 | 1 | 0 | 1
4 | 1 | 0 | 1
8 | 1 | 0 | 1
10 | 1 | 0 | 2
11 | 1 | 0 | 2
13 | 0 | 0 | 1
14 | 1 | 0 | 1
18 | 1 | 0 | 1
19 | 2 | 0 | 2
20 | 1 | 0 | 1
22 | 2 | 0 | 3
23 | 1 | 0 | 1
26 | 1 | 0 | 3
27 | 1 | 0 | 1
28 | 1 | 0 | 1
29 | 3 | 0 | 6
(17 rows)
ถ้าจะดูโครงสร้างของ View ที่ได้สร้างขึ้น ให้ใช้
\d ชื่อวิวเป้าหมาย
mydb=# \d crosstab
View "crosstab"
Column | Type | Modifiers
--------------+---------+-----------
Question No. | integer |
Supap | bigint |
Ac | bigint |
Total | bigint |
View definition: SELECT answer.qnumber AS "Question No.", sum(CASE WHEN (answer.
aname = 'สุภาพ'::"varchar") THEN 1 ELSE 0 END) AS "Supap", sum(CASE WHEN (answer
.aname = 'ac'::"varchar") THEN 1 ELSE 0 END) AS "Ac", count(*) AS "Total" FROM answer WHERE (answer.qnumber < 30) GROUP BY answer.qnumber;
ลองประยุกต์ใช้ดูนะครับ
1 Reply in this Topic. Dispaly 1 pages and you are on page number 1
1 @R04092
MS SQL Server จะใช้คำสั่งเหมือนกับ PostgreSQL ครับ แต่ไม่สามารถใช้แบบ MySQL ได้
Time: 0.1438s