views:

55

answers:

4

Hey all,

I am using this query using UNION, where both fields that contains the amount are combined into one table, and i wanted to split them into 2 fields, first for cash and other for cheque

SELECT exp_cat.cat_name, SUM(exp_cheque.exp_amount) AS Cheque
FROM exp_cat INNER JOIN exp_cheque ON exp_cat.ID = exp_cheque.exp_cat_id
GROUP BY exp_cat.cat_name;
UNION
 SELECT exp_cat.cat_name, SUM(exp_cash.exp_amount) As Cash
FROM exp_cat INNER JOIN exp_cash ON exp_cat.ID = exp_cash.exp_cat_id
GROUP BY exp_cat.cat_name;

Please use this link to understand the each table structure http://stackoverflow.com/questions/3260980/how-to-combine-2-different-table

A: 

I'm not sure I understand what you mean but if you want to have the results in different columns this might work:

SELECT exp_cat.cat_name, SUM(exp_cheque.exp_amount) AS Cheque, null as Cash
FROM exp_cat INNER JOIN exp_cheque ON exp_cat.ID = exp_cheque.exp_cat_id
GROUP BY exp_cat.cat_name;
UNION
SELECT exp_cat.cat_name, null as Checque, SUM(exp_cash.exp_amount) As Cash
FROM exp_cat INNER JOIN exp_cash ON exp_cat.ID = exp_cash.exp_cat_id
GROUP BY exp_cat.cat_name;
edosoft
+1  A: 
Select cat_name, sum(cash), sum(cheque) from

(SELECT exp_cat.cat_name, SUM(exp_cheque.exp_amount) AS Cheque,null as cash
FROM exp_cat INNER JOIN exp_cheque ON exp_cat.ID = exp_cheque.exp_cat_id;
UNION
 SELECT exp_cat.cat_name, SUM(exp_cash.exp_amount) As Cash, null as cheque
FROM exp_cat INNER JOIN exp_cash ON exp_cat.ID = exp_cash.exp_cat_id;) 
group by cat_name

Not in front of an IDE right now so I may have a syntax error in there but that is the general idea.

  1. Add stub value for cash to the base query returning cheque, and stub value for cheque to the base query returning cash.
  2. Add outer query that sums cash and cheque and groups by cat_name.
  3. (optional) Can also remove the grouping from the base queries since this will be getting done in the outer query, but it should return the same whether you do this or not.
kekekela
+1  A: 
Select exp_cat.cat_name
    , (Select Sum(c1.exp_amount)
        From exp_cheque As c1
            Inner Join exp_cat As c2
                On c2.Id = c1.exp_cat_id
        Where c2.cat_name = exp_cat.cat_name) As cheque
    , (Select Sum(c1.exp_amount)
        From exp_cash As c1
            Inner Join exp_cat As c2
                On c2.Id = c1.exp_cat_id
        Where c2.cat_name = exp_cat.cat_name) As cash
From exp_cat
Where exp_cat.cat_name Is Not Null
Group By exp_cat.cat_name

If there is a unique constraint on exp_cat.cat_name, then you can eliminate the Group By clause.

Given that this is Access, it may be more efficient in the long run to create two stored queries for cash and cheque grouped by exp_cat.cat_name. Then you could write something like:

Select exp_cat.cat_name
    , Sum( cheque.Total ) As chequeTotal
    , Sum( cash.Total ) As cashTotal
    , Sum( cheque.Total ) + Sum( cash.Total ) As ChequeAndCashTotal
From exp_cat
    Left Join chequeBycat_name As cheque
        On cheque.exp_cat.cat_name = exp_cat.cat_name
    Left Join cashBycat_name As cash
        On cash.exp_cat.cat_name = exp_cat.cat_name
Where exp_cat.cat_name Is Not Null
Group By exp_cat.cat_name

Each of the two queries would look like:

Select exp_cat.cat_name, Sum(exp_cheque.exp_amount) As Total
From exp_cat
    Inner Join exp_cheque
        On exp_cheque.exp_cat_id = exp_cat.Id
Where exp_cat.cat_name Is Not Null
Group By exp_cat.cat_name
Thomas
@Thomas you have done a great SQL command, but there is one little thing i wanted to ask you, there are some cat_name that are empty and they show up, how to disallow that to happen
Mahmoud
@Mahmoud - Simple enough. Just add a `Where exp_cat.cat_name Is Not Null` above the Group By clause.
Thomas
@Thomas it keep refusing the Where clause, Where i keep getting null Cat result
Mahmoud
@Mahmoud - I've edited my post to illustrate. With that additional Where clause, it isn't possible to get null `exp_cat.cat_name` values in the results. Instead, you might be seeing values that are empty strings. If that is the case, you could add (or replace) the Where clause to say `Len([exp_cat].[exp_name]) > 0`
Thomas
@Thomas Well i edit my WHERE clause and i keep getting the null strings
Mahmoud
@Mahmoud - Try `Len(Trim([exp_cat].[exp_name])) > 0`.
Thomas
@Thomas nope didn't work keeps on getting those empty strings
Mahmoud
@Mahmoud - This sounds like bad data. The values are not null and are not all spaces. They must contain something else like non-displayable characters. I would write a query just against `exp_cat` that shows me the ASCII value of each character. E.g. `Asc( Mid ( exp_cat.exp_name, 1, 1 ) ) As Char1, Asc( Mid ( exp_cat.exp_name, 2, 1 ) ) As Char2, Asc( Mid ( exp_cat.exp_name, 3, 1 ) ) As Char3...` out to the max length of any exp_name. If you see values like 9 (tab), 13 (carriage return), 10 (line feed) it means that those values only contain non-displayable characters and need to be fixed.
Thomas
A: 

If you want totals for cash and cheque returned on the same row for the same cat_name, try something like this:

SELECT cat_name, sum(Cheque), sum(Cash)
(SELECT exp_cat.cat_name, exp_cheque.exp_amount AS Cheque, 0 as cash,
 FROM exp_cat INNER JOIN exp_cheque ON exp_cat.ID = exp_cheque.exp_cat_id
 UNION ALL
 SELECT exp_cat.cat_name, 0 as Cheque, exp_cash.exp_amount As Cash
 FROM exp_cat INNER JOIN exp_cash ON exp_cat.ID = exp_cash.exp_cat_id) sq
GROUP BY cat_name;
Mark Bannister