กระทู้เก่าบอร์ด อ.Yeadram
1,699 18
URL.หัวข้อ /
URL
หาค่า 3 ลำดับสุดท้าย
มี table : visit
มี ฟิลด์
seq : ลำดับรับบริการ
visitdate : วันที่มารับบริการ
pid : รหัสลูกค้า
tot : มูลค่าซื้อ
จะเขียน Query ให้มูลค่าซื้อของลูกค้า เรียงลำดับ 3 ครั้งสุดท้าย
ต้องเขียนแบบไหนครับ
มี ฟิลด์
seq : ลำดับรับบริการ
visitdate : วันที่มารับบริการ
pid : รหัสลูกค้า
tot : มูลค่าซื้อ
จะเขียน Query ให้มูลค่าซื้อของลูกค้า เรียงลำดับ 3 ครั้งสุดท้าย
ต้องเขียนแบบไหนครับ
18 Reply in this Topic. Dispaly 1 pages and you are on page number 1
2 @R23015
แบบนี้ผมทำได้ครับ คือแบบอยากให้ไม่ต้องกำหนด WHERE เป็นคนๆ ครับ
อยากให้ออกมาทุกคนเลย เรียงลำดับ 3 อันดับแรก ขอบคุณครับ
อยากให้ออกมาทุกคนเลย เรียงลำดับ 3 อันดับแรก ขอบคุณครับ
3 @R23020
ในเว็บส่วนมากเค้าชอบทำกันแบบนี้ครับ
SELECT Top 3 * FROM visit ORDER BY seq DESC
ลองดูว่าตรงตามข้อมูลที่ต้องการหรือไม่ครับ
SELECT Top 3 * FROM visit ORDER BY seq DESC
ลองดูว่าตรงตามข้อมูลที่ต้องการหรือไม่ครับ
4 @R23025
แบบนี้จะออกมา 3 รายการ ซึ่งแบบที่ต้องการคือ
visitdate pid tot
5/3/2560 1 30
1/1/2560 1 20
7/1/2560 3 400
5/12/2559 3 20
8/5/2559 3 100
6/12/2559 4 10
7/11/2559 4 400
5/9/2559 4 20
pid 1 มาแค่ 2 ครั้ง นอกนั้นมา 3 ครั้งขึ้นไป เอาแค่ 3 ประมาณนี้ครับ
visitdate pid tot
5/3/2560 1 30
1/1/2560 1 20
7/1/2560 3 400
5/12/2559 3 20
8/5/2559 3 100
6/12/2559 4 10
7/11/2559 4 400
5/9/2559 4 20
pid 1 มาแค่ 2 ครั้ง นอกนั้นมา 3 ครั้งขึ้นไป เอาแค่ 3 ประมาณนี้ครับ
5 @R23029
อื่ม... หากหมายถึงต้องการคิวรี่แสดงฐานข้อมูลล่าสุด 3 รายการสุดท้ายของทุกๆ Pid อย่างนั้นหรือเปล่า (ไม่เคยเข้าใจนะ) หากใช่ เท่าที่คิดออกตอนนี้ คือ...
น่าจะต้องคิวรี่ 3 ครั้ง แล้วนำมา Union all กันมั้งครับ คือ
1. คิวรี่ข้อมูลรายการครั้งสุดท้ายของทุก pid
2. คิวรี่ข้อมูลรายการรองครั้งสุดท้ายของทุก pid
3. คิวรี่ข้อมูลรายการของก่อนรองครั้งสุดท้ายของทุก pid
แล้วนำ 3 คิวรี่นี้มา Union all กัน อะไรประมาณนี้ครับ
จากตัวอย่างก็จะได้ประมาณนี้ครับ
SELECT *
FROM (SELECT DISTINCT
(SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid) AS seq,
(SELECT Last(pid) FROM visit AS b WHERE b.pid = a.pid) AS pid,
(SELECT Last(visitdate) FROM visit AS b WHERE b.pid = a.pid) AS visitdate,
(SELECT Last(tot) FROM visit AS b WHERE b.pid = a.pid) AS tot
FROM visit AS a
GROUP BY a.pid, a.seq
UNION ALL
SELECT DISTINCT
(SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS seq,
(SELECT Last(pid) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS pid,
(SELECT Last(visitdate) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS visitdate,
(SELECT Last(tot) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS tot
FROM (SELECT DISTINCT
(SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid) AS seq,
(SELECT Last(pid) FROM visit AS b WHERE b.pid = a.pid) AS pid
FROM visit AS a
GROUP BY a.pid, a.seq) AS a
GROUP BY a.pid, a.seq
HAVING Not (SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) Is Null
UNION ALL
SELECT DISTINCT
(SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS seq,
(SELECT Last(pid) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS pid,
(SELECT Last(visitdate) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS visitdate,
(SELECT Last(tot) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS tot
FROM (SELECT DISTINCT
(SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS seq,
(SELECT Last(pid) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS pid
FROM (SELECT DISTINCT
(SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid) AS seq,
(SELECT Last(pid) FROM visit AS b WHERE b.pid = a.pid) AS pid
FROM visit AS a
GROUP BY a.pid, a.seq) AS a
GROUP BY a.pid, a.seq) AS a
GROUP BY a.pid, a.seq
HAVING Not (SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) Is Null) AS LAS
ORDER BY LAS.pid;
ปล. ไม่รู้ว่าเป็นแนวคิดดีสุดยังนะครับ นึกๆดูยังนึกออกได้เท่านี้ โจทย์แบบนี้ไม่เคยเจอ แต่เป็นโจทย์น่าสนใจดีครับ อาจมีแนวคิดดีกว่านี้จากอาจารย์ท่านอื่นๆ ก็ได้ครับ ลองปรับใช้ดูก่อน
น่าจะต้องคิวรี่ 3 ครั้ง แล้วนำมา Union all กันมั้งครับ คือ
1. คิวรี่ข้อมูลรายการครั้งสุดท้ายของทุก pid
2. คิวรี่ข้อมูลรายการรองครั้งสุดท้ายของทุก pid
3. คิวรี่ข้อมูลรายการของก่อนรองครั้งสุดท้ายของทุก pid
แล้วนำ 3 คิวรี่นี้มา Union all กัน อะไรประมาณนี้ครับ
จากตัวอย่างก็จะได้ประมาณนี้ครับ
SELECT *
FROM (SELECT DISTINCT
(SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid) AS seq,
(SELECT Last(pid) FROM visit AS b WHERE b.pid = a.pid) AS pid,
(SELECT Last(visitdate) FROM visit AS b WHERE b.pid = a.pid) AS visitdate,
(SELECT Last(tot) FROM visit AS b WHERE b.pid = a.pid) AS tot
FROM visit AS a
GROUP BY a.pid, a.seq
UNION ALL
SELECT DISTINCT
(SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS seq,
(SELECT Last(pid) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS pid,
(SELECT Last(visitdate) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS visitdate,
(SELECT Last(tot) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS tot
FROM (SELECT DISTINCT
(SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid) AS seq,
(SELECT Last(pid) FROM visit AS b WHERE b.pid = a.pid) AS pid
FROM visit AS a
GROUP BY a.pid, a.seq) AS a
GROUP BY a.pid, a.seq
HAVING Not (SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) Is Null
UNION ALL
SELECT DISTINCT
(SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS seq,
(SELECT Last(pid) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS pid,
(SELECT Last(visitdate) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS visitdate,
(SELECT Last(tot) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS tot
FROM (SELECT DISTINCT
(SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS seq,
(SELECT Last(pid) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) AS pid
FROM (SELECT DISTINCT
(SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid) AS seq,
(SELECT Last(pid) FROM visit AS b WHERE b.pid = a.pid) AS pid
FROM visit AS a
GROUP BY a.pid, a.seq) AS a
GROUP BY a.pid, a.seq) AS a
GROUP BY a.pid, a.seq
HAVING Not (SELECT Last(seq) FROM visit AS b WHERE b.pid = a.pid AND b.seq < a.seq) Is Null) AS LAS
ORDER BY LAS.pid;
ปล. ไม่รู้ว่าเป็นแนวคิดดีสุดยังนะครับ นึกๆดูยังนึกออกได้เท่านี้ โจทย์แบบนี้ไม่เคยเจอ แต่เป็นโจทย์น่าสนใจดีครับ อาจมีแนวคิดดีกว่านี้จากอาจารย์ท่านอื่นๆ ก็ได้ครับ ลองปรับใช้ดูก่อน
6 @R23039
มันประมวลผลประมาณ 10 นาทีแล้วครับ ยังไม่หยุด
7 @R23041
โค๊ดข้างบนผมคิดได้ก็เขียนเลย ดูแล้วเหมือนมันมีการใช้คำสั่งซ้ำ ใช้ Distinct แล้วยังใช้ Group by อีก และมีบางอย่างก็ลดคำสั่งลงได้ น่าจะทำให้เร็วขึ้นได้ แต่ดูแล้วก็ยังไม่ค่อยฉลาดเท่าไหร่หากนำไปใช้กับข้อมูลเรคคอร์ดเยอะ ยังไงลองทดสอบดูใหม่ครับ
SELECT *
FROM (SELECT DISTINCT a.Pid,
(SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid) AS seq,
(SELECT Last(visitdate) FROM visit AS b WHERE b.Pid = a.Pid) AS visitdate,
(SELECT Last(tot) FROM visit AS b WHERE b.Pid = a.Pid) AS tot
FROM visit AS a
UNION ALL
SELECT DISTINCT a.Pid,
(SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) AS seq,
(SELECT Last(visitdate) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) AS visitdate,
(SELECT Last(tot) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) AS tot
FROM (SELECT DISTINCT a.Pid,
(SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid) AS seq
FROM visit AS a) AS a
WHERE Not (SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) Is Null
UNION ALL
SELECT DISTINCT a.Pid,
(SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) AS seq,
(SELECT Last(visitdate) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) AS visitdate,
(SELECT Last(tot) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) AS tot
FROM (SELECT DISTINCT a.Pid,
(SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) AS seq
FROM (SELECT DISTINCT a.Pid,
(SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid) AS seq
FROM visit AS a) AS a) AS a
WHERE Not (SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) Is Null) AS qry_Last3
ORDER BY qry_Last3.Pid, qry_Last3.seq;
SELECT *
FROM (SELECT DISTINCT a.Pid,
(SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid) AS seq,
(SELECT Last(visitdate) FROM visit AS b WHERE b.Pid = a.Pid) AS visitdate,
(SELECT Last(tot) FROM visit AS b WHERE b.Pid = a.Pid) AS tot
FROM visit AS a
UNION ALL
SELECT DISTINCT a.Pid,
(SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) AS seq,
(SELECT Last(visitdate) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) AS visitdate,
(SELECT Last(tot) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) AS tot
FROM (SELECT DISTINCT a.Pid,
(SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid) AS seq
FROM visit AS a) AS a
WHERE Not (SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) Is Null
UNION ALL
SELECT DISTINCT a.Pid,
(SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) AS seq,
(SELECT Last(visitdate) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) AS visitdate,
(SELECT Last(tot) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) AS tot
FROM (SELECT DISTINCT a.Pid,
(SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) AS seq
FROM (SELECT DISTINCT a.Pid,
(SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid) AS seq
FROM visit AS a) AS a) AS a
WHERE Not (SELECT Last(seq) FROM visit AS b WHERE b.Pid = a.Pid AND b.seq < a.seq) Is Null) AS qry_Last3
ORDER BY qry_Last3.Pid, qry_Last3.seq;
8 @R23045
ลองดูว่าอย่างนี้ได้ไหม (ผมยังไม่ได้ทดสอบนะ)
select v1.visitdate, v1.pid, v1.tot from visit as v1
where v1.visitdate in (select top 3 v2.visitdate from visit as v2
where v2.pid = v1.pid
order by v2.visitdate desc)
order by v1.pid, v1.visitdate desc
select v1.visitdate, v1.pid, v1.tot from visit as v1
where v1.visitdate in (select top 3 v2.visitdate from visit as v2
where v2.pid = v1.pid
order by v2.visitdate desc)
order by v1.pid, v1.visitdate desc
9 @R23046
แหม ๆ ท่าน อ.สันติฯ เขียนสั้นยังงี้นักเรียนคงเข้าใจง่ายเนอะ
10 @R23047
แล้วที่คุณ UN บอกว่าประมวลผล 10 นาทียังไม่หยุดน่ะ ข้อมูลมากหรือเครื่องช้ากันแน่ บอกเดี๊ยนที
11 @R23048
อย่างที่ว่าไว้ ผมยังไม่ได้รันทดสอบครับ (แต่ syntax ไม่ผิดแน่ๆ) อาจทำงานไม่ตรงตามที่ต้องการหรือทำงานผิดก็ได้นะครับ คุณ UN ไปทดสอบเองแล้วกัน
12 @R23049
ผมทดสอบ SQL ของ อ.สันติสุข แล้วครับ
คิดว่าน่าจะถูกต้อง ตรงตามที่ผมเข้าใจแล้ว
รอคุณ Un มายืนยันคำตอบครับ
คิดว่าน่าจะถูกต้อง ตรงตามที่ผมเข้าใจแล้ว
รอคุณ Un มายืนยันคำตอบครับ
13 @R23057
เยี่ยมเลยครับ
14 @R23080
ขอโทษอาจารย์ทุกท่านครับ ผมทดสอบของ อ.TTT ยังไม่เสร็จเลยครับ มัน Err กำลังหาจุดอยู่ แล้วงานอื่นๆ มันยุ่งมาก เพิ่งเข้ามาอ่านอีกทีตอนนี้
ตอบ อ.U&ME เครื่องผมเครื่องใหม่ Corei5 DDR 4 GB น่าจะเร็ว
ส่วนข้อมูล จริงๆ ก็มากอยู่ 2-3 หมื่นเรคคอด แต่ผมใช้ คิวรี กรอง เหลือ 5000 เรคคอด
ตอบ อ.PichaiTC ตอนนี้ สิบกว่านาที ยังรันอยู่ครับ (ของ อ.สันติสุข) กำลังทำความเข้าใจกับสูตรอยู่ครับ
ขอบพระคุณอาจารย์ทุกท่านครับ
ตอบ อ.U&ME เครื่องผมเครื่องใหม่ Corei5 DDR 4 GB น่าจะเร็ว
ส่วนข้อมูล จริงๆ ก็มากอยู่ 2-3 หมื่นเรคคอด แต่ผมใช้ คิวรี กรอง เหลือ 5000 เรคคอด
ตอบ อ.PichaiTC ตอนนี้ สิบกว่านาที ยังรันอยู่ครับ (ของ อ.สันติสุข) กำลังทำความเข้าใจกับสูตรอยู่ครับ
ขอบพระคุณอาจารย์ทุกท่านครับ
15 @R23081
ถ้าช้า ให้สร้าง index อีกตัวนึง ที่ประกอบด้วย pid และ visitdate ครับ
16 @R23082
หมายถึง ให้ไปกำหนดที่ตารางใช่มั้ยครับ หรือทำในควิรีครับอาจารย์
17 @R23084
กำหนดในตารางครับ คิวรี่ไม่มีการสร้าง index ครับ
18 @R23085
ทำแล้ว สรุป ไม่เวิคครับ สงสัยต้องใช้วิธีอื่นครับอาจารย์
Time: 0.3497s
ประมาณนี้มั้งครับ เดาๆเอา
แต่คำสั่ง limit มันใช้ได้ไหม ใน access ผมไม่แน่ใจ
ไม่เคยลอง