I am having trouble trying to return only duplicate values in a query on Microsoft Access.
Here is my initial query:
SELECT tbl_dbextract_GP.GPNo,
[tbl_dbextract_GP].[GPFirst]+" "+[tbl_dbextract_GP].[GPLast] AS GPName,
Sum(tbl_main_ListLog.count_ToImport) AS ImportCount,
tbl_main_ListLog.SearchSequence
FROM ((tbl_main_ListLog
INNER JOIN tbl_dbextract_GPPractice
ON tbl_main_ListLog.GPPracticeID = tbl_dbextract_GPPractice.Id)
INNER JOIN tbl_dbextract_GP
ON tbl_dbextract_GPPractice.GPId = tbl_dbextract_GP.Id)
WHERE tbl_dbextract_GP.GPNo <> 'G0000'
GROUP BY tbl_dbextract_GP.GPNo,
[tbl_dbextract_GP].[GPFirst]+" "+[tbl_dbextract_GP].[GPLast],
tbl_main_ListLog.SearchSequence;
I only want to return results where there is at least 2 entries per GPNo.
The search sequence is incremental, so basically I am trying to find entries where there has been at least 2 searches.
This was my attempt:
SELECT
tbl_dbextract_GP.GPNo,
[tbl_dbextract_GP].[GPFirst] + " " + [tbl_dbextract_GP].[GPLast] AS GPName,
Sum(tbl_main_ListLog.count_ToImport) AS ImportCount,
tbl_main_ListLog.SearchSequence
FROM (((tbl_main_ListLog
INNER JOIN tbl_dbextract_GPPractice
ON tbl_main_ListLog.GPPracticeID = tbl_dbextract_GPPractice.Id)
INNER JOIN tbl_dbextract_GP
ON tbl_dbextract_GPPractice.GPId = tbl_dbextract_GP.Id)
LEFT JOIN (
SELECT tbl_main_ListLog.GPPracticeID as GPPID,
SUM(tbl_main_ListLog.SearchSequence) as SumSS
FROM tbl_main_ListLog
WHERE SumSS > 1
GROUP BY tbl_main_ListLog.GPPracticeID) SubQ
ON tbl_main_ListLog.GPPracticeID = SubQ.GPPID)
WHERE tbl_dbextract_GP.GPNo <> 'G0000'
GROUP BY tbl_dbextract_GP.GPNo,
[tbl_dbextract_GP].[GPFirst]+" "+[tbl_dbextract_GP].[GPLast],
tbl_main_ListLog.SearchSequence;
This didn't work, as it prompted me to manually enter the value for SumSS on execute, and that didn't return the right results anyway.
This is a sample output (Names redacted) - I want to return results where there is at least 2 entries per GPNo
EDIT: Modified attempt using Tim's solution - returning "Syntax error in JOIN operation":
SELECT
t3.GPNo,
t3.GPFirst + " " + t3.GPLast AS GPName,
SUM(t1.count_ToImport) AS ImportCount,
t1.SearchSequence
FROM (((tbl_main_ListLog t1
INNER JOIN tbl_dbextract_GPPractice t2
ON t1.GPPracticeID = t2.Id)
INNER JOIN tbl_dbextract_GP t3
ON t2.GPId = t3.Id)
INNER JOIN
(
SELECT t3.GPNo
FROM ((tbl_main_ListLog t1
INNER JOIN tbl_dbextract_GPPractice t2
ON t1.GPPracticeID = t2.Id)
INNER JOIN tbl_dbextract_GP t3
ON t2.GPId = g3.Id)
GROUP BY t3.GPNo
HAVING COUNT(*) > 1
) t4
ON t3.GPNo = t4.GPNo)
WHERE
t3.GPNo <> 'G0000'
GROUP BY
t3.GPNo,
t3.GPFirst + " " + t3.GPLast,
t1.SearchSequence;
Given that this is MS Access, which does not support analytic functions, doing a join to another subquery to impose the restriction on the number of searches seems like a reasonable approach, and your second attempt does not look far off. But you should be using the HAVING operator instead of WHERE, with a few other changes:
SELECT
t3.GPNo,
t3.GPFirst + " " + t3.GPLast AS GPName,
SUM(t1.count_ToImport) AS ImportCount,
t1.SearchSequence
FROM tbl_main_ListLog t1
INNER JOIN tbl_dbextract_GPPractice t2
ON t1.GPPracticeID = t2.Id
INNER JOIN tbl_dbextract_GP t3
ON t2.GPId = t3.Id
INNER JOIN
(
SELECT t3.GPNo
FROM tbl_main_ListLog t1
INNER JOIN tbl_dbextract_GPPractice t2
ON t1.GPPracticeID = t2.Id
INNER JOIN tbl_dbextract_GP t3
ON t2.GPId = t3.Id
GROUP BY t3.GPNo
HAVING COUNT(*) > 1
) t4
ON t3.GPNo = t4.GPNo
WHERE
t3.GPNo <> 'G0000'
GROUP BY
t3.GPNo,
t3.GPFirst + " " + t3.GPLast,
t1.SearchSequence;
In the subquery which I have aliased as t4, I do the same set of joins as your original query, but I then aggregate only by the GPNo. Also, I added a HAVING clause requiring that a GPNo appear two or more times in order to be retained in the result set. This subquery then filters off non matching GPNo records in your original query.
Add the Count(1) As Countr to your query and apply condition Countr>1 (apply HAVING clause as explained above).
Alternatively, in order to simplify your task, you can save the original working query as the intermediate one, e.g. Sub_With_Duplicates (Access has that feature), and then build another one (eg. Qry_No_Duplicates on the top of the intermediate and simply apply WHERE Countr>1 clause to that field. This should work.
Related
i have a sql query i'm running that joins & concatenates multiple tables, resulting in new columns, etc. I want to easily edit these fresh column values by double-clicking into the empty portions, like usual, but i read when joining tables they become read-only. I also wanted to attempt a regular INSERT cmd but don't understand what the table name is, since its all resulted from a lengthy query. How can i edit this queried table?
Below, i have pasted the query. For example, this spits out a new column change_products, and i want to edit those values but as mentioned above, cannot after joining/concatenating. Thanks!
SELECT change_ticket,
change_product,
change_desc,
change_state,
security_bulletin,
change_assigned_to,
affected,
remediated
FROM change_tickets t1
LEFT JOIN change_product_link t2 ON t1.id = t2.chg_id
LEFT JOIN (SELECT id, concat(product_name, ' ', product_version) AS change_product FROM products) chg_product ON t2.product_id = chg_product.id
LEFT JOIN change_sb_link t4 ON t1.id = t4.chg_id
LEFT JOIN security_bulletins t5 ON t5.id = t4.sb_id
LEFT JOIN product_sb_link t6 ON t5.id = t6.sb_id
LEFT JOIN (SELECT id, concat(product_name, ' ', product_version) AS affected FROM products) aff_soft ON t6.affected_software_id = aff_soft.id
LEFT JOIN (SELECT id, concat(product_name, ' ', product_version) AS remediated FROM products) rem_soft ON t6.remediated_software_id = rem_soft.id
WHERE change_state NOT IN ('Cancelled', 'Closed - Successful', 'Post-Verify') OR change_state IS NULL
ORDER BY 1
This question already has answers here:
Column "invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause"
(5 answers)
Closed 3 years ago.
I have this code in SQL:
SELECT
COUNT(*) as t,
t1.EMPLID,
t3.DNI,
t1.PUNCH_DTTM,
PUNCH_TYPE,
TCD_ID,
t2.PCADescripcion,
t2.DFIDescripcion,
t2.Alias,
t5.apellido,
t4.planta
FROM
[MatrizDB].[db_owner].[Historial_TRH] t1
LEFT JOIN
MatrizDB.db_owner.Dispositivos_TRH t2 ON t2.RefId = TCD_ID
LEFT JOIN
MatrizDB.db_owner.Pipolsoft_Legajos t3 ON t3.EMPLID = t1.EMPLID
LEFT JOIN
[MatrizDB].[dbo].[nomina_fase_two] t4 ON t4.dni_id = t3.DNI
LEFT JOIN
[MatrizDB].dbo.v_nomina t5 ON t5.nroDocumento = t4.dni_id
WHERE
CONVERT(VARCHAR(25), PUNCH_DTTM, 120) LIKE '2019-04-24%'
AND t4.dni_responsable = 30329134
AND PUNCH_TYPE = 5
When I execute the query, I get this error
is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
You have count(*) in the select, so your query is an aggregation query. You have no group by; an aggregation query with no group by returns exactly one row. What values should be in that row for the other columns?
One answer is to put all the non-aggregated columns in the group by. Another is to remove all the non-aggregated columns from the select. Another would be to replace the count(*) with a window function (say, count(*) over () or what I suspect you want is row_number() over (order by <some column>).
you have to put group by as you used aggregate function count
SELECT
count(*) as t
,t1.EMPLID
,t3.DNI
,t1.PUNCH_DTTM
,PUNCH_TYPE
,TCD_ID
,t2.PCADescripcion
,t2.DFIDescripcion
,t2.Alias
,t5.apellido
,t4.planta
FROM [MatrizDB].[db_owner].[Historial_TRH] t1
left join MatrizDB.db_owner.Dispositivos_TRH t2
on t2.RefId = TCD_ID
left join MatrizDB.db_owner.Pipolsoft_Legajos t3
on t3.EMPLID = t1.EMPLID
left join [MatrizDB].[dbo].[nomina_fase_two] t4
on t4.dni_id = t3.DNI
left join [MatrizDB].dbo.v_nomina t5
on t5.nroDocumento = t4.dni_id
where CONVERT(VARCHAR(25),PUNCH_DTTM,120) LIKE '2019-04-24%'
AND t4.dni_responsable = 30329134 and PUNCH_TYPE = 5
group by t1.EMPLID
,t3.DNI
,t1.PUNCH_DTTM
,PUNCH_TYPE
,TCD_ID
,t2.PCADescripcion
,t2.DFIDescripcion
,t2.Alias
,t5.apellido
,t4.planta
I am trying to solve the error in the below query
Yes I have checked many same questions but still can not figure out the solution
The error:
The multi-part identifier "Table_2.id" could not be bound.
When I remove the inner join the query runs perfectly fine
I have to solve this problem without turning it into explicit joins because i have so many dynamic filtering which add and x=y clauses to the end of the query
Thank you
SELECT TOP 10 username,
NAME,
table_1.authoritylevel,
totalcount,
avglevel,
table_2.pokemonid,
pokemonlevel,
table_2.id,
pokemonexp,
battlecount,
battlevictorycount,
table_1.userid
FROM table_1,
table_2,
table_3,
table_4
LEFT OUTER JOIN (SELECT Count(table_5.offereruserid) AS OfferCount,
table_5.offereduserspokemonsid
FROM table_5
GROUP BY offereduserspokemonsid) innerQuestion
ON innerQuestion.offereduserspokemonsid = table_2.id
WHERE table_3.pokemonid = table_2.pokemonid
AND pokemonplace = 'trade'
AND table_4.pokemonid = table_2.pokemonid
AND table_2.userid = table_1.userid
AND table_2.userid != 1
If you are keen on keeping the implicit joins, you could split your query into several result sets using WITH. According to this article, you can no longer do "implicit outer joins." Give this a try:
WITH OfferCounts as
(
SELECT Count(table_5.offereruserid) AS OfferCount, table_5.offereduserspokemonsid
FROM table_5
GROUP BY offereduserspokemonsid
),
EverythingElse AS
(
SELECT TOP 10 username,
NAME,
table_1.authoritylevel,
totalcount,
avglevel,
table_2.pokemonid,
pokemonlevel,
table_2.id,
pokemonexp,
battlecount,
battlevictorycount,
table_1.userid
FROM table_1,
table_2,
table_3,
table_4,
WHERE table_3.pokemonid = table_2.pokemonid
AND pokemonplace = 'trade'
AND table_4.pokemonid = table_2.pokemonid
AND table_2.userid = table_1.userid
AND table_2.userid != 1
)
Select *
From EverythingElse t1
left join OfferCounts t2 on t1.offereduserspokemonsid = t2.id
The specific problem comes from the use of implicit joins first and then an explicit join. Lesser lines of code is not a very good reason to use implicit joins, specially since it's deprecated.
Another considerations would be to use table aliases, and also to prefix every column with the corresponding table alias, even if the column is unique between those tables for readability and a code that's easier to maintain.
You are also missing the GROUP BY needed for your aggregation function. All in all, the fixed code would be:
SELECT TOP 10 username,
NAME,
T1.authoritylevel,
totalcount,
avglevel,
T2.id,
T2.pokemonid,
pokemonlevel,
pokemonexp,
battlecount,
battlevictorycount,
T1.userid,
Count(T5.offereruserid) AS OfferCount
FROM Table_1 T1
INNER JOIN Table_2 T2
ON T1.userid = T2.userid
INNER JOIN Table_3 T3
ON T2.pokemonid = T3.pokemonid
INNER JOIN Table_4 T4
ON T2.pokemonid = T4.pokemonid
INNER JOIN Table_5 T5
ON T5.offereduserspokemonsid = T2.id
WHERE pokemonplace = 'trade'
AND T2.userid != 1
GROUP BY username,
NAME,
T1.authoritylevel,
totalcount,
avglevel,
T2.id,
T2.pokemonid,
pokemonlevel,
pokemonexp,
battlecount,
battlevictorycount,
T1.userid;
But, as I said, I suggest that you add the corresponding prefixes to those columns.
I am looking to display a 'O' or 'No results found' when no records are found based off my query but can't get it right. I think the problem comes from that I am trying to display information about the records I am counting along with how many there are that fit the criteria. Perhaps its not the count that I need to change with ISNULL but something to modify the result if no rows are outputted.
Thanks for any help in advance.
select t3.countyname, t2.titleunitname, t1.transdesc, count (isnull(t3.orderkey,0)) as c1
from tblorder as t3
left join qryOrderRecord1 as t1 on t3.OrderKey = t1.OrderKey
left join qrytitleunits as t2 on t3.titleunitnum = t2.titleunitnum
WHERE t1.transdesc = 'LETTERS'
AND (t3.OrderDateTime between '7/7/2010' AND '7/7/2010')
AND t3.countyname = 'Frankfurt'
AND t2.titleunitname = 'Maxwell'
group by t3.countyname,t1.transdesc, t2.titleunitname
That count(isnull(column, 0)) is the same as count(1) or count(*). See this question for the why...
Count(*) vs Count(1)
Maybe you want count(t1.orderkey)? This would not count any null t1.orderkey's.
I think you need to count t1.orderkey t3 is on the left side of the outer join so it is the t1.orderkey values that will be NULL.
Also I moved the Filters on t1 and t2 into the JOIN conditions not the WHERE clause
If that doesn't do the trick providing some sample data in your question will help.
SELECT t3.countyname,
t2.titleunitname,
t1.transdesc ,
COUNT(t1.orderkey) AS c1 /*As dotjoe's answer suggests*/
FROM tblorder AS t3
LEFT JOIN qryOrderRecord1 AS t1
ON t3.OrderKey = t1.OrderKey
AND t1.transdesc = 'LETTERS'
LEFT JOIN qrytitleunits AS t2
ON t3.titleunitnum = t2.titleunitnum
AND t2.titleunitname = 'Maxwell'
WHERE t3.OrderDateTime BETWEEN '7/7/2010' AND '7/7/2010' /*Seems odd! Should these be
different dates?*/
AND t3.countyname = 'Frankfurt'
GROUP BY t3.countyname,
t1.transdesc ,
t2.titleunitname
Give this a shot.
select t3.countyname, t2.titleunitname, t1.transdesc, count (isnull(t3.orderkey,0)) as c1
into #Tmp
from tblorder as t3
left join qryOrderRecord1 as t1 on t3.OrderKey = t1.OrderKey
left join qrytitleunits as t2 on t3.titleunitnum = t2.titleunitnum
where t1.transdesc = 'LETTERS'
AND (t3.OrderDateTime between '7/7/2010' AND '7/7/2010')
AND t3.countyname = 'Frankfurt'
AND t2.titleunitname = 'Maxwell'
group by t3.countyname,t1.transdesc, t2.titleunitname
if ##ROWCOUNT > 0
select *
from #Tmp
else
select 'No Results Found.'
I have the next query that in my opinion is a valid one, but I keep getting error telling me that there is a proble on "WHERE em.p4 = ue.p3" - Unknown column 'ue.p3' in 'where clause'.
This is the query:
SELECT DISTINCT ue.p3
FROM
table1 AS ue INNER JOIN table2 AS e
ON ue.p3 = e.p3
WHERE
EXISTS(
SELECT 1 FROM (
SELECT (COUNT(*) >= 1) AS MinMutual
FROM table4 AS smm
WHERE
smm.p1 IN (
SELECT sem.p3 FROM table3 AS sem
INNER JOIN table2 AS em ON sem.p3 = em.p3
WHERE em.p4 = ue.p3 AND
sem.type = 'friends' AND em.p2 = 'normal' ) AND
smm.p5 IN (
15000,15151
)
) AS Mutual WHERE
Mutual.MinMutual = TRUE) LIMIT 11
If I execute the sub-query which is inside the EXISTS function, everything is O.K.
PLEASE HELP!
The reason for the error is that you can only reference one subquery layer down when correlating. Look at where the ue alias is defined, and count the number of FROM clauses until to you reach the next reference.
I re-wrote your query as:
SELECT DISTINCT ue.p3
FROM table1 AS ue
JOIN table2 AS e ON ue.p3 = e.p3
WHERE EXISTS(SELECT 1 AS MinMutual
FROM table4 AS smm
JOIN TABLE3 sem ON sem.p3 = smm.p1
AND sem.type = 'friends'
JOIN TABLE2 em ON em.p3 = sem.p3
AND em.p3 = ue.p3
AND em.p2 = 'normal'
WHERE smm.p5 IN (15000,15151)
GROUP BY ? --needs a group by clause, in order to use HAVING
HAVING COUNT(*) >= 1)
LIMIT 11
EXISTS returns true if satisfied -- it doesn't evaluate based on the subquery returning "true". There's no need for the additional subquery you have (which was causing problems anyway).
AFAIK, this kind of correlated query is not doable in mysql as of now. Join to a derived table as opposed to using the exists.