2016-01-17 19 views
7

4 tablo var.Sipariş toplamı ve sipariş değeri mysql içinde doğru bir şekilde getirilemiyor.

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 

Sipariş numarası, sipariş miktarı, sipariş tarihi, sipariş miktarı, sipariş zamanı, value_desc almak istiyorum.

Bu sorguyu çalıştırıyorum.

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 

örnek veri:

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 ​​

Yukarıdaki sorgu çıkışı sayesinde
1 NEW ORDER 
2 CONFIRM 
3 Delivered 

geçerli:

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

Ama beklenen çıkışı: Ben iki kez (veya üç kez) sipariş miktarı ve sipariş miktarı değerleri alıyorum

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

verilen siparişin durumuna göre.

Bu nasıl düzeltilir? Herhangi bir yardım çok takdir edilecektir.

+0

bir örnek çıkışını gösterir misin? 'Table_order_status' üzerindeki birleşimden kaynaklanması muhtemel. Belki de sadece en son durumu almanız gerekiyor, tüm ara değerler –

+0

@AlexTartan değil, sizin puanınızı aldım. Ama bu sipariş için son durumu almak için MAX (status_id) kullanıyorum. –

+0

Doğru olmasa da, * SELECT farklı oo.order_id ... 'işlevini kullanabilirsiniz. Ya da tüm tablo yerine, order_id tarafından gruplandırılmış olan 'table_order_status' alt grubunun üzerine katılmayı deneyin. Eğer bir SQL Fiddle (http://sqlfiddle.com/) kurmayı başarabilirseniz bir göz atabilirim –

cevap

0

İlk alt seçime, bu durum dışındaki tüm sipariş bilgilerini aldığınızda odaklanmalı ve ardından durum bilgisine katılmalısınız. şema kendisi bu sisteminizde düzenli olarak bu sorguyu yapmanız gerekiyorsa muhtemelen çok iyi performans olmaz çok karmaşık bir sorgu yapar

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 

Not: Bu gibi görünebilir

. Bir sipariş durumu kimliği alanını sipariş tablosuna taşımak için basit bir değişiklik yaptıysanız, bunu büyük ölçüde basitleştirebilirsiniz (table_order_status tablonuzun yalnızca bu tür sorgularda kullanılmayan durum değişiklikleriyle ilgili bir denetim geçmişine dönüştürülmesi için). Bu, mantıklı bir mantıkla, mevcut sipariş verisini almayı denerken bir siparişin değişim tarihi ile çalışmaya ihtiyaç duyulmadığı görünmektedir.

Bu durumda sorgu olabileceği kadar basit

olarak
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 
Eğer id aksine sipariş tablosundaki durum açıklamasına koymak istiyorsa Ayrıca bu tarama basitleştirmek olabilir

(bu fazladan tablo ortadan kaldıracak açıklamayı almak için katılın). Bu belirgin de-normalizasyonun uygulamanız için anlamlı olup olmadığı, büyük ölçüde uygulama ile kullanım durumları tarafından belirlenirdi. Örneğin, denetim verilerine çok fazla erişemiyorsanız veya yalnızca bu verileri tek bir sipariş bağlamında sunmanız gerekiyorsa, bu mantıklı olabilir.

2

Sorun bu bölümünde geçerli:

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 

toplamı o katılmak her biri ile çarpılır olsun çünkü şimdiki değerini döndürür etmez.

Bunu, yalnızca sütunları kullanmak yerine bir seçimle elde edebilirsiniz.

Ve miktar kullanılmak üzere

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

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

Yani nihai sorgu olacaktır:

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

düzenlemek -:

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 

Ve çıktısı Sahibim senin SQL geçerli değil

2

Öncelikle bu sorguda birleştirilmeye için de

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

gerek yok kaldırıldı, MySQL bu invlaid SQL görmezden ama sonuç beklediğiniz olmayacaktır.

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

sen tarafından ve toplamı/maks grubunun olmadan kullanmış alt sorgusu: onun tarafından SUM/MAX ve grup ekleyerek

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 

:

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 

sonuçlanan olurdu soruda verdiğiniz çıktıyı verir:

Yazdığınız sorguya göre doğru olanı. Çözüm, MAX (status_id) ayrı ayrı almanız gerektiğidir. Yani aşağıdaki sorguyu kullanın:

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 

Bu satırları kullanacağız:

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

beklenen çıkışı verilmesi:

1 200 2015:12:12 319:42:47 2