2009-07-03 50 views
44

Tôi có bảng mysql có dữ liệu được kết nối với ngày. Mỗi hàng có dữ liệu và ngày, như sau:Mysql: Chọn tất cả dữ liệu giữa hai ngày

2009-06-25 75 
2009-07-01 100 
2009-07-02 120 

Tôi có truy vấn mysql chọn tất cả dữ liệu giữa hai ngày. Đây là truy vấn:

SELECT data FROM tbl WHERE date BETWEEN date1 AND date2

Vấn đề của tôi là tôi cũng cần phải nhận được hàng giữa date1 và date2 thậm chí nếu không có dữ liệu cho một ngày.

Vì vậy, truy vấn của tôi sẽ bỏ lỡ những ngày trống trong khoảng thời gian từ 2009-06-25 đến 2009-07-01.

Tôi có thể theo cách nào đó thêm những ngày này chỉ với 0 dưới dạng dữ liệu không?

Trả lời

4

Bạn có bảng có tất cả các ngày không? Nếu không, bạn có thể muốn xem xét việc triển khai bảng lịch và để lại việc kết hợp dữ liệu của bạn vào bảng lịch.

38

Bạn có thể sử dụng khái niệm thường được gọi là 'bảng lịch'. Here là một hướng dẫn tốt về cách tạo bảng lịch trong MySql:

-- create some infrastructure 
CREATE TABLE ints (i INTEGER); 
INSERT INTO ints VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9); 

-- only works for 100 days, add more ints joins for more 
SELECT cal.date, tbl.data 
FROM (
    SELECT '2009-06-25' + INTERVAL a.i * 10 + b.i DAY as date 
    FROM ints a JOIN ints b 
    ORDER BY a.i * 10 + b.i 
) cal LEFT JOIN tbl ON cal.date = tbl.date 
WHERE cal.date BETWEEN '2009-06-25' AND '2009-07-01'; 

Bạn có thể muốn tạo bảng cal thay vì subselect.

+0

Josef: tôi nghĩ rằng bạn có nghĩa là http://www.artfulsoftware.com/infotree/queries.php?&bw=1504#95 – feihtthief

+4

các url hoàn toàn giống nhau, phải không? –

12
Select * from emp where joindate between date1 and date2; 

Nhưng truy vấn này không hiển thị dữ liệu thích hợp.

Ví dụ

1-jan-2013 to 12-jan-2013. 

Nhưng nó cho thấy dữ liệu

1-jan-2013 to 11-jan-2013. 
+2

Tôi đã sử dụng điều này và điều này là chính xác vì các trường ngày của tôi có loại DATETIME, vì vậy hãy đặt giá trị (cho dữ liệu trong một ngày) như sau: 'BETWEEN '2013-10-12 00:00:00' và '2013-10 -12 23: 59: 59'' đã hoạt động! Cảm ơn ngài. – arrayown

+1

@gulab, Bạn có thể sử dụng 'SELECT * FROM emp WHERE DATE (joindate) GIỮA date1 AND date2;' – shweta

10

nó rất dễ dàng để xử lý tình trạng này

Bạn có thể sử dụng GIỮA KHOẢN kết hợp với date_sub (now() , INTERVAL 30 NGÀY) VÀ NGAY BÂY GIỜ()

SELECT 
    sc_cust_design.design_id as id, 
    sc_cust_design.main_image, 
    FROM 
    sc_cust_design 
WHERE 
    sc_cust_design.publish = 1 
    AND **`datein`BETWEEN date_sub(now() , INTERVAL 30 DAY) AND NOW()** 

Chúc mừng Mã hóa :)

1

NẾU BẠN có thể tránh nó .. KHÔNG DO IT

Cơ sở dữ liệu không thực sự được thiết kế cho điều này, bạn đang có hiệu quả cố gắng để tạo ra dữ liệu (mặc dù một danh sách các ngày) trong một truy vấn.

Đối với bất kỳ ai có lớp ứng dụng phía trên truy vấn DB, giải pháp đơn giản nhất là điền dữ liệu trống vào đó.

Bạn sẽ nhiều hơn khả năng được lặp thông qua kết quả truy vấn nào và có thể thực hiện một cái gì đó như thế này:

loop_date = start_date 

while (loop_date <= end_date){ 

    if(loop_date in db_data) { 
    output db_data for loop_date 
    } 
    else { 
    output default_data for loop_date 
    } 

    loop_date = loop_date + 1 day 
} 

Những lợi ích của việc này được giảm truyền dữ liệu; truy vấn gỡ lỗi đơn giản, dễ dàng hơn; và không phải lo lắng quá mức của bảng lịch.

1

bạn phải thêm 1 ngày để ngày kết thúc, sử dụng: DATE_ADD('$end_date', INTERVAL 1 DAY)

Các vấn đề liên quan