Joining tables while using group by in SQL - mysql

I have two tables to join in SQL using the ID column in both. Table 1 has only unique values of ID as follows and I want to keep all columns of this table:
ID code 1 code 2
1 123 99
2 222 09
3 344 13
Table 2 has multiple rows of each ID as follows:
ID application_time Application Number
1 11jan2004 123
2 15oct2010 124
1 24nov2008 845
3 05sep2010 166
1 07feb2001 865
2 24aug2017 545
3 12mar2009 233
2 11dec2001 811
So, from table 2, I want to add the total count of each ID, and Min and Max of Application_time to table 1. I also need to count the number Application Numbers that start with 8. of I do not know where I should use group by (). So the outcome should look like:
ID code 1 code 2 count Min (application_time) Max (application_time)
1 123 99 3 07feb2001 24nov2008
2 222 09 3 11dec2001 24aug2017
3 344 13 2 12mar2009 05sep2010
Count of Application Number starting with 8
2
1
0

here is how you can do it:
select
t1.Id
,t1.code1
,t1.code2
, count(*) count
,min(application_time)
,max(application_time)
, sum( case when left( t2.application number, 1 ) = '8' then 1 else 0 end )
from table1 t1
join table2 t2
on t1.Id = t2.Id
group by
t1.Id
,t1.code1
,t1.code2

Related

How to get the output as following by combining data from 3 different tables

so I have 3 tables in my db, where all 3 tables contains a column which have similar data, but name of that column is different on all the 3 tables, below is an example.
Ban Table
user_id
ban_user_id
ban_date
reason
end_date
1300
1
xyz
xyz
xyz
32
1
xyz
xyz
xyz
43
2
xyz
xyz
xyz
Reports Table
user_id
last_modified_user_id
report_date
reason
end_date
1300
1
xyz
xyz
xyz
32
2
xyz
xyz
xyz
43
2
xyz
xyz
xyz
Warning Table
user_id
warning_user_id
warning_date
reason
end_date
1300
1
xyz
xyz
xyz
32
2
xyz
xyz
xyz
43
3
xyz
xyz
xyz
Now I want to fetch data by combining these 3 tables, where ban_user_id, last_modified_user_id, and warning_user_id contains the data of staff member who took the actions, so i want to group the data by the staff id.
The output i am looking for is as follows:
staff_id
total_reports
total_bans
total_warnings
1
1
2
1
2
2
1
1
3
0
0
1
where it is counting the data for each table by grouping the 2nd column, ban_user_id, last_modified_user_id, warning_user_id respectively. And than combining the data.
I tried things with UNION All and stuffs, but it didn't work out.
Thankyou in advance for your help
Use UNION ALL for all 3 tables and then aggregate:
SELECT staff_id,
COUNT(report) AS total_reports,
COUNT(ban) AS total_bans,
COUNT(warning) AS total_warnings
FROM (
SELECT last_modified_user_id AS staff_id, 1 AS report, null AS ban, null AS warning FROM Reports
UNION ALL
SELECT ban_user_id, null, 1, null FROM Ban
UNION ALL
SELECT warning_user_id, null, null, 1 FROM Warning
) t
GROUP BY staff_id;
Or:
SELECT staff_id,
SUM(report) AS total_reports,
SUM(ban) AS total_bans,
SUM(warning) AS total_warnings
FROM (
SELECT last_modified_user_id AS staff_id, 1 AS report, 0 AS ban, 0 AS warning FROM Reports
UNION ALL
SELECT ban_user_id, 0, 1, 0 FROM Ban
UNION ALL
SELECT warning_user_id, 0, 0, 1 FROM Warning
) t
GROUP BY staff_id;
See the demo.
You can use Table joins (Inner/outer/left/right) to get the data instead of union.
I'm assuming the staff_id is the equivalent of user_id column as you haven't mentioned anything about that, so your script will look something like this:
SELECT W.user_id AS staff_id,
B.ban_user_id,
R.last_modified_user_id,
W.warning_user_id
FROM Warning AS W
LEFT JOIN Reports AS R on R.user_id = W.user_id
LEFT JOIN Ban AS B on B.user_id = W.user_id
group by W.user_id

how count and sum records in three tables using mysql phpmyadmin?

I m new to this community and also new to MySQL.
Need to COUNT the clients and SUM the commission for each referrer respectively using MySQL query.
referrer table
id
referrer_name
1
referre1
2
referre2
3
referre3
4
referre4
client table
id
referrer_id
client_name
1
1
client1
2
1
client2
3
2
client3
4
3
client4
5
4
client5
commission table
id
client_id
commission
1
1
20
2
1
32
3
3
24
4
4
15
I want to achieve below output using above 3 tables.
referrer_id
referrer_name
total_client
total_commission
1
referre1
2
52
2
referre2
1
24
3
referre3
1
15
4
referre4
1
0
I have tried the following query
SELECT referrer.referrer_name as name,
(SELECT COUNT(*) FROM client WHERE client.referrer_id=referrer.id) as total_client,
(SELECT SUM(commission) FROM commission WHERE commission.client_id=client.id) as total_commission FROM referrer LEFT JOIN client ON client.referrer_id=referrer.id GROUP BY name;
Read Mysql join and Aggregate Functions
SELECT t2.referrer_id,
t1.referrer_name,
COUNT(DISTINCT t2.id) AS total_client,
SUM(t3.commission) AS total_commission
FROM referrer t1
JOIN client t2 ON t1.id = t2.referrer_id
JOIN commission t3 ON t2.id = t3.client_id
GROUP BY t1.referrer_id

how to comparison LAG function in mysql

I got complicated problem in mysql.
I have some table on mydatabase.
sample docs(this is only simple sample, actual data are so many table that I have to join)
table "merchant"
id name
1 arief
2 john
3 chena
table "transaction"
id product_id price merchant_id date
1 1 20000 2 2020-02-01
2 5 25000 1 2020-02-01
3 2 10000 3 2020-02-02
4 2 10000 2 2020-02-02
5 3 5000 2 2020-02-02
5 2 10000 2 2020-02-03
6 3 5000 3 2020-02-04
I want to know the information of merchants transaction daily "before" and "after" to comparison
like this below
name_merchant sumtrx_20-02-01 sumtrx_20-02-02 sumtrx_20-02-03 sumtrx_20-02-04
arief 1 0 0 0
john 1 2 1 0
chena 0 1 0 1
I tried with this query
select m.name, count(trx.id, trx.date = '2020-02-01') as sumtrx_20-02-01, count(trx.id, trx.date = '2020-02-02') as sumtrx_20-02-02, count(trx.id, trx.date = '2020-02-03') as sumtrx_20-02-03, count(trx.id, trx.date = '2020-02-04') as sumtrx_20-02-04 from merchant as m join transaction as trx on m.id = trx.merchant_id
group by m.name
but that query didn't work
You can use sum() instead of count().
SELECT m.name,
sum(trx.date = '2020-02-01') `sumtrx_20-02-01`,
...
sum(trx.date = '2020-02-04') `sumtrx_20-02-04`
FROM merchant m
INNER JOIN transaction trx
ON m.id = trx.merchant_id
GROUP BY m.name;
And you also need to enclose identifiers, here the column aliases, in backticks if you use special characters like - in them. Or avoid using special characters in them all together.

MySQL find difference in rows with duplicate column values

Suppose I have a table TAPS
id sequence card_tap time
1 1 61 1
1 1 62 10
1 2 2 20
1 2 2 20
2 11 12 5
2 11 12 5
2 12 62 10
2 12 61 20
I want to find the rows where id and sequence are the same while thecard_tap and time is not.
It should return
id sequence card_tap time
1 1 61 1
1 1 62 10
2 12 62 10
2 12 61 20
This assume there is only two rows for each {id,sequence}
SELECT t1.*
FROM taps t1
JOIN taps t2
ON t1.id = t2.id
AND t1.sequence = t2.sequence
WHERE t1.time <> t2.time
OR t1.card_tap <> t2.card_tap
If you have more than two rows you will get duplicate rows so maybe need add DISTINCT
Simply with this ?
Select * from tabs where id = sequence and card_tap != time
The data seems to not be normalized. Anyway, based on your tagging, I'm guessing you're looking for something to return all results like:
select distinct * from taps;
or
select * from taps group by card_tap,time;
You need to add a unique ID with an Index to better deal with the data.

mysql join two table rows in one table

I have two tables e_sku and e_availability, In e_sku table i have 45 rows with the default availability as 1, below is an example
id is_available name
1 1 UN001N
2 1 UN002N
3 1 UN003N
4 1 UN004N
5 1 UN005N
6 1 UN006N
7 1 UN007N
8 1 UN008N
9 1 UN009N
10 1 UN010N
11 1 UN011N
12 1 UN012N
13 1 UN013N
14 1 UN014N
15 1 UN015N
16 1 UN016N
17 1 UN017N
18 1 UN018N
19 1 UN019N
20 1 UN020N
21 1 UN021N
22 1 UN022N
23 1 UN023N
24 1 UN024N
25 1 UN025N
26 1 UN026N
27 1 UN027N
28 1 UN028N
29 1 UN029N
30 1 UN030N
31 1 UN031N
32 1 UN032N
33 1 UN033N
34 1 UN034N
35 1 UN035N
36 1 UN036N
37 1 UN037N
38 1 UN038N
39 1 UN039N
40 1 UN040N
41 1 UN041N
42 1 UN042N
43 1 UN043N
44 1 UN044N
45 1 UN045N
Second table is e_availability in this table i am only storing the unavailability with dates below is the example
id e_sku_id is_available working_date
1 5 0 10/20/2016
2 8 0 10/20/2016
3 10 0 10/20/2016
4 1 0 10/20/2016
5 15 0 10/20/2016
6 11 0 10/19/2016
7 1 0 10/19/2016
Because the data is capturing every date for unavailability so i am only gathering the unavailable product's data in e_availability table w.r.t. dates, Now i am looking to show the data for each day as complete skus in such a way that every day report will show 45 skus and for available sku it will show 1 from e_sku table's column is_available and for unavailable sku it will show the column of is_availability from e_availability table
I am using mysql database, I tried many join queries but not getting the report.
can any one guide about which join i require
I got the result by using this query
SELECT * FROM (SELECT id,NAME,1 AS is_available FROM e_sku
WHERE company_id = 2
AND id NOT IN (SELECT id FROM (SELECT e_sku.id,e_sku.name, edge_availability.is_available FROM edge_availability
JOIN edge_working ON edge_working.`id` = edge_availability.`working_id`
JOIN e_sku ON e_sku.id = edge_availability.`sku_id`
WHERE edge_working.`working_date` = '2016-10-19' AND edge_availability.`store_id` = 84) X)
UNION
SELECT e_sku.id,e_sku.name, edge_availability.is_available FROM edge_availability
JOIN edge_working ON edge_working.`id` = edge_availability.`working_id`
JOIN e_sku ON e_sku.id = edge_availability.`sku_id`
WHERE edge_working.`working_date` = '2016-10-19' AND edge_availability.`store_id` = 84) Y
ORDER BY id
You can use a LEFT JOIN to detect when a date isn't found in the e_availability table. The join will return NULL for all the columns in that table, then you can default to the value from e_sku.
SELECT d.date, s.id, IFNULL(a.is_available, s.is_available) AS is_available
FROM all_dates AS d
CROSS JOIN e_sku AS s
LEFT JOIN e_availability ON d.working_date = a.date AND s.id = a.e_sku_id
You need to create an additional table all_dates that contains all the dates that you want to report on. See What is the most straightforward way to pad empty dates in sql results (on either mysql or perl end)? for how you can create such a table dynamically.