I have two tables which represent bills.
List of bills and content of bills each with his relevant data which should be logically "connected" to get proper result. Example table column names are pretty self descriptive.
DROP TABLE IF EXISTS my_list;
CREATE TABLE my_list (indexl int PRIMARY KEY, docnum int, mytime text, rebate double precision, status text);
INSERT INTO my_list
(indexl, docnum, mytime, rebate, status) VALUES
(10, 5, '01.01.2014 15:20:31', 0, ''),
(11, 6, '02.01.2014 11:10:11', 10, ''),
(12, 7, '02.01.2014 09:15:01', 0, ''),
(14, 8, '03.01.2014 12:12:49', 12, ''),
(17, 9, '04.01.2014 08:19:19', 10, ''),
(18, 10, '04.01.2014 10:10:10', 0, 'S'),
(19, 11, '04.01.2014 01:04:14', 0, 'B'),
(21, 12, '05.01.2014 02:49:14', 0, ''),
(22, 13, '12.01.2014 08:12:17', 0, '');
DROP TABLE IF EXISTS my_content;
CREATE TABLE my_content (indexc int PRIMARY KEY, docnum int, code int,
aname text, price double precision, qty double precision, secondtax double precision, meas text);
INSERT INTO my_content
(indexc, docnum, code, aname, price, qty, secondtax, meas) VALUES
(10, 5, 587, 'spaghetti', 75, 1, 0, 'kg'),
(15, 6, 3432, 'salt', 3, 2, 0, 'kg'),
(16, 12, 32, 'olive oil', 4, 1.5, 5, 'kg'),
(29, 7, 3432, 'salt', 3, 1, 0, 'kg'),
(17, 6, 449, 'sugar', 5, 2, 0, 'kg'),
(18, 7, 1582, 'dried eggs', 50, 1.2, 0, 'kg'),
(19, 8, 210, 'tomato', 80, 5.5, 0, 'kg'),
(20, 9, 211, 'mustard', 5, 3, 5, 'kg'),
(22, 10, 2014, 'clove', 1, 1, 0, 'kg'),
(23, 9, 8, 'oil', 120, 4, 0, 'lit'),
(24, 11, 816, 'laurel', 4, 1, 0, 'kg'),
(25, 8, 1582, 'dried eggs', 10, 0.2, 0, 'kg'),
(26, 12, 32, 'olive oil', 4, 1, 0, 'kg'),
(28, 13, 67, 'corned beef', 40, 0.5, 0, 'kg');
For analyzing those bills I make a query which work almost good but It is sure it can be written better, shorter, more elegant and more proper.
SELECT s.code,
s.aname,
SUM( s.qty) AS sumused,
SUM( s.price * s.qty) AS bruttoprice,
SUM(( s.price/100 * l.rebate) * s.qty) AS sumrebate,
SUM((s.price - s.price/100 * l.rebate) * s.qty) AS clearprice,
SUM((s.price - s.price/100 * l.rebate) * s.qty/100 * s.secondtax) AS sumsecondtax,
SUM((s.price - s.price/100 * l.rebate) * s.qty - (s.price - s.price/100 * l.rebate) * s.qty/100 * s.secondtax) AS sumwithoutsecondtax
FROM my_content s, my_list l
WHERE s.docnum = l.docnum
AND NOT l.status='S'
AND l.mytime BETWEEN '02.01.2014 00:00:00' AND '05.01.2014 23:59:59'
GROUP BY s.code, s.aname, l.status
ORDER BY sumused
1) Is it possible to replace expression in query '(s.price/100 * l.rebate) * s.qty' with variable so it haven't to be written all the time? Ideal will be if I can write for example SUM(clearprice * s.secondtax)
2) In case when bill have satus 'S' in list his rows in content have to be skipped what is solved with condition AND NOT l.status='S'. But if status is 'B' that mean that values which have that docnum have to be subtracted (not added) to SUM. Maybe more elegant solution will be to multiply quantity in such rows with value 0-qty.
In showed query status 'B' is ignored because I don't know how to apply it.
How to do that?
3) I would actually need to group result only by s.code but I cannot remove s.aname and l.status from GROUP BY because then query don't want to work. In actual situation if I change name for certain code it will be shown separately what is not wanted.
Is it possible to get result grouped only by code but that s.aname (say last one) will be shown in result?
I do all I can for creating example tables and query on easy/instant way.
Please help on concrete question with advice or/and example.
Thanks.
EDIT I solved my query by help of 'kordirko'...
SELECT code,
MAX(aname) AS aname,
SUM(newqty) AS sumused,
SUM(price * newqty) AS bruttoprice,
SUM(crebate * newqty) AS sumrebate,
SUM(cprice * newqty) AS clearprice,
SUM(cprice * newqty/100 * secondtax) AS sumsecondtax,
SUM(cprice * newqty - cprice * newqty/100 * secondtax) AS sumwithoutsecondtax
FROM (
SELECT s.*, l.*,
s.price/100 * l.rebate AS crebate,
s.price - s.price/100 * l.rebate AS cprice,
CASE WHEN l.status = 'B' THEN 0 - s.qty ELSE s.qty END AS newqty
FROM my_content s, my_list l
WHERE s.docnum = l.docnum
AND NOT l.status='S'
AND l.mytime BETWEEN '02.01.2014 00:00:00' AND '05.01.2014 23:59:59'
) AS someAliasWhichhavetobehere
GROUP BY code
ORDER BY sumused;
Everything seem's OK only I have values -0 in result but I think that will not cause problems on further calculations. If will how can I get rid of that?