References Outer Query MySQL - mysql

i tried use "Total" in outer where, and i got error "Unknown "AL.Total", how to fix it ?
here my query :
SELECT
AL.CODE,
AL.NAME,
SUM(AL.BEGINING+AL.MUTATION) AS TOTAL
from
(SELECT
ACC.CODE,
ACC.NAME,
ACC.BEGINING,
SUM(JOURNAL.DEBIT-JOURNAL.KREDIT) AS MUTATION
FROM
G_JOURNAL INNER JOIN P ON Category.Category= G_JOURNAL.Category
INNER JOIN JOURNAL ON G_JOURNAL.NOINDEX = JOURNAL.NOINDEX_JOURNAL
INNER JOIN ACCOUNT ON JOURNAL.CODE = ACC.CODE
INNER JOIN SUBCLASS ON SUBCLASS.NOSUBCLASS= ACC.NOSUBCLASS
INNER JOIN CLASS ON SUBCLASS.NOSUBCLASS = CLASS.NOCLASS
WHERE
(MONTH(G_JOURNAL.DATE) <= '12' AND YEAR (G_JOURNAL.DATE<= '2020')
AND
SUBCLASS.NOSUBCLASS=120
GROUP BY ACC.NAME) AL
WHERE AL.TOTAL >0
GROUP BY AL.NAME
ORDER BY AL.CODE ASC

Try HAVING TOTAL >0 instead of WHERE AL.TOTAL >0,because TOTAL
is not in AL temp table
SELECT
AL.CODE,
AL.NAME,
SUM(AL.BEGINING+AL.MUTATION) AS TOTAL
from
(SELECT
ACC.CODE,
ACC.NAME,
ACC.BEGINING,
SUM(JOURNAL.DEBIT-JOURNAL.KREDIT) AS MUTATION
FROM
G_JOURNAL INNER JOIN P ON Category.Category= G_JOURNAL.Category
INNER JOIN JOURNAL ON G_JOURNAL.NOINDEX = JOURNAL.NOINDEX_JOURNAL
INNER JOIN ACCOUNT ON JOURNAL.CODE = ACC.CODE
INNER JOIN SUBCLASS ON SUBCLASS.NOSUBCLASS= ACC.NOSUBCLASS
INNER JOIN CLASS ON SUBCLASS.NOSUBCLASS = CLASS.NOCLASS
WHERE
(MONTH(G_JOURNAL.DATE) <= '12' AND YEAR (G_JOURNAL.DATE<= '2020')
AND
SUBCLASS.NOSUBCLASS=120
GROUP BY ACC.NAME) AL
GROUP BY AL.NAME
HAVING TOTAL >0
ORDER BY AL.CODE ASC

Related

Is there a method of counting an attribute that is in a GROUP BY clause?

I need have created a select statement to list out all the customers that have been to multiple merchants below.
I want to create another statement to display how many of those customers have been to each merchant.
What is the optimal method of approaching this problem?
Lists out all customers that have been to multiple merchants.
WITH valentinesDayMerchant AS (
SELECT m.MerchantId, m.MerchantGroupId, m.WebsiteName
FROM Merchant m
INNER JOIN OpeningHours oh ON m.MerchantId = oh.MerchantId AND oh.DayOfWeek = 'TUE'
LEFT JOIN devices.DeviceConnectionState AS dcs ON dcs.MerchantId = oh.MerchantId
WHERE MerchantStatus = '-' AND (m.PrinterType IN ('V','O') OR dcs.State = 1 OR dcs.StateTransitionDateTime > '2023-01-23')
)
SELECT DISTINCT ul.UserLoginId, ul.FullName, ul.EmailAddress, ul.Mobile
FROM dbo.UserLogin AS ul
INNER JOIN dbo.Patron AS p ON p.UserLoginId = ul.UserLoginId
INNER JOIN valentinesDayMerchant AS m ON (m.MerchantId = ul.ReferringMerchantId OR m.MerchantId IN (SELECT pml.MerchantId FROM dbo.PatronMerchantLink AS pml WHERE pml.PatronId = p.PatronId AND ISNULL(pml.IsBanned, 0) = 0))
LEFT JOIN (
SELECT mg.MerchantGroupId, mg.MerchantGroupName, groupHost.HostName [GroupHostName]
FROM dbo.MerchantGroup AS mg
INNER JOIN dbo.Merchant AS parent ON parent.MerchantId = mg.ParentMerchantId
INNER JOIN dbo.HttpHostName AS groupHost ON groupHost.MerchantID = parent.MerchantId AND groupHost.Priority = 0
) mGroup ON mGroup.MerchantGroupId = m.MerchantGroupId
LEFT JOIN (
SELECT po.PatronId, MAX(po.OrderDateTime) [LastOrder]
FROM dbo.PatronsOrder AS po
GROUP BY po.PatronId
) orders ON orders.PatronId = p.PatronId
INNER JOIN dbo.HttpHostName AS hhn ON hhn.MerchantID = m.MerchantId AND hhn.Priority = 1
WHERE ul.UserLoginId NOT IN (1,2,100,372) AND ul.UserStatus <> 'D' AND (
ISNULL(orders.LastOrder, '2000-01-01') > '2020-01-01' OR ul.RegistrationDate > '2022-01-01'
)
GROUP BY ul.UserLoginId, ul.FullName, ul.EmailAddress, ul.Mobile
HAVING COUNT(m.MerchantId) > 1
Methods I have tried include adding the merchant name to a group by and displaying the count of the customers, however this does not work as I cannot have anything related to the Merchant in the GROUP BY, or I wouldn't be able to use HAVING clause to identify the customers that have been to multiple merchants. I have also tried selecting all the merchants and counting the distinct customers which doesn't work as it takes into account all the customers, not specifically the customers that have been to multiple merchants only.

group and order in mysql

I have to write a query in which I need the given output.
I tried different queries but didn't work.
Actual data :
and I need Output like :
Queries like :
SELECT VCD.id,VCD.effective_date, `VCD`.`charge_id`, `C`.`head`,
`VCD`.`per`, `VCD`.`currency`, `VCD`.`amount`, `VCD`.`remarks`
FROM `vendor_charge` `VC` INNER JOIN `vendor_charge_details` `VCD`
ON `VC`.`id` = `VCD`.`vc_id` LEFT JOIN `charges` `C`
ON `C`.`id` = `VCD`.`charge_id`
WHERE `VC`.`vendor_id` = '12' AND `VCD`.`effective_date` <= '2018-05-22'
GROUP BY `VCD`.`charge_id`, `VCD`.`per`, `VCD`.`currency`
ORDER BY `C`.`head` DESC
and
SELECT VCD.id,VCD.effective_date, `VCD`.`charge_id`, `C`.`head`,
`VCD`.`per`, `VCD`.`currency`, `VCD`.`amount`, `VCD`.`remarks`
FROM `vendor_charge` `VC` INNER JOIN `vendor_charge_details` `VCD`
ON `VC`.`id` = `VCD`.`vc_id` LEFT JOIN `charges` `C`
ON `C`.`id` = `VCD`.`charge_id`
WHERE `VC`.`vendor_id` = '12' AND `VCD`.`effective_date` <= '2018-05-22'
GROUP BY `VCD`.`charge_id`, `VCD`.`per`, `VCD`.`currency`
ORDER BY `VCD`.`effective_date` DESC
I think all you need here is an additional join to a subquery which finds the latest effective_date for each charge_id:
SELECT
VCD.id,
VCD.effective_date,
VCD.charge_id,
C.head,
VC.per,
VCD.currency,
VCD.amount,
VCD.remarks
FROM vendor_charge VC
INNER JOIN vendor_charge_details VCD
ON VC.id = VCD.vc_id
INNER JOIN
(
SELECT charge_id, MAX(effective_date) AS max_effective_date
FROM vendor_charge_details
GROUP BY charge_id
) t
ON VCD.charge_id = t.charge_id AND VCD.effective_date = t.max_effective_date
LEFT JOIN charges C
ON C.id = VCD.charge_id
WHERE VC.vendor_id = '12' AND VCD.effective_date <= '2018-05-22'
ORDER BY
C.head DESC;

slow query with joins

Please am having difficulty in optimizing this query. What am trying to achieve is to join about 8 tables, of which only about 3 of the tables contains large data (1.5m records). This query returns expected records but is taking 1min to run which is bad.
I know it can be optimized to perform far better, pls i need assistance from you experts. I have index on the fields used for join already.
SELECT topic_id,
topic_title,
unit_name_abbrev,
sch_name_abbrev,
picture_small_url AS thumbnail,
profile_pix_upload_path,
first_name,
last_name,
topic_poster,
topic_replies,
topic_views,
topic_last_post_time AS topic_post_time,
sch_sub_forum_id
FROM (_sch_forum_topics
INNER JOIN _users
ON ( _users.userid = _sch_forum_topics.topic_poster )
INNER JOIN _profile
ON _profile.userid = _users.userid
INNER JOIN _class
ON _users.classid = _class.classid
INNER JOIN _level
ON _class.level_id = _level.id
INNER JOIN _unit
ON _class.unitid = _unit.unitid
INNER JOIN _department
ON _unit.deptid = _department.deptid
INNER JOIN _faculty
ON _department.facid = _faculty.facid
INNER JOIN _university
ON _faculty.schid = _university.schid)
WHERE _sch_forum_topics.sch_sub_forum_id = 4
ORDER BY _sch_forum_topics.topic_last_post_time DESC
LIMIT 0, 15
Try to filter before making JOIN's.
SELECT topic_id,
topic_title,
unit_name_abbrev,
sch_name_abbrev,
picture_small_url AS thumbnail,
profile_pix_upload_path,
first_name,
last_name,
topic_poster,
topic_replies,
topic_views,
topic_last_post_time AS topic_post_time,
sch_sub_forum_id
FROM
( select * FROM sch_forum_topics WHERE sch_sub_forum_id = 4
ORDER BY topic_last_post_time DESC
LIMIT 0, 15 ) main
INNER JOIN _users
ON ( _users.userid = main.topic_poster )
INNER JOIN _profile
ON _profile.userid = _users.userid
INNER JOIN _class
ON _users.classid = _class.classid
INNER JOIN _level
ON _class.level_id = _level.id
INNER JOIN _unit
ON _class.unitid = _unit.unitid
INNER JOIN _department
ON _unit.deptid = _department.deptid
INNER JOIN _faculty
ON _department.facid = _faculty.facid
INNER JOIN _university
ON _faculty.schid = _university.schid);

Getting the latest date from a id

I run the above sql statement and i got this.[IMG]http://i1093.photobucket.com/albums/i422/walkgirl_1993/asd-1_zps5506632e.jpg[/IMG] i'm trying display the latest date which you can see the 3 and 4. For caseid 3, it should display the latest row which is the 2012-12-20 16:12:36.000. I tried using group by, order by. Google some website said to use rank but i'm not sure about the rank as i dont really get rank. Some suggestions?
select [Case].CaseID, Agent.AgentName, Assignment.Description, A.AgentName as EditedBy, A.DateEdited from Agent inner join [Case-Agent] on [Case-Agent].AgentID = Agent.AgentID inner join [Assignment] on Assignment.AssignmentID = [Case-Agent].AssignmentID inner join [Case] on [Case].CaseID = [Case-Agent].CaseID inner join (select EditedCase.CaseID, [EditedCase].DateEdited, [Agent].AgentName from EditedCase inner join [Agent] on [Agent].AgentID = [EditedCase].AgentID) A on A.CaseID = [Case].CaseID where [Assignment].AssignmentID = 0
To do it using RANK you just need to add the RANK to the subquery and get to rank the DateEdited for each CaseID and Agent and then in the main query put a WHERE clause to only select rows where the rank is 1. I think I have got the partition clause right - its a bit hard without seeing your data.
Like this:
SELECT
[Case].CaseID
,Agent.AgentName
,Assignment.Description
,A.AgentName AS EditedBy
,A.DateEdited
FROM Agent
INNER JOIN [Case-Agent] ON [Case-Agent].AgentID = Agent.AgentID
INNER JOIN [Assignment] ON Assignment.AssignmentID = [Case-Agent].AssignmentID
INNER JOIN [Case] ON [Case].CaseID = [Case-Agent].CaseID
INNER JOIN (SELECT
EditedCase.CaseID
,[EditedCase].DateEdited
,[Agent].AgentName
,RANK ( ) OVER (PARTITION BY EditedCase.CaseID, [Agent].AgentName
ORDER BY [EditedCase].DateEdited DESC ) AS pos
FROM EditedCase
INNER JOIN [Agent] on [Agent].AgentID = [EditedCase].AgentID) A on A.CaseID = [Case].CaseID
WHERE [Assignment].AssignmentID = 0
AND pos = 1
You could also change the sub query into an aggregate query that brings back the MAX date like this:
SELECT
[Case].CaseID
,Agent.AgentName
,Assignment.Description
,A.AgentName AS EditedBy
,A.DateEdited
FROM Agent
INNER JOIN [Case-Agent] ON [Case-Agent].AgentID = Agent.AgentID
INNER JOIN [Assignment] ON Assignment.AssignmentID = [Case-Agent].AssignmentID
INNER JOIN [Case] ON [Case].CaseID = [Case-Agent].CaseID
INNER JOIN (SELECT
EditedCase.CaseID
,MAX([EditedCase].DateEdited) AS DateEdited
,[Agent].AgentName
FROM EditedCase
INNER JOIN [Agent] on [Agent].AgentID = [EditedCase].AgentID
GROUP BY
EditedCase.CaseID
,[Agent].AgentName) A on A.CaseID = [Case].CaseID
WHERE [Assignment].AssignmentID = 0
AND pos = 1
You were on the right track; you need to use a ranking function here, for example row_number():
with LatestCase as
(
select [Case].CaseID
, Agent.AgentName
, Assignment.Description
, A.AgentName as EditedBy
, A.DateEdited
, caseRank = row_number() over (partition by [Case].CaseID order by A.DateEdited desc)
from Agent
inner join [Case-Agent] on [Case-Agent].AgentID = Agent.AgentID
inner join [Assignment] on Assignment.AssignmentID = [Case-Agent].AssignmentID
inner join [Case] on [Case].CaseID = [Case-Agent].CaseID
inner join
(
select EditedCase.CaseID
, [EditedCase].DateEdited
, [Agent].AgentName
from EditedCase
inner join [Agent] on [Agent].AgentID = [EditedCase].AgentID
) A on A.CaseID = [Case].CaseID where [Assignment].AssignmentID = 0
)
select *
from LatestCase
where caseRank = 1

Only getting one result from sub select in inner join in mysql

Hi I have run into a dilemma, I am doing this query:
SELECT GROUP_CONCAT(DISTINCT(ca.category_name) SEPARATOR ', ') AS categories, pr.promo_name, pr.add_value_text, c.contract_id, c.cmeal_plan, c.cmin_markup, c.civa, c.tax_include, c.hotel_id, hi.hname, hi.hstars, im.image_file, pl.plan_name, ra.price
FROM contracts AS c
INNER JOIN hotel_info AS hi ON hi.hotel_id = c.hotel_id AND hi.destination_id = '6460'
INNER JOIN images AS im ON im.foreign_id = hi.hotel_id
INNER JOIN meal_plan AS pl ON pl.plan_code = c.cmeal_plan AND pl.lang = '1'
INNER JOIN hotel_categories AS hc ON hc.hotel_id = hi.hotel_id
INNER JOIN categories AS ca ON ca.category_code = hc.category_code AND ca.lang = '1'
LEFT JOIN
(SELECT
r.hotel_id, AVG(r.double) AS price
FROM
rates AS r ) AS ra
ON ra.hotel_id = hi.hotel_id
LEFT JOIN promotions AS pr ON pr.hotel_id = hi.hotel_id AND FIND_IN_SET(c.contract_id, pr.contract_id) > 0 AND pr.book_start <= '2012-11-01' AND pr.book_end >= '2012-11-02' AND travel_start <= '2012-11-23' AND travel_end >= '2012-11-30' AND pr.lang = '1'
WHERE c.cstart <= '2012-11-01' AND c.cend >= '2012-11-01'
AND hi.status = '1'
AND im.type ='1'
GROUP BY hi.hotel_id
I am getting all the desired results except for the sub select query.. each hotel has a price but it is only giving me back one result and the rest are all null. Is there an error in my query? If any additional information is needed please let me know and thank you in advance for any help!
You are missing the GROUP BY in your subquery, so MySQL will only return one-value. If you want all hotel_id's then you need to GROUP BY that field:
SELECT GROUP_CONCAT(DISTINCT(ca.category_name) SEPARATOR ', ') AS categories,
pr.promo_name,
pr.add_value_text,
c.contract_id,
c.cmeal_plan,
c.cmin_markup,
c.civa,
c.tax_include,
c.hotel_id,
hi.hname,
hi.hstars,
im.image_file,
pl.plan_name,
ra.price
FROM contracts AS c
INNER JOIN hotel_info AS hi
ON hi.hotel_id = c.hotel_id
AND hi.destination_id = '6460'
INNER JOIN images AS im
ON im.foreign_id = hi.hotel_id
INNER JOIN meal_plan AS pl
ON pl.plan_code = c.cmeal_plan
AND pl.lang = '1'
INNER JOIN hotel_categories AS hc
ON hc.hotel_id = hi.hotel_id
INNER JOIN categories AS ca
ON ca.category_code = hc.category_code
AND ca.lang = '1'
LEFT JOIN
(
SELECT r.hotel_id, AVG(r.double) AS price
FROM rates AS r
GROUP BY r.hotel_id <-- add a GROUP BY hotel_id then you will get avg() for each hotel
) AS ra
ON ra.hotel_id = hi.hotel_id
LEFT JOIN promotions AS pr
ON pr.hotel_id = hi.hotel_id
AND FIND_IN_SET(c.contract_id, pr.contract_id) > 0
AND pr.book_start <= '2012-11-01'
AND pr.book_end >= '2012-11-02'
AND travel_start <= '2012-11-23'
AND travel_end >= '2012-11-30'
AND pr.lang = '1'
WHERE c.cstart <= '2012-11-01'
AND c.cend >= '2012-11-01'
AND hi.status = '1'
AND im.type ='1'
GROUP BY hi.hotel_id