ค้นหาแถวทั้งหมดจากเดือนก่อนหน้า


92

ฉันต้องการเลือกแถวทั้งหมดในฐานข้อมูลของฉันที่สร้างขึ้นเมื่อเดือนที่แล้ว

ตัวอย่างเช่นหากเดือนปัจจุบันคือเดือนมกราคมฉันต้องการส่งคืนแถวทั้งหมดที่สร้างขึ้นในเดือนธันวาคมหากเดือนนั้นเป็นเดือนกุมภาพันธ์ฉันต้องการส่งคืนแถวทั้งหมดที่สร้างขึ้นในเดือนมกราคม ฉันมีคอลัมน์ในฐานข้อมูลของฉันที่รายการวันที่สร้างขึ้นในรูปแบบนี้date_created2007-06-05 14:50:17

คำตอบ:


201
SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)

70
SELECT * FROM table WHERE date_created BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE();
Ghazanfar Mir

12
คำถามของคุณไม่ค่อยตรงกับคำถามในขณะที่คำตอบด้านบนตอบ ของคุณส่งคืนแถวระหว่างวันนี้ของเดือนที่แล้วถึงเมื่อวานนี้
Matt Passell

@MattPassell ขอโทษนะคะ แต่betweenรวมขอบเขตไว้ด้วย .. มันจะรวมวันที่ปัจจุบันด้วย ทำไม / เมื่อวานจะ จำกัด แค่ไหน ?? กรุณาอธิบายให้ละเอียด?
Ghazanfar Mir

5
ฉันเข้าใจว่าคุณหมายถึงอะไร .. ใช่คุณพูดถูก .. คำถามของฉันไม่ใช่สิ่งที่ OP ต้องการ .. ฉันเข้าใจผิดคำถาม
Ghazanfar Mir

แล้วถ้าcurrent_dateวันนี้ไม่ใช่วันที่สุ่มจากลูกค้าล่ะ?
dios231

23

นี่เป็นทางเลือกอื่น สมมติว่าคุณมีฟิลด์ที่จัดทำดัชนีDATEหรือDATETIMEประเภทควรใช้ดัชนีเนื่องจากวันที่ที่จัดรูปแบบจะถูกแปลงประเภทก่อนที่จะใช้ดัชนี จากนั้นคุณจะเห็นrangeแบบสอบถามมากกว่าindexแบบสอบถามเมื่อมองด้วยอธิบาย

SELECT
    * 
FROM
    table
WHERE 
    date_created >= DATE_FORMAT( CURRENT_DATE - INTERVAL 1 MONTH, '%Y/%m/01' ) 
AND
    date_created < DATE_FORMAT( CURRENT_DATE, '%Y/%m/01' )

+1. เป็นมิตรกับดัชนีมากขึ้น คุณยังสามารถโยนสิ่งของSTR_TO_DATEไปรอบ ๆDATE_FORMATเพื่อจัดการกับวัตถุวันที่ได้เสมอ
Leigh

15

หากไม่มีวันที่ในอนาคต ...

SELECT * 
FROM   table_name 
WHERE  date_created > (NOW() - INTERVAL 1 MONTH);

ทดสอบแล้ว.


3
ฉันคิดว่าพวกเขากำลังมองหาสิ่งที่แตกต่างออกไป เช่นบันทึกทั้งหมดจากเดือนที่แล้ว (เช่น 1 ต.ค. - 31 ต.ค. 2555 23:59:59 น.) ข้อความค้นหาด้านบนจะส่งคืนค่า ~ 30 วันที่ผ่านมานับจากวันที่และเวลาของวันนี้
Leigh

13

อีกทางเลือกหนึ่งสำหรับคำตอบของ hobodave

SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)

คุณสามารถบรรลุสิ่งเดียวกันกับ EXTRACT โดยใช้ YEAR_MONTH เป็นหน่วยดังนั้นคุณไม่จำเป็นต้องใช้ AND เช่นนั้น:

SELECT * FROM table
WHERE EXTRACT(YEAR_MONTH FROM date_created) = EXTRACT(YEAR_MONTH FROM CURDATE() - INTERVAL
1 MONTH)

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

8
SELECT *
FROM  yourtable
where DATE_FORMAT(date_created, '%Y-%m') = date_format(DATE_SUB(curdate(), INTERVAL 1 month),'%Y-%m')

สิ่งนี้ควรส่งคืนระเบียนทั้งหมดจากเดือนปฏิทินก่อนหน้าซึ่งต่างจากระเบียนในช่วง 30 หรือ 31 วันที่ผ่านมา


ฉันลืมพูดถึง ... สิ่งนี้ควรส่งคืนบันทึกทั้งหมดจากเดือนปฏิทินก่อนหน้าซึ่งต่างจากบันทึกในช่วง 30 หรือ 31 วันที่ผ่านมา
Gregg

ในความคิดของฉันนี้ควรจะเป็นคำตอบที่ได้รับการยอมรับในขณะที่มันจะง่ายกว่าคำตอบที่ได้รับการยอมรับยังให้ผลเดียวกัน
แกรนท์

3

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

SELECT * 
FROM table 
WHERE 
date_created BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE();

2
ไม่ไม่ใช่ซะทีเดียว ดูคำตอบของฉันต่อความคิดเห็นของคุณเกี่ยวกับคำตอบที่ได้รับจาก @hobodave
Matt Passell

@MattPassell คุณพูดถูกฉันเข้าใจผิดคำถาม .. ฉันพลาดประเด็นที่ว่าผลลัพธ์ควร จำกัด เฉพาะบันทึกจากเดือนที่แล้วเท่านั้น
Ghazanfar Mir

2
WHERE created_date >= DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 2 MONTH)), INTERVAL 1 DAY) 
  AND created_date <= DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 1 MONTH)), INTERVAL 0 DAY) 

สิ่งนี้ใช้ได้ผลสำหรับฉัน (เลือกระเบียนทั้งหมดที่สร้างจากเดือนที่แล้วโดยไม่คำนึงถึงวันที่คุณเรียกใช้การสืบค้นในเดือนนี้)


1

select fields FROM table WHERE date_created LIKE concat(LEFT(DATE_SUB(NOW(), interval 1 month),7),'%');

อันนี้จะสามารถใช้ประโยชน์จากดัชนีได้หาก date_created ของคุณถูกสร้างดัชนีเนื่องจากไม่ได้ใช้ฟังก์ชันการแปลงใด ๆ กับค่าฟิลด์


@ggiroux - ต้องแปลงวันที่เป็นประเภทอักขระก่อนที่จะใช้ LIKE
martin Clayton

ใช่แน่นอน แต่ยังคงมีการปรับปรุงมากกว่าคำตอบที่เลือก IMHO (IFF date_created ถูกจัดทำดัชนี)
ggiroux

1

นี่คือแบบสอบถามเพื่อรับบันทึกของเดือนที่แล้ว:

SELECT *
FROM `tablename`
WHERE `datefiled`
BETWEEN DATE_SUB( DATE( NOW( ) ) , INTERVAL 1
MONTH )
AND 
LAST_DAY( DATE_SUB( DATE( NOW( ) ) , INTERVAL 1
MONTH ) )

ขอแสดงความนับถือ - saqib


คุณได้พยายามเรียกใช้แบบสอบถามนั้นแล้วหรือยัง? เท่าที่ฉันเห็นมันจะไม่เลือกวันที่ทั้งหมดจากเดือนก่อนหน้า (เช่นใน: ส่งคืนข้อมูลตั้งแต่เดือนมกราคมตลอดทั้งเดือนกุมภาพันธ์) แต่ส่งคืนข้อมูลจากช่วงที่เริ่มต้นในวันเดียวกันเมื่อหนึ่งเดือนที่แล้ว
Nico Haase

0

ทางเลือกที่มีเงื่อนไขเดียว

SELECT * FROM table
WHERE YEAR(date_created) * 12 + MONTH(date_created)
    = YEAR(CURRENT_DATE) * 12 + MONTH(CURRENT_DATE) - 1

-1
SELECT *  FROM table  
WHERE  YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)

คุณได้พยายามเรียกใช้แบบสอบถามนั้นแล้วหรือยัง? เท่าที่ฉันเห็นมันจะไม่เลือกวันที่ทั้งหมดจากเดือนก่อนหน้า (เช่นใน: ส่งคืนข้อมูลตั้งแต่เดือนมกราคมตลอดทั้งเดือนกุมภาพันธ์) แต่ส่งคืนข้อมูลจากช่วงที่เริ่มต้นในวันเดียวกันเมื่อหนึ่งเดือนที่แล้ว
Nico Haase

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