I have 4 table that I want to join:
tbl_transaksi_header
--------------------
kode_transaksi
kode_user
nama_penerima
email_penerima
alamat_penerima
bank
telpon
tbl_konfirmasi
--------------------
id
kode
member
namarekening
tbl_user
-------------------
kode_user
username_user
tbl_transaksi_detail
---------------------
kode_transaksi
harga
jumlah
status
I want to show all data including NULL in nama_rek.
I tried this:
SELECT t.status, t.kode_transaksi kode, u.username_user nama_user, t.nama_penerima penerima, t.telpon, t.bank, sum(d.harga*d.jumlah) total,k.namarekening nama_rek
FROM tbl_transaksi_header t
JOIN tbl_user u
ON t.kode_user=u.kode_user
JOIN tbl_transaksi_detail d
ON t.kode_transaksi=d.kode_transaksi
LEFT OUTER JOIN tbl_konfirmasi k
ON t.kode_transaksi=k.kode
Work fine but not showing null result, only showing 1 row result. I want something like this:
status kode nama_user penerima telpn bank total nama_rek
xxx xxx xxx xxx xxx xxx xxx NULL
xxx xxx xxx xxx xxx xxx xxx NULL
xxx xxx xxx xxx xxx xxx xxx yyy
xxx xxx xxx xxx xxx xxx xxx NULL
Sample data:
kode_transaksi kode_user nama_penerima email_penerima alamat_penerima bank telpon
kd1 1 john some#email.com florida Bank A 088833221
kd2 2 elsa some#email.com uk Bank B 088833222
kd3 1 roy some#email.com manhattan Bank C 088833223
id kode member namarekening
1 kd1 paul paul
kode_user username_user
1 paul
2 elena
kode_transaksi harga jumlah status
kd1 10 2 process
kd1 5 2 process
kd1 5 1 process
kd2 4 3 pending
kd2 3 4 pending
kd3 2 3 pending
I want this output:
status kode nama_user penerima telpon bank total nama_rek
process kd1 paul john 088833221 Bank A 35 paul
pending kd2 elena elsa 088833222 Bank B 24 NULL
pending kd2 elena roy 088833223 Bank C 6 NULL
Your join is fine; the problem is that you have a SUM() in your select with no GROUP BY. Try this:
SELECT t.kode_transaksi kode, u.username_user nama_user, t.nama_penerima penerima, t.telpon, t.bank, sum(d.harga*d.jumlah) total,k.namarekening nama_rek
FROM tbl_transaksi_header t
JOIN tbl_user u
ON t.kode_user=u.kode_user
JOIN tbl_transaksi_detail d
ON t.kode_transaksi=d.kode_transaksi
LEFT OUTER JOIN tbl_konfirmasi k
ON t.kode_transaksi=k.kode
GROUP BY
t.kode_transaksi, u.username_user, t.nama_penerima , t.telpon, t.bank,k.namarekening
Related
I have 4 tables (1 to many):
Dont say anything about that "email" relation. It is how my developer boss built it years ago.
EMPLOYEES (+-50 results)
------------------------------------------------
id name
1 EmpName 1
2 EmpName 2
CUSTOMERS (+50k results)
------------------------------------------------
id name email employee_assigned
1 John john#doe.com 12
2 Donald donald#duck.com 6
INTERESTS_CATEGORIES (+650k results)
------------------------------------------------
id customer_email category_id
1 john#doe.com 97
2 john#doe.com 13
3 donald#duck.com 56
4 donald#duck.com 126
5 donald#duck.com 45
INTERESTS_PRODUCTS (+650k results)
------------------------------------------------
id customer_email product_id
1 john#doe.com 78
2 john#doe.com 23
3 donald#duck.com 19
4 donald#duck.com 56
5 donald#duck.com 45
So I need to filter the customers by their assigned employee and their interests.
And here is the query:
SELECT
*
FROM
(
SELECT
customers.id AS 'id',
customers.name AS 'first_name',
customers.email,
employees.id AS 'employee_id'
FROM
customers,
employees
WHERE
employees.id = 2
AND
customers.employee_assigned = employees.id
) AS myCustomers
LEFT JOIN interests_categories
ON interests_categories.customer_email = myCustomers.email
LEFT JOIN interests_products
ON interests_categories.customer_email = myCustomers.email
WHERE
(
interests_categories.category_id = 20
OR
interests_categories.category_id = 21
)
GROUP BY myCustomers.email
So, the problem:
If the employee has a low number of assigned customers (like 3) query
is successfull.
If the employee has a medium-high number of assigned customers (over 100) query stucks.
I execute SHOW PROCESSLIST and it is stucked "Generating temp table".
Anyone has idea? :(
Thank you.
Check the indexes on your tables and try this:
SELECT
c.id AS 'id',
c.name AS 'first_name',
c.email,
e.id AS 'employee_id'
ic.*,
ip.*
FROM customers c
JOIN employees e
ON c.employee_assigned = e.id
LEFT JOIN interests_categories ic
ON ic.customer_email = c.email
LEFT JOIN interests_products ip
ON ic.customer_email = c.email
WHERE
(
ic.category_id IN (20,21)
AND e.id = 2
)
GROUP BY myCustomers.email
Incidentally, a less dumb design might look like as follows. If it was me, I'd start with this, and provide properly representative CREATE and INSERT statements accordingly. Also, I'm curious about where category_id comes from - because that's potentially an area for further optimization.
EMPLOYEES
------------------------------------------------
employee_id name
6 EmpName 1
12 EmpName 2
CUSTOMERS
------------------------------------------------
customer_id name email employee_assigned
1 John john#doe.com 12
2 Donald donald#duck.com 6
INTERESTS_CATEGORIES
------------------------------------------------
customer_id category_id
1 97
1 13
2 56
2 126
2 45
INTERESTS_PRODUCTS
------------------------------------------------
customer_id product_id
1 78
1 23
2 19
2 56
2 45
Table users
ID name country
--- ----- -----
100 John 1
101 Mark 4
102 Peter 3
103 Lucy 3
Table followers
ID folowerId followedId
--- --------- ------
1 102 101
2 103 101
3 102 100
4 100 101
5 100 102
5 103 100
Table country
ID name
--- -----
1 China
2 Usa
3 Italia
4 India
How to get the number of followers for a specific user grouped by country ?
Example output for user 101:
country count
------- -----
China 1
Italia 2
I have tried this:
SELECT
User.name, COUNT(Follower.id) AS FollowerCount
FROM
followers AS Follower
JOIN users AS User ON Follower.UserId = User.id
GROUP BY
User.country;
but it's not working
You should use a count and group by
select c.name, count(*)
from followers b
left join users as a on b.folloswerId = a.id
left join country on a.country = c.id
where b.followedId = 101
group by c.name
I am trying to make the notification system for my project as simple as possible on the user's side.
"john brown and 4 others liked your photo"
I tried:
Select a.id, a.item_id, a.type u.f_name, u.l_name, count(a)
From alerts
Join users on a.user_id = u.u_id
Where owner_id = {THE_USER_ID}
but it doesnt "work"
The users table
u_id | f_name | l_name
==========================
234 roy wright
654 pam brown
564 kim harris
334 tory plummer
876 rick forbes
123 paul nichol
980 mario chang
454 todd thompson
886 sam richards
215 tash gates
... ..... ........
The alerts table
id | item_id | type | user_id | owner_id
===================================================
1 21 like 234
2 21 comment 654
3 32 share 876
4 21 like 778
5 21 like 890
6 21 share 123
7 54 share 454
8 32 comment 655
9 60 comment 886
10 32 like 215
.. .. ...... ...
The results I want
id | item_id | type | u_id | f_name | l_name | amount_more
============================================================
1 21 like 234 roy wright 2
2 21 comment 654 pam brown
3 32 comment 876 rick forbes
6 21 share 123 paul nichol
7 54 share 454 todd thompson
9 60 comment 886 sam richards
10 32 like 215 tash gates
.. .. .... ... ..... ........
SELECT
MIN(CASE WHEN RowNumber = 1 THEN id END) as Id
,item_id
,type
,MIN(CASE WHEN RowNumber = 1 THEN u_id END) as u_id
,MIN(CASE WHEN RowNumber = 1 THEN f_name END) as f_name
,MIN(CASE WHEN RowNumber = 1 THEN l_name END) as l_name
,COUNT(*) - 1 as amount_more
FROM
(
SELECT
t.*
,(#rn:= if((#item = t.item_id) AND (#type = t.type),#rn + 1,
if((#item:=t.item_id) AND (#type:=t.type),1,1)
)
) as RowNumber
FROM
(SELECT *
FROM
alerts a
LEFT JOIN usersTbl u
ON a.user_id = u.u_id
WHERE
a.owner_id = 201
ORDER BY
a.item_id
,a.type
,a.id) t
CROSS JOIN (SELECT #rn:=0,#item:=0,#type:='') var
ORDER BY
item_id
,type
,id
) t2
GROUP BY
item_id
,type
ORDER BY
id
;
So you need to create a partitioned row number to identify which record you want to be considered first. Then using conditional aggregation you can choose that as your User. this works check it out here: http://rextester.com/VXZONO82847
In the Query you are not using aliases a and u properly, Use this:
Select
a.id,
a.item_id,
a.type,
u.f_name,
u.l_name,
count(a.*)
From alerts a Join users u
on(a.user_id = u.u_id)
Where owner_id = {THE_USER_ID}
group by 1,2,3,4,5;
Let's say, I have 3 tables: appointments, doctors and departments.
appointments:
id status doctor_id
---- --------- ---------
1 approved 1
2 cancelled 4
3 approved 4
4 approved 1
5 approved 4
6 NULL 5
7 approved 2
8 NULL 5
9 approved 4
10 approved 3
11 cancelled 1
12 NULL 4
13 approved 3
14 cancelled 1
15 approved 4
16 cancelled 4
17 cancelled 2
18 NULL 4
19 cancelled 1
20 cancelled 4
doctors:
id name department_id
---- --------- -------------
1 John 1
2 Robert 2
3 Patricia 3
4 Mary 1
5 Susan 3
departments:
id name
---- ---------
1 Dermatology
2 Neurology
3 Radiology
What I need is percentage of approved appointments to total of approved and cancelled (approved / (approved + cancelled) * 100) in Dermatology department, grouped by doctors.
I used the following query, which got me closer to solution.
SELECT COUNT(*) AS appointment_count,
doctors.name AS doctor_name,
appointments.status AS appointment_status
FROM appointments
LEFT JOIN doctors ON appointments.doctor_id = doctors.id
LEFT JOIN departments ON doctors.department_id = departments_id
WHERE departments.id = 1
GROUP BY doctors.id,
appointments.status
result:
count doctor_name appointment_status
----- ----------- ---------
2 John approved
3 John cancelled
0 John NULL
4 Mary approved
3 Mary cancelled
2 Mary NULL
But I need the percentage of approved / (approved + cancelled) for each doctors. So the result should be:
approved_percentage doctor_name
------------------- -----------
%40 John
%57 Mary
How can I achieve such a result?
In MySQL, the simplest way to do conditional counts and averages is simply to use the boolean expression. This suggests:
SELECT d.name, count(*),
SUM(a.status = 'approved') as approved_count,
AVG(a.status = 'approved') * 100 as approved_percentage
FROM doctors d INNER JOIN
appointments a
ON a.doctor_id = d.id
GROUP BY d.name;
You can group only by doctors and then use count(if()) functionality like this:
SELECT d.name, count(*), count(if(a.status = 'approved', 1, null)) approved_count,
count(if(a.status = 'approved', 1, null))/count(*) * 100 approved_percentage
FROM doctors d
INNER JOIN appointments a ON a.doctor_id = d.id
GROUP BY d.name
I have 7 tables db_category, db_city, db_locality, db_shop, db_shop_locality, db_shop_recommended, db_shop_views.
db_category
category_id category_name publish
1 Apparel 1
db_city
city_id city_name publish
1 bangalore 1
db_locality
locality_id locality_name publish
1 kalyan nagar 1
2 Madiwala 1
db_shop
shop_id category_id city_id locality_id shop_name publish
1 1 1 1 name 1
2 1 1 2 name1 1
3 1 1 1 name2 1
4 1 1 1 name3 1
db_shop_recommended
recommended_id category_id shop_id priority publish
1 1 1 1 1
2 1 2 2 1
db_shop_views
views_id shop_id ip_addr publish
1 1 127.0.0.1 1
2 2 ::1 1
3 4 127.0.0.1 1
4 4 ::1 1
5 3 ::1 1
I want to join all the above tables. And the conditions for the join are,
display all the rows from db_shop when publish=1 and join db_category, db_city and db_locality with db_shop
in db_shop_recommended who's priority=1 comes first and so on.
and shop_id not in db_shop_recommended, count shop_id not in db_shop_recommended from db_shop_views who's shop_id got more views.
My result should looks like below,
shop_id category_name city_name locality_name shop_name
1 Apparel bangalore kalyan nagar name (result based on `db_shop_recommended` who's priority is more)
2 Apparel bangalore Madiwala name1 (result based on `db_shop_recommended` who's priority is more)
4 Apparel bangalore kalyan nagar name4 (result based on `db_shop_views` who's view count is more)
3 Apparel bangalore kalyan nagar name3 (result based on `db_shop_views`)
I have no idea how to join and count the views. Is it possible to join in above method.
After lots of searching. Finally i got the answer.
SELECT DISTINCT s.shop_id, c.city_name, l.locality_name, ca.category_name, s.shop_name, s.shop_logo, s.cart_url, s.shop_about FROM db_shop s INNER JOIN db_city c ON c.city_id = s.city_id INNER JOIN db_category ca ON ca.category_id = s.category_id INNER JOIN db_locality l ON l.locality_id = s.locality_id LEFT JOIN (SELECT * FROM db_shop_recommended r ORDER BY r.priority ASC) r1 ON s.shop_id = r1.shop_id LEFT JOIN (select distinct g.shop_id, g.cnt from (select distinct shop_id, count(shop_id) cnt from db_shop_views group by shop_id) g inner join (select max(s.cnt) max_cnt from(select distinct shop_id, count(shop_id) cnt from db_shop_views group by shop_id) s) m on m.max_cnt = g.cnt) v ON s.shop_id = v.shop_id WHERE s.publish = 1