2016-01-17 13 views
7

Tôi có 4 bảng.Giá trị tổng và đơn đặt hàng không tìm nạp đúng cách trong mysql

table_orders

order_id 
customer_id 
order_datetime 
order_payment_type 
order_delivery_date 
delivery_time_slot 

table_order_details

order_id 
product_id 
varient_id 
quantity 
product_mrp 
product_sell_price 
product_name 

table_order_status

order_id 
status_id 
status_datetime 

table_order_status_values ​​

value_id 
value_desc 

Tôi muốn nhận được id đơn đặt hàng, số tiền đặt hàng, ngày đặt hàng, số lượng đặt hàng, thời gian đặt hàng, giá trị_desc.

Tôi đang chạy truy vấn này.

SELECT oo.order_id, oo.amount, oo.date, oo.quantity, oo.time, value_desc 
FROM 
(
    SELECT s.order_id, SUM(OD.product_sell_price * OD.quantity) as amount, 
     DATE_FORMAT(o.order_datetime, '%d/%m/%Y') as date, SUM(OD.quantity) 
     as quantity, TIME(o.order_datetime) as time, MAX(status_id) as laststatus 
    FROM table_orders o 
    INNER JOIN table_order_details AS OD ON o.order_id = OD.order_id 
    INNER JOIN table_order_status s ON s.order_id = o.order_id 
    GROUP BY o.order_id 
)oo 

INNER JOIN table_order_status_values ON value_id = laststatus 

order by order_id DESC 

mẫu dữ liệu:

Table_orders

1 1 2015:12:12:19:42:47 1 2015:12:14 1 

table_order_details

1 12 3 1 21.00 20.00 abcd 
1 13 2 2 100.00 90.00 efgh 

table_order_status

1 1 2015:12:12:19:42:47 
1 2 2015:12:12:20:42:47 

table_order_status_values ​​

1 NEW ORDER 
2 CONFIRM 
3 Delivered 

Với đầu ra truy vấn trên là:

1 400.00 12:12:2015 6 19:42:47 CONFIRM 

Nhưng dự kiến ​​sản lượng là:

1 200.00 12:12:2015 3 19:42:47 CONFIRM 

Tôi nhận được số tiền đặt hàng và giá trị khối lượng đặt hàng gấp đôi (hoặc ba lần) dựa trên số trạng thái cho thứ tự đã cho.

Cách sửa lỗi này? Bất kỳ trợ giúp sẽ được đánh giá cao.

+0

bạn có thể chỉ cho một đầu ra ví dụ? Nó có thể được gây ra bởi sự tham gia vào 'table_order_status'. Có lẽ bạn chỉ cần để có được tình trạng mới nhất, không phải tất cả các giá trị trung gian –

+0

@ AlexTartan, tôi đã nhận được quan điểm của bạn. Nhưng tôi đang sử dụng MAX (status_id) để có được trạng thái cuối cùng cho thứ tự đó. –

+0

Mặc dù không đúng, bạn * có thể * sử dụng 'CHỌN khác biệt oo.order_id ...'. Hoặc cố gắng tham gia vào một subselect của 'table_order_status' đã được nhóm lại theo order_id, thay vì toàn bộ bảng. Nếu bạn quản lý để thiết lập một SQL Fiddle (http://sqlfiddle.com/) tôi có thể xem –

Trả lời

0

Bạn nên tập trung lựa chọn đầu tiên vào việc nhận tất cả thông tin đơn đặt hàng ngoại trừ trạng thái đó và sau đó tham gia vào thông tin trạng thái.

Đó có thể trông như thế này:

SELECT 
    order_with_status.order_id AS order_id, 
    order_with_status.amount AS amount, 
    order_with_status.`date` AS `date`, 
    order_with_status.quantity AS quantity, 
    order_with_status.`time` AS `time`, 
    tosv.value_description AS current_status  
FROM (
    /* Add maximum order status value to result set */ 
    SELECT 
     order.order_id AS order_id, 
     order.amount AS amount, 
     order.`date` AS `date`, 
     order.quantity AS quantity, 
     order.`time` AS `time`, 
     MAX(tos.status) AS current_status_id 
    FROM (
     /* Get rolled-up order information as start to result set */ 
     SELECT 
      o.order_id AS order_id, 
      SUM(od.product_sell_price * od.quantity) AS amount, 
      DATE_FORMAT(o.order_datetime, '%d/%m/%Y') AS `date`, 
      SUM(od.quantity) AS `quantity`, 
      TIME(o.order_datetime) AS `time` 
     FROM table_orders AS o 
     INNER JOIN table_order_details AS od 
      ON o.order_id = od.order_id 
     GROUP BY o.order_id 
    ) as order 
    INNER JOIN table_order_status AS tos 
     ON order.order_id = tos.order_id 
) as order_with_status 
INNER JOIN table_order_status_values AS tosv 
    ON order_with_status.current_status_id = tosv.value_id 

ORDER BY order_with_status.order_id DESC 

Lưu ý rằng giản đồ của bạn tự nó làm cho điều này một câu hỏi rất phức tạp, điều đó sẽ không có khả năng thực hiện rất tốt nếu bạn cần làm truy vấn này thường xuyên trong hệ thống của bạn. Nếu bạn đã thực hiện thay đổi đơn giản để di chuyển trường id trạng thái đơn đặt hàng vào bảng thứ tự, bạn có thể đơn giản hóa điều này rất nhiều (xuống hạng bảng table_order_status của bạn để chỉ đơn giản là lịch sử kiểm tra các thay đổi trạng thái không được sử dụng trong loại truy vấn này). Điều này làm cho ý nghĩa hợp lý trong đó có vẻ không phải là một nhu cầu để làm việc với lịch sử thay đổi của một đơn đặt hàng khi cố gắng chỉ đơn giản là có được dữ liệu đặt hàng hiện tại.

Trong trường hợp này các truy vấn có thể đơn giản như

SELECT 
    o.order_id AS order_id, 
    tosv.value_description AS current_status, 
    SUM(od.product_sell_price * od.quantity) AS amount, 
    DATE_FORMAT(o.order_datetime, '%d/%m/%Y') AS `date`, 
    SUM(od.quantity) AS quantity, 
    TIME(o.order_datetime) AS `time` 
FROM table_orders AS o 
INNER JOIN table_order_status_values AS tosv 
    ON o.order_status_id = tosv.value_id 
INNER JOIN table_order_details AS od 
    ON o.order_id = od.order_id 
GROUP BY o.order_id 
ORDER BY o.order_id DESC 

Bạn có thể đơn giản hóa này hơn nữa nếu bạn muốn đưa mô tả trạng thái trong bảng thứ tự như trái ngược với id (điều này sẽ loại bỏ một bảng thêm tham gia để có được mô tả).

Bây giờ liệu việc khử chuẩn hóa rõ ràng này có ý nghĩa cho ứng dụng của bạn phần lớn sẽ được xác định bởi các trường hợp sử dụng với ứng dụng hay không. Ví dụ: nếu bạn không truy cập vào dữ liệu kiểm toán nhiều hoặc chỉ cần trình bày dữ liệu này trong ngữ cảnh của một đơn hàng, điều này có thể có ý nghĩa.

2

Bạn vấn đề là trong phần này:

SELECT s.order_id, SUM(OD.product_sell_price * OD.quantity) as amount, 
     DATE_FORMAT(o.order_datetime, '%d/%m/%Y') as date, SUM(OD.quantity) 
     as quantity, TIME(o.order_datetime) as time, MAX(status_id) as laststatus 
    FROM table_orders o 
    INNER JOIN table_order_details AS OD ON o.order_id = OD.order_id 
    INNER JOIN table_order_status s ON s.order_id = o.order_id 
    GROUP BY o.order_id 

Tổng không trả về giá trị hiện tại vì nó được nhân với mỗi tham gia.

Bạn có thể giải quyết vấn đề này bằng cách chọn thay vì chỉ sử dụng các cột.

(SELECT SUM(OD.product_sell_price * OD.quantity) FROM table_order_details as OD WHERE OD.order_id=o.order_id) as amount 

Và đối với việc sử dụng số lượng:

(SELECT SUM(OD.quantity) FROM table_order_details as OD WHERE OD.order_id=s.order_id) as quantity, 

Vì vậy, các truy vấn cuối cùng sẽ là:

SELECT oo.order_id, oo.amount, oo.date, oo.quantity, oo.time, value_desc 
FROM 
(
     SELECT 
     s.order_id, 
     (SELECT SUM(OD.product_sell_price * OD.quantity) FROM table_order_details as OD WHERE OD.order_id=s.order_id) as amount, 
     DATE_FORMAT(o.order_datetime, '%d/%m/%Y') as date, 
     (SELECT SUM(OD.quantity) FROM table_order_details as OD WHERE OD.order_id=s.order_id) as quantity, 
     TIME(o.order_datetime) as time, MAX(status_id) as laststatus 
    FROM table_orders o 
    INNER JOIN table_order_status s ON s.order_id = o.order_id 
    GROUP BY o.order_id 
)oo 

INNER JOIN table_order_status_values ON value_id = laststatus 

order by order_id DESC 

Và nó sẽ ra:

1 200 12/12/2015 3 19:42:47 CONFIRIM 

chỉnh sửa - Tôi có cũng loại bỏ các

INNER JOIN table_order_details AS OD ON o.order_id = OD.order_id 

Không cần phải cho nó được tham gia vào truy vấn này

2

Thứ nhất SQL của bạn là không hợp lệ, MySQL bỏ qua invlaid SQL này nhưng kết quả sẽ không được những gì bạn mong đợi.

SELECT o.order_id, 
    oo.amt, 
    DATE_FORMAT(o.order_datetime, '%d/%m/%Y') date, 
    oo.qty, 
    TIME(o.order_datetime) time, 
    osv.value_desc 
FROM table_orders o, table_order_status_values osv, (
    SELECT order_id, sum(quantity) qty, sum(product_sell_price*quantity) amt 
    FROM table_order_details 
    GROUP BY 1 
) AS oo, (
    SELECT order_id, max(status_id) last_status 
    FROM table_order_status 
    GROUP BY 1 
) AS os 
WHERE o.order_id = os.order_id AND os.last_status = osv.status_id 
AND o.order_id = oo.order_id 
0

Tiểu truy vấn mà bạn đã sử dụng mà không cần nhóm bằng và sum/max:

SELECT s.order_id, OD.product_sell_price * OD.quantity as amount, 
     DATE_FORMAT(o.order_datetime, '%d/%m/%Y') as date, OD.quantity 
     as quantity, TIME(o.order_datetime) as time, status_id as laststatus 
    FROM table_orders o 
    INNER JOIN table_order_details AS OD ON o.order_id = OD.order_id 
    INNER JOIN table_order_status s ON s.order_id = o.order_id 

sẽ có kết quả:

1 20*1 2015:12:12 1 19:42:47 1 
1 20*1 2015:12:12 1 19:42:47 2 
1 90*2 2015:12:12 2 19:42:47 1 
1 90*2 2015:12:12 2 19:42:47 2 

Bằng cách thêm SUM/MAX và nhóm của nó cung cấp kết quả bạn đã đưa ra trong câu hỏi:

1 400.00 12:12:2015 6 19:42:47 2 

Đó là chính xác theo truy vấn bạn đã viết. Giải pháp là bạn sẽ nhận được MAX (status_id) riêng biệt. Vì vậy, sử dụng các truy vấn sau đây:

SELECT oo.order_id, oo.amount, oo.date, oo.quantity, oo.time, value_desc 
FROM 
(
    SELECT s.order_id, SUM(OD.product_sell_price * OD.quantity) as amount, 
     DATE_FORMAT(o.order_datetime, '%d/%m/%Y') as date, SUM(OD.quantity) 
     as quantity, TIME(o.order_datetime) as time, MAX(select MAX(status_id) from table_order_status ts where ts.order_id = o.order_id group by ts.order_id) as laststatus 
    FROM table_orders o 
    INNER JOIN table_order_details AS OD ON o.order_id = OD.order_id 
    GROUP BY o.order_id 
)oo 

INNER JOIN table_order_status_values ON value_id = laststatus 

order by order_id DESC 

Nó sẽ sử dụng các hàng:

1 20*1 2015:12:12 1 19:42:47 2 
1 90*2 2015:12:12 2 19:42:47 2 

Giving sản lượng dự kiến:

1 200 2015:12:12 319:42:47 2 
Các vấn đề liên quan