2010-07-23 7 views
0

J'ai une table de Bill comme celui-cimatrice/crosstab/requête de pivot dans mySQL

BillNo - 1, ServiceCode -1, NomService - 'test Lab', ItemAmount -30

BillNo -1, ServiceCode - 2, NomService -'Consultation », ItemAmount -70

je besoin d'une sortie comme ceci

projet de loi n -1, total Montant du projet de loi-100, test-30 Lab, Consultation-70, la drogue-0, Misc- 0

Donc, fondamentalement, j'ai besoin du montant de la facture qui est la somme de tous les ItemAmount groupés par BillNo. Ensuite, dans la même rangée, j'ai besoin de distribuer ce montant de la facture aux 4 ServiceNames. Donc 100 se répartit en 30 pour le test en laboratoire et 70 pour la consultation.

Cela m'a donné ce que je veux mais ce n'est pas optimal.

SELECT 
    BD.BILLNO AS BN, 
    SUM(BD.ITEMAMOUNT) AS "Bill Amount", 
    (SELECT SUM(BD.ITEMAMOUNT) FROM BILLDETAILS BD 
     WHERE SERVICENAME LIKE '%Lab%' 
     AND BD.BILLNO = BN) AS "Lab", 
    (SELECT SUM(BD.ITEMAMOUNT) FROM BILLDETAILS BD 
     WHERE SERVICENAME LIKE '%Consult%' 
     AND BD.BILLNO = BN) AS "Consultation", 
    (SELECT SUM(BD.ITEMAMOUNT) FROM BILLDETAILS BD 
     WHERE SERVICENAME LIKE '%Procedure%' 
     AND BD.BILLNO = BN) AS "Procedures", 
    (SELECT SUM(BD.ITEMAMOUNT) FROM BILLDETAILS BD 
     WHERE SERVICENAME LIKE '%Drugs%' 
     AND BD.BILLNO = BN) AS "Drugs", 
    (SELECT SUM(BD.ITEMAMOUNT) FROM BILLDETAILS BD 
     WHERE SERVICENAME NOT LIKE '%Lab%' 
     AND SERVICENAME NOT LIKE 'Consult%' 
     AND SERVICENAME NOT LIKE '%Procedure%' 
     AND SERVICENAME NOT LIKE '%Drugs%' 
     AND BD.BILLNO = BN)AS "Miscellaneous" 
FROM BILLDETAILS BD 
GROUP BY BD.BILLNO 

Comment puis-je améliorer cette requête mySQL?

Merci. Chak.

Répondre

1

Essayez ceci:

SELECT 
    BillNo, 
    LabTest, 
    Consultation, 
    Drugs, 
    Misc, 
    LabTest + Consultation + Drugs + Misc AS BillAmount 
FROM (
    SELECT 
    BillNo, 
    IFNULL(GROUP_CONCAT(IF(ServiceCode=1, ItemAmount, NULL)), 0) AS LabTest, 
    IFNULL(GROUP_CONCAT(IF(ServiceCode=2, ItemAmount, NULL)), 0) AS Consultation, 
    IFNULL(GROUP_CONCAT(IF(ServiceCode=3, ItemAmount, NULL)), 0) AS Drugs, 
    IFNULL(GROUP_CONCAT(IF(ServiceCode=4, ItemAmount, NULL)), 0) AS Misc 
    FROM bill 
    GROUP BY BillNo 
) AS services; 

Je l'ai testé ServiceCode plutôt que ServiceName, comme je l'ai supposé que les deux sont liés. Si elles ne sont pas liées, modifiez simplement la comparaison si nécessaire.

données de test:

INSERT INTO bill (BillNo, ServiceCode, ServiceName, ItemAmount) VALUES 
(1, 1, 'Lab Test', 30), 
(1, 2, 'Consultation', 70), 
(2, 1, 'Lab Test', 40), 
(2, 2, 'Consultation', 20), 
(2, 3, 'Drugs', 15), 
(2, 4, 'Misc', 25); 

Résultats:

+--------+---------+--------------+-------+------+------------+ 
| BillNo | LabTest | Consultation | Drugs | Misc | BillAmount | 
+--------+---------+--------------+-------+------+------------+ 
|  1 | 30  | 70   | 0  | 0 |  100 | 
|  2 | 40  | 20   | 15 | 25 |  100 | 
+--------+---------+--------------+-------+------+------------+ 
0

Vous pouvez essayer cela, bien que je havnt essai it-

SELECT BillNo,count(ItemAmount) as "Total Bill Amount", 
(CASE ServiceName WHEN 'Lab test' THEN count(ServiceName) as "Lab Test" 
WHEN 'Consultation' THEN count(ServiceName) as Consultation 
WHEN 'Drugs' THEN count(ServiceName) as Drugs 
ELSE count(ServiceName) as Misc END CASE) 
from Bill group by BillNo; 
+0

Je suppose que je besoin de quelque chose comme une requête pour un rapport de vieillissement - si elle est comprise entre 30 et 60 jours, il vient dans la colonne de 60 jours etc. – Chakra

+0

'entre 30 et 60 puis" 60 jours "' en tant que nom_colonne' – Sadat