Doctrine query builder error on join - sql

How do I write the following with doctrine query builder?
SELECT
registry.id ,
registry.couple_id,
registry.gift_id,
Sum(purchase.amount) as totalContribution,
gift.title,
gift.price
FROM
gift,
registry
LEFT JOIN
purchase ON purchase.registry_id = registry.id
WHERE
registry.gift_id = gift.id
AND registry.couple_id = 1
GROUP BY
registry.couple_id,
registry.gift_id
I tried:
$qb = $this->createQueryBuilder('g') //gift
->from('\BBB\GiftBundle\Entity\Registry', 'reg')
->select('g.id , g.title, g.description, g.price, g.imageMedium')
->addSelect('SUM(p.amount) as totalContribute')
->leftJoin('\BBB\GiftBundle\Entity\Purchase', 'p', 'ON','reg.id = p.registry')
->where('reg.gift = g.id')
->AndWhere('reg.couple = :coupleID')
->orderBy('reg.id','DESC')
->groupBy('reg.couple')
->groupBy('reg.gift')
->setParameter('coupleID', $coupleID);
But it gives me following error:
[Semantical Error] line 0, col 178 near 'p ON reg.id =': Error: Identification Variable BBB\GiftBundle\Entity\Purchase used in join path expression but was not defined before.

DQL can only join tables relating to the current entity (that being Registry in this DQL). Your Registry entity will need to have a declared OneToMany relation.
Assuming that this relation was called purchases you would join like so:
->leftJoin('reg.purchases', 'p')

Related

How to use NOT EXISTS and JOIN at the same time?

We are required to display UID that is in BOS_BARCODE_IT_LOG but not exists in BOS_BARCODE_DO_LOG
The reason that I joined with OITM is because the user asked for the selection Criteria in SAP Business One.
SELECT X0."DATE",X0."ITEMCODE", X0."UID"
FROM "BOS_BARCODE_IT_LOG" X0 JOIN OITM X1 ON
X0."ITEMCODE" = X1."ItemCode"
WHERE
X1."ItemCode" = '[%0]'
AND NOT EXISTS (
SELECT X2."UID" FROM "BOS_BARCODE_DO_LOG" X2
WHERE X0."ITEMCODE" = X2."ITEMCODE" AND
X0."UID" = X2."UID" AND
X0."DATE" = X2."DATE"
)
We need that '[%0]' in order to display
The problem is that, when I tried to search any items there, the query returns no result.
What I've tried.
I Select only from one table without OITM, and neverthless, did not provide Query Selection Criteria.
I Tried this as well
SELECT X0."DATE",X0."ITEMCODE", X0."UID"
FROM "BOS_BARCODE_IT_LOG" X0
WHERE
X0."ITEMCODE" = '[%0]' AND
NOT EXISTS (
SELECT X1."UID" FROM "BOS_BARCODE_DO_LOG" X1
WHERE X0."ITEMCODE" = X1."ITEMCODE" AND
X0."UID" = X1."UID" AND
X0."DATE" = X1."DATE"
)
And it provide error.
1). [SAP AG][LIBODBCHDB DLL][HDBODBC] Syntax error or access violation;257 sql syntax error: incorrect syntax near ")": line 14 col 1 'Received Alerts' (OAIB) (at pos 299)
Another thing, is it possible to use subquery with more than one tables and provide the expected result (Not just blank result)
What I learned in the tutorial that subquery only used for one table.
This is one of the examples.
https://www.tutorialspoint.com/sql/sql-sub-queries.htm
Thanks.
We are required to display UID that is in BOS_BARCODE_IT_LOG but not exists in BOS_BARCODE_DO_LOG.
I don't undersand how your queries actually relate to the question (they have one additional table oitm, and many more columns). From the description of your question it seems like you want:
select bi.uid
from bos_barcode_it_log bi
where not exists (select 1 from bos_barcode_do_log bd where bd.uid = bi.uid)
If you need oitm for filtering, you can join (if there is not more than one row in per itemcode in oitm), or use exists:
select bi.uid
from bos_barcode_it_log bi
where
exists (select 1 from oitm o where o.itemcode = bi.itemcode)
and not exists (select 1 from bos_barcode_do_log bd where bd.uid = bi.uid)

ORA-00918: column ambiguously defined i am getting this error

SELECT
c.CONSOL_INVOICE,
cu.name,
cu.CUST_CODE,
c.bu_name,
cLang.name
FROM CONSL_INV c
LEFT JOIN customers cu ON c.cust_code = cu.CUST_CODE,
customers_lang cLang
WHERE
upper(cLang.NAME) LIKE ?
AND upper(cLang.LANGUAGE_CD) = ?
AND c.CUST_CODE = cLang.CUST_CODE
This Query Executes Correctly In Oracle Sql Developer but it does not execute in hibernate.
It gives the following error:
"ORA-00918: column ambiguously defined"
I know it's because of multiple columns having same name, but I have done it correctly but still don't know why it's not executing in hibernate.
As the others suggested use aliases:
select c.consol_invoice
,cu.name as name1
,cu.cust_code
,c.bu_name
,clang.name as name2
from consl_inv c
left join customers cu
on c.cust_code = cu.cust_code, customers_lang clang
where upper(clang.name) like ?
and upper(clang.language_cd) = ?
and c.cust_code = clang.cust_code
As you can see I've added aliases to the selected columns cu.name and clang.name so that the query result has two different columns.

SQL WHERE Statement With Multiple Account Numbers

I'm working with a SQL query and I need to display a set of information, but I have 5 records to display. The following query isn't working:
SELECT m.customer_number, m.last_name, m.billing_address_line_1, m.billing_address_line_2, m.billing_city, m.billing_state, m.phone_number1, c.equipment_serial_no, c.make, c.model_number, c.color_code
FROM customer_master as m
INNER JOIN equip_master as c ON m.customer_number = c.customer_number
WHERE m.customer_number = '19975107' AND '1039283' AND '39203821' AND '23824917' AND '1833729'
I get the following error:
Msg 4145, Level 15, State 1, Line 9 An expression of non-boolean type
specified in a context where a condition is expected, near '19978107'
That's not a valid syntax. If you want to get the list of customer_number then use IN clause.
....
WHERE m.customer_number in('19975107', '1039283', '39203821'
,'23824917' , '1833729')
You Have syntax error in your query.
It must be written like this
SELECT m.customer_number, m.last_name, m.billing_address_line_1,m.billing_address_line_2, m.billing_city, m.billing_state, m.phone_number1, c.equipment_serial_no, c.make, c.model_number, c.color_code
FROM customer_master as m
INNER JOIN equip_master as c
ON m.customer_number = c.customer_number
WHERE m.customer_number = '19975107' OR m.customer_number='1039283' OR m.customer_number='39203821' OR m.customer_number='23824917' OR m.customer_number ='1833729';
Note: Since customer_number is a primary key hence no two customer can have same value of it. Hence using AND is logically incorrect it will return empty set.

Decipher Peewee ORM Postgres query error

I'm using Peewee in my Flask project. I have an ORM query which worked in SQLite, but is now causing an error as I'm migrating to Postgres. I wondered if anyone could help me diagnose it:
stats = (
Assignment.select(
Type.name,
fn.COUNT(Type.id).alias('total'),
Assignment.select(
fn.COUNT(Assignment.id)
).where(
(Assignment.due_date < fn.Now()) & (StudentCourses.student == self) & (Assignment.type == Type.id)
).group_by(Assignment.type, StudentCourses.student).alias('completed')
)
.naive().join(Type)
.join(StudentCourses, on=(StudentCourses.course == Assignment.course))
.where(StudentCourses.student == self)
.order_by(Type.id)
.group_by(Type.name, StudentCourses.student)
)
Here's the resulting SQL:
SELECT "t2"."name",
COUNT("t2"."id") AS total,
(SELECT COUNT("t4"."id")
FROM "assignment" AS t4
WHERE ((("t4"."due_date" < Now())
AND ("t3"."student_id" = 2))
AND ("t4"."type_id" = "t2"."id"))
GROUP BY "t4"."type_id",
"t3"."student_id") AS completed
FROM "assignment" AS t1
INNER JOIN "type" AS t2 ON ("t1"."type_id" = "t2"."id")
INNER JOIN "studentcourses" AS t3 ON ("t3"."course_id" = "t1"."course_id")
WHERE ("t3"."student_id" = 2)
GROUP BY "t2"."name",
"t3"."student_id"
ORDER BY "t2"."id"
And here's the error I'm getting:
ProgrammingError: subquery uses ungrouped column "t2.id" from outer query
LINE 1: ...ND ("t3"."student_id" = 2)) AND ("t4"."type_id" = "t2"."id")...
I've tried adding the indicated columns to the group_by clause but I'm not getting any love. Does anyone have any guidance on this? Would love a fresh pair of eyes.
Your subquery is effectively joining on the outer query's Type table, so postgres is saying you need to group by Type.id in the COUNT subquery.

Problem with adding custom sql to finder condition

I am trying to add the following custom sql to a finder condition and there is something not quite right.. I am not an sql expert but had this worked out with a friend who is..(yet they are not familiar with rubyonrails or activerecord or finder)
status_search = "select p.*
from policies p
where exists
(select 0 from status_changes sc
where sc.policy_id = p.id
and sc.status_id = '"+search[:status_id].to_s+"'
and sc.created_at between "+status_date_start.to_s+" and "+status_date_end.to_s+")
or exists
(select 0 from status_changes sc
where sc.created_at =
(select max(sc2.created_at)
from status_changes sc2
where sc2.policy_id = p.id
and sc2.created_at < "+status_date_start.to_s+")
and sc.status_id = '"+search[:status_id].to_s+"'
and sc.policy_id = p.id)" unless search[:status_id].blank?
My find statement:
Policy.find(:all,:include=>[{:client=>[:agent,:source_id,:source_code]},{:status_changes=>:status}],
:conditions=>[status_search])
and I am getting this error message in my log:
ActiveRecord::StatementInvalid (Mysql::Error: Operand should contain 1 column(s): SELECT DISTINCT `policies`.id FROM `policies` LEFT OUTER JOIN `clients` ON `clients`.id = `policies`.client_id WHERE ((((policies.created_at BETWEEN '2009-01-01' AND '2009-03-10' OR policies.created_at = '2009-01-01' OR policies.created_at = '2009-03-10')))) AND (select p.*
from policies p
where exists
(select 0 from status_changes sc
where sc.policy_id = p.id
and sc.status_id = '2'
and sc.created_at between 2009-03-10 and 2009-03-10)
or exists
(select 0 from status_changes sc
where sc.created_at =
(select max(sc2.created_at)
from status_changes sc2
where sc2.policy_id = p.id
and sc2.created_at < 2009-03-10)
and sc.status_id = '2'
and sc.policy_id = p.id)) ORDER BY clients.created_at DESC LIMIT 0, 25):
what is the major malfunction here - why is it complaining about the columns?
The conditions modifier is expecting a condition (e.g. a boolean expression that could go in a where clause) and you are passing it an entire query (a select statement).
It looks as if you are trying to do too much in one go here, and should break it down into smaller steps. A few suggestions:
use the query with find_by_sql and don't mess with the conditions.
use the rails finders and filter the records in the rails code
Also, note that constructing a query this way isn't secure if the values like status_date_start can come from users. Look up "sql injection attacks" to see what the problem is, and read the rails documentation & examples for find_by_sql to see how to avoid them.
Ok, I've managed to retool this so it is more friendly to a conditions modifier and I think it is doing the sql query correctly.. however, it is returning policies that when I try to list the current status (the policy.status_change.last.status) it is set to the same status used in the query - which is not correct
here is my updated condition string..
status_search = "status_changes.created_at between ? and ? and status_changes.status_id = ?) or
(status_changes.created_at = (SELECT MAX(sc2.created_at) FROM status_changes sc2
WHERE sc2.policy_id = policies.id and sc2.created_at < ?) and status_changes.status_id = ?"
is there something obvious to this that is not returning all of the remaining associated status changes once it finds the one in the query?
here is the updated find..
Policy.find(:all,:include=>[{:client=>[:agent,:source_id,:source_code]},:status_changes],
:conditions=>[status_search,status_date_start,status_date_end,search[:status_id].to_s,status_date_start,search[:status_id].to_s])