I have a result of MySQL after Joining two tables as follows:-
ID || Category || Cost ||
========================||==================||==================||
AMWP/ABC/2016-17/1 || 1 || 123.88 ||
AMWP/CDF/2016-17/2 || 2 || 222.99 ||
AMWP/GHI/2016-17/3 || 3 || 133.90 ||
AMWP/ABC/2017-18/1 || 1 || 100.10 ||
AMWP/CDF/2017-18/2 || 2 || 200.20 ||
AMWP/GHI/2017-18/3 || 3 || 100.00 ||
I want to extract summary as per Catergory and Count of each Catergory and Sum of Cost for Only with Condition where ID has Like one of ABC/CDF/GHI and Financial Year Like 2016-17/2017-18
select category, sum(Cost)
from your_tables
where
( ID like ‘%/ABC/% or ID like ‘%/CDF%/’ or ID like ‘%/GHI/%’ )
and
( ID like ‘%/2016-17/%’ or ID like ‘%/2017-18/%’ )
and <joining condition>
group by category;
I got it the way I desired. In the following SQL, I am Using Sum instead of Count to Add 1 to TotWks whenever the Condition is True. Also, I just Adding the Cost Field to TotCost whenever the Condition is True.
SELECT
Category,
SUM(if(ID LIKE '%2017-18%' AND ID like ‘%/ABC/%, 1, 0)) AS `TotWks`,
SUM(if(ID LIKE '%2017-18%' AND ID like ‘%/ABC/%, `amwplist`.`Cost`, 0)) AS `TotCost`
FROM <main_Table>
LEFT OUTER JOIN <join_Table> ON <main_Table.ID> = <join_Table. ID>
GROUP BY <main_Table.ID>
If I Omit the GROUP BY Clause, then I will grand Total under TotWks and TotCost.
Thanks for all the help.
Related
I have 3 tables in mySQL called tb_tour_trip, tb_facilities and tb_master_facilities which have many to many relationship. I want to select 1 data in tb_tour_trip which have 2 or more master_facilities. example : i wanna select trip which have facilities: AC and WiFi
This is the tb_tour_trip table :
tb_tour_trip
============
id || name || description || price
===================================
1 || trip1 || example trip || $200
2 || trip2 || example trip || $300
This is the tb_facilities table (For MANY to MANY relations):
tb_facilities
============
id || id_master_facilities_ref || id_tour_trip_ref
===================================
1 || 1 || 1
2 || 2 || 1
3 || 1 || 2
3 || 3 || 2
And this is my tb_master_facilities table:
tb_master_facilities
============
id || name || status
====================
1 || WiFi || 1
2 || AC || 1
3 || TV || 1
if tried this Query :
SELECT id_tour_trip_ref FROM tb_facilities WHERE id_master_facilities_ref IN(1,2);
this show me id_tour_trip which have facilities : AC or Wifi, but that's not what i want.
I want the id_tour_trip which have AC AND Wifi only.
Exactly output is just :
id_tour_trip_ref
================
1
How can i do that? thanks before.
There's a number of ways to do this, but a reasonably easy to read/maintain method is this:
SELECT id
FROM tb_tour_trip AS ttt
WHERE (
SELECT COUNT(DISTINCT id_master_facilities_ref)
FROM tb_facilities AS tbf
WHERE tbf.id_tour_trip_ref = ttt.id
AND tbf.id_master_facilities_ref IN (1, 2)
) = 2;
If only to get your exact output, this could also work:
SELECT id_tour_trip_ref
FROM tb_facilities INNER JOIN tb_master_facilities ON tb_facilities.id=tb_master_facilities.id
WHERE name IN ("WiFi","AC") AND id_master_facilities_ref IN (1,2)
GROUP BY id_tour_trip_ref;
One method is aggregation with a HAVING clause:
SELECT f.id_tour_trip_ref
FROM tb_facilities f INNER JOIN
tb_master_facilities
ON f.id = mf.id
WHERE f.name IN ('WiFi', 'AC')
GROUP BY f.id_tour_trip_ref
HAVING COUNT(*) = 2;
I would join all of the tables together and just do 'where condition1 and condition2. This is propably less efficient but imho more comprehensive.
select distinct tb_tour_trip.id from tb_tour_trip
inner join tb_facilities on tb_facilities.id_tour_trip_ref = tb_tour_trip.id
inner join tb_master_facilities on tb_master_facilities.id = tb_facilities.id_master_facilities_ref
where tb_master_facilities.name = 'WiFi'
and tb_master_facilities.name = 'AC'
i've found the answer from forum on Facebook. thanks for all your advice :)
This is the exactly i need.
SELECT id_tour_trip_ref, GROUP_CONCAT(id_master_facilities_ref) AS facilities FROM tb_facilities GROUP BY id_tour_trip_ref HAVING FIND_IN_SET('1', facilities) > 0 AND FIND_IN_SET('2', facilities) > 0
I have a Table:
tblUserLoginRecord
ID || User || LoginTime
1 || Peter|| 2017-07-03
2 || Susan|| 2017-07-04
3 || Sam || 2017-07-05
4 || Sam || 2017-07-07
5 || Sam || 2017-07-08
6 || Susan|| 2017-07-09
I want to have a result that show the last LoginTime Group By User(Using ID DESC will be fine too):
ID || User || LoginTime
1 || Peter|| 2017-07-03
5 || Sam || 2017-07-08
6 || Susan|| 2017-07-09
How I do it now is:
SELECT * FROM (SELECT * FROM tblUserLoginRecord ORDER BY ID DESC) a GROUP BY User;
But it will be much slower if the table growth bigger. How can I make it better?
Thank you.
You can use select only once if you are using mysql. That will speed up things up.Also your query should be better. See below and use it, you will see the difference
Select ID , User, max(LoginTime) as date
from tblUserLoginRecord
group by User
You need to build better queries for better results which will help beyond your expectations.
I know the title doesn't make sense, I don't know how to reworded it.
So here's what I'm facing right now. I have one table, a big one, it has almost 2M rows. This is the table and it already filtered by NoRegis=1411940 and Jumlah>0
|| Kode || Nama || Kali || Hari || Resep || Jumlah ||
++======++======++======++======++=======++========++
||AL-128||SP 5 || || ||A ||5.00 ||
||AL-132||SP 10 || || ||A ||3.00 ||
||AL-132||SP 10 || || ||A ||7.00 ||
||DS-074||PARACE||3 ||1 ||R ||10.00 ||
||DS-119||ASP 81||1 ||1 ||R ||5.00 ||
||AL-242||VEN 2 || || ||A ||1.00 ||
||AL-242||VEN 2 || || ||R ||1.00 ||
I want a result that only consist of data that has Resep='R'. Something like this:
|| Kode || Nama || Kali || Hari || Resep || Jumlah ||
++======++======++======++======++=======++========++
||DS-074||PARACE||3 ||1 ||R ||10.00 ||
||DS-119||ASP 81||1 ||1 ||R ||5.00 ||
see, the last data (AL-242) has two rows consist of both Resep='R' and Resep='A', I tried something simple like
SELECT Kode,Nama,Kali,Hari,Resep,sum(Jumlah) FROM Frm_Ranap
where NoRegis=1411940 and Jumlah>0 and resep<>'A' GROUP by Kode
But I still got AL-242, which is not supposed to be there. I also tried something like
SELECT Kode,Nama,Kali,Hari,Resep,sum(Jumlah) FROM Frm_Ranap
WHERE kode not in (
select Kode FROM Frm_Ranap WHERE NoRegis=1411940 and Jumlah>0 and Resep='A')
and NoRegis=1411940 and Jumlah>0 GROUP by Kode
but every time I tried to run this query, it never show me any result and can't stop working, maybe because it has too much data.
Any sugestion?
Let's stick with the first query that returns. You just need to move the condition on A to a having clause instead of a where clause:
SELECT Kode, Nama, Kali, Hari, Resep, sum(Jumlah)
FROM Frm_Ranap
WHERE NoRegis = 1411940 and Jumlah > 0
GROUP by Kode
HAVING sum(resep = 'A') = 0;
The having expression counts the number of rows in each group (i.e. for each kode) that match the condition. The = 0 specifies that there are no such rows in the group.
You first select all rows that don't have what you want:
SELECT Kode FROM Frm_Ranap where resep<>'R' GROUP by Kode
Then you select the ones you want, but not the ones that are in the first select:
SELECT Kode,Nama,Kali,Hari,Resep,sum(Jumlah) FROM Frm_Ranap where NoRegis=1411940 and Jumlah>0 and Kode not in (SELECT Kode FROM Frm_Ranap where resep<>'R' GROUP by Kode) group by Jumlah
I Think this might help you
SELECT Kode,Nama,Kali,Hari,Resep,sum(Jumlah)
FROM Frm_Ranap
WHERE NoRegis=1411940
AND Jumlah>0
AND resep<>'A'
AND SUBSTRING(Kode, 1, 2) != 'AL'
GROUP by Kode
SUBSTRING(Kode, 1, 2) != 'AL' will filter the record which you want to eliminate
You can use not exists to select kode that doesn't have any Resep of type A. Generally, not exists is faster than not in when the subquery returns a large result set and the table is properly indexed.
select Kode,Nama,Kali,Hari,Resep,sum(Jumlah)
from Frm_Ranap t1
where NoRegis=1411940 and Jumlah>0 and Resep <> 'A'
and not exists (select 1 from Frm_Ranap t2
where t2.Kode = t1.Kode and t2.Resep = 'A'
and t2.NoRegis = 1411940 and t2.Jumlah > 0)
group by Kode
This query can take advantage of a composite index on (NoRegis,Kode,Resep,Jumlah)
Table is like this:
id || name || team || goals || data
1 || Kitten || Pets || 3 || 12
2 || Dog || Pets || 2 || 11
3 || Kitten || Animals || 5 || 6
4 || Kitten || Cats || 4 || 3
5 || Dog || Pets || 2 || 9
My basic query is:
SELECT name, team, SUM(goals), SUM(data) FROM table GROUP BY name
Results are like:
name || team || sum(goals) || sum(data)
Kitten || Pets || 12 || 21
Dog || Pets || 4 || 20
I want to be able to get the most recent team (the highest id), but so far all I've been able to get is the first team listed with the query as written. I can get the first or last team alphabetically by using min(team) or max(team), but that doesn't always give the last record that I need. Help? Also, sorry I don't know how to format things well here.
There are different ways of doing this, but here is one.
You can get the most recent record for each team like this:
select * from table where id in(select max(id) from table group by team)
I think this may be what you're asking for:
SELECT name, team, SUM(goals), SUM(data)
FROM table t1
JOIN (SELECT team
FROM table
ORDER BY id DESC
LIMIT 1) t2
ON t1.team = t2.team
GROUP BY name
I'm implementing a leaderboard for our group project.
this is my query for counting the number of status userid 2 have in the table.
$query = "SELECT COUNT(content) FROM status WHERE userid=2 ";
now, how could i query the userid with most number of status?
example table
|| content || userid ||
|| x || 1 ||
|| xx || 1 ||
|| y || 2 ||
|| yy || 2 ||
|| yyy || 2 ||
|| z || 3 ||
with result
1st = 2 with 3 status
2nd = 1 with 2 status
3rd = 3 with 1 status
what will i do to limit the result? what if i only need the top 5?
in relation to this problem
i was thinking of adding another column(number_of_status) in the user table instead of this multiple queries... which is better?
THANK YOU!
Should be able to do this with a GROUP BY:
SELECT userid, COUNT(*) AS status_count
FROM status
GROUP BY userid
ORDER BY status_count DESC
LIMIT 5
You can achieve this with a GROUP BY query, and LIMIT.
SELECT userid, COUNT(content) as statuses
FROM status
GROUP BY userid
ORDER BY statuses DESC
LIMIT 5