I have the following tables that records the details of letters vs actions, taken for them.
letter table
+-----------+-------------+
| letter_id | description |
+-----------+-------------+
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
+-----------+-------------+
action table
+-----------+--------+------------+---------------+
| action_id | ref_no | date | action_status |
+-----------+--------+------------+---------------+
| 1 | 1 | 2018-09-20 | On-Going |
| 2 | 1 | 2018-09-22 | Finished |
| 3 | 3 | 2018-09-16 | On-Going |
| 4 | 4 | 2018-09-26 | On-Going |
| 5 | 4 | 2018-09-27 | Finished |
+-----------+--------+------------+---------------+
And need to get the following output
+-----------+-------------+------------+---------------+
| letter_id | description | date | action_status |
+-----------+-------------+------------+---------------+
| 1 | A | 2018-09-22 | Finished |
| 2 | B | - | Pending |
| 3 | C | 2018-09-16 | On-Going |
| 4 | D | 2018-09-27 | Finished |
+-----------+-------------+------------+---------------+
I used the following query
select letter.letter_id,letter.description, action.date, action.action_status
from letter
left join action on letter.letter_id=action.ref_no
where (date in
(
select max(date) from action
where letter.letter_id=action.ref_no
))
But the above query generate the following output
+-----------+-------------+------------+---------------+
| letter_id | description | date | action_status |
+-----------+-------------+------------+---------------+
| 1 | A | 2018-09-20 | On-Going |
| 1 | A | 2018-09-22 | Finished |
| 2 | B | - | Pending |
| 3 | C | 2018-09-16 | On-Going |
| 4 | D | 2018-09-26 | On-Going |
| 4 | D | 2018-09-27 | Finished |
+-----------+-------------+------------+---------------+
I can not understand what I am going wrong. Can anyone help me ?
DROP TABLE IF EXISTS action;
CREATE TABLE action
(action_id SERIAL PRIMARY KEY
,letter_id INT NOT NULL
,date DATE NOT NULL
,action_status VARCHAR(20) NOT NULL
);
INSERT INTO action VALUES
(1,101,'2018-09-20','On-Going'),
(2,101,'2018-09-22','Finished'),
(3,103,'2018-09-16','On-Going'),
(4,104,'2018-09-26','On-Going'),
(5,104,'2018-09-27','Finished');
SELECT x.*
FROM action x
JOIN
( SELECT letter_id, MAX(date) max_date FROM action GROUP BY letter_id ) y
ON y.letter_id = x.letter_id
AND y.max_date = x.date;
+-----------+-----------+------------+---------------+
| action_id | letter_id | date | action_status |
+-----------+-----------+------------+---------------+
| 2 | 101 | 2018-09-22 | Finished |
| 3 | 103 | 2018-09-16 | On-Going |
| 5 | 104 | 2018-09-27 | Finished |
+-----------+-----------+------------+---------------+
Presumably, you can figure out the rest
Related
I have a MySQL database with vehicles, issued_fuel and mileage data (vs issued fuel) and want to get the following desired output.
Desired Output
I want to get results including above related data as follows :
+---------------+------------+------------+---------+----------+
| registered_no | issue_date | date | mileage | fuel_qty |
+---------------+------------+------------+---------+----------+
| SP KR-3503 | 2021-02-22 | null | null | 40 |
| SP KR-3503 | 2021-02-26 | null | null | 30 |
| null | 2021-03-03 | null | null | 40 |
| null | 2021-03-15 | null | null | 45 |
| SP KR-3503 | 2021-03-18 | null | null | 40 |
| null | 2021-03-25 | null | null | 45 |
| null | 2021-04-04 | null | null | 35 |
| SP KE-6794 | 2021-04-25 | 2021-04-25 | 150 | 40 |
+---------------+------------+------------+---------+----------+
Because the table "tbl_trip_details" includes only one mileage (150km) for vehicle_no "SP KE-6794 for the date 2021-04-25.
My tables as follows :
tbl_vehicle
+------------+---------------+--------+
| vehicle_id | registered_no | status |
+------------+---------------+--------+
| 1 | SP KR-3503 | 1 |
| 2 | SP KE-6794 | 1 |
+------------+---------------+--------+
tbl_trip_details
+---------+------------+------------+---------+--------+
| trip_id | vehicle_id | date | mileage | status |
+---------+------------+------------+---------+--------+
| 1 | 1 | 2021-04-25 | 125 | 1 |
| 2 | 1 | 2021-04-26 | 100 | 1 |
| 3 | 2 | 2021-04-25 | 150 | 1 |
+---------+------------+------------+---------+--------+
tbl_direct_fuel
+----------------+---------+------------+
| direct_fuel_id | vehicle | issue_date |
+----------------+---------+------------+
| 1 | 1 | 2021-02-22 |
| 2 | 1 | 2021-02-26 |
| 3 | 3 | 2021-03-03 |
| 4 | 3 | 2021-03-15 |
| 5 | 1 | 2021-03-18 |
| 6 | 3 | 2021-03-25 |
| 7 | 3 | 2021-04-04 |
| 8 | 2 | 2021-04-25 |
+----------------+---------+------------+
tbl_direct_fuel_details
+-----------------------------+----------------+------+----------+
| tbl_deirect_fuel_details_id | direct_fuel_id | item | fuel_qty |
+-----------------------------+----------------+------+----------+
| 1 | 1 | 1 | 40 |
| 2 | 2 | 1 | 30 |
| 3 | 3 | 1 | 40 |
| 4 | 4 | 1 | 45 |
| 5 | 5 | 1 | 40 |
| 6 | 6 | 1 | 45 |
| 7 | 7 | 1 | 35 |
| 8 | 8 | 1 | 40 |
+-----------------------------+----------------+------+----------+
I used the following query
select tv.registered_no, df.issue_date, td.date, td.mileage, df.fuel_qty
from tbl_trip_details trip
left join tbl_vehicle tv on tv.vehicle_id=trip.vehicle_id
join (select tbl_direct_fuel.direct_fuel_id, tbl_vehicle.registered_no, tbl_direct_fuel.vehicle, tbl_direct_fuel.issue_date, item, tbl_direct_fuel_details.fuel_qty, tbl_direct_fuel_details.fuel_price
from tbl_direct_fuel_details
left join tbl_direct_fuel on tbl_direct_fuel_details.direct_fuel_id = tbl_direct_fuel.direct_fuel_id
join tbl_vehicle on tbl_vehicle.vehicle_id = tbl_direct_fuel.vehicle
where tbl_direct_fuel.status=1
order by tbl_vehicle.registered_no
) AS df on df.vehicle = tv.vehicle_id
join (select tbl_trip_details.trip_id, tbl_vehicle.registered_no, tbl_trip_details.vehicle_id, tbl_trip_details.date, tbl_trip_details.mileage
from tbl_trip_details
left join tbl_vehicle on tbl_vehicle.vehicle_id = tbl_trip_details.vehicle_id
where tbl_trip_details.status=1
order by tbl_vehicle.registered_no) AS td on td.vehicle_id = tv.vehicle_id
Since the date & mileage are repeated for other records and didn't get the expected result. So the query outs the following output:
+---------------+------------+------------+---------+----------+
| registered_no | issue_date | date | mileage | fuel_qty |
+---------------+------------+------------+---------+----------+
| SP KR-3503 | 2021-02-22 | 2021-04-25 | 150 | 40 |
| SP KR-3503 | 2021-02-26 | 2021-04-25 | 150 | 30 |
| null | 2021-03-03 | 2021-04-25 | 150 | 40 |
| null | 2021-03-15 | 2021-04-25 | 150 | 45 |
| SP KR-3503 | 2021-03-18 | 2021-04-25 | 150 | 40 |
| null | 2021-03-25 | 2021-04-25 | 150 | 45 |
| null | 2021-04-04 | 2021-04-25 | 150 | 35 |
| SP KE-6794 | 2021-04-25 | 2021-04-25 | 150 | 40 |
+---------------+------------+------------+---------+----------+
What may be going wrong in my query ? Can anyone help ?
Try this query:
SELECT tv.registered_no, tdf.issue_date, ttd.date, ttd.mileage, tdfd.fuel_qty
FROM tbl_direct_fuel tdf
LEFT JOIN tbl_vehicle tv
ON tdf.vehicle=tv.vehicle_id
LEFT JOIN tbl_trip_details ttd
ON tdf.vehicle=ttd.vehicle_id
AND tdf.issue_date=ttd.date
LEFT JOIN tbl_direct_fuel_details tdfd
ON tdf.direct_fuel_id=tdfd.direct_fuel_id;
Demo fiddle
Rather than having two separate sub-queries, I try to directly get the result with a bunch of LEFT JOINs. From what I can see in the updated expected result, tbl_direct_fuel is enough to be the reference table for all the others. I's just a matter of figuring the correct ON condition.
Also, I mentioned about the missing tbl_direct_fuel.status and tbl_direct_fuel_details.fuel_price from the sample data. I'm not concerned about tbl_direct_fuel_details.fuel_price in particular because it wasn't included in the end SELECT result however, tbl_direct_fuel.status was being used in WHERE might have some impact. But after constructing the possible query, I assume that in this example, it's not required to include tbl_direct_fuel.status at all. Anyway, that's for you to figure out.
I need to check that the steps of each project were done between the start and end dates of the project. (Write a query that allows a human to know if this is the case)
This is my code:
SELECT e.idetape,
e.idprojet,
e.datedebut,
e.datefin
FROM (SELECT idprojet,
datedebut,
datefin
FROM projet) AS p
LEFT JOIN etapexprojet AS e
ON e.datedebut < p.datedebut
AND e.datefin < p.datefin
ORDER BY idprojet;
The table of EtapexProjet (There is other date inside the table EtapexProjet ):
+---------+----------+-------------+--------------+--+
| idEtape | idProjet | dateDebut | dateFin | |
+---------+----------+-------------+--------------+--+
| 1 | 1 | 2011-07-01 | 2011-09-01 | |
| 1 | 2 | 2012-05-01 | 2012-05-10 | |
| 1 | 3 | 2011-11-01 | 2012-01-20 | |
| 2 | 1 | | | |
| 2 | 2 | | | |
| 2 | 3 | | | |
| 3 | 1 | | | |
| 3 | 2 | | | |
| 3 | 3 | | | |
| 4 | 1 | | | |
| 4 | 2 | | | |
| 5 | 2 | | | |
+---------+----------+-------------+--------------+--+
The table of Projet:
+----------+----------+-----------+------------+------------+---------------+--+
| idProjet | idClient | nomProjet | dateDebut | dateFin | idResponsable | |
+----------+----------+-----------+------------+------------+---------------+--+
| 1 | 321 | Devl. | 2011-08-01 | | 1876 | |
| 2 | 321 | Maint. | 2012-05-01 | 2012-07-23 | 2231 | |
| 3 | 345 | Devl.2 | 2011-11-01 | | 2231 | |
+----------+----------+-----------+------------+------------+---------------+--+
My expected results is that to check/verify if the beginning and ending date of each idEtape is between the beginning date and the ending date of the projet its related.
You don't need to use a Derived Table (sub-select query), as you are not doing any sort of aggregation, etc on the projet table.
I believe that you are only concerned with the idetape values which lie inside the projet's datedebut and datefin.
You can change Left Join to Inner Join due to above mentioned point.
I have also increased the horizon of cases to check, as there is a possibility of datefin being NULL in either of the tables.
Try the following instead:
SELECT e.idetape,
e.idprojet,
e.datedebut,
e.datefin,
p.datedebut AS projet_datedebut,
p.datefin AS projet_datefin
FROM EtapexProjet AS e
JOIN Projet AS p
ON p.idprojet = e.idprojet
AND e.datedebut >= p.datedebut
AND (e.datefin <= p.datefin OR
p.datefin IS NULL OR
e.datefin IS NULL
)
ORDER BY e.idprojet,
e.idetape;
Please try the code below:
SELECT nomEtape, livrable, idEtape, idProjet
FROM Etape
WHERE idEtape= (SELECT MAX(idEtape)
FROM EtapexProjet
WHERE DISTINCT(idProjet)
);
I have two column with the same name in different tables.
I want to join them into one column in a view.
Here my first table stocks:
+----------+------------+------------+---------+----------------+--------+
| stock_id | stock_cost | stock_left | item_id | purchasedtl_id | trx_id |
+----------+------------+------------+---------+----------------+--------+
| 1 | 1000 | 0 | 1 | 1 | 1 |
| 2 | 1000 | 5 | 1 | 2 | 2 |
| 3 | 1000 | 1 | 1 | 3 | 4 |
+----------+------------+------------+---------+----------------+--------+
Second table stocks_out
+-------------+----------------+--------------+---------+----------+------------+--------+
| stockout_id | stockout_price | stockout_qty | item_id | stock_id | saledtl_id | trx_id |
+-------------+----------------+--------------+---------+----------+------------+--------+
| 1 | 2000 | 1 | 1 | 1 | 1 | 3 |
+-------------+----------------+--------------+---------+----------+------------+--------+
And I want to join them to be like this trx_id, trx_no, trx_closetime, trx_type stock_id, stock_cost, stockout_id, stock_out_cost, stockout_price, item_id
item_id is the field I want to join in one column.
The current Query is :
select `transactions`.`trx_id` AS `trx_id`,`transactions`.`trx_no` AS `trx_no`,`transactions`.`trx_closetime` AS `trx_closetime`,`transactions`.`trx_type` AS `trx_type`,`stocks`.`stock_id` AS `stock_id`,`stocks`.`stock_cost` AS `stock_cost`,`stock_out`.`stockout_id` AS `stockout_id`,`stock_out`.`stockout_price` AS `stockout_price` from ((`transactions` left join `stocks` on(`stocks`.`trx_id` = `transactions`.`trx_id`)) left join `stock_out` on(`stock_out`.`trx_id` = `transactions`.`trx_id`)) order by `transactions`.`trx_closetime`;
And the current result:
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+
| trx_id | trx_no | trx_closetime | trx_type | stock_id | stock_cost | stockout_id | stockout_price |
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+
| 1 | 02002-02-170415-001 | 2017-04-15 19:40:03 | 2 | 1 | 1000 | NULL | NULL |
| 2 | 02002-02-170415-002 | 2017-04-15 19:40:13 | 2 | 2 | 1000 | NULL | NULL |
| 3 | 02002-01-170415-001 | 2017-04-15 19:40:57 | 1 | NULL | NULL | 1 | 2000 |
| 4 | 02002-02-170415-003 | 2017-04-15 19:41:14 | 2 | 3 | 1000 | NULL | NULL |
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+
Found it guys.
I just need to add the following query as the column
COALESCE(`stocks`.`item_id`, `stocks_out`.`item_id`) AS `item_id`
So the query will be like
select `transactions`.`trx_id` AS `trx_id`,`transactions`.`trx_no` AS `trx_no`,`transactions`.`trx_closetime` AS `trx_closetime`,`transactions`.`trx_type` AS `trx_type`,`stocks`.`stock_id` AS `stock_id`,`stocks`.`stock_cost` AS `stock_cost`,`stock_out`.`stockout_id` AS `stockout_id`,`stock_out`.`stockout_price` AS `stockout_price`, COALESCE(`stocks`.`item_id`, `stocks_out`.`item_id`) AS `item_id from ((`transactions` left join `stocks` on(`stocks`.`trx_id` = `transactions`.`trx_id`)) left join `stock_out` on(`stock_out`.`trx_id` = `transactions`.`trx_id`)) order by `transactions`.`trx_closetime`;
And the result:
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+---------+
| trx_id | trx_no | trx_closetime | trx_type | stock_id | stock_cost | stockout_id | stockout_price | item_id |
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+---------+
| 1 | 02002-02-170415-001 | 2017-04-15 19:40:03 | 2 | 1 | 1000 | NULL | NULL | 1 |
| 2 | 02002-02-170415-002 | 2017-04-15 19:40:13 | 2 | 2 | 1000 | NULL | NULL | 1 |
| 3 | 02002-01-170415-001 | 2017-04-15 19:40:57 | 1 | NULL | NULL | 1 | 2000 | 1 |
| 4 | 02002-02-170415-003 | 2017-04-15 19:41:14 | 2 | 3 | 1000 | NULL | NULL | 1 |
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+---------+
I need to print Gross allocation, Cut Allocation & Net Allocation issued for various offices under relevant votes. I used the following tables.
1) Total issues (Gross Allocation) are in the Table, Named "issues_tot"
+---------+------+------------+
| v_code | oid | amount |
+---------+------+------------+
| 1 | 2 | 200,000.00 |
| 1 | 3 | 80,000.00 |
| 2 | 1 | 40,000.00 |
| 3 | 2 | 150,000.00 |
+---------+------+------------+
2) Cut amounts (Cut Allocation) are in the Table, Named "cp_tot"
+--------+-----+-----------+
| v_code | oid | amount |
+--------+-----+-----------+
| 1 | 2 | 68,000.00 |
| 1 | 3 | 50,000.00 |
| 3 | 2 | 75,000.00 |
+--------+-----+-----------+
3) Table, Named "vote"
+--------+-------------------------+
| v_code | vote |
+--------+-------------------------+
| 1 | 001-2-6-3-2502 |
| 2 | 001-1-4-21-2202 |
| 3 | 101-1-2-0-1405 |
+--------+-------------------------+
4) Table, Named "office"
+-----+----------------------+
| oid | office |
+-----+----------------------+
| 1 | Weeraketiya |
| 2 | Tissamaharama |
| 3 | District Sec |
+-----+----------------------+
And desired output as follows:
+--------+------------+-----------+------------+
| v_code | Gross | Cut | Net |
+--------+------------+-----------+------------+
| 1 | 200,000.00 | 68,000.00 | 132,000.00 |
| 1 | 80,000.00 | 50,000.00 | 30,000.00 |
| 2 | 40,000.00 | 0.00 | 40,000.00 |
| 3 | 150,000.00 | 75,000.00 | 75,000.00 |
+--------+------------+-----------+------------+
02) I used the following script to generate that output
select `vote`.`vote` AS `vote`,`office`.`office` AS `office`,
`issues_tot`.`amount` AS `Gross`,
coalesce(`cp_tot`.`amount`,0) AS `Cut`,
(`issues_tot`.`amount` - coalesce(`cp_tot`.`amount`,0)) AS `Net`
from (((`vote` join `issues_tot` on((`vote`.`v_code` = `issues_tot`.`v_code`))) join
`office` on((`office`.`oid` = `issues_tot`.`oid`))) left join
`cp_tot` on((`issues_tot`.`v_code` = `cp_tot`.`v_code`)))
But it generates the following output with repeated records:
+------------+----------------+--------------+-------------+--------------+
| Vote | Office | Gross | Cut | Net |
+---------------+-------------+--------------+-------------+--------------+
| 001-2-6-3-2502| Tissamaharama | 200,000.00 | 68,000.00 |132,000.00 |
| 001-2-6-3-2502| Tissamaharama | 200,000.00 | 50,000.00 | 150,000.00 |
| 001-2-6-3-2502| District Sec | 80,000.00 | 68,000.00 | 12,000.00 |
| 001-2-6-3-2502| District Sec | 80,000.00 | 50,000.00 | 30,000.00 |
| 001-1-4-21-2202| Weeraketiya | 40,000.00 | - | 40,000.00 |
| 101-1-2-0-1405 | Tissamaharama | 150,000.00 | 75,000.00 | 75,000.00 |
+------------+-----------------+--------------+-------------+--------------+
I can not understand what was going wrong. Can anyone help me?
Firstly, the following query will get what you want:
select
v.vote,
o.office,
it.amount as Gross,
coalesce(ct.amount , 0) as Cut,
it.amount - coalesce(ct.amount, 0) as Net
from issues_tot it
left join cp_tot ct
on it.v_code = ct.v_code
and it.oid = ct.oid
left join vote v
on it.v_code = v.v_code
left join office o
on it.oid = o.oid
order by it.v_code
and SQLFiddle Demo Here, the only issue is that you forget to match oid between issues_tot and cp_tot.
If there is no oid criteria, the match will do like following:
# issues_tot # cp_tot
| v_code | oid | amount | | v_code | oid | amount |
+---------+------+------------+ +--------+-----+-----------+
| 1 | 2 | 200,000.00 | -> | 1 | 2 | 68,000.00 |
| 1 | 3 | 50,000.00 |
| 1 | 3 | 80,000.00 | -> | 1 | 2 | 68,000.00 |
| 1 | 3 | 50,000.00 |
| 2 | 1 | 40,000.00 | -> no record match
| 3 | 2 | 150,000.00 | -> | 3 | 2 | 75,000.00 |
so 6 records by your query is it.
Maybe this will be an easy one for some of you MySQL masters who see this stuff like a level 3 children's book.
I have multiple tables that I'm joining to produce statistical data for a report and I'm getting tripped up at the moment trying to figure it out. It's obviously imperative the figures are correct because it impacts a number of decisions going forward.
Here's the lay of the land (not the full picture, but you'll get the point):
Affiliate Table
+----+-----------+------------+---------------------+
| id | firstname | lastname | created_date |
+----+-----------+------------+---------------------+
| 1 | Mike | Johnson | 2010-11-22 17:44:37 |
| 2 | Trevor | Wilson | 2010-12-23 16:24:24 |
| 3 | Bob | Parker | 2011-11-04 10:33:49 |
+----+-----------+------------+---------------------+
Now our query should only find results for Bob Parker (id 3) so I'll only show example results for Bob.
Affiliate Link Table
+-----+-----------+--------------+-----------+----------+---------------------+
| id | parent_id | affiliate_id | link_type | linkhash | created_date |
+-----+-----------+--------------+-----------+----------+---------------------+
| 21 | NULL | 3 | PRODUCT | fa2e82a7 | 2011-06-15 16:18:37 |
| 27 | NULL | 3 | PRODUCT | 55de2ae7 | 2011-06-23 01:03:00 |
| 28 | NULL | 3 | PRODUCT | 02cae72f | 2011-06-23 01:03:00 |
| 29 | 27 | 3 | PRODUCT | a4dfb2c8 | 2011-06-23 01:03:00 |
| 30 | 28 | 3 | PRODUCT | 72cea1b2 | 2011-06-23 01:03:00 |
| 36 | 21 | 3 | PRODUCT | fa2e82a7 | 2011-06-23 01:07:03 |
| 59 | 21 | 3 | PRODUCT | ec33413f | 2011-11-04 17:49:17 |
| 60 | 27 | 3 | PRODUCT | f701188c | 2011-11-04 17:49:17 |
| 69 | 21 | 3 | PRODUCT | 6dfb89fd | 2011-11-04 17:49:17 |
+-----+-----------+--------------+-----------+----------+---------------------+
Affiliate Stats
+--------+--------------+--------------------+----------+---------------------+
| id | affiliate_id | link_id | order_id | type | created_date |
+--------+--------------+---------+----------+----------+---------------------+
| 86570 | 3 | 21 | NULL | CLICK | 2013-01-01 00:07:31 |
| 86574 | 3 | 21 | NULL | PAGEVIEW | 2013-01-01 00:08:53 |
| 86579 | 3 | 21 | 411 | SALE | 2013-01-01 00:09:52 |
| 86580 | 3 | 36 | NULL | CLICK | 2013-01-01 00:09:55 |
| 86582 | 3 | 36 | NULL | PAGEVIEW | 2013-01-01 00:09:56 |
| 86583 | 3 | 28 | NULL | CLICK | 2013-01-01 00:11:04 |
| 86584 | 3 | 28 | NULL | PAGEVIEW | 2013-01-01 00:11:04 |
| 86586 | 3 | 30 | NULL | CLICK | 2013-01-01 00:30:18 |
| 86587 | 3 | 30 | NULL | PAGEVIEW | 2013-01-01 00:30:20 |
| 86611 | 3 | 69 | NULL | CLICK | 2013-01-01 00:40:19 |
| 86613 | 3 | 69 | NULL | PAGEVIEW | 2013-01-01 00:40:19 |
| 86619 | 3 | 69 | 413 | SALE | 2013-01-01 00:42:12 |
| 86622 | 3 | 60 | NULL | CLICK | 2013-01-01 00:46:00 |
| 86624 | 3 | 60 | NULL | PAGEVIEW | 2013-01-01 00:46:01 |
| 86641 | 3 | 60 | NULL | PAGEVIEW | 2013-01-01 00:55:58 |
| 86642 | 3 | 30 | 415 | SALE | 2013-01-01 00:56:35 |
| 86643 | 3 | 28 | NULL | PAGEVIEW | 2013-01-01 00:56:43 |
| 86644 | 3 | 60 | 417 | SALE | 2013-01-01 00:56:52 |
+--------+--------------+---------+----------+----------+---------------------+
Orders
+------+--------------+---------+---------------------+
| id | affiliate_id | total | created_date |
+------+--------------+---------+---------------------+
| 411 | 3 | 138.62 | 2013-01-01 00:09:50 |
| 413 | 3 | 312.87 | 2013-01-01 00:09:52 |
| 415 | 3 | 242.59 | 2013-01-01 00:09:55 |
| 417 | 3 | 171.18 | 2013-01-01 00:09:55 |
+------+--------------+---------+---------------------+
Now the results that I need should look like this (only show main/parent link id)
+---------+---------+
| link_id | total |
+---------+---------+
| 21 | 451.49 | <- 1 order from parent (21), 1 from child (69)
| 27 | 171.18 | <- 1 order from child (69)
| 28 | 242.59 | <- 1 order from child (30)
+---------+---------+
I'm not quite sure how to write the query so that I can sum where affiliate_link.id and affiliate_link.parent_id are combined. Is this even possible with a couple of JOINs and GROUPing?
I'm not too sure why you have denormalised affiliate_id (by placing it in each table) and, therefore, whether one can rely on all Stats and Orders that stem from a particular Link to have the same affiliate_id as that Link.
If it's possible, I'd suggest changing the AffiliateLink.parent_id column such that parent records point to themselves (rather than NULL):
UPDATE AffiliateLink SET parent_id = id WHERE parent_id IS NULL
Then it's a simple case of joining and grouping:
SELECT AffiliateLink.parent_id AS link_id,
SUM(Orders.total) AS total
FROM AffiliateLink
JOIN AffiliateStats ON AffiliateStats.link_id = AffiliateLink.id
JOIN Orders ON Orders.id = AffiliateStats.order_id
WHERE AffiliateLink.affiliate_id = 3
GROUP BY AffiliateLink.parent_id
See it on sqlfiddle.
If it's not possible to make the change, you can effectively create the resulting AffiliateLink table using UNION (but beware the performance implications, as MySQL will not be able to use indexes on the result):
(
SELECT parent_id, id, affiliate_id FROM AffiliateLink WHERE parent_id IS NOT NULL
UNION ALL
SELECT id , id, affiliate_id FROM AffiliateLink WHERE parent_id IS NULL
) AS AffiliateLink
See it on sqlfiddle.