I have this problem with JPA Query. DER
Customers make purchases and can purchase products with a limit of 1 unit per purchase per day.
This is my Native Query:
#Query("SELECT p FROM Producto p where p.idProducto not in (SELECT c.detalles FROM Compra c"
+ " JOIN c.detalles det" + " where (c.cliente=?1 and (DATE(c.fecha) = CURRENT_DATE()))"
+ " GROUP BY det.id_producto" + " HAVING (sum(det.cantidad<=1)))")
List<Producto> getProductosHabilitadosPorCliente(int idCliente);
ERROR: expecting CLOSE, found '<=' near line 1, column 278.
Thanks!!
The solution:
#Query("SELECT p FROM Producto p WHERE p.idProducto NOT IN (SELECT d.producto FROM Compra c JOIN c.detalles d WHERE ((c.cliente.idCliente=?1) AND (DATE(c.fecha)=CURRENT_DATE())) GROUP BY d.producto HAVING SUM(d.cantidad)>=3")")
Related
I have three tables:
"user" who has one or more rows associated with him in the "contractYear" table, which consists of rows in a "contract_month" table.
I want to get the result set of users who do not have contract months for the current contract year (i.e. contract Year.endDate < current date)
I made the following query:
#Query("select distinct u "
+ " from User u "
+ " left join u.contractYears cy"
+ " on cy.endDate < now()"
+ " left join cy.contractMonths cm"
+ " where cm is null")
But it doesn't work...
I assume the condition "on cy.endDate < now()" is not correct.
Maybe someone can help me make the correct query?
In HQL if you need additional filter in join clause you can add using WITH keyword
select distinct u
from User u
left join u.contractYears cy
with cy.endDate < now()
left join cy.contractMonths cm
where cm is null
See 14.3. Associations and joins section
How can I joining two tables with different column in SQL Server CE?
I have two tables:
Table Schedule
+-----+----------+------+
+ ID + Name + Type +
+-----+----------+------+
+ 1 + A + 1 +
+ 2 + B + 1 +
+ 3 + C + 2 +
+-----+----------+------+
Table Description
+-----+--------------------+
+ ID + Description +
+-----+--------------------+
+ 1 + A1 - XXXXX +
+-----+--------------------+
And what I want to get is the table like:
+-----+----------+-----------------+
+ ID + Name + Description +
+-----+----------+-----------------+
+ 1 + A + A1 - XXXXX +
+ 2 + B + - +
+ 3 + C + - +
+-----+----------+-----------------+
Where the Description column should be filled in by - when the ID is not on the Description table.
I tried this code:
SELECT S.ID, D.Description
FROM Schedule AS S
INNER JOIN Description AS D
But resulted in:
+-----+----------+-----------------+
+ ID + Name + Description +
+-----+----------+-----------------+
+ 1 + A + A1 - XXXXX +
+ 2 + B + A1 - XXXXX +
+ 3 + C + A1 - XXXXX +
+-----+----------+-----------------+
And when I tried to give ON Clause:
SELECT S.ID, D.Description
FROM Schedule AS S
INNER JOIN Description AS D ON S.ID = D.ID
It just get the row where the ID is on the Description table, like:
+-----+----------+-----------------+
+ ID + Name + Description +
+-----+----------+-----------------+
+ 1 + A + A1 - XXXXX +
+-----+----------+-----------------+
How can I do that?
[UPDATE]
I tried this code and it works:
SELECT S.ID, S.Name, COALESCE (D.Description, '-') AS Description
FROM Schedule AS S
LEFT OUTER JOIN Description AS D ON S.ID = D.ID
But now, how can I add a WHERE clause on it (pls see table SCHEDULE above)?
I tried:
SELECT S.ID, S.Name, COALESCE (D.Description, '-') AS Description
FROM Schedule AS S
LEFT OUTER JOIN Description AS D ON S.ID = D.ID AND S.Type = '1'
But still get the whole rows.
LEFT OUTER JOIN in SQL Server CE
You need to use LEFT OUTER JOIN to join the tables Schedule and Description on the key field ID. Also, use COALESCE to replace NULL values in Description column with -
Script:
SELECT S.ID
, S.Name
, COALESCE (D.Description, '-') AS Description
FROM Schedule AS S
LEFT OUTER JOIN Description AS D
ON S.ID = D.ID
Output:
Tested in Microsoft SQL Server CE version 4.0.8482.1
With WHERE clause
You need add the WHERE clause after the JOINs. If you are planning to having an ORDER BY, it should come after the WHERE clause.
Script:
SELECT S.ID
, S.Name
, COALESCE (D.Description, '-') AS Description
FROM Schedule AS S
LEFT OUTER JOIN Description AS D
ON S.ID = D.ID
WHERE (S.Type = 1)
Output:
Tested in Microsoft SQL Server CE version 4.0.8482.1
You need LEFT OUTER JOIN.
SQLFiddle: http://sqlfiddle.com/#!3/7dccf/1
Query:
select s.ID, s.Name, Coalesce(d.description,'-') as description
from schedule s
left outer join description d on d.id = s.id
SELECT S.ID, D.Description
FROM Schedule AS S FULL OUTER JOIN Description AS D
ON S.ID = D.ID
INNER JOIN means select only rows that exist in both tables.
FULL OUTER JOIN means select rows as long as they exist in one table.
You need FULL OUTER JOIN...
You need to use an OUTER JOIN instead of INNER, and use IsNull or Coalesce to replace NULL values:
SELECT S.ID, Coalesce(D.Description , '-') AS Description
FROM Schedule AS S FULL OUTER JOIN Description AS D
ON S.ID = D.ID
I have a query as
return Connection.db.Fetch<Issue, Condition , Result , Status>(
"SELECT * FROM Issue I, Condition C, Result R, Status S " +
"LEFT JOIN Issue ON Condition .ID = Issue.ConditionID" +
"LEFT JOIN Issue ON Result.ID = Issue.ResultID" +
"LEFT JOIN Issue ON Status.ID = Issue.StatusID " +
"WHERE Issue.ID= "+ issueId);
which is giving the error message:
The multi-part identifier "Condition.ID" could not be bound.
The objects "Issue" and "Issue" in the FROM clause have the same exposed names. Use correlation names to distinguish them.
What is worng with the above?
You're joining to Issue table several times, but never use aliases. This is especially a problem because you've added the same table to FROM part of your SELECT clause. Always use aliases in joins. It's the safest way.
So whenever you said Issue.ID query engine could not resolve to which one you're referring. Is it to the one in FROM part or the one in JOIN part.
Try out this code:
return Connection.db.Fetch<Issue, Condition , Result , Status>(
"SELECT * FROM Issue I, Condition C, Result R, Status S " +
"LEFT JOIN Issue i1 ON C.ID = i1.ConditionID" +
"LEFT JOIN Issue i2 ON R.ID = i2.ResultID" +
"LEFT JOIN Issue i3 ON S.ID = i3.StatusID " +
"WHERE I.ID = " + issueId);
And apart from that I strongly suggest you use parameters instead of string concatenation:
return Connection.db.Fetch<Issue, Condition , Result , Status>(
"SELECT * FROM Issue I, Condition C, Result R, Status S " +
"LEFT JOIN Issue i1 ON C.ID = i1.ConditionID" +
"LEFT JOIN Issue i2 ON R.ID = i2.ResultID" +
"LEFT JOIN Issue i3 ON S.ID = i3.StatusID " +
"WHERE I.ID = #0", issueId); // see the change in this line
After some thought this is actually invalid SQL query
The problem that you're having is not PetaPoco related at all. You've actually written an invalid SQL query. If you'd run this same statement in SSMS you'd get the same error and that's because your query is interpreted as:
SELECT * FROM Issue I, Condition C, Result R,
(Status S
LEFT JOIN Issue i1
ON C.ID = i1.ConditionID
LEFT JOIN Issue i2
ON R.ID = i2.ResultID
LEFT JOIN Issue i3
ON S.ID = i3.StatusID
)
WHERE I.ID = x;
And that's the main reason why the first two joins fail. The last one is the only one that works, because it sees both tables. You probably thought that your select makes a result of those tables and then joins as in:
SELECT * FROM (Issue I, Condition C, Result R, Status S)
LEFT JOIN ...
But that is not the case.
Depending on what kind of results you want (you may end up with a large result set the way that you're doing it) you will have to rewrite your query to a different form and possibly omit the multi table list in your FROM part.
i got 2 Entities (ModTopScope and ModInstallResults) with One-to-Many relations
and NamedQuery:
#NamedQuery(name="ModTopScope.getScopesForActiveSystems",
query="SELECT s, COUNT(s.modInstallResults) FROM ModTopScope s LEFT JOIN FETCH s.modInstallResults " +
"WHERE s.modScopeType.modSystem.activated = true " +
"GROUP BY s " +
"ORDER BY COUNT(s.modInstallResults) DESC")
It is ok, except there are no records in query result list for ModTopScope, which have no corresponding records in ModInstallResults table. How can i fix it ?
The native sql, that selects records, which have no corresponding records in mod_install_resutls table:
select s.id, count(i.id) from mod_top_scopes s left join mod_install_results i on s.id=i.scope_id group by s.id order by count(i.id)
OK, finally i wrote the correct querym i wrote comment,
SELECT DISTINCT s, COUNT(i) FROM ModTopScope s LEFT JOIN s.modInstallResults i " + "WHERE s.modScopeType.modSystem.activated = true " + "GROUP BY s " + "ORDER BY COUNT(i) DESC
I want to write a lttl complicated query in JPQL where i access a OneToMany Join table. I get QuerySyntaxException: Pan_PanRes is not mapped.
QUERY -
query = "SELECT p FROM Pan p WHERE p.id IN " +
"(SELECT p_id FROM Pan_PanRes p_prs WHERE prs_id IN " +
"(SELECT r.id FROM PRS r where r.pant = :pant))"+
" ORDER BY pr.clD"
i tried implementing this concept in MYSQL. It works fine. So i know i am not calling the join table in right way. How should it be called then?
I would like to add MYSQL statement which works fine -
mysql> select * from pan where id not in
(select pan_id from pan_panres where panres_id in
(select id from panres where pant_id = 3));
Thanks...
Solved it myself -
query = "SELECT p FROM Pan p WHERE p.id IN " +
"(SELECT p.id FROM p.panRes prs WHERE id IN " +
"(SELECT r.id FROM PanRes r where r.pant = :pant))"+
" ORDER BY pr.clD"
Where panRes is the oneToMany variable name i have used in Pan Class.