Query filter assign sub query to one field value - drupal

I have stuck in this issue from the last two days.
Please help.
I want to assign the following query .
$qr = "( select subconfigcode.field_subconfigcode_value AS configcode FROM node node LEFT JOIN field_data_field_select_parent_configuratio select_parent_configuratio ON node.nid = select_parent_configuratio.entity_id AND (select_parent_configuratio.entity_type = node AND select_parent_configuratio.deleted = 0) LEFT JOIN node select_parent_configuratio_node ON select_parent_configuratio.field_select_parent_configuratio_nid = select_parent_configuratio_node.nid LEFT JOIN field_data_field_subconfigcode subconfigcode ON select_parent_configuratio_node.nid = subconfigcode.entity_id AND (subconfigcode.entity_type = 'node' AND subconfigcode.deleted = '0') WHERE (( (select_parent_configuratio.field_select_parent_configuratio_nid = node_field_data_field_select_parent_configuratio.nid) )AND(( (node.status = '1') AND (node.type IN ('offering')) ))) ORDER BY node.created DESC, configcode ASC LIMIT 1 OFFSET 0)";
to
one view's field value.
I have used the following code.
function general_views_query_alter(&$view, &$query) {
$qr = " ( select subconfigcode.field_subconfigcode_value AS configcode FROM node node LEFT JOIN field_data_field_select_parent_configuratio select_parent_configuratio ON node.nid = select_parent_configuratio.entity_id AND (select_parent_configuratio.entity_type = node AND select_parent_configuratio.deleted = 0) LEFT JOIN node select_parent_configuratio_node ON select_parent_configuratio.field_select_parent_configuratio_nid = select_parent_configuratio_node.nid LEFT JOIN field_data_field_subconfigcode subconfigcode ON select_parent_configuratio_node.nid = subconfigcode.entity_id AND (subconfigcode.entity_type = 'node' AND subconfigcode.deleted = '0') WHERE (( (select_parent_configuratio.field_select_parent_configuratio_nid = node_field_data_field_select_parent_configuratio.nid) )AND(( (node.status = '1') AND (node.type IN ('offering')) ))) ORDER BY node.created DESC, configcode ASC LIMIT 1 OFFSET 0)";
$query->add_where(1, "node_field_data_field_select_parent_configuratio__field_data_field_subconfigcode.field_subconfigcode_value", $qr);
}
But, it is returning the following where query.
where node_field_data_field_select_parent_configuratio__field_data_field_subconfigcode.field_subconfigcode_value = '( select subconfigcode.field_subconfigcode_value AS configcode FROM node node LEFT JOIN field_data_field_select_parent_configuratio select_parent_configuratio ON node.nid = select_parent_configuratio.entity_id AND (select_parent_configuratio.entity_type = node AND select_parent_configuratio.deleted = 0) LEFT JOIN node select_parent_configuratio_node ON select_parent_configuratio.field_select_parent_configuratio_nid = select_parent_configuratio_node.nid LEFT JOIN field_data_field_subconfigcode subconfigcode ON select_parent_configuratio_node.nid = subconfigcode.entity_id AND (subconfigcode.entity_type = \'node\' AND subconfigcode.deleted = \'0\') WHERE (( (select_parent_configuratio.field_select_parent_configuratio_nid = node_field_data_field_select_parent_configuratio.nid) )AND(( (node.status = \'1\') AND (node.type IN (\'offering\')) ))) ORDER BY node.created DESC, configcode ASC LIMIT 1 OFFSET 0) ')
I want to get query without the single quote assigned for sub query and remove extra slashed added to each value.
Please help.

Answer :
Direct query is not applicable for assignment purpose in the add_where condition.
For that, I have generated the query object using.
function general_views_query_alter(&$view, &$query) {
$subQuery = db_select('node', 'node'); $subQuery->leftJoin('field_data_field_select_parent_configuratio', 'select_parent_configuratio ', 'node.nid = select_parent_configuratio .entity_id');
$subQuery->condition('select_parent_configuratio.entity_type', 'node', '=');
$subQuery->condition('select_parent_configuratio.deleted', '0', '=');
$subQuery->leftJoin('node', 'select_parent_configuratio_node', 'select_parent_configuratio.field_select_parent_configuratio_nid = select_parent_configuratio_node.nid');
$subQuery->leftJoin('field_data_field_subconfigcode', 'subconfigcode', 'select_parent_configuratio_node.nid = subconfigcode.entity_id');
$subQuery->condition('subconfigcode.entity_type', 'node', '=');
$subQuery->condition('subconfigcode.deleted', '0', '=');
$subQuery->where("select_parent_configuratio.field_select_parent_configuratio_nid = node_field_data_field_select_parent_configuratio.nid");
$subQuery->condition('node.status', "1", '=');
$subQuery->condition('node.type', array('offering'), 'IN');
$subQuery->orderBy('configcode');
$subQuery->addField('subconfigcode', 'field_subconfigcode_value', 'configcode');
//$subQuery->range(0, 1);
$query->add_where($group,'node_field_data_field_select_parent_configuratio__field_data_field_subconfigcode.field_subconfigcode_value',$subQuery,'in');
}
Using this, I am able to generate it the query and assignment to value of the variable.

Related

Being DRY in a Sqlite query with CASE statement

In the following (working) query:
SELECT q.id, q.section_id, q.type, q.required, q.condition,
CASE WHEN (t1.text_1 IS NULL) THEN
CASE WHEN ((SELECT t2.text_1 FROM translations t2 WHERE t2.item_id = q.id AND t2.item_model = 'questions' AND t2.language = 'en' LIMIT 1) IS NULL) THEN
(SELECT t3.text_1 FROM translations t3 WHERE t3.item_id = q.id AND t3.item_model = 'questions' LIMIT 1)
ELSE
(SELECT t2.text_1 FROM translations t2 WHERE t2.item_id = q.id AND t2.item_model = 'questions' AND t2.language = 'en' LIMIT 1)
END
ELSE
t1.text_1
END
AS translation
FROM questions q
LEFT JOIN translations t1 ON t1.item_id = q.id
AND t1.item_model = 'questions'
AND t1.language = 'fr'
ORDER BY q.position
You can see that the part (SELECT t2.text_1 FROM translations t2 WHERE t2.item_id = q.id AND t2.item_model = 'questions' AND t2.language = 'en' LIMIT 1) is repeated twice (the first to check if it's null, and the second to get the value).
Could the repeated same query a performance issue (I guess so)?
Is there a better way to rewrite this query, being DRY?
You can replace the inner CASE statement with coalesce() function:
coalesce(SELECT t2.text_1 FROM translations t2 WHERE t2.item_id = q.id AND t2.item_model = 'questions' AND t2.language = 'en' LIMIT 1,
SELECT t3.text_1 FROM translations t3 WHERE t3.item_id = q.id AND t3.item_model = 'questions' LIMIT 1)
From the documenation:
coalesce(X,Y,...)
The coalesce() function returns a copy of its first non-NULL argument,
or NULL if all arguments are NULL. Coalesce() must have at least 2
arguments.
Similar is the ifnull() function.

Semantical Error, Symfony DQL

I have a query that perform normally with MySQL :
SELECT *
FROM td_user u
JOIN td_ranking ranking ON ranking.user_id = u.id
JOIN (
SELECT x.user_id,
MAX(x.id) AS default_id
FROM td_ranking x
GROUP BY x.user_id
) y
ON y.user_id = ranking.user_id
AND y.default_id = ranking.id
I try to transform it in DQL for run it in Symfony :
$query = $this->_em->createQuery('
SELECT u.*,ranking.*
FROM UserBundle:User u
JOIN UserBundle:Ranking ranking
WITH ranking.user_id = u.id
JOIN (
SELECT x.user_id, MAX(x.id) AS default_id
FROM UserBundle:Ranking x
GROUP BY x.user_id
) y
ON y.user_id = ranking.user_id
AND y.default_id = ranking.id'
);
$results = $query->getResult();
I have this error :
[Semantical Error] line 0, col 113 near '(SELECT x.user_id,': Error: Class '(' is not defined.
Do you have any idea please ? Thanks!
Use native query
$rsm = new ResultSetMapping();
$sql = "
SELECT *
FROM td_user u
JOIN td_ranking ranking ON ranking.user_id = u.id
JOIN (
SELECT x.user_id,
MAX(x.id) AS default_id
FROM td_ranking x
GROUP BY x.user_id
) y
ON y.user_id = ranking.user_id
AND y.default_id = ranking.id
";
$result = $this->getEntityManager()->createNativeQuery($sql, $rsm)->getResult();

MSDAX 2012 Onhand Calculation from InventSum & InventTrans tables

I have used the below query to calculate the onhand quantity from InventTrans table but that onhand does not match with the AvailPhysical and/or PhysicalInvent of InventSum table. I have tried matching with other quantities as well but onhand is not matching. Please guide me what am i missing here
SELECT T1.ITEMID AS ITEMID
,T1.QTY
,T1.INVENTDIMID AS INVENTDIMID
,DATEDIFF(dd, T3.TRANSDATE, getdate()) AS Age
,t19.price as RetailPrice
,t1.CurrencyCode AS CurrencyKey
,T1.DATAAREAID AS DATAAREAID
,T1.PARTITION AS PARTITION
FROM INVENTTRANS T1
LEFT JOIN INVENTTRANSORIGIN T2 ON (
T1.INVENTTRANSORIGIN = T2.RECID
AND (T1.DATAAREAID = T2.DATAAREAID)
AND (T1.PARTITION = T2.PARTITION)
)
INNER JOIN INVENTTRANSPOSTING T3 ON (
(
(
(
T1.VOUCHERPHYSICAL = T3.VOUCHER
AND (T1.DATAAREAID = T3.DATAAREAID)
AND (T1.PARTITION = T3.PARTITION)
)
)
AND (
T1.DATEPHYSICAL = T3.TRANSDATE
AND (T1.DATAAREAID = T3.DATAAREAID)
AND (T1.PARTITION = T3.PARTITION)
)
)
AND (
T1.INVENTTRANSORIGIN = T3.INVENTTRANSORIGIN
AND (T2.DATAAREAID = T3.DATAAREAID)
AND (T2.PARTITION = T3.PARTITION)
)
) and t3.INVENTTRANSPOSTINGTYPE in (0)
LEFT JOIN INVENTDIM t4 ON (
t4.inventdimid = t1.inventdimid
AND t4.PARTITION = t1.PARTITION
AND t4.dataareaid = t1.dataareaid
)
LEFT OUTER JOIN INVENTTABLEMODULE T19 ON T19.ItemID = T1.ItemID AND T19.DataAreaID = T1.DataAreaID and T19.Partition = T1.Partition AND T19.MODULETYPE=0
LEFT OUTER JOIN INVENTTABLE T20 ON T1.ITEMID = T20.ITEMID AND T1.DATAAREAID = T20.DATAAREAID
where T20.ITEMTYPE <> 2
Any help would be greatly appreciated.

Subquery with sum function to pull in multiple records

SubQuery pulling in the same record in the "ON_ORDER" column. I want the query to pull in the ON_ORDER qty per Item. Can someone please show me what I am not doing right? I have been on this for quite awhile.
SELECT
N.SITEID,
C.LOCATION,
(I.EX2AREARESP||I.EX2STDSTS||I.EX2APPTYPE) AS STD,
I.ITEMNUM,
I.COMMODITY,
I.COMMODITYGROUP,
I.DESCRIPTION,
I.ISSUEUNIT,
C.AVGCOST,
SUM(NVL(B.CURBAL,0)) AS CURBAL,
NVL(SUM(D.SHIPPEDQTY),0) AS IN_TRANSIT,
(
SELECT
SUM(PL.ORDERQTY - NVL(PL.RECEIVEDQTY,0))
FROM MSCRADS.PO P,
MSCRADS.POLINE PL,
MXRADS.ITEM I
WHERE P.PONUM = PL.PONUM
AND PL.LINETYPE = 'ITEM'
AND P.RECEIPTS <> 'COMPLETE'
AND PL.ITEMNUM = I.ITEMNUM
AND P.ORDERDATE >= TO_DATE('2014/05/26','YYYY/MM/DD')
AND PL.RECEIPTSCOMPLETE = '0'
AND P.INTERNAL = '0'
AND PL.ISSUE = '0'
AND P.STATUS NOT IN ('COMPLETE','CLOSE','CAN')
AND P.SITEID <> 'MS'
AND P.REVISIONNUM = PL.REVISIONNUM
AND (P.HISTORYFLAG = '0' OR (P.HISTORYFLAG = '1'
AND P.STATUS = 'CLOSE' AND PL.RECEIVEDQTY > '0'))
AND NOT (P.STATUS = 'COMPLETE'
AND (PL.RECEIVEDQTY = '0' OR PL.RECEIVEDQTY IS NULL))
) AS "ON_ORDER",
NVL(SUM(CASE WHEN D.RESTYPE = 'APSOFT' THEN D.RESERVEDQTY
ELSE NULL END),0) AS "ALLOCATED",
NVL(SUM(CASE WHEN D.RESTYPE = 'APHARD' THEN D.RESERVEDQTY
ELSE NULL END),0) AS "RESERVE",
N.MINLEVEL AS ROP,
N.ORDERQTY AS EOQ,
N.DELIVERYTIME AS LEADTIME,
NVL(N.SSTOCK,0) "SAFETY STOCK",
CASE N.REORDER WHEN 1 THEN 'AUTO_RE-ORDER'
WHEN 0 THEN 'MANUAL_RE-ORDER'
ELSE ' '
END AS "REORDER PROCESS",
N.STATUS "INVENTORY STATUS"
FROM MXRADS.INVENTORY N
LEFT OUTER JOIN
MXRADS.ITEM I
ON I.ITEMNUM = N.ITEMNUM
LEFT OUTER JOIN
MSCRADS.INVCOST C
ON N.ITEMNUM = C.ITEMNUM
AND N.LOCATION = C.LOCATION
LEFT OUTER JOIN
MSCRADS.INVBALANCES B
ON N.ITEMNUM = B.ITEMNUM
AND N.LOCATION = B.LOCATION
LEFT OUTER JOIN
MSCRADS.INVRESERVE D
ON N.ITEMNUM = D.ITEMNUM
AND N.LOCATION = D.LOCATION
WHERE N.SITEID <> 'MS'
AND N.LOCATION = '&WHSE'
AND N.STATUS = 'ACTIVE'
--AND N.ITEMNUM = '505611'
GROUP BY
N.SITEID,
C.LOCATION,
(I.EX2AREARESP||I.EX2STDSTS||I.EX2APPTYPE),
I.ITEMNUM,
I.COMMODITY,
I.COMMODITYGROUP,
I.DESCRIPTION,
I.ISSUEUNIT,
C.AVGCOST,
N.MINLEVEL,
N.ORDERQTY,
N.DELIVERYTIME,
N.SSTOCK,
N.REORDER,
N.STATUS
ORDER BY 4

Querying against LINQ to SQL relationships

Using LINQ to SQL
db.Products.Where(c => c.ID == 1).Skip(1).Take(1).ToList();
executes
SELECT [t1].[ID], [t1].[CategoryID], [t1].[Name], [t1].[Price], [t1].[Descripti
n], [t1].[IsFeatured], [t1].[IsActive]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ID], [t0].[CategoryID], [t0].[Name
, [t0].[Price], [t0].[Description], [t0].[IsFeatured], [t0].[IsActive]) AS [ROW
NUMBER], [t0].[ID], [t0].[CategoryID], [t0].[Name], [t0].[Price], [t0].[Descrip
ion], [t0].[IsFeatured], [t0].[IsActive]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[ID] = #p0
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN #p1 + 1 AND #p1 + #p2
ORDER BY [t1].[ROW_NUMBER]
-- #p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1]
-- #p1: Input Int (Size = 0; Prec = 0; Scale = 0) [1]
-- #p2: Input Int (Size = 0; Prec = 0; Scale = 0) [1]
It's using ROW_NUMBER for pagination... good.
Now, I'm trying to use relationships generated by LINQ to SQL to paginate data. Using the query...
var cat = db.Categories.Where(c => c.ID == 1).SingleOrDefault();
cat.Products.Where(c => c.ID == 1).Skip(1).Take(1).ToList();
SELECT [t0].[ID], [t0].[Name]
FROM [dbo].[Categories] AS [t0]
WHERE [t0].[ID] = #p0
-- #p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1
SELECT [t0].[ID], [t0].[CategoryID], [t0].[Name], [t0].[Price], [t0].[Descriptio
n], [t0].[IsFeatured], [t0].[IsActive]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[CategoryID] = #p0
-- #p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1
Now the use of ROW_NUMBER and pagination is gone... it's getting all Products where CategoryID = 1... why is it getting ALL rows?
I think its because the category is in memory. You are asking it, implicitly, to get the products of the category. This implicit request for data is for filled, and then in memory (where the category is at this point) the query is executed.
I'm thinking its equivalent to :
var cat = db.Categories.Where(c => c.ID == 1).SingleOrDefault();
var prods = db.Products.Where(c => c.ID == 1).ToList();
var r = prods.Where(p.CategoryID == cat.ID).Skip(1).Take(1);
Note the significance, what if cat changes in memory? The size of the collection could vary.
NOTE: Thanks for the headache :)
have you tried:
var cat = db.Categories.Where(c => c.ID == 1);
var prod = cat.Products.Where(c => c.ID == 1).Skip(1).Take(1).ToList();
You haven't assigned the output of your second LINQ query. So 'cat' is still the first query only.

Resources