Split multiple count using in mysql with same table - mysql

I have a query in below format:
SELECT ETM.etm_Taxonomy, COUNT( PE.pp_profileID ) AS total_counts
FROM expertise_taxonomymaster AS ETM
LEFT JOIN expertise_taxonomy AS ET ON ETM.etm_ID = ET.`et_Taxonomy`
LEFT JOIN expertise AS E ON E.et_Taxonomy = ET.`et_ID`
LEFT JOIN profile_expertise AS PE ON PE.pp_expertiseID = E.et_ID
WHERE PE.pp_profileID IN (
SELECT PJ.pj_profileID
FROM jobtitle_taxonomymaster AS JTM
LEFT JOIN jobtitle_taxonomy AS JT ON JTM.jtm_ID = JT.`jt_Taxonomy`
LEFT JOIN jobtitle AS J ON J.jt_taxonomy = JT.`jt_ID`
LEFT JOIN profile_jobtitle AS PJ ON PJ.pj_jobtitleID = J.jt_ID
WHERE JTM.jtm_Taxonomy = 'Associate'
OR JTM.jtm_Taxonomy = 'Partner'
)
AND et_lawfirmID in (195,196)
GROUP BY etm_Taxonomy
And I have results as follows:
etm_Taxonomy total_counts
Advertising 18
Antitrust 47
Banking 258
But I need below results, Count should be split based on the JTM.ttm_Taxonomy field
etm_Taxonomy Patners195 Partners196 Associates195 Associates196
Advertising 18 18 18 18
Antitrust 47 47 47 47
Banking 258 258 258 258

Try this way:
SELECT ETM.etm_Taxonomy,
SUM (CASE WHEN PJ_TAX.jtm_Taxonomy = 'Associate' THEN 1 ELSE 0 END) AS Associates,
SUM (CASE WHEN PJ_TAX.jtm_Taxonomy = 'Partner' THEN 1 ELSE 0 END) AS Partners,
SUM (CASE WHEN PJ_TAX.jtm_Taxonomy = 'Consultant' THEN 1 ELSE 0 END) AS Consultants,
SUM (CASE WHEN PJ_TAX.jtm_Taxonomy = 'Counsel' THEN 1 ELSE 0 END) AS Counsels,
COUNT(PE.pp_profileID ) AS total_counts
FROM expertise_taxonomymaster AS ETM
LEFT JOIN expertise_taxonomy AS ET ON ETM.etm_ID = ET.`et_Taxonomy`
LEFT JOIN expertise AS E ON E.et_Taxonomy = ET.`et_ID`
LEFT JOIN profile_expertise AS PE ON PE.pp_expertiseID = E.et_ID
INNER JOIN
(
SELECT DISTINCT PJ.pj_profileID,JTM.jtm_Taxonomy
FROM jobtitle_taxonomymaster AS JTM
LEFT JOIN jobtitle_taxonomy AS JT ON JTM.jtm_ID = JT.`jt_Taxonomy`
LEFT JOIN jobtitle AS J ON J.jt_taxonomy = JT.`jt_ID`
LEFT JOIN profile_jobtitle AS PJ ON PJ.pj_jobtitleID = J.jt_ID
WHERE JTM.jtm_Taxonomy = 'Associate'
OR JTM.jtm_Taxonomy = 'Partner'
OR JTM.jtm_Taxonomy = 'Consultant'
OR JTM.jtm_Taxonomy = 'Counsel'
) as PJ_TAX
ON PE.pp_profileID= PJ_TAX.pj_profileID
WHERE et_lawfirmID =195
GROUP BY etm_Taxonomy

First of all: Your left outer joins are no outer joins really, because in your WHERE clause you say you want certain ETs and PEs only.
Mainly you want to join everything, then see whether partner or associate and whether 195 or 196 and count accordingly. This can be done with a CASE construct inside COUNT. Only problem may be duplicates leading to incorrect counts. Im am not completely sure about your database structure. In case there can be duplicate profileIDs with your inner query, you need a derived query with distinct, rather than just joining everything directly. Check if this works for you:
select
etm.etm_taxonomy,
count(case when t.jtm_taxonomy = 'Partner' and et_lawfirmid = 195 then 1 end) as patners195,
count(case when t.jtm_taxonomy = 'Partner' and et_lawfirmid = 196 then 1 end) as patners196,
count(case when t.jtm_taxonomy = 'Associate' and et_lawfirmid = 195 then 1 end) as associates195,
count(case when t.jtm_taxonomy = 'Associate' and et_lawfirmid = 196 then 1 end) as associates196
from expertise_taxonomymaster as etm
join expertise_taxonomy as et on etm.etm_id = et.et_taxonomy
join expertise as e on e.et_taxonomy = et.et_id
join profile_expertise as pe on pe.pp_expertiseid = e.et_id
join
(
select distinct pj.pj_profileid, jtm.jtm_taxonomy
from jobtitle_taxonomymaster as jtm
join jobtitle_taxonomy as jt on jtm.jtm_id = jt.jt_taxonomy
join jobtitle as j on j.jt_taxonomy = jt.jt_id
join profile_jobtitle as pj on pj.pj_jobtitleid = j.jt_id
where jtm.jtm_taxonomy in ('Associate', 'Partner')
) as t on t.pj_profileid = pe.pp_profileid
where et.et_lawfirmid in (195,196);
group by etm.etm_taxonomy;

Related

MySQL JOIN with count / distinct

I've got multiple tables in my database.
Below is my SQL. It all works well for the majority.
How my system works is I may have a game which may sit in multiple competitions therefore will get called into this query more than once through the various JOINS.
It's like Liverpool playing a game but that game earns points for two competitions. It's not two games even though it'll appear twice. It's also not two rows in my database table 'game'.
What I have works for everything but the games that are in two competitions and where I want to do a few counts.
So my query code at the bottom works, but if I try add in
SUM(CASE WHEN g.isRanfurly = 1 THEN 1 ELSE 0 END) as TTLTests,
then this fails as it counts those games twice.
Any ideas?
SELECT DISTINCT(g.gameId), gd.playerId, t.teamName,
COUNT(distinct gd.gameId) as Appearances,
SUM(gd.tries) as TTLTries,
COUNT(CASE WHEN g.isTestMatch = 1 THEN 1 ELSE 0 END) as TTLTests,
IF(gd.homeaway = 1, g.team1Id, g.team2Id) as myteamId
FROM `gamedata` gd
JOIN `games` g ON gd.gameId = g.gameId
JOIN `teams` t ON t.teamId = IF(gd.homeaway = 1, g.team1Id, g.team2Id)
JOIN `roundgames` rg ON rg.gameId = gd.gameId
JOIN `rounds` r ON r.roundId = rg.roundId
JOIN `competitions` c ON r.competitionId = c.competitionId
WHERE `playerId` = 1 AND `didntPlay` = 0 AND t.teamType = 2
group by t.teamName
You can try the below - remove the else 0 from the conditional count
SELECT gd.playerId, t.teamName,
COUNT(distinct gd.gameId) as Appearances,
SUM(gd.tries) as TTLTries,
COUNT(CASE WHEN g.isTestMatch = 1 THEN 1 END) as TTLTests,
IF(gd.homeaway = 1, g.team1Id, g.team2Id) as myteamId
FROM `gamedata` gd
JOIN `games` g ON gd.gameId = g.gameId
JOIN `teams` t ON t.teamId = IF(gd.homeaway = 1, g.team1Id, g.team2Id)
JOIN `roundgames` rg ON rg.gameId = gd.gameId
JOIN `rounds` r ON r.roundId = rg.roundId
JOIN `competitions` c ON r.competitionId = c.competitionId
WHERE `playerId` = 1 AND `didntPlay` = 0 AND t.teamType = 2
group by gd.playerId, t.teamName
The solution was to use DISTINCT within the SUM
SUM(CASE WHEN g.isTestMatch = 1 THEN gd.tries ELSE 0 END) as TTLTestTries,

MySQL select two columns multiple name value pair

I need help about generating query for multiple column.
part of my tbl_advert_specific_fields_values table look like:
id advert_id field_name field_value
1 654 t1_sqft 50
2 655 t1_yearbuilt 1999
3 1521 t2_doorcount 5
4 656 t1_yearbuilt 2001
5 656 t1_sqft 29
6 654 t1_yearbuilt 2004
SELECT p.*, p.id AS id, p.title AS title, usr.id as advert_user_id,
p.street_num, p.street,c.icon AS cat_icon,c.title AS cat_title,c.title AS cat_title,
p.description as description,
countries.title as country_name,
states.title as state_name,
date_FORMAT(p.created, '%Y-%m-%d') as fcreated
FROM tbl AS p
LEFT JOIN tbl_advertmid AS pm ON pm.advert_id = p.id
INNER JOIN tbl_usermid AS am ON am.advert_id = p.id
LEFT JOIN tbl_users AS usr ON usr.id = am.user_id
INNER JOIN tbl_categories AS c ON c.id = pm.cat_id
INNER JOIN tbl_advert_specific_fields_values AS asfv ON asfv.advert_id = p.id
LEFT JOIN tbl_countries AS countries ON countries.id = p.country
LEFT JOIN tbl_states AS states ON states.id = p.locstate
WHERE p.published = 1 AND p.approved = 1 AND c.published = 1
AND (asfv.field_name = 't1_yearbuilt'
AND CONVERT(asfv.field_value,SIGNED) <= 2004 )
AND (asfv.field_name = 't1_sqft'
AND CONVERT(asfv.field_value,SIGNED) <= 50)
AND p.price <= 10174945 AND (p.advert_type_id = 1)
AND (c.id = 43 OR c.parent = 43)
GROUP BY p.id
ORDER BY p.price DESC
ok, the problem is in this asfv query part that are generated dynamically. It belong to objects which represent adverts by its specific fields. asfv is actually advert_specific_fields_values table (table name say all about it).
Without part:
AND (asfv.field_name = 't1_yearbuilt'
AND CONVERT(asfv.field_value,SIGNED) <= 2004 )
AND (asfv.field_name = 't1_sqft'
AND CONVERT(asfv.field_value,SIGNED) <= 50)
query return all adverts that belong on advert_type_id and price of them are less than 10.174.945,00 €.
All what I need is query update that return only adverts, for example t1_yearbuilt less than 2005 and t1_sqft less than 51 (advert_id => 654,656).
I also need query for values between for example t1_sqft >=30 AND t1_sqft <=50 (advert_id => 654).
Can anybody know how, update this query?
TNX

Unable to get exact result using left outer join in mysql banking system?

SELECT
BB.NAME BranchName,
VI.NAME Village,
COUNT(BAC.CBSACCOUNTNUMBER) 'No.Of Accounts',
SUM(BAC.CURRENTBALANCE) SumOfAmount,
SUM(CASE
WHEN transactiontype = 'C' THEN amount
ELSE 0
END) AS CreditTotal,
SUM(CASE
WHEN transactiontype = 'D' THEN amount
ELSE 0
END) AS DebitTotal,
SUM(CASE
WHEN transactiontype = 'C' THEN amount
WHEN transactiontype = 'D' THEN - 1 * amount
ELSE 0
END) AS CurrentBalance
FROM CUSTOMER CU
JOIN APPLICANT AP
ON AP.CUSTOMER_CODE = CU.CODE
JOIN ADDRESS AD
ON AD.ENTITYCODE = AP.CODE
JOIN VILLAGE VI
ON VI.CODE = AD.VILLAGE_CODE
AND VI.STATE_CODE = AD.STATE_CODE
AND VI.DISTRICT_CODE = AD.DISTRICT_CODE
AND VI.BLOCK_CODE = AD.BLOCK_CODE
AND VI.PANCHAYAT_CODE = AD.PANCHAYAT_CODE
JOIN BANKBRANCH BB
ON BB.CODE = CU.BANKBRANCH_CODE
JOIN BANKACCOUNT BAC
ON BAC.ENTITYCODE = CU.CODE
LEFT OUTER JOIN accounttransaction ACT
ON ACT.BANKACCOUNT_CBSACCOUNTNUMBER= BAC.CBSACCOUNTNUMBER
AND ACT.TRANDATE <= '2013-07-01'
AND BAC.ACCOUNTOPENINGDATE < '2013-07-01'
WHERE BAC.ENTITY = 'CUSTOMER'
AND AD.ENTITY = 'APPLICANT'
GROUP BY BB.NAME,VI.NAME;
Here in one branch from the BANKBRANCK table having 263 accounts when I executed the above query using Left outer join the count is increasing to 293 which is wrong because only accounts opened under that branch is 263 the result is 293 which is wrong.
If I remove the Left outer join then my result is 263 for one branch when I include the Left out join then count is increasing to 293, please help me where is the problem
This is the continuous for the below question
http://stackoverflow.com/questions/17277899/unable-to-get-left-outer-join-result-in-mysql-query/17279769#17279769
This Part
LEFT OUTER JOIN accounttransaction ACT
ON ACT.BANKACCOUNT_CBSACCOUNTNUMBER= BAC.CBSACCOUNTNUMBER
AND ACT.TRANDATE <= '2013-07-01'
AND BAC.ACCOUNTOPENINGDATE < '2013-07-01'
Allows for more than 1 row on the accounttransaction table to be returned, which will allow the row count to increase from 263 to 293. Left Join does not implicitly limit the joined data to only one match.

MySQL Row Output Cells into Columns

My question is how do you get row cell output into separate columns to make viewing that data more readable.
I have the following SQL Query:
SELECT TD.name AS Conditions, PV.value AS Frequency, MSL.name AS
Mailing_List_Subscriptions, Count(CI.uid) AS Users_Signup_Count
FROM conditions_interest CI
INNER JOIN profile_values PV
ON CI.uid = PV.uid
INNER JOIN hwmailservice_user_lists MSUL
ON CI.uid = MSUL.uid
INNER JOIN hwmailservice_lists MSL
ON MSUL.list_id = MSL.list_id
INNER JOIN term_data TD
ON CI.tid = TD.tid
WHERE (PV.value = 'daily' OR PV.value = 'weekly') AND CI.email = '1'
GROUP BY PV.value, TD.name, MSL.name
ORDER BY TD.name;
With the following output:
So all the mailing list subscriptions would have there own separate column with the counts associated with the conditions. So like this:
Conditions Frequency Newsletter Partners Annoucements marketing
Abscessed Tooth Daily 95 91 98 98
Abscessed Tooth Weekly 6 4 7 7
If more clarification is needed I will edit my post.
MySQL does not have a PIVOT function which is what you are doing, so you will want to use a CASE:
SELECT x.Conditions,
x.Frequency,
SUM(CASE WHEN Mailing_List_Subscriptions = 'newsletter' THEN Users_Signup_Count END) newsletter,
SUM(CASE WHEN Mailing_List_Subscriptions = 'partners' THEN Users_Signup_Count END) partners,
SUM(CASE WHEN Mailing_List_Subscriptions = 'announcements' THEN Users_Signup_Count END) announcements,
SUM(CASE WHEN Mailing_List_Subscriptions = 'marketing' THEN Users_Signup_Count END) marketing
FROM
(
SELECT TD.name AS Conditions, PV.value AS Frequency,
MSL.name AS Mailing_List_Subscriptions,
Count(CI.uid) AS Users_Signup_Count
FROM conditions_interest CI
INNER JOIN profile_values PV
ON CI.uid = PV.uid
INNER JOIN hwmailservice_user_lists MSUL
ON CI.uid = MSUL.uid
INNER JOIN hwmailservice_lists MSL
ON MSUL.list_id = MSL.list_id
INNER JOIN term_data TD
ON CI.tid = TD.tid
WHERE (PV.value = 'daily' OR PV.value = 'weekly') AND CI.email = '1'
GROUP BY PV.value, TD.name, MSL.name
) x
GROUP BY x.Conditions, x.Frequency
ORDER BY x.name

How can I make more than one select queries in single select query.

I have to write a query where, I need to fetch records for last week, last month, and for all.
For this problem I wrote 3 diffrent queries (for last week, for last month and for all)
For Weekly Info :-
SELECT bu.brand_name AS 'Brand_Name',COUNT(s.unique) AS '# Item Sold',SUM(s.price) AS 'Total_Price'
FROM item_details s
LEFT JOIN sales_order o ON s.fk_sales_order = o.id_sales_order
LEFT JOIN customer_info AS c ON o.fk_customer_id = c.id_customer
LEFT JOIN simple_details cc ON s.unique = cc.unique
LEFT JOIN config_details cf ON cc.fk_config_id = cf.config_id
LEFT JOIN brand_details cb ON cf.fk_brand_id = cb.brand_id
LEFT JOIN category_details ctc ON cf.fk_category_id = ctc.category_id
LEFT JOIN gender_details g ON cf.fk_gender_id = g.gender_id
LEFT JOIN buyers AS bu ON bu.brand_name = cb.name AND bu.category_name = ctc.name AND bu.gender = g.name
WHERE bu.buyers = 'xyz' AND DATE_FORMAT(o.created_date,'%Y-%m-%d') >= #weekstartdate AND DATE_FORMAT(o.created_date,'%Y-%m-%d') <= #weekenddate
GROUP BY bu.brand_name
For Monthly Info :-
SELECT bu.brand_name AS 'Brand_Name',COUNT(s.unique) AS '# Item Sold',SUM(s.price) AS 'Total_Price'
FROM item_details s
LEFT JOIN sales_order o ON s.fk_sales_order = o.id_sales_order
LEFT JOIN customer_info AS c ON o.fk_customer_id = c.id_customer
LEFT JOIN simple_details cc ON s.unique = cc.unique
LEFT JOIN config_details cf ON cc.fk_config_id = cf.config_id
LEFT JOIN brand_details cb ON cf.fk_brand_id = cb.brand_id
LEFT JOIN category_details ctc ON cf.fk_category_id = ctc.category_id
LEFT JOIN gender_details g ON cf.fk_gender_id = g.gender_id
LEFT JOIN buyers AS bu ON bu.brand_name = cb.name AND bu.category_name = ctc.name AND bu.gender = g.name
WHERE bu.buyers = 'xyz' AND DATE_FORMAT(o.created_date,'%Y-%m-%d') >= #monthstartdate AND DATE_FORMAT(o.created_date,'%Y-%m-%d') <= #monthenddate
GROUP BY bu.brand_name
For All Records :-
SELECT bu.brand_name AS 'Brand_Name',COUNT(s.unique) AS '# Item Sold',SUM(s.price) AS 'Total_Price'
FROM item_details s
LEFT JOIN sales_order o ON s.fk_sales_order = o.id_sales_order
LEFT JOIN customer_info AS c ON o.fk_customer_id = c.id_customer
LEFT JOIN simple_details cc ON s.unique = cc.unique
LEFT JOIN config_details cf ON cc.fk_config_id = cf.config_id
LEFT JOIN brand_details cb ON cf.fk_brand_id = cb.brand_id
LEFT JOIN category_details ctc ON cf.fk_category_id = ctc.category_id
LEFT JOIN gender_details g ON cf.fk_gender_id = g.gender_id
LEFT JOIN buyers AS bu ON bu.brand_name = cb.name AND bu.category_name = ctc.name AND bu.gender = g.name
WHERE bu.buyers = 'xyz'
GROUP BY bu.brand_name
and these are working fine (giving currect output).
But problem is that, I have to merge these three queries in single one.
Where output should be as
Brand name, item_sold(week), total_price(week),item_sold(month), total_price(month),item_sold(all), total_price(all)
How can I write this query?
Without looking deep into your code, the obvious solution would be
SELECT
all.brand_name
pw.items_sold items_sold_week
pw.total_price total_price_week
pm.items_sold items_sold_month
pm.total_price total_price_month
all.items_sold items_sold_all
all.total_price total_price_all
FROM
(your all-time select) all
JOIN (your per-month select) pm ON all.brand_name = pm.brand_name
JOIN (your per-week select) pw ON all.brand_name = pw.brand_name
Though you probably should rethink your entire approach and make sure whether you really want that kind of logic in a DB layer or it is better to be in your application.
You could use case to limit aggregates to a subset of rows:
select bu.brand_name
, count(case when date_format(o.created_date,'%Y-%m-%d') >= #weekstartdate
and date_format(o.created_date,'%Y-%m-%d') <= #weekenddate
then 1 end) as '# Item Sold Week'
, sum(case when date_format(o.created_date,'%Y-%m-%d') >= #weekstartdate
and date_format(o.created_date,'%Y-%m-%d') <= #weekenddate
then s.price end) as 'Total_Price Week'
, count(case when date_format(o.created_date,'%Y-%m-%d') >= #monthstartdate
and date_format(o.created_date,'%Y-%m-%d') <= #monthstartdate
then 1 end) as '# Item Sold Month'
, ...
If all three selects uses the same fields in the results, you can UNION them:
SELECT *
FROM (SELECT 1) AS a
UNION (SELECT 2) AS b
UNION (SELECT 3) AS c
If you need to tell week/mon/all records from each other - just add constant field containing "week" or "mon"
You cam use the UNION.keyword between the queries to bundle them.together BUT tje column types and sequence must be the same in all queries. You could add an identifier to each set