I'm trying to code the following query using Zend_Db_Select:
SELECT p1.SKU,
(
SELECT ',' + Status
FROM "Products" "p2"
WHERE p2.SKU = p1.SKU
ORDER BY "Status"
FOR XML PATH ('')
) AS "Statuses"
FROM "Products" p1
GROUP BY SKU
This is what I have so far:
$s1 = $products->select()
->setIntegrityCheck(false)
->from(array('p2' => 'Products'),
new Zend_Db_Expr("',' + Status")
)
->where('p2.SKU = p1.SKU')
->order('Status');
$s2 = $products->select()
->from(array('p1' => 'Products'),
array('p1.SKU',
'Statuses' => new Zend_Db_Expr('(' . $s1 . ')')
)
)
->group('SKU');
echo $s2;
$dbRowSet = $Products->fetchAll($s2);
That gives me this:
SELECT "p1"."SKU",
(
SELECT ',' + Status
FROM "Products" AS "p2"
WHERE (p2.SKU = p1.SKU)
ORDER BY "Status" ASC
) AS "Statuses"
FROM "Products" AS "p1"
GROUP BY "SKU"
I can't figure out how to get the required FOR XML PATH ('')
.
Also, isn't using the .
operator with $s1
calling __toString()
, instead of leaving it as a native Zend_Db_Select object. Is there any other way to get the parens around $s1
?
Alternatively, is there another way to do this whole query? I want to return each SKU and a concatenated grouping of all Statuses (a la GROUP_CONCAT()
in MySQL). The table is huge, so iterating over them in PHP takes an unacceptably long time.
Looks like I was close, and with KSiimson's comments about string conversion in mind, this works:
$s1 = $products->select()
->setIntegrityCheck(false)
->from(array('p2' => 'Products'),
new Zend_Db_Expr("',' + Status")
)
->where('p2.SKU = p1.SKU')
->order('Status');
$s2 = $products->select()
->from(array('p1' => 'Products'),
array('p1.SKU',
'Statuses' => new Zend_Db_Expr('(' . $s1 .
" FOR XML PATH(''))")
)
)
->group('SKU');
echo $s2;
$dbRowSet = $Products->fetchAll($s2);
This just concats the FOR XML PATH clause with the first query as a string. Not quite as elegant as I was hoping for, but "perfect is the enemy of good".