SQL column reference is invalid - sql

I am using Jaspersoft's iReport to create a report that will pull data from my Maintenance Assistant CMMS database. The DB is on the localhost, and I am not creating any tables or columns. MA CMMS takes care of that. I only want to pull the data to arrange in a report.
Here is my code:
SELECT *
FROM "tblworkordertask"
WHERE "dbltimespenthours" > 0
AND "dtmdatecompleted" BETWEEN $P{DATE_FROM} AND $P{DATE_TO}
GROUP BY "intworkorderid"
and my error:
Caused by: java.sql.SQLSyntaxErrorException: Column reference 'tblWorkOrderTask.id' is invalid, or is part of an invalid expression.  For a SELECT list with a GROUP BY, the columns and expressions being selected may only contain valid grouping expressions and valid aggregate expressions.
I don't know why the error is referring to 'tblWorkOrderTask.id' because I don't have such a column, nor did I ask for that column.
If I take out the group by clause, it works fine, but as you could expect, I get multiple results with the same WorkOrderID. I want to group it by this column, and then count the results. I tried using SELECT DISTINCT, but then I get errors about columns that aren't selected.

You're selecting all columns in the tblWorkOrderTask table. The "id" column is the first column in that table. You are getting an error because you do not have all columns specified in the select list.
This select would work, but I'm not sure what information you need out of your table.
SELECT id, intworkorderid
FROM tblWorkOrderTask
group by id, intworkorderid
http://www.w3schools.com/sql/sql_groupby.asp

Get rid of the GROUP BY clause -- if you're just trying to order the result, then use ORDER BY instead; but otherwise, you don't need either.
EDIT
As the error says, everythign in your SELECT list must be one of two things -- either 1) also listed in your GROUP BY list, or 2) an aggregated value. Here is a sample that will work:
SELECT intworkorderid, COUNT(*)
FROM "tblworkordertask"
WHERE "dbltimespenthours" > 0
AND "dtmdatecompleted" BETWEEN $P{DATE_FROM} AND $P{DATE_TO}
GROUP BY "intworkorderid"

Yes - in order to use group by, you need to be specific in the select line.
So first, decide which fields you want to display. If you want them all, then include them all.
As soon as you add a COUNT() function to get a count of the selected fields, you will need to add the GROUP BY clause. COUNT() is an AGGREGATE function, like SUM() and AVG().
It's a little counter-intuitive and a bit of a pain to specify so many fields in the GROUP BY clause, but it's necessary.
The FIRST GROUP BY field is the most important, since this is usually what you are concerned about.
This first field can be any of the SELECTed fields, it is not necessarily the first.
Include EVERY field in your GROUP BY that is not an AGGREGATE function like COUNT().
Also, if you are trying to COUNT a group of orders, you probably don't want or need all of the fields in the SELECT.
You probably want to specify just the fields that are unique to the work order ID.
Example: If you want to get a COUNT of these fields, you would specify all of the SELECTED fields EXCEPT the COUNT().
SELECT
intWorkOrderID,
COUNT(id),
strDescription
FROM tblworkordertask
WHERE dbltimespenthours > 0
AND dtmdatecompleted BETWEEN $P{DATE_FROM} AND $P{DATE_TO}
GROUP BY
intworkorderid,
strDescription

Related

why distinct and order by doesn't work together in sql query?

enter image description here I am learning how to order by is used in SQL query, then I learned that order by and distinctly don't work together but, when I try to do it practically it worked. I am so confused even after asking chatgpt what the relationship is between order by and distinct.
I learned that when executing SQL queries, the ORDER BY clause comes after the SELECT clause. This means that the database will first retrieve the data specified in the SELECT clause, and then sort it based on the criteria specified in the ORDER BY clause. If the column used in the ORDER BY clause is not present in the SELECT clause, the database will automatically include that column in the select and do order by on both the columns and give result column only column given in SELECT.
However, when using both DISTINCT and ORDER BY together, the outcome may not be what is expected. This is because DISTINCT acts on both the columns in the SELECT clause and the column in the ORDER BY clause. This may cause unexpected results, especially in MySQL.
I found that when I tried this in practice, it still produced the desired results, which makes me question if I learned something incorrectly or if there is missing information that I am unaware of.
I am using the MYSQL database.
It seems there are some spaces before your unique value. It will be appropriate to perform TRIM/RTRIM and remove these spaces in the DISTINC clause itself.
It should be something like this:
DISTINCT TRIM(value) AS trim_value
...
ORDER BY trim_value
Also, it is possible that these are not spaces but some other characters which need to be replace, too.

An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause

I'm trying to build a query that groups and sums two different fields for the same ID. Then I'm trying to extract only the records that are different where the grouped total is different from the summed total.
For example - The sum([EstimatedEmployeesAtLocation]) should equal the grouped Estimatedtotalemployees is the same for each record.
This is what three records would look like
ID 1,1,1
Estimatedtotalemployees 10,10,10
EstimatedEmployeesAtLocation 6,2,1
I know the issue is something with using an aggregate function in the where clause, because the query works until I add the where clause. But I don't know the correct syntax. Can someone please advise?
select ID, Estimatedtotalemployees, sum([EstimatedEmployeesAtLocation]) emploc
from Rawdata
where sum([EstimatedEmployeesAtLocation]) <> EstimatedTotalEmployees
group by policyNumber, EstimatedTotalEmployees
This is the error message.An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference. I'm just starting to use SQL beyond basic querying so any help is much appreciated -
SQLs are evaluated in roughly the following order:
FROM - the data is joined
WHERE - the data is filtered
GROUP BY - the data is aggregated
SELECT - the result set is produced
You can't use a SUM(...) in a WHERE clause because it hasn't been calculated yet; it's done as part of the GROUP BY and SELECT
You also can't have ID in your select list because you haven't grouped by it.
You might be better off asking a new question/editing some detail into this one that sets out what raw data you have (and please put it with columns across the top, rows downwards, like SSMS shows you), what you've tried (e.g the above sql), and what your desired result is (again, rows run horizontally and columns run vertically, otherwise someone will end up giving you a pivot). Right now you seem to have given the raw data but have labelled it as the result data, and it looks the wrong way round so I'm not sure if it needs rotating or not
Here's my best stab at what you're after:
select ID, MAX(Estimatedtotalemployees), SUM([EstimatedEmployeesAtLocation])
from Rawdata
group by ID
having SUM([EstimatedEmployeesAtLocation]) <> MAX(EstimatedTotalEmployees)

Postgres - Group by without having to aggregate?

This is hard to explain, but say I have this query:
SELECT *
FROM "late_fee_tiers"
And it returns this:
I have a validation in code set up to prevent duplicate days from being saved (notice there are 2 rows of days = 2).
I want my query to double-check there are only unique rows of day, and if there are multiple, select the first one (so it should return 3 rows with 2,3,5).
My first thought is to use GROUP BY day, while selecting a MIN("id").
The problem is, I don't understand SQL enough, because it forces me to add different aggregator functions to every single column... but what if I don't want to do that? I want THAT row to be "chosen" according to the single aggregator function I define, I don't need multiple aggregators creating some weird hybrid row. I just want the MIN() function to choose that 1 row and fill in all the rest of the values for that row.
What function do I use to do this, or how would I do it?
Thanks
You want to use DISTINCT ON:
select distinct on (day) *
from "late_fee_tiers"
order by day, id;
Why day is also required in the order by:
From the official documentation:
The DISTINCT ON expression(s) must match the leftmost ORDER BY
expression(s). The ORDER BY clause will normally contain additional
expression(s) that determine the desired precedence of rows within
each DISTINCT ON group.

Sql error in simple query? Any ideas?

I'm getting the error:
Column 'A10000012VICKERS.dbo.IMAGES.idimage' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Any ideas why I would be getting this error or how to fix it? I thought that I was just asking for the size of a number of filestream columns and the values of two others?
SELECT
idimage,
filetype,
SUM(DATALENGTH(filestreamimageoriginal)) AS original,
SUM(DATALENGTH(filestreamimagefull)) AS [full],
SUM(DATALENGTH(filestreamimageextra)) AS extra,
SUM(DATALENGTH(filestreamimagelarge)) AS large,
SUM(DATALENGTH(filestreamimagemedium)) AS medium,
SUM(DATALENGTH(filestreamimagesmall)) AS small, SUM(DATALENGTH(filestreamimagethumbnail)) AS thumbnail
FROM A10000012VICKERS.dbo.IMAGES WHERE display = 1
I don't really see how that query could generate that message. There is no column with that name. However, the query does have an obvious error.
Your query is an aggregation query because it uses SUM() in the SELECT clause. However, this will return only one row, unless you also have a GROUP BY.
Add this to the end of your query:
GROUP BY idimage, filetype
Or, remove these columns from the SELECT.
By using an aggregation function (SUM) you are aggregating your records. As you have specified no GROUP BY clause you will get one result row, i.e. an aggregation over all rows. In this aggregation, however, there is no longer one idimage or one filetype that you could show in your results.
So either use an aggregation function on these, too (e.g. max(idimage), min(filetype)) or remove them from the query, if you really want one aggregate over all these rows.
If, however, you want to aggregate per idimage and filetype, then add GROUP BY idimage, filetype at the end of your query.

How to get other columns in this query

I am using a group by clause in my query. I want to get other columns not specified in the group by parameters
SELECT un.user, un.role
FROM [Unique] un
group by user, role
In the query about [Unique] has 7 columns altogether. How do I get the other columns?
In most databases (MySQL and SQLite are the exceptions I know of), you cannot include a column in a GROUP BY SELECT unless:
The column is included in the GROUP BY clause.
The column is aggregated in one of the supported aggregate functions.
In MySQL and SQLite, the rows inside the aggregate groups from which the extra values get taken are undefined.
If you want extra columns in any other engine, you can wrap the column names in MAX():
SELECT un.user, un.role, MAX(un.city), MAX(un.bday)
FROM [Unique] un
GROUP BY user, role
In this case, the values for the extra columns are likely to come from different rows in the input record set. If this is important (sometimes it isn't since the extra columns come from the one side of a one-to-many JOIN), you can't use this technique.
Just to be clear: If you use GROUP BY in a SELECT, then each row you get back is constructed out of groups of multiple rows in the table you're SELECTing against. If you include columns that are not part of the GROUP BY clause, you're not giving the engine any instructions on which row from the table you want that value read from. Most engines, therefore, do not allow you to run this kind of SQL. MySQL does, with undefined results but I personally consider it bad practice to do this.
You have to choose on what basis you want the other columns. If multiple entries exist for the same user / role, do you want the first / last / random? You have to make choices on the other columns, by aggregating them or choosing to include them in the group by statement.
Some RDBMS do provide a default behaviour for performing this, but since the question is just marked SQL, we do not know if it applies.
Have you tried just specifying them?
SELECT un.user, un.role, un.col3, un.col4
FROM [Unique] un
group by user, role
You need to use a Order By to get extra column. or you end up specifying every column in your group by.
Use LEFT JOIN to self-join the Unique or use the SELECT with GROUP BY as sub-query.