How i turned postgres query to query builder format codeigniter? - sql

i want to select datas from many tables here is the code
how to turned this
SELECT a.*, b.penyusun, c.keywords
FROM cb_monograf a
INNER JOIN (
select row_number() over (order by id_monograf) nomer, id_monograf, string_agg(id_penyusun::varchar,'-') penyusun
from cb_penyusun_monograf
group by id_monograf
) b ON a.id_monograf = b.id_monograf
INNER JOIN (
select row_number() over (order by id_monograf) nomer, id_monograf, string_agg(id_keywords::varchar,'-') keywords
from cb_keywords_monograf
group by id_monograf
) c ON a.id_monograf = c.id_monograf
WHERE a.jenis = 'buku'
into somekind of this format
$this->db->select('a.*,b.penyusun')
->from('cb_monograf a')
->join("($subquery1) b","a.id_monograf = b.id_monograf","inner")
->where('jenis', $param_type);

You're not far off - try this:
// Just to keep code a bit clearer
$db = $this->db;
// Firstly build the selects
$db->select('row_number() over (order by id_monograf) nomer, id_monograf, string_agg(id_penyusun::varchar,'-') penyusun')
$db->group_by('id_monograf');
$q1 = $db->get_compiled_select('cb_penyusun_monograf');
$db->select('row_number() over (order by id_monograf) nomer, id_monograf, string_agg(id_keywords::varchar,'-') keywords');
$db->group_by('id_monograf');
$q2 = $db->get_compiled_select('cb_keywords_monograf');
// Final query
$db->select('a.*, b.penyusun, c.keywords');
$db->join("($q1) b",'a.id_monograf = b.id_monograf','inner');
$db->join("($q2) c",'a.id_monograf = c.id_monograf','inner');
$db->where('a.jenis','buku');
$data = $db->get('cb_monograf a')->result_array(); // or row_array()
Note this query can be improved if your postgresl supports USING() (and inner can probably be dropped as well) to this:
$db->select('a.*, b.penyusun, c.keywords');
$db->join("($q1) b",'id_monograf'); // inner may also not be required
$db->join("($q2) c",'id_monograf'); // inner may also not be required
$db->where('a.jenis','buku');
$data = $db->get('cb_monograf a')->result_array(); // or row_array()

Related

Optimize many subqueries with same source

Does anyone have any idea how to optimize such a query?
How do you encapsulate this into one query?
,(SELECT top 1 WFD_AttDecimal2 as Nocleg
FROM WFElements INNER JOIN
WFElementDetails ON WFElements.WFD_ID = WFElementDetails.DET_WFDID
Where
WFD_STPID = #KrokSlownikUdostepnionyKraj
and dbo.ClearWFElemID (WFD_AttChoose20) = KrajDoDiety6 -- id kraju
and dbo.ClearWFElemID (WFD_AttChoose9) = #Spolka) as NoclegStawka7
,(SELECT top 1 WFD_AttDecimal3 as NoclegPrzelicznik
FROM WFElements INNER JOIN
WFElementDetails ON WFElements.WFD_ID = WFElementDetails.DET_WFDID
Where
WFD_STPID = #KrokSlownikUdostepnionyKraj
and dbo.ClearWFElemID (WFD_AttChoose20) = KrajDoDiety6 -- id kraju
and dbo.ClearWFElemID (WFD_AttChoose9) = #Spolka) as NoclegPrzelicznik7
,PelneDoby6 * (select MinDieta from #MinDieta where RodzajDelegacji = KrajZagr6) as MinIloscDiet7
from #Dieta4
You can use OUTER APPLY or CROSS APPLY and select all the necessary columns within that, you can then access all of them in the SELECT
SELECT
wfd.Nocleg as NoclegStawka7
, wfd.NoclegPrzelicznik as NoclegPrzelicznik7
, d.PelneDoby6 * (select md.MinDieta from #MinDieta md where RodzajDelegacji = KrajZagr6) as MinIloscDiet7
from #Dieta4 d
OUTER APPLY (
SELECT TOP (1)
WFD_AttDecimal2 as Nocleg,
WFD_AttDecimal3 as NoclegPrzelicznik
FROM WFElements INNER JOIN
WFElementDetails ON WFElements.WFD_ID = WFElementDetails.DET_WFDID
Where
WFD_STPID = #KrokSlownikUdostepnionyKraj
and dbo.ClearWFElemID (WFD_AttChoose20) = KrajDoDiety6 -- id kraju
and dbo.ClearWFElemID (WFD_AttChoose9) = #Spolka
) wfd;
Note also:
I suggest you rethink your usage of a scalar function ClearWFElemID as it can be slow. Use a join or a Table Valued function instead.
TOP (1) without an ORDER BY is a code-smell: you may get a different result each time.
Always specify the table alias when using subqueries, or you risk getting the wrong results.

SQL query to LINQ INNER JOIN

I need to translate SQL query to LINQ and have no idea how.
I have two tables: Bins and DataFromBins.
DataFromBins contains column BinId which refers to Bins.Id
What my query does is selecting most recent row for each BinId from DataFromBins and joining some data from Bins for these BinIds.
Please help :(
SELECT BinId, Address, Lon, Lat, MaxFillLevel, Distance
FROM (
SELECT DataFromBins.*
FROM (
SELECT DataFromBins.BinId, MAX(DataFromBins.Date) AS Date
FROM DataFromBins
GROUP BY DataFromBins.BinId
) AS latest_records
INNER JOIN DataFromBins ON DataFromBins.BinId = latest_records.BinId
AND DataFromBins.Date = latest_records.Date
) AS most_recent
INNER JOIN Bins ON most_recent.BinId = Bins.Id
I guess you are seeking the code below. The trick is to split your subqueries ;)
suppose _db is your context.
var latestRecords = from t in _db.DataFromBins
group t by t.BinId into g
select new
{
BinId = g.Key,
Date = (from t2 in g select t2.Date).Max()
};
var mostRecents = from itm in latestRecords
join bin in _db.DataFromBins on new {BinId = itm.BinId, Date =itm.Date } equals new {BinId = bin.BinId , Date =bin.Date}
select bin;
var finalQuery = from recent in mostRecents
join bin _db.Bins on recent.BinId equals bin.Id
select new {
bin.BinId,bin.Address, bin.Lon, bin.Lat, bin.MaxFillLevel, bin.Distance
}

Comparing Query Result With Table and Retrieve Specific Field

My Query
SELECT
stoMast.sStockistCode,
stoMast.sStateName,
stoMast.sDivision,
stateMap.sRMCode
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast ON
stateMap.sStateName = stoMast.sStateName
WHERE
stateMap.sRMCode = 'MCNE04001'
and
stoMast.sDivision = 'CIDIS'
except
select
sStockistCode,
sStateName,
sDivision,
sRMCode
From
tblEntry
Again I would like to compare the query result columns
sStockistCode
sStateName
sDivision
with tblStockistMaster with the same fields
sStockistCode
sStateName
sDivision
and retrieve the STOCKIST NAME.
Don't know how to compare the above query result with the table.
Maybe you can use following SQL code used with CTE expression
;with cte as (
SELECT
stoMast.sStockistCode,
stoMast.sStateName,
stoMast.sDivision,
stateMap.sRMCode
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast ON
stateMap.sStateName = stoMast.sStateName
WHERE
stateMap.sRMCode = 'MCNE04001'
and
stoMast.sDivision = 'CIDIS'
except
select
sStockistCode,
sStateName,
sDivision,
sRMCode
From
tblEntry
)
select
cte.*,
sm.sStockistName
from cte
left join tblStockistMaster as sm
on sm.sStockistCode = cte.sStockistCode and
sm.sStateName = cte.sStateName and
sm.sDivision = cte.sDivision
-- I retrieve the stockist Name
SELECT
stoMast.sStockistName,
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast
ON stateMap.sStateName = stoMast.sStateName
-- I'm joining table entry If I can match
LEFT JOIN
tblEntry tbl
on tbl.sStockistCode = stoMast.sStockistName
AND tbl.sStateName = stoMast.sStateName
AND tbl.sDivision = stoMast.sDivision
AND tbl.sRMCode = stateMap.sRMCode
WHERE
stateMap.sRMCode = 'MCNE04001'
and stoMast.sDivision = 'CIDIS'
-- And The the exept thing, I don't want that got a match with the tableentry
AND COALESCE(tbl.sStockistCode, tbl.sStateName, tbl.sDivision, tbl.sRMCode) is null
I expect it is what you wanted to get. On another way please help us understand wht you come from (tables and idea of what data can be in) and the result you want. Will be easier to create a query.

how to convert SQL select statement to LINQ

Hi i'm new to SQL and LINQ and i need to convert this sql statement to LINQ
select r.*,
(Select name From org_table where org_ID= r.org_ID )org
(Select name From Depart_table where Depart_ID= r.Depart_ID)depart
from reserve_table r
where name like '
try it this way:
var result = from r in reserve_table
where r.name.Contains("something")
select new {
org = (from o in org_table where o.Org_ID = r.Org_ID select o.name)
depart = (from d in Depart_table where d.Depart_ID = r.Depart_ID select d.name)
// add the rest
}

LINQ 2 SQL: top 1 post per member ordered by created data

Okay so I have the sql to work this out as asked in the stackoverflow question here.
Does anyone know how to translate this to linq 2 sql? I'm guessing that the easiest way is to add a stored procedure, but I am curious to see if it can be linq-a-fied :P
select p.*
from post p join
(
select memberId, max(createdDate) as maxd
from post
group by memberId
) as p2 on p.memberid = p2.memberid and p.createdDate=p2.maxd
order by p.createdDate desc
I'm not totally sure this is the most efficient way to run this query (maybe it is, but I've got a feeling there's a better way. Haven't thought of it yet).
from
post in Nt_Post
join
memberdates in (
from
p_inner in Nt_Post
group
p_inner by p_inner.MemberId into grouped
select new {
MemberId = grouped.Key,
ActivationDate = grouped.Max(m => m.ActivationDate)
})
on
new { post.MemberId, post.ActivationDate }
equals
new { memberdates.MemberId, memberdates.ActivationDate }
orderby post.ActivationDate
select post;
Here is the query working within LinqPad on my database (not createdDate is actually activationDate and the Post table is Nt_Post. Thanks to Rex M for commming up with the solution :P
var q =
from
post in Nt_Post
join
memberdates in (
from
p_inner in Nt_Post
group
p_inner by p_inner.MemberId into grouped
select new {
MemberId = grouped.Key,
ActivationDate = grouped.Max(m => m.ActivationDate)
})
on
new { post.MemberId, post.ActivationDate }
equals
new { memberdates.MemberId, memberdates.ActivationDate }
orderby post.ActivationDate
select post;
q.Dump();
The sql generated is:
SELECT [t0].[Id], [t0].[Title], [t0].[Teaser], [t0].[Text], [t0].[ActivationDate], [t0].[CreatedDate], [t0].[LastModifiedDate], [t0].[IsActive], [t0].[Permalink], [t0].[MemberId], [t0].[HomePageVisibility], [t0].[Image], [t0].[ImageContentType], [t0].[HasNotifiedRTR]
FROM [nt_Post] AS [t0]
INNER JOIN (
SELECT MAX([t1].[ActivationDate]) AS [value], [t1].[MemberId]
FROM [nt_Post] AS [t1]
GROUP BY [t1].[MemberId]
) AS [t2] ON ([t0].[MemberId] = [t2].[MemberId]) AND ([t0].[ActivationDate] = [t2].[value])
ORDER BY [t0].[ActivationDate]