How to do INNER JOIN with 2 Column COUNTS equal - mysql

I am trying to perform the following query:
SELECT wwpqsr.statistic_ref_id,
wwpqsr.create_time,
wwpqm.name
FROM wp_wp_pro_quiz_statistic_ref AS wwpqsr
INNER JOIN wp_wp_pro_quiz_statistic AS wwpqs
ON ( wwpqs.statistic_ref_id = wwpqsr.statistic_ref_id
AND COUNT(wwpqs.correct_count) AS correct =
COUNT(wwpqs.incorrect_count) AS incorrect)
INNER JOIN wp_wp_pro_quiz_master AS wwpqm
ON (wwpqm.id = wwpqsr.quiz_id)
WHERE wwpqsr.user_id = 1;
I need to do a limit on the result here at the end, that is not being shown right now for functionality purposes, since I need to only get results returned from the p_wp_pro_quiz_statistic table where the count of correct_count equals the count of rows from the incorrect_count column. How can I do this within an INNER JOIN here? All within 1 query? Possible? The above code returns empty result, where it should not be an empty result. How should something like this be done?

As I said in comments, you can't use aggregate functions as a where clause unless it is a field from a subquery. For your case I think you are looking for:
SELECT wwpqsr.statistic_ref_id,
wwpqsr.create_time,
wwpqm.name
FROM wp_wp_pro_quiz_statistic_ref AS wwpqsr
INNER JOIN wp_wp_pro_quiz_statistic AS wwpqs
ON ( wwpqs.statistic_ref_id = wwpqsr.statistic_ref_id )
INNER JOIN wp_wp_pro_quiz_master AS wwpqm
ON (wwpqm.id = wwpqsr.quiz_id)
WHERE wwpqsr.user_id = 1
GROUP
BY wwpqsr.statistic_ref_id,
wwpqsr.create_time,
wwpqm.name
HAVING COUNT(wwpqs.correct_count) = COUNT(wwpqs.incorrect_count);

Related

select count with another select and inner join

Is it possible to use two "select" in the same query?
I tried it but got the syntax error several times.
My query example:
SELECT
comp.id,
comp.document,
comp.dateStart,
comp.companyName,
comp.fantasyName,
comp.legalNature,
comp.mainActivity,
comp.situation,
comp.shareCapital,
comp.idCompanyStatus,
pp.userCredentialId,
uc.name,
cs.name AS 'nameStatus',
cs.color AS 'colorStatus',
cs.description,
comp.idPurchasedProduct,
comp.actived,
comp.createAt,
comp.updateAt,
comp.phone
FROM `PurchasedProduct` pp
INNER JOIN
`Company` comp on comp.idPurchasedProduct = pp.id
INNER JOIN
`UserCustomer` uc on pp.userCredentialId = uc.credentialId
INNER JOIN
`CompanyStatus` cs on cs.id = comp.idCompanyStatus
WHERE
comp.actived = 1
LIMIT 0,5;
SELECT COUNT(id) AS totalItems, CEILING(COUNT(id) / 10) AS totalPages FROM Company;
I would like the result shown to be all queries on the screen.
Basically, what I want is that the result shown when executing the query is the first and second "select" together.
I really don't know how or don't understand how to do this.
Example:
first result with seconde result
I want to show both results at once.
The documents is fake, not real. Only for demo.
You should be able to do by having the second query as its own JOIN query. Since there is no group by, it is only returning a single row. By no join condition, the value will be available for every row otherwise. So you SHOULD be able to get by doing
select
[ all your other columns ],
JustCounts.TotalItems,
JustCounts.TotalPages
from
[PurchasedProduct and all your other joins]
JOIN ( SELECT
COUNT(id) AS totalItems,
CEILING(COUNT(id) / 10) AS totalPages
FROM Company ) as JustCounts
where
[rest of your original query]

Join Select Statement after on

Is it possible to join on a part of a string that i split up?
I tried something:
SELECT param.par_name,
PARPAT.pp_pattern,
KOM.kom_name
FROM inv.inv_parpat PARPAT
INNER JOIN inv.inv_param PARAM
ON PARPAT.pp_par_id = PARAM.par_id
INNER JOIN inv.inv_komponente KOM
ON KOM.kom_id = (SELECT Substr(PARPAT.pp_pattern,
Instr(PARPAT.pp_pattern, ':') + 1
)
FROM inv.inv_parpat)
WHERE PARPAT.pp_pattern LIKE '%ATA%';
This statement says:
Single row subquery returns more than one row
Why do you use a sub query? You already have this table, why not use it? :
SELECT param.PAR_NAME,
PARPAT.PP_PATTERN,
KOM.KOM_NAME
FROM INV.INV_PARPAT PARPAT
INNER JOIN INV.INV_PARAM PARAM
ON PARPAT.PP_PAR_ID = PARAM.PAR_ID
INNER JOIN INV.INV_KOMPONENTE KOM
on KOM.KOM_ID = SUBSTR(PARPAT.PP_PATTERN,INSTR(PARPAT.PP_PATTERN, ':')+1)
WHERE PARPAT.PP_PATTERN LIKE '%ATA%';
You need to join it to PARPAT based on the substring column. If you join with a subquery,the subquery should return only one value (like a max() or min() function will do). Else you can use a IN clause with a subquery. But remember, there are performance considerations while using IN. For your case, try the below query:
SELECT param.PAR_NAME,
PARPAT.PP_PATTERN,
KOM.KOM_NAME
FROM INV.INV_PARPAT PARPAT
INNER JOIN INV.INV_PARAM PARAM ON PARPAT.PP_PAR_ID = PARAM.PAR_ID
INNER JOIN INV.INV_KOMPONENTE KOM on KOM.KOM_ID = (SUBSTR(PARPAT.PP_PATTERN,INSTR(PARPAT.PP_PATTERN, ':')+1))
WHERE PARPAT.PP_PATTERN LIKE '%ATA%';

MySQL group by twice and COUNT

Some sql query gives me the following result:
As you can see, it already has GROUP BY.
So what I need? I need to group it again (by treatment_name) and count rows for each group. See more details on screenshot.
Here is full query:
SELECT
treatment_summaries.*
FROM `treatment_summaries`
INNER JOIN
`treatments`
ON
`treatments`.`treatment_summary_id` = `treatment_summaries`.`id`
AND
(treatment <> '' and treatment is not null)
INNER JOIN
`treatment_reviews`
ON
`treatment_reviews`.`treatment_id` = `treatments`.`id`
INNER JOIN
`conditions_treatment_reviews`
ON
`conditions_treatment_reviews`.`treatment_review_id` = `treatment_reviews`.`id`
INNER JOIN
`conditions` ON `conditions`.`id` = `conditions_treatment_reviews`.`condition_id`
INNER JOIN `conditions_treatment_summaries` `conditions_treatment_summaries_join`
ON
`conditions_treatment_summaries_join`.`treatment_summary_id` = `treatment_summaries`.`id`
INNER JOIN `conditions` `conditions_treatment_summaries`
ON `conditions_treatment_summaries`.`id` = `conditions_treatment_summaries_join`.`condition_id`
WHERE
`conditions`.`id` = 9
AND `conditions`.`id` IN (9)
AND (latest_review_id is not null)
GROUP BY
treatment_reviews.id
ORDER BY
treatment_summaries.reviews_count desc
LIMIT 20 OFFSET 0
Maybe there is another issue, cause GROUP BY should not leave same lines (for given column), but anyway you can wrap it like this:
SELECT * FROM ( YOUR_SQL_SELECT_WITH_EVERYTHING ) GROUP BY id
So the result you get will behave as another table and you can do all operations like GROUP BY again.

MySQL Inner Join with where clause sorting and limit, subquery?

Everything in the following query results in one line for each invBlueprintTypes row with the correct information. But I'm trying to add something to it. See below the codeblock.
Select
blueprintType.typeID,
blueprintType.typeName Blueprint,
productType.typeID,
productType.typeName Item,
productType.portionSize,
blueprintType.basePrice * 0.9 As bpoPrice,
productGroup.groupName ItemGroup,
productCategory.categoryName ItemCategory,
blueprints.productionTime,
blueprints.techLevel,
blueprints.researchProductivityTime,
blueprints.researchMaterialTime,
blueprints.researchCopyTime,
blueprints.researchTechTime,
blueprints.productivityModifier,
blueprints.materialModifier,
blueprints.wasteFactor,
blueprints.maxProductionLimit,
blueprints.blueprintTypeID
From
invBlueprintTypes As blueprints
Inner Join invTypes As blueprintType On blueprints.blueprintTypeID = blueprintType.typeID
Inner Join invTypes As productType On blueprints.productTypeID = productType.typeID
Inner Join invGroups As productGroup On productType.groupID = productGroup.groupID
Inner Join invCategories As productCategory On productGroup.categoryID = productCategory.categoryID
Where
blueprints.techLevel = 1 And
blueprintType.published = 1 And
productType.marketGroupID Is Not Null And
blueprintType.basePrice > 0
So what I need to get in here is the following table with the columns below it so I can use the values timestamp and sort the entire result by profitHour
tablename: invBlueprintTypesPrices
columns: blueprintTypeID, timestamp, profitHour
I need this information with the following select in mind. Using a select to show my intention of the JOIN/in-query select or whatever that can do this.
SELECT * FROM invBlueprintTypesPrices
WHERE blueprintTypeID = blueprintType.typeID
ORDER BY timestamp DESC LIMIT 1
And I need the main row from table invBlueprintTypes to still show even if there is no result from the invBlueprintTypesPrices. The LIMIT 1 is because I want the newest row possible, but deleting the older data is not a option since history is needed.
If I've understood correctly I think I need a subquery select, but how to do that? I've tired adding the exact query that is above with a AS blueprintPrices after the query's closing ), but did not work with a error with the
WHERE blueprintTypeID = blueprintType.typeID
part being the focus of the error. I have no idea why. Anyone who can solve this?
You'll need to use a LEFT JOIN to check for NULL values in invBlueprintTypesPrices. To mimic the LIMIT 1 per TypeId, you can use the MAX() or to truly make sure you only return a single record, use a row number -- this depends on whether you can have multiple max time stamps for each type id. Assuming not, then this should be close:
Select
...
From
invBlueprintTypes As blueprints
Inner Join invTypes As blueprintType On blueprints.blueprintTypeID = blueprintType.typeID
Inner Join invTypes As productType On blueprints.productTypeID = productType.typeID
Inner Join invGroups As productGroup On productType.groupID = productGroup.groupID
Inner Join invCategories As productCategory On productGroup.categoryID = productCategory.categoryID
Left Join (
SELECT MAX(TimeStamp) MaxTime, TypeId
FROM invBlueprintTypesPrices
GROUP BY TypeId
) blueprintTypePrice On blueprints.blueprintTypeID = blueprintTypePrice.typeID
Left Join invBlueprintTypesPrices blueprintTypePrices On
blueprintTypePrice.TypeId = blueprintTypePrices.TypeId AND
blueprintTypePrice.MaxTime = blueprintTypePrices.TimeStamp
Where
blueprints.techLevel = 1 And
blueprintType.published = 1 And
productType.marketGroupID Is Not Null And
blueprintType.basePrice > 0
Order By
blueprintTypePrices.profitHour
Assuming you might have the same max time stamp with 2 different records, replace the 2 left joins above with something similar to this getting the row number:
Left Join (
SELECT #rn:=IF(#prevTypeId=TypeId,#rn+1,1) rn,
TimeStamp,
TypeId,
profitHour,
#prevTypeId:=TypeId
FROM (SELECT *
FROM invBlueprintTypesPrices
ORDER BY TypeId, TimeStamp DESC) t
JOIN (SELECT #rn:=0) t2
) blueprintTypePrices On blueprints.blueprintTypeID = blueprintTypePrices.typeID AND blueprintTypePrices.rn=1
You don't say where you are putting the subquery. If in the select clause, then you have a problem because you are returning more than one value.
You can't put this into the from clause directly, because you have a correlated subquery (not allowed).
Instead, you can put it in like this:
from . . .
(select *
from invBLueprintTypesPrices ibptp
where ibtp.timestamp = (select ibptp2.timestamp
from invBLueprintTypesPrices ibptp2
where ibptp.blueprintTypeId = ibptp2.blueprintTypeId
order by timestamp desc
limit 1
)
) ibptp
on ibptp.blueprintTypeId = blueprintType.TypeID
This identifies the most recent records for all the blueprintTypeids in the subquery. It then joins in the one that matches.

How to fix a count() in a query with a "group by" clause?

I have a function that gets a SQL code and inserts a count field in it and executes the query to return the number of rows in it. The objective is to have a dynamic SQL code and be able to get its record count no matter what code it has, because I use it in a registry filter window and I never know what code may be generated, because the user can add as many filters as he/she wants.
But as I use the group by clause, the result is wrong because it is counting the number of times a main registry appears because of the use on many join connections.
The result of that code above should only one row with a columns with 10 as result, but I get a new table with the first columns with a 2 in the first row and a 1 on the other rows.
If I take off the group by clause I will receive a 11 as a count result, but the first row will be counted twice.
What should I do to get a single row and the correct number?
SELECT
COUNT(*) QUERYRECORDCOUNT, // this line appears only in the Count() function
ARTISTA.*,
CATEGORIA.NOME AS CATEGORIA,
ATIVIDADE.NOME AS ATIVIDADE,
LOCALIDADE.NOME AS CIDADE,
MATRICULA.NUMERO AS MAP
FROM
ARTISTA
LEFT JOIN PERFIL ON PERFIL.REGISTRO = ARTISTA.ARTISTA_ID
LEFT JOIN CATEGORIA ON CATEGORIA.CATEGORIA_ID = PERFIL.CATEGORIA
LEFT JOIN ATIVIDADE ON ATIVIDADE.ATIVIDADE_ID = PERFIL.ATIVIDADE
LEFT JOIN LOCALIDADE ON LOCALIDADE.LOCALIDADE_ID = ARTISTA.LOCAL_ATIV_CIDADE
LEFT JOIN MATRICULA ON MATRICULA.REGISTRO = ARTISTA.ARTISTA_ID
WHERE
((ARTISTA.SIT_PERFIL <> 'NORMAL') AND (ARTISTA.SIT_PERFIL <> 'PRIVADO'))
GROUP BY
ARTISTA.ARTISTA_ID
ORDER BY
ARTISTA.ARTISTA_ID;
This always gives you the number of rows for any query you have:
Select count(*) as rowcount from
(
Paste your query here
) as countquery
Since your are GROUPING BY ARTISTA.ARTISTA_ID, COUNT(*) QUERYRECORDCOUNT will return records count for each ARTISTA.ARTISTA_ID value.
If you want GLOBAL count, then you need to use a nested query:
SELECT COUNT(*) AS QUERYRECORDCOUNT
FROM (SELECT
ARTISTA.*,
CATEGORIA.NOME AS CATEGORIA,
ATIVIDADE.NOME AS ATIVIDADE,
LOCALIDADE.NOME AS CIDADE,
MATRICULA.NUMERO AS MAP
FROM
ARTISTA
LEFT JOIN PERFIL ON PERFIL.REGISTRO = ARTISTA.ARTISTA_ID
LEFT JOIN CATEGORIA ON CATEGORIA.CATEGORIA_ID = PERFIL.CATEGORIA
LEFT JOIN ATIVIDADE ON ATIVIDADE.ATIVIDADE_ID = PERFIL.ATIVIDADE
LEFT JOIN LOCALIDADE ON LOCALIDADE.LOCALIDADE_ID = ARTISTA.LOCAL_ATIV_CIDADE
LEFT JOIN MATRICULA ON MATRICULA.REGISTRO = ARTISTA.ARTISTA_ID
WHERE
((ARTISTA.SIT_PERFIL <> 'NORMAL') AND (ARTISTA.SIT_PERFIL <> 'PRIVADO'))
GROUP BY
ARTISTA.ARTISTA_ID
ORDER BY
ARTISTA.ARTISTA_ID);
In this case, you may not need to select those many columns.
If you need to retrieve the all records count with details, then better to use two separate queries.