Flat-Plat-Blue-Dark GTK 3.20 Theme/Style

A Material Design-like flat theme for GTK3, GTK2, and GNOME Shell.

Flatplatblue-dark-Mockup-Trans

  • This theme is currently tested on Ubuntu 16.04
  • GTK theme and Shell theme based on Flat-Plat-Blue theme

Installation

  1. Download a archive.
  2. Extract it to the themes directory.
    • For system-wide installation to /usr/share/themes
    • For user-specific installation to ~/.themes
  3. Use gnome-tweak-tool to change the theme.

GDM (Lock/Login Screen)

  1. Backup an existing .gresource file. (Skip this step when you just update it.)

    Plain text
    Copy to clipboard
    Open code in new window
    EnlighterJS 3 Syntax Highlighter
    sudo cp /usr/share/gnome-shell/gnome-shell-theme.gresource /usr/share/gnome-shell/gnome-shell-theme.gresource.bk~
    sudo cp /usr/share/gnome-shell/gnome-shell-theme.gresource /usr/share/gnome-shell/gnome-shell-theme.gresource.bk~
    sudo cp /usr/share/gnome-shell/gnome-shell-theme.gresource /usr/share/gnome-shell/gnome-shell-theme.gresource.bk~
  2. Replace with the new one.
    • If you put this theme in /usr/share/themes:
      Plain text
      Copy to clipboard
      Open code in new window
      EnlighterJS 3 Syntax Highlighter
      sudo cp /usr/share/themes/Flat-Plat-Blue-Dark/gnome-shell/gnome-shell-theme.gresource /usr/share/gnome-shell
      sudo cp /usr/share/themes/Flat-Plat-Blue-Dark/gnome-shell/gnome-shell-theme.gresource /usr/share/gnome-shell
      sudo cp /usr/share/themes/Flat-Plat-Blue-Dark/gnome-shell/gnome-shell-theme.gresource /usr/share/gnome-shell
    • If you put this theme in ~/.themes:
      Plain text
      Copy to clipboard
      Open code in new window
      EnlighterJS 3 Syntax Highlighter
      sudo cp ~/.themes/Flat-Plat-Blue-Dark/gnome-shell/gnome-shell-theme.gresource /usr/share/gnome-shell
      sudo cp ~/.themes/Flat-Plat-Blue-Dark/gnome-shell/gnome-shell-theme.gresource /usr/share/gnome-shell
      sudo cp ~/.themes/Flat-Plat-Blue-Dark/gnome-shell/gnome-shell-theme.gresource /usr/share/gnome-shell
      
  3. Restart GNOME Shell (press Alt+F2, then type r).

Screenshots

Change Log

  • 2016/06/07/
    – Initial release
  • 2016/06/12
    – Fix switch and top bar
    – Improved ripple effect

P.S./ป.ล.
ช่วงนี้ดาร์ก ๆ ก็ใช้ธีมดาร์ก ๆ หล่ะกัน ^_^

มาใช้ zsh กัน มัน Cool กว่าเยอะ

เดิมปกติ bash shell ซึ่งเป็น shell มาตรฐานของ Ubuntu ก็เพียงพอต่อการใช้งานในระดับนึงแล้วหล่ะ แต่ไม่เคยมีอะไรพอดี ^_^ zsh ช่วยให้อะไรหลายอย่างง่ายขึ้น เช่น ช่วยเพิ่ม Productivity ให้ developer noob ส่วน feature เด่น ๆ ของ zsh คร่าว ๆ ก็มี

  • Autocompleted
  • ตรวจคำสั่งที่พิมพ์ผิด (ก็ไม่ทุกคำสั่งหรอก)
  • รองรับ Right-hand prompt
  • Plugin/Module เด่น ๆ ก็มี Oh my zsh และ Prezto

เริ่มก็ลง zsh กันซะ

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
sudo apt install zsh
sudo apt install zsh
sudo apt install zsh

ต่อมาก็เปลี่ยนเข้าใช้ zsh เป็นค่าเริ่มต้นเมื่อเปิด Terminal โดยใช้คำสั่ง chsh

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
a@b:~$ chsh
Password:
Changing the login shell for a
Enter the new value, or press ENTER for the default
Login Shell [/bin/bash]: /bin/zsh
a@b:~$ chsh Password: Changing the login shell for a Enter the new value, or press ENTER for the default Login Shell [/bin/bash]: /bin/zsh
a@b:~$ chsh
Password: 
Changing the login shell for a
Enter the new value, or press ENTER for the default
  Login Shell [/bin/bash]: /bin/zsh

แล้วก็ใช้ path ของ zsh ไปแทน bash shell แล้วก็ login เข้าใหม่ไป 1 ที

ทีนี้อย่างอื่นก็ได้หมดละ ต่อไปก็เพิ่ม Module ให้ zsh เป็นสเต็ปต่อไป อย่างที่บอกคือมันมีเด่น ๆ อยู่ 2 ตัวคือ Oh My zsh และ Prezto

  • Oh my zsh (http://ohmyz.sh/) เป็น configuration framework ที่รวบรวม plugin และ theme สำหรับ zsh เพื่อให้ใช้งานได้อย่างมีประสิทธิภาพยิ่งขึ้น โดยจะรวบรวม plugin สำหรับโปรแกรมหลาย ๆ ตัวที่มักใช้กันบ่อย ๆ พวก git, vagrant, composer, rails, docker อื่น ๆ อีก
  • Prezto (https://github.com/sorin-ionescu/prezto) เป็น configuration framework ของ zsh เช่นเดียวกับ oh-my-zsh เริ่มเดิมทีนั้น Prezto นั้นเป็น fork ของ oh-my-zsh แต่เนื่องจากแนวคิดไปคนละทางกับ oh-my-zsh เลยถูก rewrite ใหม่ ทำให้เราเพิ่มความสามารถหรือลูกเล่นให้กับ zsh ได้มากเดิม ไม่ว่าจะเป็น theme หรือ plugin (ใน Prezto จะเรียกว่า module) ซึ่งดูแล้วส่วนมากจะเป็นพวก alias ซะมากกว่า

เราเลือก Prezto นะ ^_^ วิธีใช้/ติดตั้ง ก็มีคนเขียนเอาไว้ดีมาก (ขี้เกียจเขียนต่อ 555) ตามนี ลองใช้ Prezto กับ zsh (https://armno.github.io/2015/03/24/oh-my-zsh-to-prezto)

ปล. ส่วน Theme เราก็ชอบ Theme powerlevel9k (https://github.com/bhilburn/powerlevel9k)powerlevel9k

หากจะอธิบายว่าความรักคืออะไรจะเปิดพจนานุกรมดูก็ได้ ไม่ผิดอะไรแต่ไม่ได้ผล

หากจะอธิบายว่าความรักคืออะไรจะเปิดพจนานุกรมดูก็ได้ ไม่ผิดอะไรแต่ไม่ได้ผล

ประโยคหนึ่งจากคำนำของหนังสือเล่มนี้ “สถิติฉบับการ์ตูน” โดย Takehiko Ohgami แปลโดยบดินทร์ พรวิลาวัณย์ ของสำนักพิมพ์ ส.ส.ท – สมาคมส่งเสริมเทคโนโลยี(ไทย-ญี่ปุ่น) ขนาดก็ไม่ใหญ่มาก 240 หน้า
9789744436269

เราซื้อหนังสือเล่มนี้มาตอนปลายเดือนมกราคมที่ผ่านมา จากร้านซีเอ็ดบุ๊ค (เล่มละ 265 บาท) มันก็อยู่ในถุงซีเอ็ดและวางอยู่หลังรถตั้งแต่นั้นเป็นต้นมา จนเมื่ออาทิตย์ที่แล้วเราเอารถไปล้างและเด็กล้างรถก็เก็บ ๆ สมบัติหลังรถเรามารวม ๆ กอง ๆ ไว้ด้วยกัน ^_^

อืมมม เดี๋ยวคงหาเวลาอ่าน เราเลือกเล่มนี้เพราะมันมีเหตุต้องระลึกชาติและต้องใช้เรื่องเกี่ยวกับสถิตินิดหน่อย เบื่อ ๆ แนววิชาการจ๋าถ้าเลี่ยงได้ก็จะเลี่ยง เอาแบบอ่านง่าย ๆ หล่ะกัน ก่อนซื้อก็สุ่มอ่านบางบท บางหน้า อืมม อ่านง่ายดี งั้นเอาเลย

ปกติเราเข้าห้องน้ำจะหยิบการ์ตูนไปอ่านด้วย วันนี้เดินไปหยิบเล่มนี้หล่ะกัน ด้วยตัวหนังสือเองถึงแม้จะเปลี่ยนวิธีถ่ายทอดเป็นการ์ตูนซะครึ่งนึง แต่ความเป็นวิชาการก็ยังถ่ายทอดได้ไม่มีตก บกพร่อง อืมมถือว่าดี

มันทำให้เราตามไปดูหนังสือเล่มอื่นของสำนักพิมพ์นี้และคนเขียน/คนแปล เผื่อมีเรื่องที่อยากอ่าน

ระดับความชอบ : 4 out of 5 stars (4 / 5)

Re-Visit

วันนี้ 20 กุมภาพันธ์ 2559 เป็นวันที่วงพอสกลับมามีเพลงให้ฟังอีกครั้งชื่อเพลง “รักอยู่รอบกาย” เราก็รอฟังเพลงนะ เพลงที่เป็นเสียงร้องของคุณโจ้  แต่ก็มีดราม่านิดหน่อยแต่เราก็รอฟังจากแหล่ง Official นะ รอฟังแบบตื่นเต้นเลย

ช่วงที่รอฟังเพลงด้วย อ่านการ์ตูนไปเรื่อยเปื่อย (นี่คือช่วงว่างแว๊บนึงจริง ๆ ) นึกถึงรายงานทางด้านสาธารณสุขรายงานหนึ่งที่คนขอรายงานมักจะบอกว่า “Re-Visit โรค XX ภายใน YY ชั่วโมง/วัน นะ” ทำนองนี้ คำว่า Re-Visit ง่าย ๆ บ้าน ๆ ก็คือการกลับมารักษาซ้ำด้วยโรคเดิม จะสาเหตุหนึ่ง สอง สาม หรืออะไรก็แล้วแต่ ซึ่งกลุ่มรายงานนี้มักจะถูกนำมาเป็น CQI ของโรงพยาบาลด้วย

เรื่องคุณภาพเรื่องนั้นจบไปหล่ะกัน แต่เราในฐานะของนักคอมพิวเตอร์ที่จะนำเสนอข้อมูลตรงนั้นออกมา มาดูหนึ่งในวิธีในการเรียกดูข้อมูล Re-Visit ออกมากันดีกว่า

สมมุติว่าเรามีข้อมูลดัมมี่ หุ่นนิ่ง ๆ ตั้งไว้หล่ะกัน (เราใช้บริการจากเว็บ www.generatedata.com เหมือนเดิม ทุกอย่างสมมุติหมดนะ วันที่เอย โรคเอย เผื่อสงสัย)

  • id เป็น PK เฉย ๆ
  • HN เป็น Hospital Number ใครไปโรงพยาบาล ก็จะได้ยินคำนี้ คือรหัสที่โรงพยาบาลตั้งขึ้นแทนตัวบุคคลเพื่อไม่ให้ซ้ำกันหล่ะกัน
  • VisitDateTime เป็นวันที่เข้าทำการรักษา
  • PDX เป็นโรคที่วินิจฉัย

สมมุติมีข้อมูลประมาณนี้

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
DROP TABLE IF EXISTS `Visit`;
CREATE TABLE IF NOT EXISTS `Visit` (
`id` mediumint(9) NOT NULL,
`HN` varchar(255) DEFAULT NULL,
`VisitDateTime` datetime(6) DEFAULT NULL,
`PDX` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
TRUNCATE TABLE `Visit`;
INSERT DELAYED INTO `Visit` VALUES
(1000, '10', '2015-12-28 12:03:00.000000', 'Z133'),
(1001, '10', '2016-08-01 12:21:00.000000', 'J069'),
(1002, '9', '2015-11-25 12:42:00.000000', 'K30'),
(1003, '4', '2015-07-13 12:14:00.000000', 'Z00'),
(1004, '10', '2015-12-21 12:20:00.000000', 'U77'),
(1005, '4', '2015-08-31 12:16:00.000000', 'K30'),
(1006, '3', '2016-05-26 12:16:00.000000', 'Z00'),
(1007, '10', '2015-04-29 12:10:00.000000', 'K30'),
(1008, '7', '2015-02-24 12:59:00.000000', 'J069'),
(1009, '10', '2016-06-06 12:11:00.000000', 'Z00'),
(1010, '2', '2015-04-21 12:29:00.000000', 'Z00'),
(1011, '5', '2016-02-09 12:08:00.000000', 'Z000'),
(1012, '7', '2016-07-12 12:09:00.000000', 'E119'),
(1013, '6', '2016-02-04 12:29:00.000000', 'Z480'),
(1014, '3', '2016-10-31 12:52:00.000000', 'Z133'),
(1015, '7', '2015-05-24 12:47:00.000000', 'Z133'),
(1016, '7', '2016-01-01 12:34:00.000000', 'Z000'),
(1017, '3', '2015-08-01 12:11:00.000000', 'Z133'),
(1018, '8', '2016-02-22 12:27:00.000000', 'U77'),
(1019, '6', '2015-08-29 12:54:00.000000', 'Z480'),
(1020, '1', '2016-02-28 12:43:00.000000', 'E119'),
(1021, '8', '2015-10-18 12:19:00.000000', 'Z480'),
(1022, '7', '2016-05-29 12:30:00.000000', 'Z133'),
(1023, '1', '2016-07-23 12:47:00.000000', 'J069'),
(1024, '3', '2015-12-08 12:42:00.000000', 'Z00'),
(1025, '7', '2016-12-08 12:45:00.000000', 'U77'),
(1026, '5', '2016-12-10 12:42:00.000000', 'Z480'),
(1027, '3', '2015-05-21 12:19:00.000000', 'Z480'),
(1028, '7', '2016-11-28 12:45:00.000000', 'U77'),
(1029, '7', '2015-06-27 12:16:00.000000', 'J00'),
(1030, '10', '2015-08-23 12:33:00.000000', 'E119'),
(1031, '5', '2015-12-05 12:22:00.000000', 'Z9912'),
(1032, '8', '2016-12-27 12:27:00.000000', 'Z133'),
(1033, '1', '2016-05-01 12:12:00.000000', 'E119'),
(1034, '9', '2015-07-06 12:26:00.000000', 'Z133'),
(1035, '3', '2015-07-05 12:49:00.000000', 'Z9912'),
(1036, '3', '2015-03-03 12:35:00.000000', 'J00'),
(1037, '1', '2016-09-07 12:25:00.000000', 'U77'),
(1038, '8', '2016-03-31 12:25:00.000000', 'K30'),
(1039, '9', '2016-03-21 12:51:00.000000', 'Z000'),
(1040, '3', '2015-03-11 12:38:00.000000', 'Z480'),
(1041, '2', '2016-10-12 12:29:00.000000', 'Z000'),
(1042, '4', '2016-08-13 12:04:00.000000', 'E119'),
(1043, '8', '2015-11-10 12:13:00.000000', 'E119'),
(1044, '5', '2016-07-08 12:57:00.000000', 'Z133'),
(1045, '6', '2015-05-12 12:05:00.000000', 'J069'),
(1046, '8', '2016-01-23 12:27:00.000000', 'U77'),
(1047, '2', '2016-01-21 12:03:00.000000', 'J00'),
(1048, '4', '2015-12-29 12:38:00.000000', 'K30'),
(1049, '2', '2016-10-02 12:26:00.000000', 'Z133'),
(1050, '8', '2015-06-07 12:40:00.000000', 'Z000'),
(1051, '10', '2015-07-21 12:33:00.000000', 'Z9912'),
(1052, '2', '2017-02-08 12:02:00.000000', 'K30'),
(1053, '2', '2015-08-26 12:34:00.000000', 'U77'),
(1054, '4', '2017-02-05 12:52:00.000000', 'Z133'),
(1055, '7', '2016-05-07 12:07:00.000000', 'J069'),
(1056, '2', '2016-12-20 12:57:00.000000', 'Z480'),
(1057, '5', '2015-04-07 12:39:00.000000', 'U77'),
(1058, '6', '2015-08-24 12:52:00.000000', 'E119'),
(1059, '6', '2015-08-10 12:54:00.000000', 'K30'),
(1060, '5', '2016-01-09 12:19:00.000000', 'Z000'),
(1061, '1', '2015-05-26 12:31:00.000000', 'K30'),
(1062, '7', '2017-02-05 12:46:00.000000', 'J00'),
(1063, '7', '2016-12-24 12:16:00.000000', 'Z480'),
(1064, '1', '2016-01-20 12:04:00.000000', 'Z480'),
(1065, '6', '2016-01-06 12:38:00.000000', 'U77'),
(1066, '4', '2015-12-19 12:56:00.000000', 'E119'),
(1067, '1', '2016-11-29 12:37:00.000000', 'J069'),
(1068, '9', '2015-03-26 12:36:00.000000', 'U77'),
(1069, '1', '2016-08-17 12:01:00.000000', 'K30'),
(1070, '3', '2016-02-26 12:42:00.000000', 'J069'),
(1071, '6', '2016-08-23 12:17:00.000000', 'J00'),
(1072, '10', '2016-03-19 12:54:00.000000', 'Z9912'),
(1073, '1', '2017-02-18 12:31:00.000000', 'Z000'),
(1074, '9', '2016-02-05 12:51:00.000000', 'Z480'),
(1075, '9', '2015-11-14 12:30:00.000000', 'K30'),
(1076, '6', '2015-03-23 12:34:00.000000', 'E119'),
(1077, '10', '2015-08-26 12:11:00.000000', 'Z9912'),
(1078, '9', '2015-05-04 12:58:00.000000', 'Z480'),
(1079, '9', '2016-01-04 12:47:00.000000', 'U77'),
(1080, '8', '2016-03-28 12:53:00.000000', 'Z480'),
(1081, '6', '2016-03-21 12:05:00.000000', 'Z480'),
(1082, '6', '2016-07-05 12:16:00.000000', 'Z000'),
(1083, '3', '2015-06-19 12:00:00.000000', 'Z133'),
(1084, '1', '2016-05-19 12:26:00.000000', 'Z000'),
(1085, '6', '2015-12-15 12:05:00.000000', 'U77'),
(1086, '5', '2015-05-31 12:28:00.000000', 'Z9912'),
(1087, '2', '2015-05-25 12:53:00.000000', 'K30'),
(1088, '6', '2016-11-09 12:51:00.000000', 'J069'),
(1089, '5', '2016-07-24 12:22:00.000000', 'J069'),
(1090, '10', '2016-12-11 12:22:00.000000', 'J069'),
(1091, '1', '2015-09-25 12:37:00.000000', 'J069'),
(1092, '9', '2015-06-26 12:13:00.000000', 'Z133'),
(1093, '8', '2016-10-24 12:21:00.000000', 'Z000'),
(1094, '1', '2017-01-25 12:07:00.000000', 'Z00'),
(1095, '5', '2015-09-21 12:21:00.000000', 'E119'),
(1096, '6', '2017-02-05 12:05:00.000000', 'Z480'),
(1097, '4', '2016-05-13 12:52:00.000000', 'Z9912'),
(1098, '7', '2016-12-08 12:38:00.000000', 'Z000'),
(1099, '6', '2015-08-26 12:00:00.000000', 'Z00');
--
-- Indexes for table `Visit`
--
ALTER TABLE `Visit`
ADD PRIMARY KEY (`id`);
DROP TABLE IF EXISTS `Visit`; CREATE TABLE IF NOT EXISTS `Visit` ( `id` mediumint(9) NOT NULL, `HN` varchar(255) DEFAULT NULL, `VisitDateTime` datetime(6) DEFAULT NULL, `PDX` varchar(255) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; TRUNCATE TABLE `Visit`; INSERT DELAYED INTO `Visit` VALUES (1000, '10', '2015-12-28 12:03:00.000000', 'Z133'), (1001, '10', '2016-08-01 12:21:00.000000', 'J069'), (1002, '9', '2015-11-25 12:42:00.000000', 'K30'), (1003, '4', '2015-07-13 12:14:00.000000', 'Z00'), (1004, '10', '2015-12-21 12:20:00.000000', 'U77'), (1005, '4', '2015-08-31 12:16:00.000000', 'K30'), (1006, '3', '2016-05-26 12:16:00.000000', 'Z00'), (1007, '10', '2015-04-29 12:10:00.000000', 'K30'), (1008, '7', '2015-02-24 12:59:00.000000', 'J069'), (1009, '10', '2016-06-06 12:11:00.000000', 'Z00'), (1010, '2', '2015-04-21 12:29:00.000000', 'Z00'), (1011, '5', '2016-02-09 12:08:00.000000', 'Z000'), (1012, '7', '2016-07-12 12:09:00.000000', 'E119'), (1013, '6', '2016-02-04 12:29:00.000000', 'Z480'), (1014, '3', '2016-10-31 12:52:00.000000', 'Z133'), (1015, '7', '2015-05-24 12:47:00.000000', 'Z133'), (1016, '7', '2016-01-01 12:34:00.000000', 'Z000'), (1017, '3', '2015-08-01 12:11:00.000000', 'Z133'), (1018, '8', '2016-02-22 12:27:00.000000', 'U77'), (1019, '6', '2015-08-29 12:54:00.000000', 'Z480'), (1020, '1', '2016-02-28 12:43:00.000000', 'E119'), (1021, '8', '2015-10-18 12:19:00.000000', 'Z480'), (1022, '7', '2016-05-29 12:30:00.000000', 'Z133'), (1023, '1', '2016-07-23 12:47:00.000000', 'J069'), (1024, '3', '2015-12-08 12:42:00.000000', 'Z00'), (1025, '7', '2016-12-08 12:45:00.000000', 'U77'), (1026, '5', '2016-12-10 12:42:00.000000', 'Z480'), (1027, '3', '2015-05-21 12:19:00.000000', 'Z480'), (1028, '7', '2016-11-28 12:45:00.000000', 'U77'), (1029, '7', '2015-06-27 12:16:00.000000', 'J00'), (1030, '10', '2015-08-23 12:33:00.000000', 'E119'), (1031, '5', '2015-12-05 12:22:00.000000', 'Z9912'), (1032, '8', '2016-12-27 12:27:00.000000', 'Z133'), (1033, '1', '2016-05-01 12:12:00.000000', 'E119'), (1034, '9', '2015-07-06 12:26:00.000000', 'Z133'), (1035, '3', '2015-07-05 12:49:00.000000', 'Z9912'), (1036, '3', '2015-03-03 12:35:00.000000', 'J00'), (1037, '1', '2016-09-07 12:25:00.000000', 'U77'), (1038, '8', '2016-03-31 12:25:00.000000', 'K30'), (1039, '9', '2016-03-21 12:51:00.000000', 'Z000'), (1040, '3', '2015-03-11 12:38:00.000000', 'Z480'), (1041, '2', '2016-10-12 12:29:00.000000', 'Z000'), (1042, '4', '2016-08-13 12:04:00.000000', 'E119'), (1043, '8', '2015-11-10 12:13:00.000000', 'E119'), (1044, '5', '2016-07-08 12:57:00.000000', 'Z133'), (1045, '6', '2015-05-12 12:05:00.000000', 'J069'), (1046, '8', '2016-01-23 12:27:00.000000', 'U77'), (1047, '2', '2016-01-21 12:03:00.000000', 'J00'), (1048, '4', '2015-12-29 12:38:00.000000', 'K30'), (1049, '2', '2016-10-02 12:26:00.000000', 'Z133'), (1050, '8', '2015-06-07 12:40:00.000000', 'Z000'), (1051, '10', '2015-07-21 12:33:00.000000', 'Z9912'), (1052, '2', '2017-02-08 12:02:00.000000', 'K30'), (1053, '2', '2015-08-26 12:34:00.000000', 'U77'), (1054, '4', '2017-02-05 12:52:00.000000', 'Z133'), (1055, '7', '2016-05-07 12:07:00.000000', 'J069'), (1056, '2', '2016-12-20 12:57:00.000000', 'Z480'), (1057, '5', '2015-04-07 12:39:00.000000', 'U77'), (1058, '6', '2015-08-24 12:52:00.000000', 'E119'), (1059, '6', '2015-08-10 12:54:00.000000', 'K30'), (1060, '5', '2016-01-09 12:19:00.000000', 'Z000'), (1061, '1', '2015-05-26 12:31:00.000000', 'K30'), (1062, '7', '2017-02-05 12:46:00.000000', 'J00'), (1063, '7', '2016-12-24 12:16:00.000000', 'Z480'), (1064, '1', '2016-01-20 12:04:00.000000', 'Z480'), (1065, '6', '2016-01-06 12:38:00.000000', 'U77'), (1066, '4', '2015-12-19 12:56:00.000000', 'E119'), (1067, '1', '2016-11-29 12:37:00.000000', 'J069'), (1068, '9', '2015-03-26 12:36:00.000000', 'U77'), (1069, '1', '2016-08-17 12:01:00.000000', 'K30'), (1070, '3', '2016-02-26 12:42:00.000000', 'J069'), (1071, '6', '2016-08-23 12:17:00.000000', 'J00'), (1072, '10', '2016-03-19 12:54:00.000000', 'Z9912'), (1073, '1', '2017-02-18 12:31:00.000000', 'Z000'), (1074, '9', '2016-02-05 12:51:00.000000', 'Z480'), (1075, '9', '2015-11-14 12:30:00.000000', 'K30'), (1076, '6', '2015-03-23 12:34:00.000000', 'E119'), (1077, '10', '2015-08-26 12:11:00.000000', 'Z9912'), (1078, '9', '2015-05-04 12:58:00.000000', 'Z480'), (1079, '9', '2016-01-04 12:47:00.000000', 'U77'), (1080, '8', '2016-03-28 12:53:00.000000', 'Z480'), (1081, '6', '2016-03-21 12:05:00.000000', 'Z480'), (1082, '6', '2016-07-05 12:16:00.000000', 'Z000'), (1083, '3', '2015-06-19 12:00:00.000000', 'Z133'), (1084, '1', '2016-05-19 12:26:00.000000', 'Z000'), (1085, '6', '2015-12-15 12:05:00.000000', 'U77'), (1086, '5', '2015-05-31 12:28:00.000000', 'Z9912'), (1087, '2', '2015-05-25 12:53:00.000000', 'K30'), (1088, '6', '2016-11-09 12:51:00.000000', 'J069'), (1089, '5', '2016-07-24 12:22:00.000000', 'J069'), (1090, '10', '2016-12-11 12:22:00.000000', 'J069'), (1091, '1', '2015-09-25 12:37:00.000000', 'J069'), (1092, '9', '2015-06-26 12:13:00.000000', 'Z133'), (1093, '8', '2016-10-24 12:21:00.000000', 'Z000'), (1094, '1', '2017-01-25 12:07:00.000000', 'Z00'), (1095, '5', '2015-09-21 12:21:00.000000', 'E119'), (1096, '6', '2017-02-05 12:05:00.000000', 'Z480'), (1097, '4', '2016-05-13 12:52:00.000000', 'Z9912'), (1098, '7', '2016-12-08 12:38:00.000000', 'Z000'), (1099, '6', '2015-08-26 12:00:00.000000', 'Z00'); -- -- Indexes for table `Visit` -- ALTER TABLE `Visit` ADD PRIMARY KEY (`id`);
DROP TABLE IF EXISTS `Visit`;
CREATE TABLE IF NOT EXISTS `Visit` (
  `id` mediumint(9) NOT NULL,
  `HN` varchar(255) DEFAULT NULL,
  `VisitDateTime` datetime(6) DEFAULT NULL,
  `PDX` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

TRUNCATE TABLE `Visit`;

INSERT DELAYED INTO `Visit` VALUES
(1000, '10', '2015-12-28 12:03:00.000000', 'Z133'),
(1001, '10', '2016-08-01 12:21:00.000000', 'J069'),
(1002, '9', '2015-11-25 12:42:00.000000', 'K30'),
(1003, '4', '2015-07-13 12:14:00.000000', 'Z00'),
(1004, '10', '2015-12-21 12:20:00.000000', 'U77'),
(1005, '4', '2015-08-31 12:16:00.000000', 'K30'),
(1006, '3', '2016-05-26 12:16:00.000000', 'Z00'),
(1007, '10', '2015-04-29 12:10:00.000000', 'K30'),
(1008, '7', '2015-02-24 12:59:00.000000', 'J069'),
(1009, '10', '2016-06-06 12:11:00.000000', 'Z00'),
(1010, '2', '2015-04-21 12:29:00.000000', 'Z00'),
(1011, '5', '2016-02-09 12:08:00.000000', 'Z000'),
(1012, '7', '2016-07-12 12:09:00.000000', 'E119'),
(1013, '6', '2016-02-04 12:29:00.000000', 'Z480'),
(1014, '3', '2016-10-31 12:52:00.000000', 'Z133'),
(1015, '7', '2015-05-24 12:47:00.000000', 'Z133'),
(1016, '7', '2016-01-01 12:34:00.000000', 'Z000'),
(1017, '3', '2015-08-01 12:11:00.000000', 'Z133'),
(1018, '8', '2016-02-22 12:27:00.000000', 'U77'),
(1019, '6', '2015-08-29 12:54:00.000000', 'Z480'),
(1020, '1', '2016-02-28 12:43:00.000000', 'E119'),
(1021, '8', '2015-10-18 12:19:00.000000', 'Z480'),
(1022, '7', '2016-05-29 12:30:00.000000', 'Z133'),
(1023, '1', '2016-07-23 12:47:00.000000', 'J069'),
(1024, '3', '2015-12-08 12:42:00.000000', 'Z00'),
(1025, '7', '2016-12-08 12:45:00.000000', 'U77'),
(1026, '5', '2016-12-10 12:42:00.000000', 'Z480'),
(1027, '3', '2015-05-21 12:19:00.000000', 'Z480'),
(1028, '7', '2016-11-28 12:45:00.000000', 'U77'),
(1029, '7', '2015-06-27 12:16:00.000000', 'J00'),
(1030, '10', '2015-08-23 12:33:00.000000', 'E119'),
(1031, '5', '2015-12-05 12:22:00.000000', 'Z9912'),
(1032, '8', '2016-12-27 12:27:00.000000', 'Z133'),
(1033, '1', '2016-05-01 12:12:00.000000', 'E119'),
(1034, '9', '2015-07-06 12:26:00.000000', 'Z133'),
(1035, '3', '2015-07-05 12:49:00.000000', 'Z9912'),
(1036, '3', '2015-03-03 12:35:00.000000', 'J00'),
(1037, '1', '2016-09-07 12:25:00.000000', 'U77'),
(1038, '8', '2016-03-31 12:25:00.000000', 'K30'),
(1039, '9', '2016-03-21 12:51:00.000000', 'Z000'),
(1040, '3', '2015-03-11 12:38:00.000000', 'Z480'),
(1041, '2', '2016-10-12 12:29:00.000000', 'Z000'),
(1042, '4', '2016-08-13 12:04:00.000000', 'E119'),
(1043, '8', '2015-11-10 12:13:00.000000', 'E119'),
(1044, '5', '2016-07-08 12:57:00.000000', 'Z133'),
(1045, '6', '2015-05-12 12:05:00.000000', 'J069'),
(1046, '8', '2016-01-23 12:27:00.000000', 'U77'),
(1047, '2', '2016-01-21 12:03:00.000000', 'J00'),
(1048, '4', '2015-12-29 12:38:00.000000', 'K30'),
(1049, '2', '2016-10-02 12:26:00.000000', 'Z133'),
(1050, '8', '2015-06-07 12:40:00.000000', 'Z000'),
(1051, '10', '2015-07-21 12:33:00.000000', 'Z9912'),
(1052, '2', '2017-02-08 12:02:00.000000', 'K30'),
(1053, '2', '2015-08-26 12:34:00.000000', 'U77'),
(1054, '4', '2017-02-05 12:52:00.000000', 'Z133'),
(1055, '7', '2016-05-07 12:07:00.000000', 'J069'),
(1056, '2', '2016-12-20 12:57:00.000000', 'Z480'),
(1057, '5', '2015-04-07 12:39:00.000000', 'U77'),
(1058, '6', '2015-08-24 12:52:00.000000', 'E119'),
(1059, '6', '2015-08-10 12:54:00.000000', 'K30'),
(1060, '5', '2016-01-09 12:19:00.000000', 'Z000'),
(1061, '1', '2015-05-26 12:31:00.000000', 'K30'),
(1062, '7', '2017-02-05 12:46:00.000000', 'J00'),
(1063, '7', '2016-12-24 12:16:00.000000', 'Z480'),
(1064, '1', '2016-01-20 12:04:00.000000', 'Z480'),
(1065, '6', '2016-01-06 12:38:00.000000', 'U77'),
(1066, '4', '2015-12-19 12:56:00.000000', 'E119'),
(1067, '1', '2016-11-29 12:37:00.000000', 'J069'),
(1068, '9', '2015-03-26 12:36:00.000000', 'U77'),
(1069, '1', '2016-08-17 12:01:00.000000', 'K30'),
(1070, '3', '2016-02-26 12:42:00.000000', 'J069'),
(1071, '6', '2016-08-23 12:17:00.000000', 'J00'),
(1072, '10', '2016-03-19 12:54:00.000000', 'Z9912'),
(1073, '1', '2017-02-18 12:31:00.000000', 'Z000'),
(1074, '9', '2016-02-05 12:51:00.000000', 'Z480'),
(1075, '9', '2015-11-14 12:30:00.000000', 'K30'),
(1076, '6', '2015-03-23 12:34:00.000000', 'E119'),
(1077, '10', '2015-08-26 12:11:00.000000', 'Z9912'),
(1078, '9', '2015-05-04 12:58:00.000000', 'Z480'),
(1079, '9', '2016-01-04 12:47:00.000000', 'U77'),
(1080, '8', '2016-03-28 12:53:00.000000', 'Z480'),
(1081, '6', '2016-03-21 12:05:00.000000', 'Z480'),
(1082, '6', '2016-07-05 12:16:00.000000', 'Z000'),
(1083, '3', '2015-06-19 12:00:00.000000', 'Z133'),
(1084, '1', '2016-05-19 12:26:00.000000', 'Z000'),
(1085, '6', '2015-12-15 12:05:00.000000', 'U77'),
(1086, '5', '2015-05-31 12:28:00.000000', 'Z9912'),
(1087, '2', '2015-05-25 12:53:00.000000', 'K30'),
(1088, '6', '2016-11-09 12:51:00.000000', 'J069'),
(1089, '5', '2016-07-24 12:22:00.000000', 'J069'),
(1090, '10', '2016-12-11 12:22:00.000000', 'J069'),
(1091, '1', '2015-09-25 12:37:00.000000', 'J069'),
(1092, '9', '2015-06-26 12:13:00.000000', 'Z133'),
(1093, '8', '2016-10-24 12:21:00.000000', 'Z000'),
(1094, '1', '2017-01-25 12:07:00.000000', 'Z00'),
(1095, '5', '2015-09-21 12:21:00.000000', 'E119'),
(1096, '6', '2017-02-05 12:05:00.000000', 'Z480'),
(1097, '4', '2016-05-13 12:52:00.000000', 'Z9912'),
(1098, '7', '2016-12-08 12:38:00.000000', 'Z000'),
(1099, '6', '2015-08-26 12:00:00.000000', 'Z00');

--
-- Indexes for table `Visit`
--
ALTER TABLE `Visit`
  ADD PRIMARY KEY (`id`);

ข้อมูล Re-Visit ในที่นี้หมายถึงมีการเข้ามารักษาซ้ำ (ในโรคเดิม) เช่น

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
+------+------+----------------------------+-------+
| id | HN | VisitDateTime | PDX |
+------+------+----------------------------+-------+
| 1033 | 1 | 2016-05-01 12:12:00.000000 | E119 |
| 1020 | 1 | 2016-02-28 12:43:00.000000 | E119 |
| 1067 | 1 | 2016-11-29 12:37:00.000000 | J069 |
| 1023 | 1 | 2016-07-23 12:47:00.000000 | J069 |
| 1091 | 1 | 2015-09-25 12:37:00.000000 | J069 |
| 1069 | 1 | 2016-08-17 12:01:00.000000 | K30 |
| 1061 | 1 | 2015-05-26 12:31:00.000000 | K30 |
| 1037 | 1 | 2016-09-07 12:25:00.000000 | U77 |
+------+------+----------------------------+-------+ | id | HN | VisitDateTime | PDX | +------+------+----------------------------+-------+ | 1033 | 1 | 2016-05-01 12:12:00.000000 | E119 | | 1020 | 1 | 2016-02-28 12:43:00.000000 | E119 | | 1067 | 1 | 2016-11-29 12:37:00.000000 | J069 | | 1023 | 1 | 2016-07-23 12:47:00.000000 | J069 | | 1091 | 1 | 2015-09-25 12:37:00.000000 | J069 | | 1069 | 1 | 2016-08-17 12:01:00.000000 | K30 | | 1061 | 1 | 2015-05-26 12:31:00.000000 | K30 | | 1037 | 1 | 2016-09-07 12:25:00.000000 | U77 |
+------+------+----------------------------+-------+
| id   | HN   | VisitDateTime              | PDX   |
+------+------+----------------------------+-------+
| 1033 | 1    | 2016-05-01 12:12:00.000000 | E119  |
| 1020 | 1    | 2016-02-28 12:43:00.000000 | E119  |
| 1067 | 1    | 2016-11-29 12:37:00.000000 | J069  |
| 1023 | 1    | 2016-07-23 12:47:00.000000 | J069  |
| 1091 | 1    | 2015-09-25 12:37:00.000000 | J069  |
| 1069 | 1    | 2016-08-17 12:01:00.000000 | K30   |
| 1061 | 1    | 2015-05-26 12:31:00.000000 | K30   |
| 1037 | 1    | 2016-09-07 12:25:00.000000 | U77   |

จะเห็นว่า อีตา HN=1 มารักษาหลายครั้งและบางครั้งที่มาก็ถูกวินิจฉัยด้วยโรคเดิม ๆ ที่เคยมา บางครั้งก็ไม่ซ้ำ แต่เราสนใจตัวที่ซ้ำหล่ะกัน ตามโจทย์ที่ว่า “Re-Visit โรค XX ภายใน YY ชั่วโมง/วัน นะ” วิธีการก็คือ เราจะใช้การ JOIN ตัวมันเองออกมาเพื่อหาความต่าง ส่วนฟังก์ชั่น TIMESTAMPDIFF ก็หาความต่างของสองช่วงเวลาในหน่วยที่กำหนด ลองหาอ่านเพิ่มเติมนะครับ 😛

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
SELECT
A.*,
V.*,
TIMESTAMPDIFF(DAY, A.VisitDateTime, V.VisitDateTime) AS DayOfReVisit
FROM Visit A
LEFT JOIN Visit V ON A.HN = V.HN AND A.PDX = V.PDX
WHERE A.VisitDateTime > V.VisitDateTime
ORDER BY A.HN;
SELECT A.*, V.*, TIMESTAMPDIFF(DAY, A.VisitDateTime, V.VisitDateTime) AS DayOfReVisit FROM Visit A LEFT JOIN Visit V ON A.HN = V.HN AND A.PDX = V.PDX WHERE A.VisitDateTime > V.VisitDateTime ORDER BY A.HN;
SELECT 
    A.*,
    V.*,
    TIMESTAMPDIFF(DAY, A.VisitDateTime, V.VisitDateTime) AS DayOfReVisit
FROM Visit A 
    LEFT JOIN Visit V ON A.HN = V.HN AND A.PDX = V.PDX
WHERE A.VisitDateTime > V.VisitDateTime
ORDER BY A.HN;

ผลลัพธ์ก็จะประมาณนี้

Selection_051

นี่ก็แค่หนึ่งในหลาย ๆ วิธี ขอให้สนุกกับการดูข้อมูล ฮ่าาาาา

ปล. ไปรอฟังเพลงรักอยู่รอบกายด้วยกัน

Still.

ท่ามกลางความเสียใจที่ไม่มีใครสน
ท่ามกลางหยดน้ำตาที่มันยังรินไหลหล่น

— ฉากที่แพ้ Music Video นี้ก็คือตั้งแต่นาทีที่ 0.49-1.35 เราว่ามันพิีคสุด ๆ แล้ว

Auto-reconnecting Logitech Bluetooth Mouse (M557) under Ubuntu 15.04

  1. Press the bluetooth mouse’s discovery mode.
  2. Open a terminal and type the command
    Plain text
    Copy to clipboard
    Open code in new window
    EnlighterJS 3 Syntax Highlighter
    hcitool scan
    hcitool scan
    hcitool scan

    ReconnectBTMouse

  3. Insert the line with the rest of the entries below the starting <devices> tag in file
    Plain text
    Copy to clipboard
    Open code in new window
    EnlighterJS 3 Syntax Highlighter
    /usr/share/gnome-bluetooth/pin-code-database.xml
    /usr/share/gnome-bluetooth/pin-code-database.xml
    /usr/share/gnome-bluetooth/pin-code-database.xml
    Plain text
    Copy to clipboard
    Open code in new window
    EnlighterJS 3 Syntax Highlighter
    <!-- Logitech Bluetooth Mouse M557 -->
    <device oui="00:1F:20:" type="mouse" name="Bluetooth Mouse M557" pin="0000"/>
    <!-- Logitech Bluetooth Mouse M557 --> <device oui="00:1F:20:" type="mouse" name="Bluetooth Mouse M557" pin="0000"/>
    <!-- Logitech Bluetooth Mouse M557 -->
    <device oui="00:1F:20:" type="mouse" name="Bluetooth Mouse M557" pin="0000"/>

     

  4. Enjoy your USB Port.

1 ปีที่ผ่านมา

ต้นปีที่แล้วพยายามตั้งเป้าไว้หลายเรื่อง จะสิ้นปีแล้ว แต่ความสำเร็จของเป้าหมายเสือกสวนทาง เริ่มชักห่วยลงทุกที T_T ปีนี้ตั้งเป้าไว้ไม่เยอะ เพราะปีที่แล้วก็ไม่ผ่านเยอะเหมือนกัน

อ่านหนังสือ Textbook ให้จบ 2 เล่ม

เอาง่าย ๆ เลยว่าเราห่วยภาษาอังกฤษ แล้วเราก็อยากเก่ง (คิดดีนะ) อยากพูด ฟัง อ่าน เขียน ให้รู้เรื่องขึ้นมาบ้าง คือพูดกับฟังที่เอาไว้ที่หลังหล่ะกัน เน้นอ่านก่อนเพราะคิดว่าง่ายสำหรับเราที่สุดละ ต้นปียัดเท็กซ์บุคลงแทบเล็ต ส่วนใหญ่แต่ก็คือทั้งหมดแหล่ะ คือเกี่ยวกับคอมพิวเตอร์ล้วน ๆ ด้วยความที่ตั้งเป้าหมายที่ 2 ว่าต้องรู้เทคโนโลยีใหม่ ทำข้อนี้สำเร็จแม่งได้ 2 เรื่อง วิน (แม่งคืออย่างโกง 5555) ท้ายสุดก็คืออยู่แบบนั้นแหล่ะ คือมีอ่านแบบผ่าน ๆ หลายเล่ม แต่เสือกเลือกเฉพาะในบทในเรื่องที่สนใจ ซึ่งก็ถือว่าไม่จบเล่มนะ

ผลคือข้อนี้ ไม่ผ่าน

ศึกษาเทคโนโลยีใหม่ 1 อย่าง

โลกกว้างและไปเร็วมากยิ่งอายุมากขึ้นก็ยิ่งเดินช้า ที่จริงประสบการณ์มันควรจะเป็นไปในทิศทางเดียวกันกับเวลาที่ผ่านไปใช่ไหม ถ้ามองผิวเผินคือใช่ มันเป็นเช่นนั้นแหล่ะ แต่จริง ๆ แล้วคือประสบการณ์ในเทคโนโลยีเก่า ๆ (คืออย่างแก่อ่ะ) งั้นเป้านี้ก็ตั้งไว้ 1 เรื่องหล่ะกัน ช่วงกลางปี มองเรื่อง AngularJS/React กับ NoSQL ไว้

ผลคือข้อนี้ ไม่ผ่าน ดูแป๊บ ๆ ก็เลิกไปโดยปริยาย มีประเด็นให้วิเคราะห์ต่อนิดนึงเรื่องแรงจูงใจในการเรียนรู้ ปีนี้มันไม่มีเกี่ยวกับฟิลล์นี้จริง ๆ ?

เข้านอนก่อนหกทุ่มทุกวัน

พอแก่ตัวขึ้นสุขภาพเริ่มชักแย่ มันอาจมีหลายปัจจัยนะแต่เราเชื่อว่าอย่างนึงคือ การพักผ่อนให้เพียงพอ เราใช้งานร่างกายเราหักโหมเกินไป มันอาจได้บางอย่างมาแต่ระยะยาวแล้วมันไม่คุ้มเลย เราทำงานเกิน 10 ชม. ต่อวันซึ่งปกติมันเยอะเกินไปแล้ว มีช่วงนึงถือเอาสเต็ปของคุณภูภู่มาปรับกับชีวิตทำงานเลยเรื่องเวลานอนคืออย่างโหด

B6CkqWTCcAA9fTm

ก่อน 6 ทุ่มมันได้แค่ไม่ถึงเดือนพูดแล้วเศร้า ยิ่งช่วงปลายปีมีหนังของคุณเต๋อ “ฟรีแลนซ์..ห้ามป่วย ห้ามพัก ห้ามรักหมอ ” ขำด้วย เจ็บจิ๊ด เดินออกจากโรง ใช่ เราต้องรักตัวเองเราต้องทำให้ได้ รีบนอน ดูแลสุขภาพ ออกกำลังาย พอหนังออกก็กลับไปวัฎจักรเดิม เชี้ยยยยยย

ผลข้อนี้ก็ไม่ผ่าน

เก็บเงินออม 50 % ของรายได้ทั้งปี

เราไม่มีปัจจัยให้ต้องฟุ่มเฟือยเท่าไหร่นะ ส่วนใหญ่เท่าที่สังเกตสันดานและพฤติกรรมตัวเองแล้วมักใช้จ่ายไปในเรื่องไร้สาระ 555 เพราะงั้นก็เก็บ ๆ ออม ๆ หล่ะกัน อย่างน้อยก็เก็บไว้เยอะ ๆ พอได้เยอะ ๆ แล้วเอามาใช้เรื่องไร้สาระได้เยอะขึ้น 5555

มันมีช่วงเบียดเบียดเงินออมไปช่วงนึง ซึ่งที่จริงแล้วมันผิดวินัยกับตัวเองด้วยแล้วมันก็ส่งผลกระทบหลายเรื่อง เอาเป็นว่าเป็นบทเรียนให้เรียนรู้นะ และจดจำไม่โกรธแต่ไม่ลืม คือมันจะไม่เกิดกรณีแบบนี้อีก ไม่สัญญาหรอกแต่จะไม่ทำ

ผลข้อนี้ก็ไม่ผ่าน

ออก Dirty Lab/Open source เล็ก ๆ อย่างน้อย 2 โปรเจค

มันต้องมีอะไรที่ทำให้ชีวิตสบายขึ้นสำหรับคนขี้เกียจ ข้อนี้ผ่านนะ 5555

ปีหน้า (พ.ศ. 2559) ตั้งเป้าหมายใหม่

  • อ่านเท็กซ์บุคเกี่ยวกับเทคโนโลยีใหม่  2 เล่ม (รวมเป้าหมายเดิมปี 2558 ซะ โตไปไม่โกงนะแจ๊ะ)
  • นอนก่อน 5 ทุ่ม ลดเวลาลงสิ หกทุ่มไม่นอนใช่ไหม
  • เงินออม 50% ของรายได้ แบงค์ปัจจุบันมันไม่เอื้อมั้ง (โทษไปเรื่อย) เดิมเป็นกรุงไทยแต่ปีนี้จะเปลี่ยนแม่งเลย ดู ME by TMB อัตราดอกเบี้ยที่ 2.55 % นี่โอเลยนะ พี่เล็กเริ่มไปก่อนละคงต้องไปปรึกษา
  • ปีหน้าปั่นจักรยานให้ได้ 1,400 กม. เหมือนจะเยอะใช่ไหม แต่วันละ 5 กม.เอง 😛
  • Dirty Lab 2 เผื่อเป้าอื่นไม่ผ่าน ไอ้นีปีนี้ผ่านปีหน้าก็ต้องผ่านสิ

เค้าบอกว่าให้ตั้งเป้าหมายโง่ ๆ จะได้ผลลัพธ์ง่าย ๆ จะได้มีกำลังใจ ปีหน้าธันวามาดูกันอีกที เย้ ๆ ๆ ๆ

MySQL : Select the count of values grouped by ranges

ถ้าเราเคยเห็นรายงานหรือกราฟที่นำเสนอข้อมูลในรูปแบบของช่วงข้อมูล ที่เห็นกันบ่อย ๆ ก็เช่นรายงานปิรามิดประชากรอันนี้ชัดเลย ไม่คุ้นก็ประมาณนี้ (นี่อ้างอิงข้อมูลสุขภาพของจังหวัดเราเลยนะ)

GroupByRange_01

ข้อมูลปิรามิดประชากรบอกอะไร // เพิ่มสาระ

ปิรามิดประชากร แสดงเพื่อให้เปรียบเทียบเห็นความแตกต่างของข้อมูลระหว่างทั้งสองเพศได้ชัดเจน กราฟแท่งแทนข้อมูลของเพศชายและหญิงจะวางคู่กันไว้ด้านขวาและด้านซ้ายของแกนปิรามิด สำหรับแต่ละหมวดอายุ โดยอายุน้อยที่สุดจะอยู่แท่งล่างสุด เริ่มตั้งแต่หมวดอายุ 0 – 4 ปี, 5 – 9 ปี สูงขึ้นเรื่อยๆ ด้านบนสุดคือหมวดอายุที่สุงที่สุด ซึ่งจะมีจำนวนประชากรน้อยกว่าหมวดอายุอื่นๆ ทำให้ส่วนบนเป็นยอดแหลม จึงเรียกว่าปิรามิด
รูปร่างของปิรามิดจะแสดงให้เห็นถึงผลสะสมของการเกิด การตายและการย้ายถิ่น เช่น

-ถ้าอัตราเกิดยังคงสูงขึ้น ประชากรในวัยเด็กจะมีจำนวนมากขึ้นเรื่อยๆ ฐานของปิรามิดจะกว้างออก ถ้าอัตราเกิดกำลังลดลง ฐานของปิรามิดจะค่อยๆ แคบเข้า
-ถ้าอัตราตายลดลง อันเป็นผลมาจากความก้าวหน้าทางการแพทย์และสุขอนามัยที่ทำให้คนอายุยืนขึ้น ยอดของปิรามิดซึ่งแสดงถึงจำนวนประชากรวัยสูงอายุก็จะค่อยๆ กว้างออก
-การตายในสงครามหรืออุบัติเหตุที่เกิดจากการใช้ชีวิตโลดโผนในหมู่วัยรุ่นชาย อาจทำให้จำนวนประชากรชายน้อยกว่าหญิงในหมวดอายุเดียวกัน ซึ่งจะแสดงให้เห็นจากแท่งกราฟด้านซ้ายจะสั้นกว่าด้านขวา

คร่าว ๆ ก็ประมาณนี้ แต่ก่อนจะได้ข้อมูลลักษณะนี้มาเราก็มักจะมีแหล่งข้อมูลดิบว่าคนนี้เป็นใคร อายุเท่าไหร่เป็นร้อยเป็นล้านเรคคอร์ด แล้วค่อยมาแยกตามกลุ่มข้อมูลอีกที ในที่นี้เราจะแยกตามกลุ่มอายุเพื่อให้ได้ข้อมูลนำไปพล็อตกราฟในลักษณะปิรามิดข้างบน

สมมุตินะครับสมมุติเราจะแบ่งกลุ่มข้อมูลออกเป็นช่วง ๆ ละ 5 ปีหล่ะกัน จากข้อมูลที่เราสร้างแบบดัมมี่ขึ้นมา (เราใช้บริการจากเว็บ generatedata.com นะ สะดวกดี)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
DROP TABLE `persondemo`;
CREATE TABLE `persondemo` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`age` mediumint default NULL,
PRIMARY KEY (`id`)
) AUTO_INCREMENT=1;
INSERT INTO `persondemo` (`age`) VALUES (11),(88),(73),(75),(8),(45),(40),(61),(62),(69),(28),(1),(84),(5),(13),(75),(76),(78),(45),(35),(23),(52),(56),(40),(91),(6),(61),(41),(52),(42),(33),(90),(4),(55),(90),(75),(97),(28),(36),(2),(51),(46),(49),(79),(87),(22),(76),(3),(9),(56),(23),(45),(56),(85),(65),(30),(31),(21),(13),(36),(88),(22),(20),(16),(73),(95),(17),(56),(29),(94),(59),(38),(31),(36),(47),(37),(33),(3),(90),(22),(41),(85),(76),(90),(54),(58),(73),(30),(12),(4),(3),(38),(78),(78),(26),(85),(78),(68),(31),(11);
DROP TABLE `persondemo`; CREATE TABLE `persondemo` ( `id` mediumint(8) unsigned NOT NULL auto_increment, `age` mediumint default NULL, PRIMARY KEY (`id`) ) AUTO_INCREMENT=1; INSERT INTO `persondemo` (`age`) VALUES (11),(88),(73),(75),(8),(45),(40),(61),(62),(69),(28),(1),(84),(5),(13),(75),(76),(78),(45),(35),(23),(52),(56),(40),(91),(6),(61),(41),(52),(42),(33),(90),(4),(55),(90),(75),(97),(28),(36),(2),(51),(46),(49),(79),(87),(22),(76),(3),(9),(56),(23),(45),(56),(85),(65),(30),(31),(21),(13),(36),(88),(22),(20),(16),(73),(95),(17),(56),(29),(94),(59),(38),(31),(36),(47),(37),(33),(3),(90),(22),(41),(85),(76),(90),(54),(58),(73),(30),(12),(4),(3),(38),(78),(78),(26),(85),(78),(68),(31),(11);
DROP TABLE `persondemo`;

CREATE TABLE `persondemo` (
  `id` mediumint(8) unsigned NOT NULL auto_increment,
  `age` mediumint default NULL,
  PRIMARY KEY (`id`)
) AUTO_INCREMENT=1;

INSERT INTO `persondemo` (`age`) VALUES (11),(88),(73),(75),(8),(45),(40),(61),(62),(69),(28),(1),(84),(5),(13),(75),(76),(78),(45),(35),(23),(52),(56),(40),(91),(6),(61),(41),(52),(42),(33),(90),(4),(55),(90),(75),(97),(28),(36),(2),(51),(46),(49),(79),(87),(22),(76),(3),(9),(56),(23),(45),(56),(85),(65),(30),(31),(21),(13),(36),(88),(22),(20),(16),(73),(95),(17),(56),(29),(94),(59),(38),(31),(36),(47),(37),(33),(3),(90),(22),(41),(85),(76),(90),(54),(58),(73),(30),(12),(4),(3),(38),(78),(78),(26),(85),(78),(68),(31),(11);

วิธีแรก คำสั่ง SQL ที่มักเห็นอยู่บ่อย ๆ ในการแบ่งชุดข้อมูลก็จะเป็นการใช้ CASE ..WHEN มีกี่ช่วงก็แบ่งไป

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
SELECT SUM(CASE WHEN COL1 BETWEEN 0 AND 4 THEN 1 END)
, SUM(CASE WHEN COL1 BETWEEN 5 AND 9 THEN 1 END)
, SUM(CASE WHEN COL1 BETWEEN 10 AND 14 THEN 1 END)
, SUM(CASE WHEN COL1 BETWEEN 15 AND 19 THEN 1 END)
, SUM(CASE WHEN COL1 BETWEEN 20 AND 24 THEN 1 END)
...
...
...
FROM YOURTABLE
...
SELECT SUM(CASE WHEN COL1 BETWEEN 0 AND 4 THEN 1 END) , SUM(CASE WHEN COL1 BETWEEN 5 AND 9 THEN 1 END) , SUM(CASE WHEN COL1 BETWEEN 10 AND 14 THEN 1 END) , SUM(CASE WHEN COL1 BETWEEN 15 AND 19 THEN 1 END) , SUM(CASE WHEN COL1 BETWEEN 20 AND 24 THEN 1 END) ... ... ... FROM YOURTABLE ...
SELECT  SUM(CASE WHEN COL1 BETWEEN 0 AND 4 THEN 1 END)
,       SUM(CASE WHEN COL1 BETWEEN 5 AND 9 THEN 1 END)
,       SUM(CASE WHEN COL1 BETWEEN 10 AND 14 THEN 1 END)
,       SUM(CASE WHEN COL1 BETWEEN 15 AND 19 THEN 1 END)
,       SUM(CASE WHEN COL1 BETWEEN 20 AND 24 THEN 1 END)
... 
... 
... 
FROM YOURTABLE 
...

อีกวิธีนึง ก็ใช้ฟังก์ชันทางคณิตศาสตร์ของ SQL เอง วันนี้จะเสนอ FLOOR() เพื่อมาคำนวณหาช่วงข้อมูล ฟังก์ชันนี้ไปอ่านเพิ่มเติมเอาหล่ะกันนะ ^_^

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
SELECT
CONCAT(5 * FLOOR((age/5)), ' - ', 5 * FLOOR((age/5)) + 4) AS `range`,
COUNT(id) AS `NumberOfPerson`
FROM `persondemo`
GROUP BY 1
ORDER BY 5 * FLOOR((age/5))
SELECT CONCAT(5 * FLOOR((age/5)), ' - ', 5 * FLOOR((age/5)) + 4) AS `range`, COUNT(id) AS `NumberOfPerson` FROM `persondemo` GROUP BY 1 ORDER BY 5 * FLOOR((age/5))
SELECT
    CONCAT(5 * FLOOR((age/5)), ' - ', 5 * FLOOR((age/5)) + 4) AS `range`,
    COUNT(id) AS `NumberOfPerson`
FROM `persondemo`
GROUP BY 1
ORDER BY 5 * FLOOR((age/5))

ข้อมูลที่ได้ก็ประมาณนี้

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
+---------+----------------+
| range | NumberOfPerson |
+---------+----------------+
| 0 - 4 | 7 |
| 5 - 9 | 4 |
| 10 - 14 | 5 |
| 15 - 19 | 2 |
| 20 - 24 | 7 |
| 25 - 29 | 4 |
| 30 - 34 | 7 |
| 35 - 39 | 7 |
| 40 - 44 | 5 |
| 45 - 49 | 6 |
| 50 - 54 | 4 |
| 55 - 59 | 7 |
| 60 - 64 | 3 |
| 65 - 69 | 3 |
| 70 - 74 | 3 |
| 75 - 79 | 11 |
| 80 - 84 | 1 |
| 85 - 89 | 6 |
| 90 - 94 | 6 |
| 95 - 99 | 2 |
+---------+----------------+
20 rows in set (0.00 sec)
+---------+----------------+ | range | NumberOfPerson | +---------+----------------+ | 0 - 4 | 7 | | 5 - 9 | 4 | | 10 - 14 | 5 | | 15 - 19 | 2 | | 20 - 24 | 7 | | 25 - 29 | 4 | | 30 - 34 | 7 | | 35 - 39 | 7 | | 40 - 44 | 5 | | 45 - 49 | 6 | | 50 - 54 | 4 | | 55 - 59 | 7 | | 60 - 64 | 3 | | 65 - 69 | 3 | | 70 - 74 | 3 | | 75 - 79 | 11 | | 80 - 84 | 1 | | 85 - 89 | 6 | | 90 - 94 | 6 | | 95 - 99 | 2 | +---------+----------------+ 20 rows in set (0.00 sec)
+---------+----------------+
| range   | NumberOfPerson |
+---------+----------------+
| 0 - 4   |              7 |
| 5 - 9   |              4 |
| 10 - 14 |              5 |
| 15 - 19 |              2 |
| 20 - 24 |              7 |
| 25 - 29 |              4 |
| 30 - 34 |              7 |
| 35 - 39 |              7 |
| 40 - 44 |              5 |
| 45 - 49 |              6 |
| 50 - 54 |              4 |
| 55 - 59 |              7 |
| 60 - 64 |              3 |
| 65 - 69 |              3 |
| 70 - 74 |              3 |
| 75 - 79 |             11 |
| 80 - 84 |              1 |
| 85 - 89 |              6 |
| 90 - 94 |              6 |
| 95 - 99 |              2 |
+---------+----------------+
20 rows in set (0.00 sec)

ดึกมากแล้ว นอนเหอะ นะ ^_^