Subquery with GROUPBY on calculated field: Your query does not include the specified expression '' as part of an aggregate function - sql

I get the following error message
"Your query does not include the specified expression 'SampleCode' as part of an aggregate function."
I've looked into aggregate functions and have tried various ways to GROUP BY using the individual data fields that make up the code but I can't seem to get anything to work.
'SampleCode' is a concatenated query field (query name: datqry_SampleNumber) that is based on data from 3 different tables to create a unique value as follows...
SampleCode: IIf([tbl_Carcass.SampleNumber]="-999","-999",
"NPT-" & [tbl_SurveyInfo.SurveyYear*] & "-" &
[datqry_TransectData.Project_Code] & "-" & [tbl_Carcass.SampleNumber])
for SampleNumber values > 0001 (-999 is a placeholder indicating no SampleNumber assigned). Note, SurveyYear* is a calculated field based on the SurveyDate data field.
So, since SampleCode needs to be unique to each sample, I am trying to build a duplicate query, based on the aforementioned query, to identify duplicate SampleCodes so they can be relabeled and archived w/ a unique qualifier. The criteria for the duplicate query operation is as follows
In (SELECT [SampleCode] FROM [datqry_SampleNumber] As Tmp
GROUP BY [SampleCode] HAVING Count(*)>1 )
Any ideas on how to tackle this problem? Thank you in advance for your help and suggestions.

This looks like it might be a limitation of the JET engine used by Access to interpret its SQL.
It appears to be having trouble working with the subquery because it contains an aggregation of a calculated field (SampleCode in your case).
Try saving this as a separate query called, e.g. qryDuplicates:
SELECT [SampleCode] FROM [datqry_SampleNumber]
GROUP BY [SampleCode] HAVING Count(*)>1;
Then what you are trying to do will work as expected:
SELECT * from someTable WHERE someField IN (
SELECT * FROM qryDuplicates
);
TECHNICAL NOTE: I've tested it out and it is indeed specific to the fact that SampleCode is a calculated field. Doing exactly the same kind of grouped subquery works as expected when the field in question is not calculated.
With this test database this query works:
SELECT * FROM Table2 WHERE Field3 IN (
SELECT Field1 FROM datqry_SampleNumber
GROUP BY Field1 HAVING COUNT(*) > 1
);
And this doesn't
SELECT * FROM Table2 WHERE Field3 IN (
SELECT SampleCode FROM datqry_SampleNumber
GROUP BY SampleCode HAVING COUNT(*) > 1
);

Related

How to make a new column in SELECT clause and fill it with a string/list dynamically with concat of all condition statements satisfied?

So there are two tables in a database. I have to find out whichever rows have discrepancy based on certain conditions (in couple of cases that's just equality checking between fields). I report ID of those rows.
The problem is to also include the reasons in another column as to why that ID is reported. Because an id can be fail multiple conditions (like mismatch on two fields), I just wanted to include all of those reasons in another column.
Basic idea is to append all the mismatches in another column.
I've looked at several SO questions but they don't exactly my use case. So now I'm thinking it's not possible with SQL.
I searched Google for "enter dynamic column values based on conditions sql", and hit : SQL Conditional column data return in a select statement : This adds a static column
I also learned it's possible to add another column in SELECT with dynamic content like this:
SELECT id, CASE
WHEN columnname "DEF" then "I" ELSE "YOU" newColumnName
FROM tableName
But I have not been able to find dynamic column value assignment and update SQL. That's the problem.
Expected results:
I just want to be able to concat all the cases "strings" which a record is applicable for.
Do this with the two tables.
So because I have two tables to work with I have to put these conditions in the WHERE sub-clause, and not in the SELECT one.
So, if for ID = 345, column "FOO_MAN" does not match between two tables, and column "BAR_TOO" also does not match between two tables, then?
Then I want my select clause to capture information like this:
ID | REASON
345 | FOO_MAN BAR_TWO
It's probably easier to build this type of query dynamically (e.g. using a stored procedure) based on the conditions you want to test, but here is a small example which shows how it can be done:
SELECT t1.id,
CONCAT_WS(' ',
CASE WHEN t1.foo != t2.foo THEN 'foo' END,
CASE WHEN t1.bar != t2.bar THEN 'bar' END
) AS reason
FROM t1
JOIN t2 ON t2.id = t1.id
WHERE t1.foo != t2.foo OR t1.bar != t2.bar
Output (for my demo on dbfiddle)
id reason
2 foo
4 bar
5 foo bar

t-sql query returns undefined after using ORDER BY

I am currently working with a MS SQL database on Windows 2012 Server
I need to query only 1 column from a table that I only have access to read, not make any kind of changes.
Problem is that the name of the column is "Value"
My code is this:
SELECT 'Value' FROM table
If I add
`ORDER BY 'Value'`
The issue is that the query is returning an empty list of results.
Things I've tried already
I tried replacing ' with `"' but this didn't work either.
I also tried writing SELECT * instead of SELECT VALUE
Using the table name in the SELECT or ORDER clauses again didn't help
You are claiming that this query:
SELECT 'Value'
FROM table
ORDER BY 'Value'
Is returning no rows. That's not quite correct. It is returning an error because SQL Server does not allow constant expressions as keys for ORDER BY (or GROUP BY for that matter).
Do not use single quotes. In this case:
SELECT 'Value' as val
FROM table
ORDER BY val;
Or, if value is a column in the table:
SELECT t.Value
FROM table t
ORDER BY t.Value;
Value is not a reserved word in SQL Server, but if it were, you could escape it:
SELECT t.[Value]
FROM table t
ORDER BY t.[Value];
it looks like your table has null values. and because of the order by all null values come first.
try to add filter like this
select Value FROM table
where Value is not null and Value <> ''
order by Value

Access SQL query that uses a field from one table within where clause to create a calculated field

This really isn't that complicated but I can't wrap my head around it. Ive searched thoroughly but even coming up with a search string or title for this question was hard enough. The explanation will tell all:
Table "labelDrops" has fields "PO" and "Qty" (among other unrelated fields)
Table "imageLiveCount" has field "PO"
I want to count instances (count(imageLiveCount.id)) where imageLiveCoount.PO = labelDrops.PO and then subtract that from the "QTY" to create a calculated field called "QtyLeft".
The result would basically look like "SELECT PO, Qty, answerToThisQuestion AS QtyLeft FROM labelDrops"
Start by creating a query which gives you the count for each PO in your imageLiveCount table:
SELECT i.PO, Count(*) AS CountOfInstances
FROM imageLiveCount AS i
GROUP BY i.PO
If that query returns what you want, join it to the labelDrops table and compute QtyLeft:
SELECT
l.PO,
l.Qty,
(l.Qty - sub.CountOfInstances) AS QtyLeft
FROM
labelDrops AS l
INNER JOIN
(
SELECT i.PO, Count(*) AS CountOfInstances
FROM imageLiveCount AS i
GROUP BY i.PO
) AS sub
ON l.PO = sub.PO

SQL Server where column in where clause is null

Let's say that we have a table named Data with Id and Weather columns. Other columns in that table are not important to this problem. The Weather column can be null.
I want to display all rows where Weather fits a condition, but if there is a null value in weather then display null value.
My SQL so far:
SELECT *
FROM Data d
WHERE (d.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%' OR d.Weather IS NULL)
My results are wrong, because that statement also shows values where Weather is null if condition is not correct (let's say that users mistyped wrong).
I found similar topic, but there I do not find appropriate answer.
SQL WHERE clause not returning rows when field has NULL value
Please help me out.
Your query is correct for the general task of treating NULLs as a match. If you wish to suppress NULLs when there are no other results, you can add an AND EXISTS ... condition to your query, like this:
SELECT *
FROM Data d
WHERE d.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%'
OR (d.Weather IS NULL AND EXISTS (SELECT * FROM Data dd WHERE dd.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%'))
The additional condition ensures that NULLs are treated as matches only if other matching records exist.
You can also use a common table expression to avoid duplicating the query, like this:
WITH cte (id, weather) AS
(
SELECT *
FROM Data d
WHERE d.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%'
)
SELECT * FROM cte
UNION ALL
SELECT * FROM Data WHERE weather is NULL AND EXISTS (SELECT * FROM cte)
statement show also values where Wether is null if condition is not correct (let say that users typed wrong sunny).
This suggests that the constant 'sunny' is coming from end-user's input. If that is the case, you need to parameterize your query to avoid SQL injection attacks.

sql server - how to execute the second half of 'or' clause only when first one fails

Suppose I have a table with following records
value text
company/about about Us
company company
company/contactus company contact
I have a very simple query in sql server as below. I am having problem with the 'or' condition. In below query, I am trying to find text for value 'company/about'. If it is not found, then only I want to run the other side of 'or'. The below query returns two records as below
value text
company/about about Us
company company
Query
select
*
from
tbl
where
value='company/about' or
value=substring('company/about',0,charindex('/','company/about'))
How can I modify the query so the result set looks like
value text
company/about about Us
A bit roundabout, but you can check for the existence of results from the first where clause:
select
*
from
tbl
where
value='company/about' or
(
not exists (select * from tbl where value='company/about')
and
value=substring('company/about',0,charindex('/','company/about'))
)
Since your second condition can be re-written as value = 'company' this would work (at least for the data and query you've presented):
select top(1) [value], [text]
from dbo.MyTable
where value in ('company/about', 'company')
order by len(value) desc
The TOP() ignores the second row if both are found, and the ORDER BY ensures that the first row is always the one with 'company/about', if it exists.