how can i use paginate() function with db::select - laravel

First of all, I'm interested in how to use the paginate function with a simple query.
for example, I have this query:
$query = "SELECT
dw.id,
w.word,
d.definition,
dw.user_id,
IF(IFNULL(dw.definition_id, 0) = 0,
(SELECT COUNT(phrase_id)
FROM phrase_word wp1 WHERE wp1.user_id = dw.user_id AND wp1.word_id = dw.word_id),
(SELECT COUNT(phrase_id)
FROM phrase_word wp2 WHERE wp2.user_id = dw.user_id AND wp2.word_id = dw.word_id AND wp2.definition_id = dw.definition_id)
) phrases_count
FROM definition_word AS dw
INNER JOIN words AS w ON w.id = dw.word_id
LEFT JOIN definitions AS d ON d.id = dw.definition_id
WHERE dw.user_id = 2";
I Can't use the paginate method in this way.
$unknown_words = DB::select($query)->paginate(5);
Or if it's possible how to convert
"IF(IFNULL(dw.definition_id, 0) = 0,
(SELECT COUNT(phrase_id)
FROM phrase_word wp1 WHERE wp1.user_id = dw.user_id AND wp1.word_id = dw.word_id),
(SELECT COUNT(phrase_id)
FROM phrase_word wp2 WHERE wp2.user_id = dw.user_id AND wp2.word_id = dw.word_id AND wp2.definition_id = dw.definition_id)
) phrases_count";
this piece of the query into a query builder.

I think you have a better option you can use laravel joins select and table method and you could achieve your desire output as below.
$unknown_words = DB::table('definition_word as dw')
->join('words as w', 'w.id', '=', 'dw.word_id')
->leftJoin('definitions as d', 'd.id', '=', 'dw.definition_id')
->select(
'dw.id',
'w.word',
'd.definition',
'dw.user_id',
DB::raw('IF(IFNULL(dw.definition_id, 0) = 0,
(SELECT COUNT(phrase_id)
FROM phrase_word wp1 WHERE wp1.user_id = dw.user_id AND wp1.word_id = dw.word_id),
(SELECT COUNT(phrase_id)
FROM phrase_word wp2 WHERE wp2.user_id = dw.user_id AND wp2.word_id = dw.word_id AND wp2.definition_id = dw.definition_id)
) as phrases_count')
)->where('dw.user_id', 2)->paginate(15)

Related

Inner Join in Codeigniter with multiple table

I wants to create a display function in crudodel of codeigniter to display records on Invoice no 13. I'd run the bellow Query on sql. Its working as per my requirement. Now I've to convert this Query in codeigniter using Inner Join.
SELECT b1.Invoice_No,
cust_name,
cust_address,
cust_contact,
Item_name,
Item_qty,
Item_amount
FROM tbl_bill_invoice AS b1
INNER JOIN tbl_billmenu AS b2 ON(b2.Invoice_No = b1.Invoice_No)
INNER JOIN tbl_billcustomer AS b3 ON(b3.cust_id = b1.cust_id)
WHERE b1.Invoice_no = 13
Try this
$this->db->select('b1.Invoice_No, cust_name, cust_address, cust_contact, Item_name, Item_qty, Item_amount');
$this->db->from(' tbl_bill_invoice as b1');
$this->db->join('tbl_billmenu as b2', 'b2.Invoice_No = b1.Invoice_No', 'inner');
$this->db->join('tbl_billcustomer as b3', 'b3.cust_id = b1.cust_id', 'inner');
$this->db->where('b1.Invoice_no', 13);
return $this->db->get()->row();
Take look,
$invoice_no = 13;
$this->db->select('b1.Invoice_No, cust_name, cust_address, cust_contact, Item_name, Item_qty, Item_amount');
$this->db->from('tbl_bill_invoice b1');
$this->db->join('tbl_billmenu b2', 'b2.Invoice_No = b1.Invoice_No', 'inner');
$this->db->join('tbl_billcustomer b3', 'b3.cust_id = b1.cust_id', 'inner');
$this->db->where('b1.Invoice_no', $invoice_no);
$query = $this->db->get();
if ($query->num_rows() > 0) {
return $query->row();
} else {
return array();
}
Simply write this
$sql = "SELECT b1.Invoice_No,
cust_name,
cust_address,
cust_contact,
Item_name,
Item_qty,
Item_amount
FROM tbl_bill_invoice AS b1
INNER JOIN tbl_billmenu AS b2 ON(b2.Invoice_No = b1.Invoice_No)
INNER JOIN tbl_billcustomer AS b3 ON(b3.cust_id = b1.cust_id)
WHERE b1.Invoice_no = 13";
$result = $this->db->query($sql)->result();

Column ambiguously defined Oracle SQL

I'm facing this ambiguously defined error. I understand this is due to alias not defined properly but I am not able to understand in the below query why this error is coming. I'm using Oracle.
SELECT
papf.person_number as personnumber,
paam.position_id as position,
fabu.bu_name
FROM
(SELECT
papf.person_number,
paam.person_id,
fabu.bu_name,
fabu.bu_id,
paam.assignment_id,
paam.assignment_number,
paam.action_code,
paam.effective_start_date,
wft.outcome,
htd.state,
htd.status,
Count(paam.assignment_id)
over (
PARTITION BY paam.assignment_id) rowcnt
FROM
per_all_assignments_m paam,
per_all_people_f papf,
hrc_txn_header hth,
hrc_arm_process_vl hapv,
hrc_txn_data htd,
fa_fusion_soainfra.wftask wft,
fun_all_business_units_v fabu
WHERE
paam.primary_assignment_flag = 'Y'
AND paam.effective_latest_change = 'Y'
AND paam.assignment_status_type = 'ACTIVE'
AND paam.action_code IN ( 'GLB_TRANSFER', 'TRANSFER' )
AND hth.subject = 'PER_ALL_PEOPLE_F'
AND hth.subject_id = paam.person_id
AND hth.object IN ( 'PER_ALL_ASSIGNMENTS_M', 'PER_ALL_PEOPLE_F' )
AND hth.object_id = Decode(hth.object, 'PER_ALL_ASSIGNMENTS_M', paam.assignment_id,
'PER_ALL_PEOPLE_F', paam.person_id)
AND hapv.process_id = hth.process_id
AND hapv.txn_module_identifier IN ( 'Transfers', 'ManageEmployment', 'AddWorkRelationship' )
AND htd.transaction_id = hth.transaction_id
AND wft.identificationkey = To_char(hth.transaction_id)
AND SYSDATE BETWEEN papf.effective_start_date AND papf.effective_end_date
AND paam.person_id = papf.person_id
and sysdate between fabu.date_from and fabu.date_to
and fabu.status='A'
and paam.business_unit_id=fabu.bu_id
GROUP BY papf.person_number,
paam.person_id,
paam.assignment_id,
fabu.bu_name,
fabu.bu_id,
paam.assignment_number,
paam.action_code,
paam.effective_start_date,
wft.outcome,
htd.state,
htd.status) t1,
per_all_people_f papf,
per_all_assignments_m paam,
fun_all_business_units_v fabu
WHERE rowcnt = 1
AND outcome = 'APPROVE'
AND state = 'COMPLETE'
AND status = 'APPROVED'
AND paam.person_id = t1.person_id
AND paam.action_code = t1.action_code
AND paam.assignment_status_type = 'INACTIVE'
AND paam.assignment_sequence = 1
AND paam.effective_start_date = t1.effective_start_date
AND paam.assignment_type = 'E'
and papf.person_id = t1.person_id
AND papf.effective_start_date = t1.effective_start_date
AND fabu.bu_id = t1.bu_id
I'm defining the paam table and papf table the same way and not facing issue in them.
Why I am facing this error when I try to add fabu table in end ?
You forgot to add t1. when refer to some columns that can be found in other tables:
WHERE t1.rowcnt = 1
AND t1.outcome = 'APPROVE'
AND t1.state = 'COMPLETE'
AND t1.status = 'APPROVED'

Doctrine subquery syntax

I need to reproduce with doctrine a AND statement from an sql query
AND ((SELECT e2.candidature_id_ca FROM evaluateur_candidature e2 WHERE
e.candidature_id_ca = e2.candidature_id_ca AND e2.role_evaluateur =
'evaluateur' ) IS NULL )
It's so easy to reproduce this with doctrine i tried :
$query->andWhere('(SELECT e2.candidature_id_ca FROM evaluateur_candidature e2 WHERE
e.candidature_id_ca = e2.candidature_id_ca AND e2.role_evaluateur = ?)' , 'evaluateur' , 'IS NULL ');
But i get
Couldn't find class e2
Someone know how i could do it ? thanks in advance
UPDATE here the full doctrine query :
$query = Doctrine_Query::create()
->from('Candidature c')
->innerJoin('c.RoleActeur ra_cand ON c.id_ca = ra_cand.id_ca AND ra_cand.id_role = 4')
->innerJoin('ra_cand.Acteur ac_cand')
->innerJoin('c.CandidatureActeur ca ON c.id_ca = ca.id_ca')
->where('c.id_stca = 5');
$query->leftJoin('c.EvaluateurCandidature ec');
//here i would like to get the "Candidature collection" who not have records in the table EvaluateurCandidature when the column role_evaluateur is set to "evaluation".
//$query->andWhere('ec.role_evaluateur = ? ) ? )', 'evaluateur' ,'IS NULL ');
$query->andWhere('(SELECT e2.candidature_id_ca FROM evaluateur_candidature e2 WHERE
e.candidature_id_ca = e2.candidature_id_ca AND e2.role_evaluateur = ?)' , 'evaluateur' , 'IS NULL ');
As per your description you could include another condition on join EvaluateurCandidature to join only records where role_evaluateur is set to "evaluation" after that select only records where id of EvaluateurCandidature is null
$query = Doctrine_Query::create()
->from('Candidature c')
->innerJoin('c.RoleActeur ra_cand ON c.id_ca = ra_cand.id_ca AND ra_cand.id_role = 4')
->innerJoin('ra_cand.Acteur ac_cand')
->innerJoin('c.CandidatureActeur ca ON c.id_ca = ca.id_ca')
->leftJoin("c.EvaluateurCandidature ec WITH ec.role_evaluateur = 'evaluation'")
->where('c.id_stca = 5')
->andWhere('ec.id IS NULL');
WITH keyword

LINQ Left Join with use of Where Or syntax

How can I migrate this stored procedure into LINQ
DECLARE #customerIDs TABLE (customerID INT)
DECLARE #c INT
if (#customerName != '')
BEGIN
INSERT INTO #customerIDs
select id from customer
where name like '%' + #customerName + '%'
SELECT #c = COUNT(*) FROM #customerIDs
END
else
SET #c = 0
-- Insert statements for procedure here
SELECT DISTINCT l.*, dbo.GetListOfBranches(l.id) as 'list_of_branches', dbo.GetTopLevelCustomer(cid.customerID) FROM [login] l
LEFT JOIN login_to_customer ltc ON ltc.login_id = l.id
LEFT JOIN #customerIDs cid ON cid.customerID = ltc.customer_id
WHERE
(#c = 0 OR ltc.customer_id = cid.customerID) AND
(l.surname LIKE '%' + ISNULL(#surname, l.surname) + '%') AND
(l.forename LIKE '%' + ISNULL(#forename, l.forename) + '%') AND
(user_type = ISNULL(#userType, user_type)) AND
(l.active = ISNULL(#active, l.active))
ORDER BY surname ASC
I have got this so far:
List<Int32> customerIds = new List<int>();
if (!String.IsNullOrEmpty(customerName))
{
CustomerDataContext custDataContext = new CustomerDataContext();
customerIds = (from a in custDataContext.Customers
where a.name.Contains(customerName)
select a.id).ToList<Int32>();
}
LoginDataContext dataContext = new LoginDataContext();
var query = (from t in dataContext.logins
join t2 in dataContext.login_to_customers on t.id equals t2.login_id into a
from subquery in a.DefaultIfEmpty()
select new { t, listOfBranches = dataContext.GetListOfBranches(t.id), topLevelCustomer = dataContext.GetTopLevelCustomer(t.id) });
I need would then do a
if (customerIds.Count() > 0)
{
query = query.Where(a => customerIds.Contains(a.t.customer_id))
}
but as I need to perform the distinct I cant have the customer_id column in the query. Is there a way to include the
LEFT JOIN #customerIDs cid ON cid.customerID = ltc.customer_id
WHERE
(#c = 0 OR ltc.customer_id = cid.customerID)
Within the LINQ?
Thanks,
Richard

Joining queries with Entity Framework

I have the table
MOVIES_RATING:
MovieID int
MovieRating decimal
I'd like to get 2 values using one query:
select COUNT(*)
FROM [dbo].[MOVIES_RATING]
where [dbo].[MOVIES_RATING].[MovieID] = 78
and
select SUM([dbo].[MOVIES_RATING].Rating)
FROM [dbo].[MOVIES_RATING]
where [dbo].[MOVIES_RATING].[MovieID] = 78
That's what I got in LINQ:
(from p in ef.MOVIES_RATING.Where(r => r.MovieID== movie_id)
let movieRates = ef.MOVIES_RATING.Where(r => r.MovieID == movie_id)
let count = movieRates.Count()
let averageUserRating = movieRates.Sum(c => c.MOVIES_RATING)/count
select new MovieRating {AverageUserRating = averageUserRating, VoteCount = count})
.Take(1);
Looks awful as well as SQL being generated:
SELECT
[Limit1].[MovieID] AS [MovieID],
[Limit1].[C2] AS [C1],
[Limit1].[C1] AS [C2]
FROM ( SELECT TOP 1
[GroupBy1].[A1] AS [C1],
[Extent1].[MovieID] AS [MovieID],
[GroupBy2].[A1] / CAST( [GroupBy1].[A1] AS decimal(19,0)) AS [C2]
FROM [dbo].[MOVIES_RATING] AS [Extent1]
CROSS JOIN (SELECT
COUNT(1) AS [A1]
FROM [dbo].[MOVIES_RATING] AS [Extent2]
WHERE [Extent2].[MovieID] = 78 ) AS [GroupBy1]
CROSS JOIN (SELECT
SUM([Extent3].[Rating]) AS [A1]
FROM [dbo].[MOVIES_RATING] AS [Extent3]
WHERE [Extent3].[MovieID] = 78 ) AS [GroupBy2]
WHERE [Extent1].[MovieID] = 78
) AS [Limit1]
I'm not sure it is best solution, so any help is appreciated.
I know It can be done using stored procedure, but if its could be done using LINQ it would be better.
from r in ef.MOVIES_RATING
group r by r.MovieID into g
where g.Key == movie_id
select new
{
Count = g.Count(),
Sum = g.Sum(r => r.Rating)
}
(or perhaps filter first then group; it probably translates to the same SQL anyway)
Another approach, using Aggregate:
ef.MOVIES_RATING
.Where(r => r.MovieID == movie_id)
.Aggregate(
new { Count = 0, Sum = 0 },
(acc, r) => new { Count = acc.Count + 1, Sum = acc.Sum + r.Rating });
(not sure how it translates to SQL though)
What about simple query:
var query = from m in context.Movies
where m.Id == 78
select new
{
Count = m.MovieRatings.Count(),
Sum = m.MovieRatings.Sum(mr => mr.Rating)
};
var data = query.SingleOrDefault();
Moving average computation to your application code should reduce the SQL query complexity.

Resources