How can we group SQL once it is grouped in inner query - php

Here i have one table for purchase.
| Invoice No | Customer | Amount | Invoice Date(mm-dd-yy) |
| 101 | ABC | 1000 | 01-01-2020 |
| 102 | XYZ | 1000 | 01-01-2020 |
| 103 | ABC | 1000 | 02-01-2020 |
| 104 | XYZ | 1000 | 03-01-2020 |
| 105 | PQR | 1000 | 01-01-2020 |
| 106 | ABC | 1000 | 03-01-2020 |
Now I have to make Customer wise report.
so grouping will be on Customer which will be like this.
$sql->group(customer);
So after this table will generate like below..
| Invoice No | Customer | Amount | Invoice Date(mm-dd-yy) |
| 106 | ABC | 3000 | 03-01-2020 |
| 104 | XYZ | 2000 | 03-01-2020 |
| 105 | PQR | 1000 | 01-01-2020 |
I also have to make summary for this as like.
| Invoice Amount | Total Count |
| 5000 | 5 |
above all things are done, but the problem is i also have to generate Date Wise summary
So how i get Date Wise summary?
SELECT
`t`.*,
FORMAT(SUM(COALESCE(t.Total_Purchase_Amount_fororder, 0.00)), 2) AS Total_Purchase_Amount
FROM
(
SELECT
`invoice_item`.*,
`sr`.*,
cust_comp.name AS cust_name,
cust_comp.id AS cust_id,
MAX(FROM_UNIXTIME(invoice.date, '%Y')) AS `Transaction_Year`,
MAX(FROM_UNIXTIME(invoice.date, '%m')) AS `Transaction_Month`,
MAX(FROM_UNIXTIME(invoice.date, '%m-%Y')) AS `Transaction_Month_Year`,
FORMAT(COALESCE(COUNT(invoice.to_type_id), 0.00), 2) AS `Total_Purchases`,
COUNT(invoice.to_type_id) AS `Total_Purchases_forsummary`,
FORMAT(COALESCE(SUM(invoice_item.amountAfterDiscount) - COALESCE(total_return, 0.00) , 0.00), 2) AS `Total_Purchase_Amount`,
SUM(invoice_item.amountAfterDiscount) - COALESCE(total_return, 0.00) AS `Total_Purchase_Amount_fororder`,
FORMAT(COALESCE(MAX(invoice_item.amountAfterDiscount) - COALESCE(total_return, 0.00) , 0.00), 2) AS `Max_Purchase_Amount`
FROM
`invoice`
INNER JOIN
`cust_comp`
ON cust_comp.id = invoice.to_type_id
INNER JOIN
(
SELECT
SUM(amountWithTax) AS `amountWithTax`,
SUM(amountAfterDiscount) AS `amountAfterDiscount`,
FORMAT(sum(tax_amount), 2) AS `tax_amount`,
`invoice_item`.`invoice_id`,
`invoice_item`.`invoice_item_inventory_id`
FROM
`invoice_item`
WHERE
(
invoice_item.item_status NOT IN
(
8
)
)
GROUP BY
`invoice_item`.`invoice_id`
)
AS `invoice_item`
ON invoice_item.invoice_id = invoice.invoice_id
LEFT JOIN
(
SELECT
`sr`.`sales_return_id`,
`sr`.`invoice_id` AS `return_invoice_id`,
SUM(COALESCE(return_amountAfterDiscount, 0.00)) AS total_return,
`sri`.*
FROM
`sales_return` AS `sr`
INNER JOIN
(
SELECT
`sri`.`sales_return_id` AS `item_sales_return_id`,
COALESCE(amountAfterDiscount, 0.00) AS `return_amountAfterDiscount`
FROM
`sales_return_item` AS `sri`
)
AS `sri`
ON sri.item_sales_return_id = sr.sales_return_id
WHERE
(
sr.invoice_id = invoice_id
)
GROUP BY
`sr`.`invoice_id`
)
AS `sr`
ON sr.return_invoice_id = invoice.invoice_id
WHERE
(
invoice.invoice_status NOT IN
(
8,
6
)
)
AND
(
invoice.date >= 1596240000
)
GROUP BY
`invoice`.`to_type_id`
)
AS `t`
Expected Result for date wise summary is:
| Invoice Amount| Total Count | Invoice Date |
| 3000 | 3 | 01-01-2020 |
| 1000 | 1 | 02-01-2020 |
| 2000 | 2 | 03-01-2020 |

Related

PHP Codeigniter MySQL query - join 4 tables together, with 3 tables using group by one column from each table

Items Table
+----+------+
| id | name |
+----+------+
| 1 | abc |
| 2 | def |
| 3 | ghi |
+----+------+
Buy Table
+------+-------------+-------+---------+
| b_id | b_date | b_qty | b_itmid |
+------+-------------+-------+---------+
| 1 | 2020-05-01 | 10 | 1 |
| 2 | 2020-05-01 | 20 | 1 |
| 3 | 2020-05-02 | 5 | 2 |
| 3 | 2020-05-03 | 10 | 3 |
+------+-------------+-------+---------+
Rent Table
+------+-------------+-------+---------+
| r_id | r_date | r_qty | r_itmid |
+------+-------------+-------+---------+
| 1 | 2020-05-03 | 5 | 2 |
| 2 | 2020-05-03 | 10 | 2 |
| 3 | 2020-05-04 | 15 | 3 |
+------+-----------+---------+---------+
Sell Table
+------+-------------+-------+---------+
| s_id | s_date | s_qty | s_itmid |
+------+-------------+-------+---------+
| 1 | 2020-05-03 | 10 | 1 |
| 2 | 2020-05-05 | 20 | 3 |
| 3 | 2020-05-06 | 5 | 3 |
+------+-----------+---------+---------+
And I'm trying to get outputs with php foreach something like this ...
$trans_date
$buy_qty
$rent_qty
$sell_qty
$item
In case item id 1
+-------------+--------------+---------------+---------------+------+
| trans_date | buy_qty | rent_qty | sell_qty | item |
+-------------+--------------+---------------+---------------+------+
| 2020-05-01 | 30 | 0 | 0 | abc |
| 2020-05-02 | 0 | 0 | 0 | abc |
| 2020-05-03 | 0 | 0 | 10 | abc |
| 2020-05-04 | 0 | 0 | 0 | abc |
| 2020-05-05 | 0 | 0 | 0 | abc |
| 2020-05-06 | 0 | 0 | 0 | abc |
+-------------+--------------+---------------+---------------+------+
This is the query I've come for one table (b_date column has timestamp value)...
$query = $this->db->query("
SELECT FROM_UNIXTIME(b_date,'%d %M') AS date_b
, SUM(b_qty) AS qty_b
FROM buytable
WHERE b_itmid = 1
AND MONTH(FROM_UNIXTIME(b_date)) = MONTH(CURDATE())
GROUP
BY DATE(FROM_UNIXTIME(b_date))
");
if ($query->num_rows() > 0) {
foreach ($query->result() as $data) {
$result[] = $data;
}
return $result;
}
Finally I've found the correct answer https://stackoverflow.com/a/61875506/7554875
select d.date, b.qty_buy, r.qty_rent, s.qty_sell, i.name
from items i
cross join (
select b_date as date from buy
union all select r_date as date from rent
union all select s_date as date from sell
) d
left join (select b_date as date, b_itmid, sum(b_qty) qty_buy
from buy group by date, b_itmid) b
on b.date = d.date and b.b_itmid = i.id
left join (select r_date as date, r_itmid, sum(r_qty) qty_rent
from rent group by date, r_itmid) r
on r.date = d.date and r.r_itmid = i.id
left join (select s_date as date, s_itmid, sum(s_qty) qty_sell
from sell group by date, s_itmid) s
on s.date = d.date and s.b_itmid = i.id
where i.id = 1 and d.date >= date_format(curent_date, '%Y-%m-01')
order by d.date

How to manage SELECT data from 3 different table's using with JOIN?

I have 3 different table's.
driver
| id | name |
|-----|------|
| 10 | abc |
| 21 | xyz |
booking
| id | driver_id | booking_amount |
|----|-----------|----------------|
| 1 | 10 | 250 |
| 2 | 10 | 150 |
| 3 | 21 | 200 |
| 4 | 21 | 300 |
income
| id | driver_id | credit | debit | date |
|----|-----------|--------|-------|----------|
| 1 | 10 | 100 | | 1-1-2019 |
| 2 | 10 | 250 | | 2-1-2019 |
| 3 | 10 | | 200 | 3-1-2019 |
| 4 | 21 | 250 | | 1-1-2019 |
| 5 | 21 | 400 | | 2-1-2019 |
| 6 | 21 | | 50 | 3-1-2019 |
driver.id = booking.driver_id
driver.id = income.driver_id
I have use this query >>
SELECT driver.*, sum(booking.total_booking_income) as total_income
FROM driver
JOIN booking ON driver.id=booking.driver_id
GROUP BY driver.id
ORDER BY driver.id DESC
Note : but i am not able to add balance field in my this query.
i want to all driver records of income after group of booking and group of income by driver id like
| id | driver_id | driver_name | total_income | balance |
|----|-----------|-------------|--------------|---------|
| 1 | 10 | abc | 400 | -250 |
| 2 | 21 | xyz | 500 | 100 |
Assuming balance is the difference between the credit and the debit then:
SELECT d.*, sum(b.total_booking_income) as total_income,
i.balance
FROM driver d JOIN
booking b
ON d.id = b.driver_id LEFT JOIN
(SELECT i.driver_id,
SUM(i.credit) - SUM(i.debit) as balance
FROM income i
GROUP BY i.driver_id
) i
ON i.driver_id = d.id
GROUP BY d.id, i.balance
ORDER BY d.id DESC;

MySQL: linking tables with extracted sum of column per row

I have 3 tables:
MySQL: I need to link these tables and extracted sum of one of the column per row in the resulting table
tblRedemption
+---------------------+
| OrderID | OrderDesc |
+---------------------+
| 1000001 | aaaa |
| 1000002 | bbbb |
| 1000003 | cccc |
| 1000004 | dddd |
+---------------------+
tblLink
+------------------------+
| SubmissionID | OrderID |
+------------------------+
| 201 | 1000001 |
| 202 | 1000002 |
| 203 | 1000003 |
| 204 | 1000004 |
+------------------------+
tblSubmissions
+-------------------------------------------+
| SubmissionID | Name | Mobile | Amount |
+-------------------------------------------+
| 150 | Amy | 1111111111 | 10 |
| 200 | Bob | 2222222222 | 20 |
| 201 | Carl | 3333333333 | 30 |
| 202 | Dave | 4444444444 | 10 |
| 203 | Carl | 3333333333 | 25 |
| 204 | Fin | 5555555555 | 35 |
+-------------------------------------------+
Expected Results:
+---------------------------------------------------------------------+
| SubmissionID | Name | mobile | OrderDesc | Amount | TotalAmount |
+---------------------------------------------------------------------+
| 201 | Carl | 3333333333 | aaaa | 30 | 55 |
| 203 | Carl | 3333333333 | bbbb | 25 | 55 |
| 204 | Fin | 5555555555 | cccc | 35 | 35 |
| 202 | Dave | 4444444444 | dddd | 10 | 10 |
+---------------------------------------------------------------------+
Number of tblSubmission is a bigger list than the tblredemption.
There are customers with multiple entries tblSubmission identified by their mobile (see Carl).
The table tbLink joins the 2 tblSubmission and tblRdemption.
The resulting table also needs a new column which holds the total amount for each particular customer (by mobile).
The expected results needs to include:
The SubmissionID and OrderDesc from the "tblRedemption" table.
The Name, Mobile and Amount from the tblSubmissions table.
All my queries ether gives me a small subset or just one row, or "multiple rows returned".
Any ideas?
Try this:
select l.submissionid, s.name, s.mobile, s.amount, t.totalamount
from tbllink l
inner join tblsubmissions s on l.submissionid = s.submissionid
inner join (
select `name`, sum(amount) as totalamount
from tblsubmissions
group by `name`
) t on s.`name` = t.`name`
Example: http://sqlfiddle.com/#!9/2ea56a/5
Same query totalled by mobile number
select l.submissionid, s.name, s.mobile, s.amount, t.totalamount
from tbllink l
inner join tblsubmissions s on l.submissionid = s.submissionid
inner join (
select mobile, sum(amount) as totalamount
from tblsubmissions
group by mobile
) t on s.mobile = t.mobile
EDIT:
Including order desc is relatively easy also. Let's see:
select l.submissionid, s.name, s.mobile, r.orderdesc, s.amount, t.totalamount
from tbllink l
inner join tblredemption r on l.orderid = r.orderid
inner join tblsubmissions s on l.submissionid = s.submissionid
inner join (
select `name`, sum(amount) as totalamount
from tblsubmissions
group by `name`
) t on s.`name` = t.`name`
Example: http://sqlfiddle.com/#!9/63540/2
Tables
create table tblredemption (orderid int, orderdesc varchar(100));
insert into tblredemption values (1000001, 'aaaa'), (1000002, 'bbbb'), (1000003, 'cccc'), (1000004, 'dddd');
create table tbllink (submissionid int, orderid int);
insert into tbllink values (201,1000001), (202,1000002), (203,1000003), (204,1000004);
create table tblsubmissions (
submissionid int,
`name` varchar(20),
mobile varchar(20),
amount int
);
insert into tblsubmissions values
( 150 , 'Amy' , '1111111111', 10 ),
( 200 , 'Bob' , '2222222222' , 20 ),
( 201 , 'Carl' , '3333333333' , 30 ),
( 202 , 'Dave' , '4444444444' , 10 ),
( 203 , 'Carl' , '3333333333' , 25 ),
( 204 , 'Fin' , '5555555555' , 35 );
Results:
| submissionid | name | mobile | orderdesc | amount | totalamount |
|--------------|------|------------|-----------|--------|-------------|
| 201 | Carl | 3333333333 | aaaa | 30 | 55 |
| 203 | Carl | 3333333333 | cccc | 25 | 55 |
| 202 | Dave | 4444444444 | bbbb | 10 | 10 |
| 204 | Fin | 5555555555 | dddd | 35 | 35 |

sum the quantity from 3rd relational table

I have following tables, i want to fetch the purchase_order and his order_quantity and sum of received quantity for each purchase_order. i know how to sum the quantity from single table but from multiple tables, it is confusing me a lot...
mysql> select * from purchase_order;
+-------------------+-------------------------+-------+---------------------+
| purchase_order_id | purchase_order | cost | created_on |
+-------------------+-------------------------+-------+---------------------+
| 1 | Dell Computer 000001256 | 10000 | 2015-02-19 22:14:52 |
| 2 | HP Computer 000001256 | 50000 | 2015-02-19 22:14:52 |
+-------------------+-------------------------+-------+---------------------+
2 rows in set (0.00 sec)
mysql> select * from purchase_order_detail;
+--------------------------+-------------------+---------+------------------+
| purchase_order_detail_id | purchase_order_id | item_id | ordered_quantity |
+--------------------------+-------------------+---------+------------------+
| 1 | 1 | 279 | 100 |
| 2 | 1 | 286 | 100 |
| 3 | 2 | 279 | 200 |
| 4 | 2 | 286 | 300 |
+--------------------------+-------------------+---------+------------------+
4 rows in set (0.00 sec)
mysql> select * from delivery_order;
+-------------------+--------------------------+-------------------+---------------------+
| delivery_order_id | purchase_order_detail_id | recieved_quantity | recieved_on |
+-------------------+--------------------------+-------------------+---------------------+
| 1 | 1 | 50 | 2015-02-19 22:22:51 |
| 2 | 2 | 50 | 2015-02-19 22:24:59 |
| 3 | 1 | 50 | 2015-02-19 22:34:14 |
| 4 | 3 | 70 | 2015-02-20 11:11:31 |
| 5 | 4 | 150 | 2015-02-20 11:11:31 |
| 6 | 3 | 90 | 2015-02-20 11:12:20 |
| 7 | 4 | 100 | 2015-02-20 11:12:20 |
| 8 | 3 | 40 | 2015-02-20 11:12:55 |
| 9 | 4 | 50 | 2015-02-20 11:12:55 |
+-------------------+--------------------------+-------------------+---------------------+
So far, i have this query, but id doesn't returns correct record..
SELECT po.purchase_order_id, SUM(pod.ordered_quantity) AS Sum_of_ordered_quantity, SUM(dor.recieved_quantity) AS Sum_of_recieved_quantity
FROM purchase_order AS po
INNER JOIN purchase_order_detail AS pod ON po.purchase_order_id = pod.purchase_order_id
INNER JOIN delivery_order AS dor ON dor.purchase_order_detail_id = pod.purchase_order_detail_id
GROUP BY po.purchase_order_id
it returns this,
+-------------------+-------------------------+--------------------------+
| purchase_order_id | Sum_of_ordered_quantity | Sum_of_received_quantity |
+-------------------+-------------------------+--------------------------+
| 1 | 300 | 150 |
| 2 | 1500 | 500 |
+-------------------+-------------------------+--------------------------+
you can see in the question that , purchase_order_id 1 has 200 ordered quantity and 150 received quantity while purchase_order_id 2 has 500 ordered_quantity and 500 received quantity.
Please try this code:
SELECT po.purchase_order_id,
SUM(pod.ordered_quantity) AS Sum_of_ordered_quantity,
(SELECT `mySelect`.`desired_sum` FROM
(SELECT B.`purchase_order_id` AS myID, SUM( `A`.`recieved_quantity` ) AS desired_sum
FROM `delivery_order` AS A
LEFT JOIN `purchase_order_detail` AS B ON A.purchase_order_detail_id = B.purchase_order_detail_id
GROUP BY B.`purchase_order_id` ) AS mySelect
WHERE `mySelect`.`myID` = `po`.`purchase_order_id`) AS Sum_of_received_quantity
FROM purchase_order AS po
INNER JOIN purchase_order_detail AS pod ON po.purchase_order_id = pod.purchase_order_id
GROUP BY po.purchase_order_id
This is usual while doing aggregate sum function with multiple many-to-many tables with different joining condition.
One way is to use correlated subquery to get the aggregate value and then do the join. Something as
select
po.purchase_order_id,
pod.Sum_of_ordered_quantity,
do.Sum_of_received_quantity
from purchase_order po
join
(
select purchase_order_id,sum(ordered_quantity) as Sum_of_ordered_quantity
from purchase_order_detail
group by purchase_order_id
)pod on pod.purchase_order_id = po.purchase_order_id
join
(
select
t1.purchase_order_id,
sum(t2.recieved_quantity) as Sum_of_received_quantity
from purchase_order_detail t1
join delivery_order t2 on t1.purchase_order_detail_id = t2.purchase_order_detail_id
group by t1.purchase_order_id
)do on do.purchase_order_id = po.purchase_order_id
DEMO

Find the number of rooms availble from the below table structure

I have the following table structure:
roominfo table
+---------+----------------+---------------+
| Room_id | room_type_name | maximum_rooms |
+---------+----------------+---------------+
| 1 | A | 16 |
| 2 | B | 14 |
| 3 | C | 7 |
| 4 | D | 2 |
| 5 | E | 2 |
+---------+----------------+---------------+
bookedtable stores all the rooms booked within that date:
+------------+--------------+---------------+----------------+---------+
| room_bk_id | checkin_date | checkout_date | maxroomsbooked | room_id |
+------------+--------------+---------------+----------------+---------+
| 1 | 2014-01-28 | 2014-01-29 | 8 | 1 |
| 2 | 2014-01-29 | 2014-01-30 | 2 | 4 |
| 3 | 2014-01-28 | 2014-01-29 | 4 | 1 |
+------------+--------------+---------------+----------------+---------+
bookingprogress table to avoid the race condition (it blocks upto the expire time) I set the maximum expire time as 15 minutes from current time
+------------+----------------+-----------------+----------------+---------+---------------+---------------------+
| room_pg_id | checkinpg_date | checkoutpg_date | maxroomsbooked | room_id | sessionid | ExpireTime |
+------------+----------------+-----------------+----------------+---------+---------------+---------------------+
| 1 | 2014-01-28 | 2014-01-29 | 2 | 1 | AdsddsA23asd | 2014-01-28 00:15:00 |
| 2 | 2014-01-29 | 2014-01-30 | 2 | 5 | AdsQWerasdwe | 2014-01-28 00:18:00 |
| 3 | 2014-01-28 | 2014-01-29 | 1 | 2 | BdrtQWerasdwe | 2014-01-28 00:20:00 |
+------------+----------------+-----------------+----------------+---------+---------------+---------------------+
The workflow is:
User checks for the available rooms by providing checkin date, checkout date and no of rooms.
I need to find and display the rooms are available which are not blocked or booked for that particular period.
The executed query was (might be small mistakes -- Here I gave overview of what I have done --So modified my query according to that)
SELECT tbook.*,
SUM(tbook.maxroomsbooked + tprogress.maxroomsbooked) AS bookedrooms
FROM bookedtable AS tbook
JOIN bookingprogress AS tprogress USING (Room_id)
JOIN roominfo AS troomtype USING (Room_id)
WHERE tbook.checkout_date > '2014-01-28'
AND tprogress.checkoutpg_date > '2014-01-28'
AND tprogress.ExpireTime < '2014-01-27 00:10:00'
AND tprogress.room_id = 1
GROUP BY Room_id
From the above tables I tried to get the rooms which are available for booking. But I didn't get the expected result.
See it on sqlfiddle.
Could you please provide me with the solution?
One way would be to use NOT EXISTS subqueries. For example, if a user is interested in booking '2014-02-01' to '2014-02-07':
SELECT *
FROM roominfo r
WHERE NOT EXISTS (
SELECT *
FROM bookedtable b
WHERE b.room_id = r.room_id
AND NOT (
b.checkin_date < '2014-02-07'
AND b.checkout_date > '2014-02-01'
)
LIMIT 1
)
AND NOT EXISTS (
SELECT *
FROM bookingprogress p
WHERE p.room_id = r.room_id
AND p.ExpireTime > CURRENT_TIME
AND NOT (
p.checkinpg_date < '2014-02-07'
AND p.checkoutpg_date > '2014-02-01'
)
LIMIT 1
)

Categories