how to simplify the selection query - mysql

I have to selection queries like below in a stored procedure.
SELECT #licenseCount = COUNT(*) FROM ServicePool SP
INNER JOIN UserPackages UP ON UP.ServicePoolId = SP.Id
AND SP.UserId = UP.UserId
INNER JOIN Package P ON P.Id = UP.PackageId
LEFT OUTER JOIN CompanyProfile C ON C.LicenseId = SP.Id
INNER JOIN CompanyProfile CP ON CP.CurrencyId = P.CurrencyId
INNER JOIN PackageCategory PC ON PC.OrganizationTypeId = CP.OrganisationType
AND PC.PackageId = P.Id
WHERE SP.Active = 1
AND SP.UserId = #uId
AND P.Active = 1
and CP.CompanyID = #cId
and ISNULL(C.CompanyID,0) = 0
AND DATEDIFF(DAY,GETDATE(),DATEADD(DAY,P.ValidityPeriod,UP.PurchaseDate)) > 0
SELECT #paymentCount = COUNT(*) FROM ServicePool SP
INNER JOIN UserPackages UP ON UP.ServicePoolId=SP.Id
AND SP.UserId = UP.UserId
INNER JOIN Package P ON P.Id = UP.PackageId
LEFT OUTER JOIN CompanyProfile C ON C.LicenseId = SP.Id
INNER JOIN CompanyProfile CP ON CP.CurrencyId = P.CurrencyId
INNER JOIN PackageCategory PC ON PC.OrganizationTypeId = CP.OrganisationType
AND PC.PackageId = P.Id
WHERE SP.Active = 1
AND SP.UserId = #uId
AND P.Active = 1
and CP.CompanyID = #cId
and ISNULL(C.CompanyID,0) = 0
AND DATEDIFF(DAY,GETDATE(),DATEADD(DAY,P.ValidityPeriod,UP.PurchaseDate)) > 0
AND UP.PaymentStatus = 'P'
As you can see, the only difference between the above two selection queries is that, at the end of second one, there is an extra where condition, AND UP.PaymentStatus = 'P'.
So I was wondering is there any way I can simplify this queries?

Below would be the query
SELECT #licenseCount = COUNT(*), #paymentCount = COUNT(case when UP.PaymentStatus = 'P' then 1 else 0 end) FROM ServicePool SP
INNER JOIN UserPackages UP ON UP.ServicePoolId = SP.Id
AND SP.UserId = UP.UserId
INNER JOIN Package P ON P.Id = UP.PackageId
LEFT OUTER JOIN CompanyProfile C ON C.LicenseId = SP.Id
INNER JOIN CompanyProfile CP ON CP.CurrencyId = P.CurrencyId
INNER JOIN PackageCategory PC ON PC.OrganizationTypeId = CP.OrganisationType
AND PC.PackageId = P.Id
WHERE SP.Active = 1
AND SP.UserId = #uId
AND P.Active = 1
and CP.CompanyID = #cId
and ISNULL(C.CompanyID,0) = 0
AND
DATEDIFF(DAY,GETDATE(),DATEADD(DAY,P.ValidityPeriod,UP.PurchaseDate))
You can define #paymentCount variable in the first query itself
Test Results -
hive> select * from test_so_t1;
OK
123 90001 90001
123 90001 90002
123 90001 90003
123 90002 90001
123 90002 90002
123 90003 90002
123 90003 90003
Time taken: 0.118 seconds, Fetched: 7 row(s)
hive> select count(case when mem_id=90001 then 1 else 0 end) as groupBy, group_id from test_so_t1 group by group_id;
Total MapReduce CPU Time Spent: 3 seconds 900 msec
OK
7 123
Time taken: 17.271 seconds, Fetched: 1 row(s)

Related

A query is taking 9 hours to import 1.900.000 rows from Database A to Amazon Quicksight

Log History:
2020/04/13 22:12:36 Completed
Ingestion completed in 9 hours 22 minutes 1 seconds.
Rows dropped: 0, Rows ingested: 1916870
Manual, Full refresh
SELECT
uc.name,
u.username AS usuario,
u.firstname,
u.lastname,
c.fullname AS titulo_bit,
CASE
WHEN EXISTS(SELECT ci.id
FROM mdl_certificate_issues ci
LEFT JOIN mdl_certificate ce ON (ci.certificateid = ce.id)
WHERE ci.userid = u.id
AND ce.course = c.id)
THEN 100
ELSE
ROUND(COUNT(cmc.completionstate) * 100 / (SELECT COUNT(*)
FROM mdl_course_modules
WHERE course = cm.course
AND deletioninprogress IS false
AND completion IS true))
END AS porcentaje_avance_bit,
uai.company_area AS area_old,
u.department,
u.address,
u.institution,
muca.name AS area,
FROM_UNIXTIME(cmc.timemodified) as course_progress_time
FROM mdl_course_modules_completion cmc
LEFT JOIN mdl_course_modules cm ON (cmc.coursemoduleid = cm.id)
LEFT JOIN mdl_course c ON (cm.course = c.id)
LEFT JOIN mdl_user u ON (cmc.userid = u.id)
LEFT JOIN mdl_u_user_additional_info uai ON (u.id = uai.mdl_user_id)
LEFT JOIN mdl_u_company_area muca ON uai.company_area_id = muca.id
RIGHT JOIN mdl_u_company uc ON (uai.mdl_u_company_id = uc.id)
WHERE cm.deletioninprogress IS false
AND cm.completion IS true
AND cmc.completionstate != 0
AND u.deleted IS FALSE
AND c.visible IS TRUE
GROUP BY cm.course, cmc.userid, uc.name, uai.company_area, muca.id, FROM_UNIXTIME(cmc.timemodified)
ORDER BY usuario, course_progress_time desc

mysql form subarray(array aggregation) and return

I have the following mysql query
select m.flat_id,
f.flat_no,
fo.owner_name,
oc.occupant_name,
b.block_name,
f.floor_no,
f.floor_id,
m.user_id as user_map_id
from svk_apt_flats_users_mapping m
left join svk_apt_users u on u.user_id = m.user_id and u.association_id = 2
and u.customer_id = 2 and u.is_active = 1 and u.user_id is not null
left join svk_apt_flats f on f.flat_id = m.flat_id and f.is_active = 1
left join svk_apt_blocks b on b.block_id = f.block_id and b.is_active = 1
left join svk_apt_flat_owners fo on u.user_role_type_id = 4 and fo.is_active = 1 and fo.user_id = m.user_id
left join svk_apt_occupants oc on u.user_role_type_id = 5 and oc.is_active = 1 and oc.user_id = m.user_id
where f.block_id = 3
and m.user_id <> 2
and m.customer_id = 2
and m.association_id = 2
and m.is_active = 1
and m.is_active = 1
and (case when m.user_role_type_id = 5 then true else m.is_approved = 1 end)
and Output :
I want to aggregate the rows who have same 'user_map_id' into one row.
Is there any solutions in mysql ?
Use group by
select m.flat_id,
f.flat_no,
fo.owner_name,
oc.occupant_name,
b.block_name,
f.floor_no,
f.floor_id,
m.user_id as user_map_id
from svk_apt_flats_users_mapping m
left join svk_apt_users u on u.user_id = m.user_id and u.association_id = 2
and u.customer_id = 2 and u.is_active = 1 and u.user_id is not null
left join svk_apt_flats f on f.flat_id = m.flat_id and f.is_active = 1
left join svk_apt_blocks b on b.block_id = f.block_id and b.is_active = 1
left join svk_apt_flat_owners fo on u.user_role_type_id = 4 and fo.is_active = 1 and fo.user_id = m.user_id
left join svk_apt_occupants oc on u.user_role_type_id = 5 and oc.is_active = 1 and oc.user_id = m.user_id
where f.block_id = 3
and m.user_id <> 2
and m.customer_id = 2
and m.association_id = 2
and m.is_active = 1
and m.is_active = 1
and (case when m.user_role_type_id = 5 then true else m.is_approved = 1 end)
group by u.user_role_type_id;
MySQL will pick the values of the first row for all columns if you do not specifiy an aggregate function like SUM, AVG etc. onto them

Split multiple count using in mysql with same table

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;

How to Sum & Group By the results of a Union select query

I have a query which Union's two separate queries with the same fields / data types. The query is as follows:
SELECT BusinessUnitName, BuildingNumber, Description, Value_1,
LifeRemaining, Sum_Quant
FROM
(
SELECT bu.BusinessUnitName, b.BuildingNumber, ec.Description, SUM(cc.MonetaryValue) AS Value_1,
cc.LifeRemaining, SUM(a.Quantity) AS Sum_Quant
FROM tbBuildingLinkBusinessUnit as blb INNER JOIN
tbBusinessUnit as bu ON blb.BusinessUnitID = bu.BusinessUnitID INNER JOIN
tbBuilding as b ON blb.BuildingID = b.BuildingID INNER JOIN
tbFloor ON b.BuildingID = tbFloor.BuildingID INNER JOIN
tbRoom as r ON tbFloor.FloorID = r.FloorID INNER JOIN
tbConditionComponent as cc INNER JOIN
tbAsset as a ON cc.ParentID = a.AssetUID INNER JOIN
tbElement as e ON cc.ElementID = e.ElementID AND a.ElementID = e.ElementID INNER JOIN
tbElementCategory as ec ON e.ElementCategoryID = ec.ElementCategoryID ON r.RoomID = a.LocationID
WHERE (cc.MonetaryValue > 0)
GROUP BY bu.BusinessUnitName, b.BuildingNumber, ec.Description, a.Status, cc.LifeRemaining
HAVING (a.Status = 0)
UNION
SELECT bu.BusinessUnitName, b.BuildingNumber, ec.Description, SUM(cc.MonetaryValue) AS Value_1,
cc.LifeRemaining, SUM(a.Quantity) AS Sum_Quant
FROM tbBuildingLinkBusinessUnit as blb INNER JOIN
tbBusinessUnit as bu ON blb.BusinessUnitID = bu.BusinessUnitID INNER JOIN
tbBuilding as b ON blb.BuildingID = b.BuildingID INNER JOIN
tbConditionComponent as cc INNER JOIN
tbAsset as a ON cc.ParentID = a.AssetUID INNER JOIN
tbElement as e ON cc.ElementID = e.ElementID AND a.ElementID = e.ElementID INNER JOIN
tbElementCategory as ec ON e.ElementCategoryID = ec.ElementCategoryID ON b.BuildingID = a.LocationID
WHERE (cc.MonetaryValue > 0)
GROUP BY bu.BusinessUnitName, b.BuildingNumber, ec.Description, a.Status, cc.LifeRemaining
HAVING (a.Status = 0)
) AS x
ORDER BY BusinessUnitName, Description
The results of the individual select queries are as follows with the first two lines coming from query 1 and the second two lines coming from query 2:
TEST PROPERTY | 1/A | Electrical services | 515.82 | 0 | 3
TEST PROPERTY | 1/A | Electrical services | 125 | 1 | 2
TEST PROPERTY | 1/A | Electrical services | 381.6 | 0 | 8
TEST PROPERTY | 1/A | Electrical services | 80615.93 | 5 | 7
My question is how can I now amalgamate the results of the the two queries so that the first result from both queries perform a SUM as they both have the value 0 in column 5? This will result in 3 rows of result with rows 1 and 3 combined.
Thanks in advance
Use
Derived GROUP BY your_value
Try like below,
SELECT BusinessUnitName, BuildingNumber, Description,
LifeRemaining, SUM(Value_1) as Value, SUM(Sum_Quant) as Quant
FROM
(
SELECT bu.BusinessUnitName, b.BuildingNumber, ec.Description, SUM(cc.MonetaryValue) AS Value_1,
cc.LifeRemaining, SUM(a.Quantity) AS Sum_Quant
FROM tbBuildingLinkBusinessUnit as blb INNER JOIN
tbBusinessUnit as bu ON blb.BusinessUnitID = bu.BusinessUnitID INNER JOIN
tbBuilding as b ON blb.BuildingID = b.BuildingID INNER JOIN
tbFloor ON b.BuildingID = tbFloor.BuildingID INNER JOIN
tbRoom as r ON tbFloor.FloorID = r.FloorID INNER JOIN
tbConditionComponent as cc INNER JOIN
tbAsset as a ON cc.ParentID = a.AssetUID INNER JOIN
tbElement as e ON cc.ElementID = e.ElementID AND a.ElementID = e.ElementID INNER JOIN
tbElementCategory as ec ON e.ElementCategoryID = ec.ElementCategoryID ON r.RoomID = a.LocationID
WHERE (cc.MonetaryValue > 0)
GROUP BY bu.BusinessUnitName, b.BuildingNumber, ec.Description, a.Status, cc.LifeRemaining
HAVING (a.Status = 0)
UNION
SELECT bu.BusinessUnitName, b.BuildingNumber, ec.Description, SUM(cc.MonetaryValue) AS Value_1,
cc.LifeRemaining, SUM(a.Quantity) AS Sum_Quant
FROM tbBuildingLinkBusinessUnit as blb INNER JOIN
tbBusinessUnit as bu ON blb.BusinessUnitID = bu.BusinessUnitID INNER JOIN
tbBuilding as b ON blb.BuildingID = b.BuildingID INNER JOIN
tbConditionComponent as cc INNER JOIN
tbAsset as a ON cc.ParentID = a.AssetUID INNER JOIN
tbElement as e ON cc.ElementID = e.ElementID AND a.ElementID = e.ElementID INNER JOIN
tbElementCategory as ec ON e.ElementCategoryID = ec.ElementCategoryID ON b.BuildingID = a.LocationID
WHERE (cc.MonetaryValue > 0)
GROUP BY bu.BusinessUnitName, b.BuildingNumber, ec.Description, a.Status, cc.LifeRemaining
HAVING (a.Status = 0)
) Derived GROUP BY BusinessUnitName, BuildingNumber, Description,
LifeRemaining
ORDER BY BusinessUnitName, Description
For reference
https://social.msdn.microsoft.com/forums/sqlserver/en-US/cd32bf58-c581-404b-a384-e62cdda7a131/union-all-and-group-by-query
hope it helps...

mysql query hotel availability (Not calculate the total price)

Search the list of accommodation and the total price..
Here is my query and output: http://sqlfiddle.com/#!2/eaf58/43
query:
SELECT count(candidates.accommodation_id) as total, candidates.accommodation_id, omc_accommodation_season_period.season_id,
room_1, r1_price.price_normal AS room_1_price,
(SELECT SUM(room1_price.price_normal)
FROM omc_accommodation_room_pricelist room1_price
INNER JOIN omc_accommodation_room room1
ON room1_price.accommodation_id = room1.accommodation_id
INNER JOIN omc_accommodation_season_period so1
ON room1_price.accommodation_id = so1.accommodation_id
AND room1_price.season_id = so1.season_id
INNER JOIN omc_accommodation accommodation1
ON room1_price.accommodation_id = accommodation1.id
WHERE
so1.date BETWEEN '2013-08-13' AND '2013-08-15' AND
room1.quantity >= 3 AND room1.pax_max = 1 AND
accommodation1.id = candidates.accommodation_id AND
room1.id = room_1) AS room_1_sum,
room_2,r2_price.price_normal AS room_2_price,
omc_accommodation_season_period.date
FROM (SELECT r1.accommodation_id, r1.id AS room_1,
r2.id AS room_2, r1.quantity AS room_1_quantity,
r2.quantity AS room_2_quantity
FROM
omc_accommodation_room r1
INNER JOIN
omc_accommodation_room r2 ON r1.accommodation_id = r2.accommodation_id
WHERE
r1.quantity >= 3 AND r2.quantity >= 4 AND r1.pax_max = 1 AND r2.pax_max = 2) AS candidates
LEFT JOIN omc_accommodation_season_period
ON candidates.accommodation_id = omc_accommodation_season_period.accommodation_id
AND date BETWEEN '2013-08-13' AND '2013-08-15'
AND omc_accommodation_season_period.date <> 0
LEFT JOIN omc_accommodation_room_extra_quota eq1
ON (candidates.accommodation_id = eq1.accommodation_id
AND room_1 = eq1.room_type_id
AND eq1.date=omc_accommodation_season_period.date)
LEFT JOIN omc_accommodation_room_extra_quota eq2
ON (candidates.accommodation_id = eq2.accommodation_id
AND room_2 = eq2.room_type_id
AND eq2.date=omc_accommodation_season_period.date)
LEFT JOIN omc_accommodation
ON candidates.accommodation_id = omc_accommodation.id
LEFT JOIN omc_accommodation_room_pricelist r1_price
ON (candidates.accommodation_id = r1_price.accommodation_id
AND room_1= r1_price.room_type_id)
LEFT JOIN omc_accommodation_room_pricelist r2_price
ON (candidates.accommodation_id = r2_price.accommodation_id
AND room_1 = r2_price.room_type_id)
WHERE
r1_price.season_id = omc_accommodation_season_period.season_id
AND
r2_price.season_id = omc_accommodation_season_period.season_id
GROUP BY candidates.accommodation_id, omc_accommodation_season_period.date
Problem is just to calculate the total price of each room..
Help me fix it up..
Many thanks in advance
SELECT rsp1.date, rsp1.season_id, r1.hotel_id, r1.id AS room_1, rp1.price_normal AS room_1_price, SUM(rp1.price_normal) AS room_1_total, r2.id AS room_2, rp2.price_normal AS room_2_price
FROM
omc_hotel_room r1
LEFT JOIN omc_hotel_room r2 ON r1.hotel_id = r2.hotel_id
INNER JOIN omc_hotel_room_pricelist rp1 ON r1.hotel_id = rp1.hotel_id AND r1.id = rp1.room_type_id
INNER JOIN omc_hotel_room_pricelist rp2 ON r1.hotel_id = rp1.hotel_id AND r2.id = rp2.room_type_id
LEFT JOIN omc_hotel_season_period rsp1 ON r1.hotel_id = rsp1.hotel_id
WHERE
r1.pax_max = 1 AND
rp1.price_normal <> 0 AND
r2.pax_max = 2 AND
rp2.price_normal <> 0 AND
rsp1.date BETWEEN '2013/08/13' AND '2013/08/15'
GROUP BY r1.hotel_id, rsp1.date