Totally 12 db tables(some tables repeated). I have to fetch SUM(values) from each table of particular date.I have used UNION query,But it returns the value of first table used in query.
Remaining table returned nothing.Can Anybody help me.Here my code.
$sel = mysql_query("
SELECT
SUM(collection_amount) AS cash_total
FROM
collection_entry
WHERE
date='$entered_date'
AND collection_type='DC'
UNION
SELECT
SUM(amt) AS cheque_redeposit_total
FROM
cheque_redeposit
WHERE
redeposited_on1
OR redeposited_on2='$entered_date'
UNION
SELECT
SUM(collection_amount) AS not_cleared_total
FROM
collection_entry
WHERE
cheque_status='not cleared'
AND date='$entered_date'
UNION
SELECT
SUM(collection_amt) AS route_collection_total
FROM
route_collection
WHERE
entered_date='$entered_date'
UNION
SELECT
SUM(amt) AS return_total
FROM
cheque_return
WHERE
return_date1 OR return_date2 OR return_date3='$entered_date'
UNION
SELECT
SUM(collection_amount) AS cheque_total
FROM
collection_entry
WHERE
collection_type='CC'
AND date='$entered_date'
UNION
SELECT
SUM(debit2) AS voucher_receipt_total
FROM
voucher_posting
WHERE
receipt_type='R'
AND date='$entered_date'
UNION
SELECT
SUM(credit2) AS voucher_payment_total
FROM
voucher_posting
WHERE
receipt_type='P'
AND date='$entered_date'
UNION
SELECT
SUM(amt) AS others_total
FROM
others_remittance
WHERE
entered_date='$entered_date'
UNION
SELECT
SUM(amt) AS short_total
FROM
short_remittance
WHERE
entered_date='$entered_date'
UNION
SELECT
SUM(amount) AS more_paid
FROM
difference
WHERE
entered_date='$entered_date'
and paid_type='more'
UNION
SELECT
SUM(amount) AS unpaid
FROM
difference
WHERE
entered_date='$entered_date'
and paid_type='unpaid'");
while($row=mysql_fetch_array($sel))
{
$cash_total=$row['cash_total'];
$cheque_redeposit_total=$row['cheque_redeposit_total'];
$not_cleared_total=$row['not_cleared_total'];
$route_collection_total=$row['route_collection_total'];
$return_total=$row['return_total'];
$cheque_total=$row['cheque_total'];
$voucher_receipt_total=$row['voucher_receipt_total'];
$voucher_payment_total=$row['voucher_payment_total'];
$others_total=$row['others_total'];
$short_total=$row['short_total'];
$more_paid=$row['more_paid'];
$unpaid=$row['unpaid'];
$net_total = (($cash_total + $route_collection_total) - $return_total);
}
UNION just appends rows to one another. So in your case you just get a list of your sums in a row-wise fashion.
[value for cash_total]
[value for cheque_redeposit_total]
[value for not_cleared_total]
...
If you really have to get all the data in one row, you can use something like this:
SELECT * FROM
(SELECT SUM(collection_amount) AS cash_total FROM collection_entry WHERE date='$entered_date' AND collection_type='DC') as t1,
(SELECT SUM(amt) AS cheque_redeposit_total FROM cheque_redeposit WHERE redeposited_on1 OR redeposited_on2='$entered_date') AS t2,
(SELECT SUM(collection_amount) AS not_cleared_total FROM collection_entry WHERE cheque_status='not cleared' AND date='$entered_date') AS t3,
(SELECT SUM(collection_amt) AS route_collection_total FROM route_collection WHERE entered_date='$entered_date') AS t4,
...
Related
I have a union of three tables (t1, t2, t3).
Each rerun exactly the same number of records, first column is id, second amount:
1 10
2 20
3 20
1 30
2 30
3 10
1 20
2 40
3 50
Is there a simple way in SQL to sum it up, i.e. to only get:
1 60
2 80
3 80
select id, sum(amount) from (
select id,amount from table_1 union all
select id,amount from table_2 union all
select id,amount from table_3
) x group by id
SELECT id, SUM(amount) FROM
(
SELECT id, SUM(amount) AS `amount` FROM t1 GROUP BY id
UNION ALL
SELECT id, SUM(amount) AS `amount` FROM t2 GROUP BY id
) `x`
GROUP BY `id`
I groupped each table and unioned because i think it might be faster, but you should try both solutions.
Subquery:
SELECT id, SUM(amount)
FROM ( SELECT * FROM t1
UNION ALL SELECT * FROM t2
UNION ALL SELECT * FROM t3
)
GROUP BY id
Not sure if MySQL uses common table expression but I would do this in postgres:
WITH total AS(
SELECT id,amount AS amount FROM table_1 UNION ALL
SELECT id,amount AS amount FROM table_2 UNION ALL
SELECT id,amount AS amount FROM table_3
)
SELECT id, sum(amount)
FROM total
I think that should do the trick as well.
As it's not very clear from previous answers, remember to give aliases (on MySQL/MariaDb) or you'll get error:
Every derived table must have its own alias
select id, sum(amount) from (
select id,amount from table_1 union all
select id,amount from table_2 union all
select id,amount from table_3
) AS 'aliasWhichIsNeeded'
group by id
Yes!!! Its okay! Thanks!!!!
My code finishing:
SELECT SUM(total)
FROM (
(SELECT 1 as id, SUM(e.valor) AS total FROM entrada AS e)
UNION
(SELECT 1 as id, SUM(d.valor) AS total FROM despesa AS d)
UNION
(SELECT 1 as id, SUM(r.valor) AS total FROM recibo AS r WHERE r.status = 'Pago')
) x group by id
SELECT BANKEMPNAME, workStation, SUM (CALCULATEDAMOUNT) FROM(
SELECT BANKEMPNAME, workStation, SUM(CALCULATEDAMOUNT) AS CALCULATEDAMOUNT,SALARYMONTH
FROM dbo.vw_salaryStatement
WHERE (ITEMCODE LIKE 'A%')
GROUP BY BANKEMPNAME,workStation, SALARYMONTH
union all
SELECT BANKEMPNAME, workStation, SUM(CALCULATEDAMOUNT) AS CALCULATEDAMOUNT,SALARYMONTH
FROM dbo.vw_salaryStatement
WHERE (ITEMCODE NOT LIKE 'A%')
GROUP BY BANKEMPNAME, workStation, SALARYMONTH) as t1
WHERE SALARYMONTH BETWEEN '20220101' AND '20220131'
group by BANKEMPNAME, workStation
order by BANKEMPNAME asc
IN MSSQL You can write this way, But Doing UNION ALL THE Column should be the same for both ways.
I have given this example So that you can understand the process...
I would like to know if is possible to return the results from UNION grouped by their alias.
For instance:
(SELECT * FROM table1) AS first
UNION
(SELECT * FROM table2) AS second
so that the result is:
first = contains all table1 rows
second = contains all table2 rows
Practically i want an associative array like this:
[]=>[
'first'=>[table1 results],
'second'=>[table2 results]
]
I tried it but doesn't work. Maybe i'm doing it bad.
Can this be done with a single query or i've to do 2 separated queries.
Thanks.
You cannot do this with union because it removes duplicates. You can with union all.
One way is:
SELECT t.*, 0 as which FROM table1 t
UNION ALL
SELECT t.*, 1 FROM table2 t
ORDER BY which;
If you don't want to see which in the output, use a subquery:
select . . .
from (select t.*, 0 as which from table1 t union all
select t.*, 1 as which from table1 t
) t
order by which;
I have two separate calendars: reservation_schedule and maintenance_schedule calendars. Reservation_schedule fetch data from reservation table and maintenance_schedule fetch data from maintenance table. My goal is to put both fetched data from the two calendars into one calendar.
Here is the query I used for the reservation_schedule:
SELECT acode
FROM reservation
WHERE month(etd) = '".$month."'
AND dayofmonth(etd) = '".$dayArray["mday"]."'
AND year(etd) = '".$year."'
ORDER BY etd
And for the maintenance_schedule:
SELECT DISTINCT s.reg AS 'reg',
a.date AS 'date'
FROM (SELECT Curdate()
+ INTERVAL (a.a + (10 * b.a) + (100 * c.a)) day AS Date
FROM (SELECT 0 AS a
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9) AS a
CROSS JOIN (SELECT 0 AS a
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9) AS b
CROSS JOIN (SELECT 0 AS a
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9) AS c) a
INNER JOIN maintenance_sched s
ON a.date >= s.date_from
AND a.date <= s.date_to
WHERE Month(date) = '".$month."'
AND Dayofmonth(date) = '".$dayArray["mday"]."'
AND Year(date) = '".$year."'
I can show data from both of them by using UNION but I want the data from the maintenance table to be outputted as string with strikethrough. I'm outputting the query result in this code:
$chkEvent_res = mysql_query($chkEvent_sql) or die(mysql_error());
if (mysql_num_rows($chkEvent_res) > 0) {
$event_title = "<br/>";
while ($ev = mysql_fetch_array($chkEvent_res)) {
$event_title .= stripslashes($ev["reg"])."<br/>";
//$event_title .= "<del>".stripslashes($ev["acode"])."</del><br/>";
}
mysql_free_result($chkEvent_res);
} else {
$event_title = "";
}
If I use the query with UNION, I can't set the output string from maintenance to have strikethrough since it runs the query once. How can I achieve having the fetched data from maintenance table to output with strikethrough? Should I go for the one query with UNION? If I do, how can I separate the data coming from maintenance table and reservation table? If I go with separating the query, how can I run it? Should it be something like $chkEvent_res = mysql_query($chkEvent_sql1) and mysql_query($chkEvent_sql2) or die(mysql_error());? Please help, thanks.
The only way you can UNION these 2 queries is if you have the same number of columns in each query, and each column have the same data type. Not sure about the data types involved -- you have "acode" being returned from the first query and "reg" and "date" from the second query.
Assuming you could actually UNION your results and get what you need, you could consider adding an additional column to your results, returning the source of the query:
SELECT Field1, Field2, Field3, 'Table1' Source
FROM TABLE1
...
UNION
SELECT Field1, Field2, Field3, 'Table2' Source
FROM Table2
...
The you could use that Source column to format your results accordingly.
Here's some additional information about using UNION:
http://dev.mysql.com/doc/refman/5.0/en/union.html
Following up my question where I used the answer to generate data on my calendar called maintenance calendar showing the aircraft's maintenance schedule. This is the MySQL query for it:
SELECT DISTINCT s.reg AS 'reg',
a.date AS 'date'
FROM (SELECT Curdate()
+ INTERVAL (a.a + (10 * b.a) + (100 * c.a)) day AS Date
FROM (SELECT 0 AS a
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9) AS a
CROSS JOIN (SELECT 0 AS a
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9) AS b
CROSS JOIN (SELECT 0 AS a
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9) AS c) a
INNER JOIN maintenance_sched s
ON a.date >= s.date_from
AND a.date <= s.date_to
WHERE Month(date) = '".$month."'
AND Dayofmonth(date) = '".$dayArray["mday"]."'
AND Year(date) = '".$year."'
Here is the maintenance_sched database:
And the calendar looks like this (based on the data from maintenance_sched):
Then, I have another calendar called reservation calendar with the same code as the maintenance calendar though with different query. This is the reservation calendar query: SELECT acode FROM reservation WHERE month(etd) = '".$month."' AND dayofmonth(etd) = '".$dayArray["mday"]."' AND year(etd) = '".$year."' ORDER BY etd".
The reservation table is this:
And the reservation calendar looks like this:
EDIT:
What I want to do is: have these two calendar in one calendar with the result of maintenance_sched query outputted as string with strikethrough. But I can't seem to make the two queries work out together as one.
I do think the answer to this question is to simply join the two queries. An example of this might be like below where you just null out any columns that aren't in your second table.
SELECT id, date, field3, description
FROM table1
UNION
SELECT id, date, field3, null
FROM table2
As there is no relationship among both the table we cannot go for joins, it would be better to go for UNION to combine the result.
This query uses group_concat so will generate common results in following form
2013-03-15 | RP-C1728, RP-C1086
2013-03-08 | RP-C1728, RP-C1086, RP-C143
If you dont want record in this format then just remove group_concat, group by clause from the query.
Query
SELECT a.date, group_concat(a.reg)
FROM
(SELECT DISTINCT s.reg AS 'reg',
a.date AS 'date'
FROM (SELECT Curdate()
+ INTERVAL (a.a + (10 * b.a) + (100 * c.a)) day AS Date
FROM (SELECT 0 AS a
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9) AS a
CROSS JOIN (SELECT 0 AS a
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9) AS b
CROSS JOIN (SELECT 0 AS a
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9) AS c) a
INNER JOIN maintenance_sched s
ON a.date >= s.date_from
AND a.date <= s.date_to
WHERE Month(date) = '".$month."'
AND Dayofmonth(date) = '".$dayArray["mday"]."'
AND Year(date) = '".$year."'
UNION ALL
SELECT acode as 'reg', date as 'date' //Add the date logic here as per your need
FROM reservation
WHERE month(etd) = '".$month."' AND
dayofmonth(etd) = '".$dayArray["mday"]."' AND
year(etd) = '".$year."' ORDER BY etd) a
GROUP BY a.date;
NOTE For the second query add the according date logic
Using PHP and MySQL I'm trying to get all the distinct values out the number and type columns from all 4 of the tables listed below:
table_1
ID|t1_number|t1_type
1|1|new
2|1|old
3|2|new
4|3|new
5|1|old
table_2
ID|t2_number|t2_type
1|1|future
2|1|new
3|3|past
4|3|new
5|1|new
table_3
ID|t3_number|t3_type
1|1|past
2|1|new
3|1|new
4|1|new
5|1|old
table_4
ID|t4_number|t4_type
1|1|new
2|4|new
3|3|old
4|2|new
5|1|new
The values I want from the above tables would be:
numbers: 1,2,3,4
types: new,old,future,past
Here is what I have so far; but I'm not sure if the SQL is correct or how to format the while loop to get the values out.
$sql = "SELECT DISTINCT table_1.t1_number, table_2.t2_number, table_3.t3_number, table_4.t4_number, table_1.t1_type, table_2.t2_type, table_3.t3_type, table_4.t4_type
FROM table_1
JOIN table_2
JOIN table_3
JOIN table_4";
$result = #mysql_query($sql, $con) or die(mysql_error());
while($row = mysql_fetch_array($result)) {
$numbers= $row[?????????];
}
Doing this in a single query risks duplicating a value in the output for either the number or type column, in the case that one list has more values than the other. To get a distinct list of values for either column, this needs to be separate queries:
Number
SELECT t1_number AS num
FROM TABLE_1
UNION
SELECT t2_number
FROM TABLE_2
UNION
SELECT t3_number
FROM TABLE_3
UNION
SELECT t4_number
FROM TABLE_4
Type
SELECT t1_type AS type
FROM TABLE_1
UNION
SELECT t2_type
FROM TABLE_2
UNION
SELECT t3_type
FROM TABLE_3
UNION
SELECT t4_type
FROM TABLE_4
There's no value to running DISTINCT in this UNION query, because duplicates will be removed, and this deals with only one column.
It's not completely clear what you're asking for. Do you want the four distinct numbers, and then the four distinct types?
SELECT t1_number FROM table_1
UNION SELECT t2_number FROM table_2
UNION SELECT t3_number FROM table_3
UNION SELECT t4_number FROM table_4;
SELECT t1_type FROM table_1
UNION SELECT t2_type FROM table_2
UNION SELECT t3_type FROM table_3
UNION SELECT t4_type FROM table_4;
Or do you want each distinct pair of number & type?
SELECT t1_number, t1_type FROM table_1
UNION SELECT t2_number, t2_type FROM table_2
UNION SELECT t3_number, t3_type FROM table_3
UNION SELECT t4_number, t4_type FROM table_4;
The neat thing about UNION is that it implicitly reduces the result to distinct rows. You can preserve duplicates if you use UNION ALL.
With SQL:
SELECT DISTINCT t1_number AS num FROM t1
WHERE num NOT IN (SELECT t2_number FROM t2)
AND num NOT IN (SELECT t3_number FROM t3)
AND num NOT IN (SELECT t4_number FROM t4)
The same idea will work for the types.
I think this is what you want:
select distinct number_value, type_value from (
select t1_number as number_value, t1_type as type_value from table_1
union
select t2_number as number_value, t2_type as type_value from table_2
union
select t3_number as number_value, t3_type as type_value from table_3
union
select t4_number as number_value, t4_type as type_value from table_4
)