JPA Group by with multiple field - jpa

I am getting following error while using named query blog.findBlogs
"Your select and having clauses must only include aggregates or values that also appear in your grouping clause."
In select clause I have used b.id so it must allow to perform this query without error. I also tried same query from mysql workbench and its working perfectly fine.
#NamedQueries( value = {
#NamedQuery (name = "blog.findBlogs", query = "SELECT " +
"NEW com.vo.Blog(b.id, b.blogId, b.createDate, b.tags, b.url, COUNT(r.emotion)) " +
"FROM Blog b JOIN b.rates r " +
"GROUP BY b.id")
})
regards, Amit J.

In general, a GROUP BY query in SQL must obey a rule that everything which appears in the SELECT clause must either appear in the GROUP BY clause or be inside an aggregate function, such as COUNT.
I also tried same query from mysql workbench and its working perfectly fine.
It turns out that MySQL is one of a few databases which does not enforce this rule. But JPA appears to not allow this, so it fails for you running from JPA even though the underlying database is a lax version of MySQL.
Here is how you can modify your code to run without error:
#NamedQueries( value = {
#NamedQuery (name = "blog.findBlogs", query = "SELECT " +
"NEW com.vo.Blog(b.id, COUNT(r.emotion)) " +
"FROM Blog b JOIN b.rates r " +
"GROUP BY b.id")
})
If you're wondering what the logical problem with your original query was, it is that, for a given b.id value, JPA cannot figure out which blog, date, and tags value to choose for that group.

Related

Access - Searching through two identical table structures

I currently have two identical tables (As far as columns) in my access database. I setup a form that allows a user to enter an ID and search through ONE of the tables.
I am trying to have it search through a second table as well, but my query doesn’t return results from BOTH tables. I am only able to retrieve results from the first table.
I used query design to build my query which was basically just selecting the table I need and bringing down all the fields in the criteria section. When I tried to build the second query, I selected both tables and matched the ID’s from both tables, but the results were not correct (ID existed in both tables, but only showed ID from one table).
Private Sub cmdSearch_Click()
If Nz(comboID, "") <> "" Then
'DoCmd.OpenQuery "Inquiries Query", acViewNormal, acReadOnly
DoCmd.OpenQuery "both tables", acViewNormal, acReadOnly
Else
' If Nz(txtReportDate, "") = "" Then
MsgBox "NOTICE! Please enter a ID"
Exit Sub
End If
End Sub
I think what you want is a union all query.
"SELECT * FROM Table1 WHERE ID = " & comboID.value & _
"UNION ALL SELECT * FROM Table2 WHERE ID = " & comboID.value & ";"
This would runs two separate select queries and combine all the columns that are the same.
Note: if you have the exact same record in both tables it will show up twice.

In SSRS, why do I get the error "item with same key has already been added" , when I'm making a new report?

I'm getting the following error in SSRS:
An error occurred while the query design method was being saved.
An item with the same key has already been added
What does an "item" denote, though? I even tried editing the RDL and deleting all references to the Stored Procedure I need to use called prc_RPT_Select_BI_Completes_Data_View.
Could this possibly have to do with the fact that the Stored Procedure uses Dynamic SQL (the N' notation)?
In the stored procedure I have:
SET #SQL += N'
SELECT bi.SupplierID as ''Supplier ID''
,bi.SupplierName as ''Supplier Name''
,bi.PID as ''PID''
,bi.RespondentID as ''Respondent ID''
,lk_slt.Name as ''Entry Link Type''
,ts.SurveyNumber as ''Initial Survey ID'''
It appears that SSRS has an issue(at leastin version 2008) - I'm studying this website that explains it
Where it says if you have two columns(from 2 diff. tables) with the same name, then it'll cause that problem.
From source:
SELECT a.Field1, a.Field2, a.Field3, b.Field1, b.field99 FROM TableA a
JOIN TableB b on a.Field1 = b.Field1
SQL handled it just fine, since I had prefixed each with an alias
(table) name. But SSRS uses only the column name as the key, not table
+ column, so it was choking.
The fix was easy, either rename the second column, i.e. b.Field1 AS
Field01 or just omit the field all together, which is what I did.
I face the same issue. After debug I fixed the same. if the column name in your SQL query has multiple times then this issue occur. Hence use alias in SQL query to differ the column name.
Ex:
The below query will work proper in sql query but create issue in SSRS report:
Select P.ID, P.FirstName, P.LastName, D.ID, D.City, D.Area, D.Address
From PersonalDetails P
Left Join CommunicationDetails D On P.ID = D.PersonalDetailsID
Reason : ID has mentioned twice (Multiple Times)
Correct Query:
Select P.ID As PersonalDetailsID, P.FirstName, P.LastName, D.ID, D.City, D.Area, D.Address
From PersonalDetails P
Left Join CommunicationDetails D On P.ID = D.PersonalDetailsID
I have experience this issue in past. Based on that I can say that generally we get this issue if your dataset has multiple fieldnames that points to same field source.
Take a look into following posts for detail error description
https://bi-rootdata.blogspot.com/2012/09/an-error-occurred-during-report.html
https://bi-rootdata.blogspot.com/2012/09/an-item-with-same-key-has-already-been.html
In your case, you should check your all field names returned by Sp prc_RPT_Select_BI_Completes_Data_View and make sure that all fields has unique name.
I had the same error in a report query. I had columns from different tables with the same name and the prefix for each table (eg: select a.description, b.description, c.description) that runs ok in Oracle, but for the report you must have an unique alias for each column so simply add alias to the fields with the same name (select a.description a_description, b.description b_description and so on)
Sorry, it is a response to an old thread, but might still be useful.
In addition to above responses,
This generally happens when two columns with same name, even from different tables are included in the same query.
for example if we joining two tables city and state where tables have column name
e.g. city.name and state.name.
when such a query is added to the dataset, SSRS removes the table name or the table alias and only keeps the name, whih eventually appears twice in the query and errors as duplicate key.
The best way to avoid it is to use alias such as calling the column names
city.name as c_name
state.name as s_name.
This will resolve the issue.
I got this error message with vs2015 enterprise, ssdt 14.1.xxx, ssrs. For me I think it was something different than described above with a 2 column, same name problem. I added this report, then deleted the report, then when I tried to add the query back in the ssrs wizard I got this message, " An error occurred while the query design method was being saved :invalid object name: tablename" . where tablename was the table on the query the wizard was reading. I tried cleaning the project, I tried rebuilding the project. In my opinion Microsoft isn't completing cleaning out the report when you delete it and as long as you try to add the original query back it won't add. The way I was able to fix it was to create the ssrs report in a whole new project (obviously nothing wrong with the query) and save it off to the side. Then I reopened my original ssrs project, right clicked on Reports, then Add, then add Existing Item. The report added back in just fine with no name conflict.
I just got this error and i came to know that it is about the local variable alias
at the end of the stored procedure i had like
select #localvariable1,#localvariable2
it was working fine in sql but when i ran this in ssrs
it was always throwing error but after I gave alias it is fixed
select #localvariable1 as A,#localvariable2 as B
SSRS will not accept duplicated columns so ensure that your query or store procedure is returning unique column names.
If you are using SPs and if the sps have multiple Select statements (within if conditions) all those selects needs to be handled with unique field names.

DB2 Query Structure Using User-Defined Function as a Table

I'm a little new to DB2, and am having trouble developing a query. I have created a user-defined function that returns a table of data which I want to then join and select from in larger select statement. I'm working on a sensitive db, so the query below isn't what I'm literally running, but it's almost exactly like it (without the other 10 joins I have to do lol).
select
A.customerId,
A.firstname,
A.lastname,
B.orderId,
B.orderDate,
F.currentLocationDate,
F.currentLocation
from
customer A
INNER JOIN order B
on A.customerId = B.customerId
INNER JOIN table(getShippingHistory(B.customerId)) as F
on B.orderId = F.orderId
where B.orderId = 35
This works great if I run this query without the where clause (or some other where clause that doesn't check for an ID). When I include the where clause, I get the following error:
Error during Prepare 58004(-901)[IBM][CLI Driver][DB2/LINUXX8664]
SQL0901N The SQL statement failed because of a non-severe system
error. Subsequent SQL statements can be processed. (Reason "Bad Plan;
Unresolved QNC found".) SQLSTATE=58004
I have tracked the issue down to fact that I'm using one of join criteria for the parameters (B.customerId). I have validated this fact by replacing B.customerId with a valid customerId, and the query works great. Problem is, I don't know the customerId when calling this query. I know only the orderId (in this example).
Any thoughts on how to restructure this so I can make only 1 call to get all the info? I know the plan is the problem b/c the customerId isn't getting resolved before the function is called.
So if I understand correctly, the function getShippingHistory(customerId) returns a table.
And if you call it with a single customer Id that table gets joined in your query above no problem at all.
But the way you have the query written above, you are asking db2 to call the function for every row returned by your query (i.e. every b.customerId that matches your join and where conditions).
So I'm not sure what behaviour you are expecting, because what you're asking for is a table back for every row in your query, and db2 (nor I) can figure out what the result is supposed to look like.
So in terms of restructuring your query, think about how you can change the getShippingHistory logic when multiple customer Ids are involved.
i found the best solution (given the current query structure) is to use a LEFT join instead of an INNER join in order force the LEFT part of the join to happen which will resolve the customerId to a value by the time it gets to the function call.
select
A.customerId,
A.firstname,
A.lastname,
B.orderId,
B.orderDate,
F.currentLocationDate,
F.currentLocation
from
customer A
INNER JOIN order B
on A.customerId = B.customerId
LEFT JOIN table(getShippingHistory(B.customerId)) as F
on B.orderId = F.orderId
where B.orderId = 35

Postgresql Faulty Syntax on select/join/group

What about the following is not proper syntax for Postgresql?
select p.*, SUM(vote) as votes_count
FROM votes v, posts p
where p.id = v.`voteable_id`
AND v.`voteable_type` = 'Post'
group by v.voteable_id
order by votes_count DESC limit 20
I am in the process of installing postgresql locally but wanted to get this out sooner :)
Thank you
MySQL is a lot looser in its interpretation of standard SQL than PostgreSQL is. There are two issues with your query:
Backtick quoting is a MySQL thing.
Your GROUP BY is invalid.
The first one can be fixed by simply removing the offending quotes. The second one requires more work; from the fine manual:
When GROUP BY is present, it is not valid for the SELECT list expressions to refer to ungrouped columns except within aggregate functions, since there would be more than one possible value to return for an ungrouped column.
This means that every column mentioned in your SELECT either has to appear in an aggregate function or in the GROUP BY clause. So, you have to expand your p.* and make sure that all those columns are in the GROUP BY, you should end up with something like this but with real columns in place of p.column...:
select p.id, p.column..., sum(v.vote) as votes_count
from votes v, posts p
where p.id = v.voteable_id
and v.voteable_type = 'Post'
group by p.id, p.column...
order by votes_count desc
limit 20
This is a pretty common problem when moving from MySQL to anything else.

TSQL syntax - Is aliasing with a quoted prefix depricated?

Can anyone tell me if writing a query in the following tsql syntax is either (1) currently -- or going to be soon -- deprecated by MSFT, or (2) in opposition to some best practice of which I'm not aware?
SELECT
'CustName' = (SELECT Lastname + ', ' + Firstname FROM Cust WHERE CustID = O.CustID),
'ProdName' = (SELECT ProductName FROM Product WHERE ProductID = O.ProductID)
FROM Orders O
The specific question is putting the new column name all the way to the "front" or left of the line as opposed to writing the subquery and putting the new column name in square brackets after the subquery. Obviously both will work, but the DBAs reviewing my database code typically give me a WTF look when they see this, even though I tell them it's far more readable because all of your column names are on the left...
Is there something wrong with writing queries in this manner?
CLARIFICATION: The point isn't the subqueries in the SELECT statement, it's whether the syntax:
'NewColumnName' = OldColumnName
is going away anytime soon. I chose to demonstrate the question with a pair of subqueries rather than using the giant and esoteric custom function calls and case statements that are actually in the production code I'm using.
According to SQL 2005 BOL here (ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/instsql9/html/c10eeaa5-3d3c-49b4-a4bd-5dc4fb190142.htm) and here: http://msdn.microsoft.com/en-us/library/ms143729(SQL.90).aspx and in the 2008 doc here: http://msdn.microsoft.com/en-us/library/ms143729.aspx (look under "Transact-SQL" features) this will be deprecated in a future release (unspecified).
However, it's a bit subtle. This deprecation warning actually only applies to the use of the quotation marks in this context, not the column-alias-first format. I.E., this will be deprecated:
'AliasName' = NewValue
However, this is still valid and even listed as a replacement for it:
AliasName = NewValue
So just take the apostrophes out and you're good.
There's absolutely nothing wrong with the
column alias = expression
syntax and it isn't deemed to be either deprecated soon or bad practice!
The main problem with the query, is that you should be using joins to connect the Orders table to the Cust and Product tables. The query looks like you are assuming there is only one Customer and one Product per order - think about what would happen if that wasn't true....
SELECT
'CustName' = C.Lastname + ', ' + C.Firstname,
'ProdName' = P.ProductName
FROM Orders O
JOIN Cust C on C.CustID = O.CustID
JOIN Product P on P.ProductID= O.ProductID
I typically see this syntax when using a subquery to set a variable, #MyValue = (subquery) for example. So there was a bit of a WTF from me for a minute as well. However, I see your point, and overall I can't imagine that it is something that would be not supported in the future.
Personally though I prefer a more formatted manner, and a distinct "AS" definition. I would write it something like this.
SELECT
(SELECT Lastname + ', ' + Firstname
FROM Cust
WHERE CustID = O.CustID
) AS CustName,
(SELECT ProductName
FROM Product
WHERE ProductID = O.ProductID
) AS ProdName
FROM Orders O
I personally find this easier to read....but more than likely that is just me...
My guess is people balk at it because it's specific to MSSQL, not supported by other systems (at least, not the ones I have available to me right now). It's like listening to an unfamiliar dialect - you can see what the person is getting at, but you can't see why on Earth they would choose to speak that way.
You are aliasing a column name in a strange, unfamiliar way. i had to run it to see if it was even valid.
Rather than doing what's strange and uncommon, do what people expect:
SELECT
(SELECT Lastname + ', ' + Firstname FROM Cust WHERE CustID = O.CustID) AS CustName,
(SELECT ProductName FROM Product WHERE ProductID = O.ProductID) AS ProdName
FROM Orders O