Select DISTINCT from multiple columns of multiple tables with PHP and MySQL - php

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
)

Related

multiple sum from different tables [duplicate]

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...

MySQL return union select results separated in groups

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;

mysql query select distinct value from two table with the count of sum value in two table

I have two tables in db
1- i want to select distinct value from 2 tables
2- i want to print the number of each value
Ex: if i have on t1
t1
--------------
a
a
a
b
t2:
t2
--------------
a
b
c
the result will be:
a (4)
b (2)
c (1)
i try this but it not what i want
$sql=mysqli_query($conn,"select db_shopname from tbl_order UNION
SELECT db_shopname FROM tbl_item order by db_shopname asc")
or die(mysqli_error($conn));
$count=mysqli_num_rows($sql);
while($res=mysqli_fetch_array($sql)){
echo $res['db_shopname'];echo $count ;echo"<br/>";
}
You need UNION ALL instead of UNION. That way you merge the values from 2 tables into 1 virtual table. Then you can count the number of individual values using GROUP BY clause. Example:
select f, COUNT(f) as countf FROM
(select t1.f from t1 union all select t2.f from t2) t
GROUP BY f
SQL Fiddle
In PHP you can then use $res['countf'] to print the count
try this one :
select a.t1,count(a.t1) as cnt from(select t1 from t1 UNION all
select t2 as t1 from t2 )a group by a.t1

update user score from other tables

I have a few tables that each have their own scores for each user. I would like to create a trigger that will add up all those scores for each user and put them in a field called score in the users table.
Tables (They essentially have the same fields with a few different ones) :
Table 1 : {id, user_id, score}
Table 2 : {id, user_id, score}
Table 3 : {id, user_id, score}
users : {id, name, overall_score}
// Overall _score has a value already , so i just want to add the score fields from the other tables to this one.
To achieve this lets first write the select query and get sum of all the scores per user from the 3 given tables and this is how it could be done
select u.*, y.total from users u
left join
(
select user_id,sum(score) as total from(
select user_id, score from table_1
union all
select user_id, score from table_2
union all
select user_id, score from table_3
)x group by x.user_id
)y on y.user_id = u.id
Here is the demo http://www.sqlfiddle.com/#!9/6f936/1
Now lets convert the select to an update command and it will be as
update users u
left join
(
select user_id,sum(score) as total from(
select user_id, score from table_1
union all
select user_id, score from table_2
union all
select user_id, score from table_3
)x group by x.user_id
)y on y.user_id = u.id
set u.overall_score = coalesce(y.total,0)
here is the demo http://www.sqlfiddle.com/#!9/c6993/1
To select data from multiple tables, you can use SQL JOINS.
See the example below:
SELECT table1.score, table2.score, table3.score
FROM table1 LEFT JOIN table2
ON table1.id=table2.id LEFT JOIN table3 ON table1.id=table3.id
This code will select the score column from table1, table2, and table3 and create one row per user_id, each containing one score-column/ table (in this case 3/ row). It's almost like having a fourth table containing all the scores, and then when you fetch them in PHP, it'd be like fetching an existing row from the database.
EDIT:
To Update the users table in the same query, you could use something like this:
UPDATE `users`,
(
SELECT table1.id as tid, table1.score as t1,
table2.score as t2, table3.score as t3
FROM table1 LEFT JOIN table2 ON table1.id=table2.id
LEFT JOIN table3 ON table1.id=table3.id
) as total
SET total_score = (t1 + t2 + t3) WHERE id = tid

Union query to fetch SUM values

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,
...

Categories