How to union two tables with group values? - mysql

How to union two tables with group values?
My query:
SELECT
employee.employee_name,
count(employee.employee_name) as count,
sum(table1.position) as totalshares
FROM
erom_kmch.table1
LEFT OUTER JOIN
erom.employee
ON employee.bene_type_table1=table1.bene_type
AND employee.bene_stype_table1=table1.bene_stype
WHERE
table1.date = '2016-04-15'
group by
employee.employee_name
UNION
SELECT
employee.employee_name,
count(employee.employee_name) as count,
sum(table2.shares) as totalshares
FROM
erom_kmch.table2
LEFT OUTER JOIN
erom.employee
ON employee.type_table2=table2.type
AND employee.bo_substat_table2=table2.bo_substat
WHERE
table2.date = '2016-04-15'
group by
employee.employee_name
Returns:
employee_name count totalshares
NULL 0 0 21967
Clearing Member 9 9 1386
devloper-php 4 4 1984
devloper-.net 46 46 410713
devloper-.android 2
NULL 4056461 0 117154
devloper-.C#php 2 5 31618309
devloper-.net
Resident Individual 939 25 361020 22762
But I need the output like this:
employee_name count totalshares
NULL 0 139121
Clearing Member 15 5355
devloper-php 9 2293
devloper-.net 46 433475
devloper-.android 2 4056461
devloper-.C# 2 31618
Resident Individual 3668 2662925
Individual- Director 1 100
I am joining and union two tables and I need to group the values of two tables. I am getting two output, I need the sum and count of two tables as one output.

You should use Subquery:
SELECT
[YourField]
, [YourAggregate]
FROM
(SELECT
table1.holder
, table1.bene_type
, table1.bene_stype
, employee.employee_name
, COUNT(employee.employee_name) AS [count]
, SUM(table1.position) AS totalshares
FROM
erom_kmch.table1
LEFT OUTER JOIN
erom.employee
ON employee.bene_type_table1=table1.bene_type AND employee.bene_stype_table1=table1.bene_stype
WHERE
table1.date = '2016-04-15'
GROUP BY
employee.employee_name
UNION
SELECT
table2.cust_name
, table2.type
, table2.bo_substat
, employee.employee_name
, COUNT(employee.employee_name) as [count]
, SUM(table2.shares) as totalshares
FROM
erom_kmch.table2
LEFT OUTER JOIN
erom.employee
ON employee.type_table2=table2.type AND employee.bo_substat_table2=table2.bo_substat
WHERE
table2.date = '2016-04-15'
GROUP BY employee.employee_name
) AS A
GROUP BY
[YourField]
NOTE: You should also make the query easy to read.

Related

Getting data form 2 tables and summing values of the result

I have 2 tables with information: ID, persona_id, total_amount
The persona ID can repeat dozen of times. So i get all the one persons id total_amount with query:
select d.id as debt_id, p.name as persona, sum(d.total_amount) as total_amount
from debt d
join persons p on d.persona_id = p.id group by p.name
I want to get data from each table in one query and do aritmethic propertys with the total_amount column and return it as 1 tabel.
TABLE 1
id persons_id total_amount
1 2 50
2 3 100
3 2 200
4 5 300
5 1 500
TABLE 2
id persons_id total_amount
1 2 25
2 1 100
3 5 50
4 3 100
5 4 300
As a result i want to get the 2 tables comined with arithmetic operation (-, +, / , * ) of Total amount columns.Basicaly a change to get the ending result total amount in form i want for different cases.
What worked for me based on JohnHC answear was :
select c.id, c.persona_id, c.total_amount - d.total_amount as new_total
from ( select c.id , c.persona_id, sum(c.total_amount) as total_amount from credit c
join persons p on c.persona_id = p.id
group by p.name) c
inner join ( select d.id, d.persona_id, sum(d.total_amount) as total_amount from debt d
join persons p on d.persona_id = p.id
group by p.name) d
on c.persona_id = d.persona_id
group by c.id, c.persona_id
If you want the total, try:
select id, person_id, sum(total_amount)
from
(
select id, person_id, total_amount
from table1
union all
select id, person_id, total_amount
from table2
)
group by id, person_id
If you want to do other things, try:
select t1.id, t1.person_id, t1.total_amount [+ - / *] t2.total_amount as new_total
from table1 t1
inner join table2 t2
on t1.id = t2.person_id
group by t1.id, t1.person_id

MySQL - Display null column from child table if all values are not distinct

I have the following tables, for example:
invoices
ID Name
1 A
2 B
3 C
4 D
5 E
transactions
ID Invoice_ID User_ID
1 1 10
2 1 10
3 1 10
4 2 30
5 3 20
6 3 40
7 2 30
8 2 30
9 4 40
10 3 50
Now I want to make a select that will pull the invoices and the user_id from the related transactions, but of course if I do that I won't get all the ids, since they may be distinct but there will be only one column for that. What I want to do is that if there are distinct User_ids, I will display a pre-defined text in the column instead of the actual result.
select invoices.id, invoices.name, transactions.user_id(if there are distinct user_ids -> return null)
from invoices
left join transactions on invoices.id = transactions.invoice_id
and then this would be the result
ID Name User_ID
1 A 10
2 B 30
3 C null
4 D 40
5 E null
Is this possible?
You can do the following :
select
invoices.id,
invoices.name,
IF (
(SELECT COUNT(DISTINCT user_id) FROM transactions WHERE transactions.invoice_id = invoices.id) = 1,
(SELECT MAX(user_id) FROM transactions WHERE transactions.invoice_id = invoices.id),
null
) AS user_id
from invoices
Or, alternatively, you can use the GROUP_CONCAT function to output a comma-separated list of users for each invoice. It is not exactly what you asked, but maybe in fact it will be more useful :
select
invoices.id,
invoices.name,
GROUP_CONCAT(DISTINCT transactions.user_id SEPARATOR ',') AS user_ids
from invoices
left join transactions on invoices.id = transactions.invoice_id
group by invoices.id
Try somethingh like:
select i.id, i.name, t.user_id
from invoices i left join
(
select invoice_ID, User_ID
from transactions
group by invoice_ID
having count(invoice_ID)=1
) t on i.id=t.invoice_id
SQL fiddle
You could list all the transactions that have multiple user ids, like this:
select invoices.id, invoices.name, null
from invoices
left join transactions on invoices.id = transactions.invoice_id having count(distinct transactions.user_id) > 1
Also, I think this CASE might suit your needs here:
select invoices.id, invoices.name,
case when count(distinct transactions.user_id) > 1 then null else transactions.user_id end
from invoices
left join transactions on invoices.id = transactions.invoice_id
group by invoices.id
although, I'm not sure this is syntactically correct

How to get results count in SQL

I have two tables:
TB_Departament
(
id_dep, nome
1 , RRHH
2 , Security
3 , logistics
)
TB_Incident
(
id_tipo, id_dep
1 , 1
2 , 3
1 , 3
2 , 1
1 , 3
2 , 1
2 , 1
)
If I count the records department get this:
select d.nome, count(i.id_tipo) as Num from TB_Departament d, TB_Incident i
where i.id_dep = d.id_dep
group by d.nome
resp:
RRHH 4
logistics 3
but I need this:
RRHH 4
Security 0
logistics 3
How can i modify the query to get the right answer?
Try:
SELECT d.nome, count(i.id_tipo)
FROM TB_Departament d LEFT JOIN
TB_Incident i
ON d.id_dep = i.id_dep
GROUP BY d.nome
ON MSSQL, this would be as follow, including an order by clause in case you want the results to come out by id_dep #
SELECT x.name,x.Num FROM (
select d.id_dep, d.name AS name, count(i.id_tipo) AS Num from TB_Department d
LEFT OUTER JOIN TB_Incident i
ON i.id_dep= d.id_dep
group by d.name, d.id_dep) AS x
ORDER BY x.id_dep

SQL - How to calculate column value and join with another table

As I am not good with MySQL query's so I wish someone help me for creating this kind of sql query.
I having two MySQL tables which is describe bellow:
Table Name: rating
-------------------
property_id user_id area_rate_count safety_rate_count friendly_rate_count walkability_rate_count
4 28 1 1 1 2
5 38 2 3 4 1
5 40 2 2 3 1
6 40 2 3 1 4
10 43 2 2 3 1
Table Name: listing
-------------------
property_id title
4 Sample 1
5 Sample 2
6 Sample 3
10 Sample 4
11 Sample 5
12 Sample 6
Now first I want to sum each column and divide. (area_rate_count, safety_rate_count, friendly_rate_count, walkability_rate_count). For example In property_id:5 having two times so first calculate column sum and divide by 2.
After calculation we will get this output:
Table Name: rating (After Calculation)
--------------------------------------
property_id rate
4 5
5 9 (Divided by 2 because this property_id is two times in table)
6 10
10 8
And Finally I want join this result to my listing table and result looks something like this:
Table Name: listing
-------------------
property_id title rate
4 Sample 1 5
5 Sample 2 9 (Divided by 2 becouse property_id is two times in table)
6 Sample 3 10
10 Sample 4 8
11 Sample 5 0
12 Sample 6 0
Thanks.
I think you want the avg() aggregation function along with a join:
select l.property_id, l.title,
coalesce(avg(area_rate_count + safety_rate_count + friendly_rate_count + walkability_rate_count
), 0) as rate
from listing l left outer join
property_id p
on l.property_id = p.property_id
group by l.property_id, l.title ;
If I understood it right I think you need this:
select l.property_id, l.title, coalesce(r.ssum/if(r.ct=0,1,r.ct), 0) as rate
from listing l LEFT JOIN
(select property_id,
sum(area_rate_count+safety_rate_count
+friendly_rate_count+walkability_rate_count) ssum,
count(*) ct
from rating
group by property_id ) r
ON l.property_id = r.property_id
order by l.property_id
See it here on fiddle: http://sqlfiddle.com/#!2/589d6/5
Edit
As OP asked on the comments that he wants all columns from listing here is what he want:
select l.*, coalesce(r.ssum/if(r.ct=0,1,r.ct), 0) as rate
from listing l LEFT JOIN
(select property_id,
sum(area_rate_count+safety_rate_count
+friendly_rate_count+walkability_rate_count) ssum,
count(*) ct
from rating
group by property_id ) r
ON l.property_id = r.property_id
order by l.property_id
CREATE TEMPORARY TABLE IF NOT EXISTS
temp_table ( INDEX(col_2) )
ENGINE=MyISAM
AS (
SELECT
property_id,
AVG(area_rate_count) as area_rate_count,
AVG(safety_rate_count) as safety_rate_count,
AVG(friendly_rate_count) as friendly_rate_count,
AVG(walkability_rate_count) as walkability_rate_count
FROM rating
GROUP BY property_id
)
SELECT * FROM listing L
JOIN temp_table T
ON L.property_id = T.property_id
Use the below statement to get distinct property_id with its own rate
select property_id, sum(separaterating)/count(property_id) from (
select property_id,sum(area_rate_count , safety_rate_count , friendly_rate_count , walkability_rate_count) as separaterating from rating group by property_id AS temp ) group by
property_id
you can then join with the other table to get the final result as below
select * from ( select property_id, sum(separaterating)/count(property_id) from (
select property_id,sum(area_rate_count , safety_rate_count , friendly_rate_count , walkability_rate_count) as separaterating from rating group by property_id AS temp ) group by
property_id) AS A inner join listing AS B on A.property_id = B.property_id
try this:
select a.prop_id as property_id, l.title, a.allratings / b.numberofreviews as rate
from
(
select property_id as prop_id, SUM(coalesce(area_rate_count,0) + coalesce(safety_rate_count,0) + coalesce(friendly_rate_count,0) + coalesce(walkability_rate_count,0)) as allratings
from rating
group by property_id
) a inner join
(
select property_id, count(distinct user_id) as numberofreviews
from rating
group by property_id
) b on a.property_id = b.property_id
inner join listing l on a.property_id = l.property_id
Try This Query
select ls.property_id,ls.title,inr.rate from listing as ls
left join
(select r.property_id as pid,r.rate/r.cnt as rate from
(select property_id,user_id,(area_rate_count+safefty_rate_count+friendly_rate_count+walkability_rate_count) as rate,count(*) as cnt from rating group by property_id) as r) as inr on inr.pid=ls.property_id

Counting results of join on duplicate field

I have a table1 containing duplicate column value
Table1
id code
1 201202 0000 1111
2 201202 0000 9999
3 201203 0000 9999
4 201203 0000 0999
5 201204 1000 1999
6 201204 2000 2999
7 201205 3000 3999
8 201205 4000 4999
9 201205 5000 5999
Table 2
id numbers
1 2012020010
2 2012024929
3 2012033838
4 2012052434
5 2012052229
6 2012052232
I want to count all the numbers in table2 that are substring of distinct code in table 1
i.e. result should be
code frequency
201202 2
201203 1
201205 3
I have been able to get all the numbers for every code but can't figure out how to count them
SELECT DISTINCT table1.code , table1.id, table2.number AS ph_npa, count( * )
FROM table1
INNER JOIN table2 ON substr( table2.number, 1, 6 ) = table1.code
GROUP BY table1.number
any help is appreciated.
SELECT t1.code, COUNT(*) AS frequency
FROM table_one AS t1
LEFT JOIN table_two AS t2
ON t2.numbers LIKE CONCAT(t1.code, '%')
GROUP BY t1.code
Either use LEFT JOIN or INNER JOIN depending on if you want rows with frequency = 0 or not. All I did was basicly to run a LIKE as join condition with the % wildcard.
Try out the following. It can have performance hits on large data sets, but will get you started. It is working with my test data.
SELECT SUBSTR(t2.numbers, 1,6) AS CODE, COUNT(*) AS frequency
FROM table_2 t2
WHERE SUBSTR(t2.numbers, 1,6) IN (SELECT t1.code FROM table_1 t1)
GROUP BY SUBSTR(t2.numbers, 1,6)
Let me know if its working!
I'm not really one for using the "inner join" syntax and prefer to just use the cleaner looking implicit join on the data.
select
count(*)
from
npanxxsmall n, phone_numbers p
where
substr(n.code, 1, 6) = substr(p.number, 1, 6);
Let me know if this works!
ok I got it working and query is super fast
SELECT
DISTINCT A.code as code,
B.Counts AS frequency
FROM table1 AS A
INNER JOIN (
SELECT substr( number, 1, 6 ) AS subnumber, count( 1 ) AS Counts
FROM table2
GROUP BY substr( number, 1, 6 )
)
AS B ON A.code = B.subnumber
i.e.
select the number and frequency of number from table 2
and then join with distinct code form table 1