ทำไมเราใช้ Group by 1 และ Group by 1,2,3 ในการสืบค้น SQL?


26

ในแบบสอบถาม SQL เราจะใช้กลุ่มตามข้อเพื่อใช้ฟังก์ชั่นรวม

  • แต่วัตถุประสงค์เบื้องหลังการใช้ค่าตัวเลขแทนชื่อคอลัมน์กับ Group by clause คืออะไร ตัวอย่างเช่น: จัดกลุ่มตาม 1

3
ใช้order by 1เฉพาะเมื่อนั่งที่mysql> พรอมต์ ORDER BY id ASCในรหัสการใช้งาน หมายเหตุตัวพิมพ์เล็กชื่อฟิลด์และทิศทางการสั่งซื้อที่ชัดเจน
dotancohen

คำตอบ:


28

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

เหตุผลที่คนทำ:

  • พวกเขาขี้เกียจ - ฉันไม่รู้ว่าทำไมผู้คนถึงคิดว่าประสิทธิภาพการทำงานของพวกเขาดีขึ้นด้วยการเขียนรหัสสั้น ๆ แทนที่จะพิมพ์เพื่อเพิ่มอีก 40 มิลลิวินาทีเพื่อรับรหัสที่แท้จริงมากขึ้น

เหตุผลมันไม่ดี:

  • ไม่ใช่การจัดทำเอกสารด้วยตนเอง - มีคนกำลังจะต้องแยกวิเคราะห์รายการ SELECT เพื่อหาการจัดกลุ่ม จริงๆแล้วมันจะมีความชัดเจนมากขึ้นใน SQL Server ซึ่งไม่สนับสนุนการจัดกลุ่มคาวบอยที่รู้ว่าจะเกิดอะไรขึ้นอย่างที่ MySQL ทำ

  • มันเปราะบางคนเข้ามาและเปลี่ยนรายการ SELECT เพราะผู้ใช้ทางธุรกิจต้องการเอาท์พุทรายงานที่ต่างออกไป หากคุณใช้ชื่อคอลัมน์ใน GROUP BY คำสั่งซื้อในรายการ SELECT จะไม่เกี่ยวข้อง

SQL Server รองรับ ORDER BY [ลำดับ]; นี่คือข้อโต้แย้งแบบขนานกับการใช้งาน:


9

MySQL อนุญาตให้คุณGROUP BYใช้นามแฝง ( ปัญหาเกี่ยวกับนามแฝงของคอลัมน์ ) นี่จะเป็นการดีกว่าถ้าทำGROUP BYกับตัวเลข

Google มีตัวอย่างมากมายเกี่ยวกับการใช้งานและสาเหตุที่หลายคนหยุดใช้งาน

จะซื่อสัตย์กับคุณฉันไม่ได้ใช้หมายเลขคอลัมน์ORDER BYและGROUP BYตั้งแต่ปี 1996 (ที่ผมทำของ Oracle PL / SQL การพัฒนาในเวลานั้น) การใช้หมายเลขคอลัมน์นั้นใช้สำหรับตัวจับเวลาเก่าและความเข้ากันได้แบบย้อนกลับช่วยให้นักพัฒนาสามารถใช้ MySQL และ RDBMS อื่น ๆ ที่ยังคงอนุญาตได้


8

พิจารณากรณีด้านล่าง:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Apps         |         1 |
| 2016-05-31 | Applications |         1 |
| 2016-05-31 | Applications |         1 |
| 2016-05-31 | Apps         |         1 |
| 2016-05-31 | Videos       |         1 |
| 2016-05-31 | Videos       |         1 |
| 2016-06-01 | Apps         |         3 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Videos       |         2 |
| 2016-06-01 | Apps         |         2 |
+------------+--------------+-----------+

คุณต้องค้นหาจำนวนการดาวน์โหลดต่อบริการต่อวันโดยพิจารณาจากแอพและแอพพลิเคชั่นเป็นบริการเดียวกัน การจัดกลุ่มโดยdate, servicesจะส่งผลให้AppsและApplicationsถูกพิจารณาว่าเป็นบริการที่แยกต่างหาก

ในกรณีนั้นแบบสอบถามจะเป็น:

 select date, services, sum(downloads) as downloads
 from test.zvijay_test
 group by date,services

และเอาท์พุท:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Apps         |         2 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Apps         |         5 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+

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

วิธีหนึ่งคือการแทนที่Appsด้วยการApplicationsใช้CASEนิพจน์หรือIFฟังก์ชั่นแล้วจัดกลุ่มพวกเขาผ่านบริการเป็น:

select 
  date,
  if(services='Apps','Applications',services) as services,
  sum(downloads) as downloads
from test.zvijay_test 
group by date,services

แต่สิ่งนี้ยังคงจัดกลุ่มบริการที่พิจารณาAppsและApplicationsเป็นบริการที่แตกต่างกันและให้ผลลัพธ์เหมือนเดิมก่อนหน้านี้:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Applications |         5 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+

การจัดกลุ่มมากกว่าหมายเลขคอลัมน์ช่วยให้คุณสามารถจัดกลุ่มข้อมูลในคอลัมน์ aliased

select
  date,
  if(services='Apps','Applications',services) as services,
  sum(downloads) as downloads
from test.zvijay_test
group by date,2;

และให้ผลลัพธ์ที่ต้องการดังนี้:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         4 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         9 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+

ฉันได้อ่านมาหลายครั้งแล้วว่านี่เป็นวิธีที่ขี้เกียจในการเขียนแบบสอบถามหรือการจัดกลุ่มในคอลัมน์ชื่อแทนไม่ทำงานใน MySQL แต่นี่เป็นวิธีการจัดกลุ่มคอลัมน์ที่มีชื่อแทน

นี่ไม่ใช่วิธีการเขียนแบบสอบถามที่ต้องการใช้เฉพาะเมื่อคุณต้องการจัดกลุ่มเหนือคอลัมน์ที่มีนามแฝง


" แต่นี่ยังรวมกลุ่มบริการที่พิจารณาแอพและแอพพลิเคชั่นเป็นบริการที่แตกต่างกันและให้ผลลัพธ์เหมือนเดิมก่อนหน้านี้ " สิ่งนี้จะไม่ได้รับการแก้ไขหรือไม่หากคุณเลือกชื่ออื่น (ไม่ขัดแย้ง) สำหรับนามแฝง
Daddy32

3

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


0

มันใช้งานได้สำหรับฉัน รหัสจัดกลุ่มแถวสูงสุด 5 กลุ่ม

SELECT
USR.UID,
USR.PROFILENAME,
(
    CASE 
    WHEN MOD(@curRow, 5) = 0 AND @curRow > 0 THEN
        @curRow := 0
    ELSE
        @curRow := @curRow + 1 
        /*@curRow := 1*/ /*AND @curCode := USR.UID*/
    END
) AS sort_by_total  
FROM
    SS_USR_USERS USR,
    (
        SELECT
            @curRow := 0,
            @curCode := ''
    ) rt
ORDER BY
    USR.PROFILENAME,
    USR.UID

ผลจะเป็นดังนี้

ป้อนคำอธิบายรูปภาพที่นี่


0
SELECT dep_month,dep_day_of_week,dep_date,COUNT(*) AS flight_count FROM flights GROUP BY 1,2;

SELECT dep_month,dep_day_of_week,dep_date,COUNT(*) AS flight_count FROM flights GROUP BY 1,2,3;

พิจารณาข้อความค้นหาด้านบน: จัดกลุ่มตาม 1 หมายถึงจัดกลุ่มตามคอลัมน์แรกและกลุ่มโดย 1,2 หมายถึงจัดกลุ่มตามคอลัมน์แรกและสองและกลุ่มที่ 1,2,3 หมายถึงจัดกลุ่มตามคอลัมน์ที่สองและสามแรก ตัวอย่างเช่น:

กลุ่มที่ 1,2

ภาพนี้แสดงสองคอลัมน์แรกที่ถูกจัดกลุ่มตาม 1,2 คือมันไม่ได้พิจารณาค่าที่แตกต่างกันของ dep_date เพื่อค้นหาการนับ (เพื่อคำนวณการรวมกันที่แตกต่างกันทั้งหมดของสองคอลัมน์แรกจะถูกนำมาพิจารณา) ในขณะที่ผลลัพธ์แบบสอบถามที่สองนี้ กลุ่มละ 1,2,3

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.