Mysql EXISTS not recognizing Alias of previous table - mysql

What I try to achieve is the following, I have a Hierarchical table with data.
Each category may have 3 subcategories(maximum).
So I want to check if the subordinated subcategories have subcategories(descendants) and in the last AND condition if they have products.
The problem is that my ALIAS tree1 is not recognized in the last AND condition.
/* SQL Error (1054): Unknown column 'tree1.Node_ID' in 'on clause' */
Here is my query, any help would be appreciated.
SELECT tree1.Node_ID, tree1.Bez,
IF(EXISTS(SELECT * FROM `301` as tree2 WHERE tree2.Node_Parent_ID <=> tree1.Node_ID LIMIT 1),1,0) as descendants
FROM `301` as tree1
WHERE tree1.TreeTypNr = 1
AND tree1.Node_Parent_ID <=> 100001
AND EXISTS(
SELECT * FROM `400`
INNER JOIN `302` ON `302`.Node_ID = tree1.Node_ID
WHERE `400`.GenArtNr = `302`.GenArtNr
AND `400`.VknZielNr = 18302
AND `400`.VknZielArt = 2
LIMIT 1
)

I've swapped two rows:
`400`.GenArtNr = `302`.GenArtNr (put in ON cluase)
and
`302`.Node_ID = tree1.Node_ID (put in WHERE condition)
Try this:
SELECT tree1.Node_ID, tree1.Bez,
IF(EXISTS(SELECT * FROM `301` as tree2 WHERE tree2.Node_Parent_ID <=>
tree1.Node_ID LIMIT 1),1,0) as descendants
FROM `301` as tree1
WHERE tree1.TreeTypNr = 1
AND tree1.Node_Parent_ID <=> 100001
AND EXISTS(
SELECT * FROM `400`
INNER JOIN `302` ON `400`.GenArtNr = `302`.GenArtNr
WHERE `302`.Node_ID = tree1.Node_ID
AND `400`.VknZielNr = 18302
AND `400`.VknZielArt = 2
LIMIT 1
)

Related

Include another select column based on data - MySQL

How do I include SUM((pm.Quantity * bl.TotalQty)) AS NextBOMItemCount WHERE projectbomlist.ParentPartNum = bl.PartNum?
The data should not be changed, the same data should be retrieved, the however additional column has to be included.
VIEW: `NEWprojectBOMItemCount
select
`pm`.`ProjectCode` AS `ProjectCode`,
`bl`.`PartNum` AS `PartNum`,
sum((`pm`.`Quantity` * `bl`.`TotalQty`)) AS `BOMItemCount`,
`bl`.`mp` AS `mp`,
`p`.`complete` AS `complete`,
`bl`.`RMInd` AS `RMInd`,
`bl`.`M_PartNum` AS `M_PartNum`
from
(
(`projectmachine` `pm` join `projectbomlist` `bl`)
join `projects` `p`
)
where
(
(`pm`.`MachineListID` = `bl`.`MachineListID`)
and (`pm`.`ProjectCode` = `bl`.`ProjectCode`)
and (`pm`.`ProjectCode` = `p`.`ProjectCode`)
and (`p`.`AfterProjectHeirarchyInd` = 'Y')
)
and and pm.ProjectCode = 'AB212323'
group by
`pm`.`ProjectCode` ,
`bl`.`PartNum`
order by
`pm`.`ProjectCode` ,
`bl`.`PartNum`
Or, another option can be, please consider above view used in below query, please suggest changes to the below query as shown above (repeating here)
`sum((pm.Quantity * bl.TotalQty)) AS NextBOMItemCount where projectbomlist.ParentPartNum = bl.PartNum` - in place of `(select-NextBOMItemCount)`?
Please see PBLH.ParentPartNum is the column that I should compare with BL.ProjectCode to get NextBOMItemCount value.
QUERY calling view: NEWprojectBOMItemCount
Select
BL.PartNum PartNumber,
PBLH.ParentPartNum NextBOM,
(select-NextBOMItemCount),
BOMItemCount TotalQty,
PL.Description,
BL.MP as PartType,
PL.Vendor,
PL.QBType
from
NEWprojectBOMItemcount BL,
bomwiz.partslist PL,
bomwiz.projectbomlistheirarchy PBLH
Where
BL.PartNum = PL.PartNum
And BL.PartNum = PBLH.PartNum
And BL.ProjectCode = PBLH.ProjectCode
And BL.projectCode = 'AB212323'
Order By PartNumber
I think that you are looking for conditional aggregation. Your requirement could be expressed as follows:
SUM(
CASE WHEN blh.ParentPartNum = bl.PartNum
THEN pm.Quantity * bl.TotalQty
ELSE 0
END
) AS NextBOMItemCount
Let me pinpoint other issues with your query:
you have unwanted parentheses all around, and I am suspicious about the syntax of the JOINs ; you need to move conditions to the ON clause of the relevant JOIN.
every non-aggregated column must appear in the GROUP BY clause - you have missing columns there
backquotes are usually not needed
Here is an updated version of the query:
SELECT
pm.ProjectCode AS ProjectCode,
bl.PartNum AS PartNum,
SUM(pm.Quantity * bl.TotalQty) AS BOMItemCount,
SUM(
CASE WHEN blh.ParentPartNum = bl.PartNum
THEN pm.Quantity * bl.TotalQty
ELSE 0
END
) AS NextBOMItemCount,
bl.mp AS mp,
p.complete AS complete,
bl.RMInd AS RMInd,
bl.M_PartNum AS M_PartNum
FROM
projectmachine AS pm
INNER JOIN projectbomlist AS bl
ON pm.MachineListID = bl.MachineListID
AND pm.ProjectCode = bl.ProjectCode
INNER JOIN join projects AS p
ON pm.ProjectCode = p.ProjectCode
AND p.AfterProjectHeirarchyInd = 'Y'
INNER JOIN projectbomlistheirarchy blh
ON bl.ProjectCode = blh.ProjectCode
WHERE
pm.ProjectCode = 'AB212323'
GROUP BY
pm.ProjectCode,
bl.PartNum,
bl.mp,
p.complete,
bl.RMInd,
bl.M_PartNum
ORDER BY
pm.ProjectCode,
bl.PartNum

MySQL - How can I do a conditional WHERE and OR clause Query?

Problem 1:
I need to add a field in a WHERE clause with a condition in my stored procedure, so what is the right syntax for the below query in CASE condition?
Problem 2:
OR condition is giving me all records with values 0,1,2,3,4 for below condition (I need tqm.is_imp = 1 if not found then tqm.is_imp IN (0,2,3,4)). What should I do? Please help.
tqm.is_imp = 1 OR tqm.is_imp IN (0,2,3,4)
My Query:
SELECT tqm.id INTO selectedQuestionNumber
FROM tc_question_master tqm
INNER JOIN tc_question_mapping tqmap ON tqmap.tc_question_id = tqm.id
WHERE tqmap.syllabus_chapter_details_id IN (SELECT cms_id from topic where chapter_id IN (SELECT id from MyChapters))
AND tqm.marks = CurMark
CASE WHEN CurQuestionType > 0 THEN
AND tqm.question_type = CurQuestionType
END
AND (tqm.level_of_question = 'Easy' OR tqm.level_of_question
IN ('Moderate','Difficult','Very difficult'))
AND (tqm.is_imp = 1 OR tqm.is_imp IN (0,2,3,4))
AND tqm.id NOT IN (SELECT q.question_id FROM QBDetails q)
ORDER BY RAND() LIMIT 1;
The upper part is just a reformat, but lower as you approach the logic that was a case expression, most of that is pure guess.
SELECT
tqm.id INTO selectedQuestionNumber
FROM tc_question_master tqm
INNER JOIN tc_question_mapping tqmap ON tqmap.tc_question_id = tqm.id
WHERE tqmap.syllabus_chapter_details_id IN (
SELECT
cms_id
FROM topic
WHERE chapter_id IN (
SELECT
id
FROM MyChapters
)
)
AND (
tqm.level_of_question = 'Easy'
OR tqm.level_of_question IN ('Moderate', 'Difficult', 'Very difficult')
)
AND (
tqm.is_imp = 1
OR tqm.is_imp IN (0, 2, 3, 4)
)
AND tqm.id NOT IN (
SELECT
q.question_id
FROM QBDetails q
)
## now it is really vague
AND (
tqm.marks = CurMark
OR
(CurQuestionType > 0 AND tqm.question_type = CurQuestionType)
)
## end of guesswork
ORDER BY
RAND()
LIMIT 1;

mysql combine 2 queries from same table

This is query 1:
SELECT distinct c.chem_gene, m.String_name, m.ScopeNote
FROM mesher m INNER JOIN chem_base c
ON (c.chem_name = m.String_name AND m.ScopeNote <> '' )
where match (c.chem_gene) against('ACTN3, MTHFR' in boolean mode)
group by c.chem_gene, c.chem_name;
which outputs 3 columns in rows like this:
'ACTN3', 'Estradiol', 'The 17-beta-isomer of estradiol...'
This is query 2 (taking the output from column 2, "Estradiol"):
SELECT String10 FROM mesher where String_name = "Estradiol" AND String10 <>'' LIMIT 1;
which outputs a single row in a single column:
'Estrogens'
How can I modify query 1 so that for each row returned the additional query is made against the result in the second column (i.e.'Estradiol') to produce this output:
'ACTN3', 'Estradiol', 'The 17-beta-isomer of estradiol...', 'Estrogens'
If I understand correctly, you can use a correlated subquery:
SELECT c.chem_gene, m.String_name, m.ScopeNote,
(SELECT mm.String10
FROM mesher mm
WHERE mm.String_name = m.String_name AND mm.String10 <> ''
LIMIT 1
)
FROM mesher m INNER JOIN
chem_base c
ON c.chem_name = m.String_name AND m.ScopeNote <> ''
WHERE match(c.chem_gene) against( 'ACTN3, MTHFR' in boolean mode)
GROUP BY c.chem_gene, c.chem_name, m.ScopeNote ;
The select distinct is not necessary.

How to update a table with subquery using data from the same table

I would like to update a column from a table, and the data i want to put in is the result of a mathematical operation using subquerys that references the update table.
The problem is I want to update every row using data from the same row in the mathematical operation mentioned above.
Here's the example:
UPDATE licenses as lic
SET lic.numSessions =
(
select difference from
(select
(
select (p.numSessions * p.numMonth) as num from products p
inner join licenses l on p.idProduct = l.idProduct and l.idpatient = lic.idPatient and l.currentLicense = 1
)
-
(
SELECT COUNT(distinct s.idSession) as num
FROM sessions s
WHERE s.idPatient = lic.idPatient
AND s.dateValue >= (select l.dateCreated from licenses l where l.idPatient = lic.idPatient and l.currentLicense = 1) AND s.status = 2
)
as difference
)
x
);
EDIT:
Example of what i want:
Every row of 'licenses' has a 'idPatient'. Let's call it 'X'.
I want to see how many sessions X has done (for example 10) and then substract this number from the total number of sessions of 'X's' product have (for example 50). So the result in the update for X will be: 50 - 10 = 40.
The subqueries alone work perfectly, I'have the value of 50, then the value of 10, and then when I try to substract I have the value 40 as a column named 'difference'.
The problem I've got is that the query can't recognize the value 'lic.idPatient' inside the first subquery in the substract operation:
/* SQL Error (1054): Unknown column 'lic.idPatient' in 'on clause' */
Thanks in advance and sorry for my writing, I'm not native English.
You have to write query like this
UPDATE licenses AS licNew
SET licNew.numSessions =
(
SELECT x.difference FROM
((SELECT
(
SELECT (p.numSessions * p.numMonth) AS num FROM products p
INNER JOIN licenses l ON p.idProduct = l.idProduct AND l.idpatient = lic.idPatient AND l.currentLicense = 1
)
-
(
SELECT COUNT(DISTINCT s.idSession) AS num
FROM sessions s
WHERE s.idPatient = 6361
AND s.dateValue >= (SELECT l.dateCreated FROM licenses l WHERE l.idPatient = 6361 AND l.currentLicense = 1) AND s.status = 2
))
AS difference, lic.idPatient
FROM licenses lic
)
X WHERE licNew.idPatient = x.idPatient
);
In general, you cannot modify a table and select from the same table in a subquery.
Please refer this link.

set a mysql user variable per row?

The following SQL statement sets a user variable #id which I'm then using in the trailing subquery. My problem is the #id variable only gets set to the first items.id in the result set - not "per row" - so the result from the subquery is the same for every row in the main select. Does anyone know if there's a way to reset the #id variable for each row??
select
items.id
,items.title
,#id := items.id
,(
select
group_concat(x.y)
from
(
select
group_concat(ledger.stockcode) as y
from
ledger
where
#id = ledger.itemid
group by
ledger.stockcode
having
sum(ledger.stockqty) > 0
) as x
) as extras
from
items
where
items.id = 196
Try this query
select
a.id
,a.title
,b.y as extras
from
items a
inner join
(select
group_concat(ledger.stockcode) as y
from
ledger
where
ledger.itemid = 196
group by
ledger.stockcode
having
sum(ledger.stockqty) > 0) b
on
a.id = 196 AND a.id = b.itemid