Zend Framework2 how to make Concat and Left Join - zend-framework2

Does not work:
$sql = new Sql($this->adapter);
$select = $sql->select();
$select->from('request')
->columns(array('*', new Expression("CONCAT(up1.value,' ',up2.value) as display_name")))
->join(array('up1'=>'user_profile'), "up1.user_id = request.request_user_id AND up1.key = 'user_first_name'", array('up1.value'), 'left')
->join(array('up2'=>'user_profile'), "up2.user_id = request.request_user_id AND up2.key = 'user_last_name'", array('up2.value'), 'left')
;
return $select;
How to make the right?

You specified fields for both joins:
->join(array('up1'=>'user_profile'), "up1.user_id = request.request_user_id AND up1.key = 'user_first_name'", array('up1.value'), 'left')
->join(array('up2'=>'user_profile'), "up2.user_id = request.request_user_id AND up2.key = 'user_last_name'", array('up2.value'), 'left')
When query is converted to actual sql, these fields will be automatically namespaced, so you will get "up1.up1.value" in fields list.
Remove fields references from joins and it should work.
UPD. Right, there's more to it. You can't pass 'user_first_name' as a string value to the "on" parameter of join as it will be interpreted as a column name. So you have to pass an expression:
$select = $sql->select();
$select->from('request')
->columns(array('*', new Expression('CONCAT(up1.value,"#",up2.value) as display_name')));
$expressionString = '? = ? AND ? = ?';
$types = array(Expression::TYPE_IDENTIFIER, Expression::TYPE_IDENTIFIER, Expression::TYPE_IDENTIFIER, Expression::TYPE_VALUE);
$parameters = array('request.user_id', 'up1.user_id', 'up1.key', 'first_name');
$expression1 = new Expression($expressionString, $parameters, $types);
$parameters = array('request.user_id', 'up2.user_id', 'up2.key', 'last_name');
$expression2 = new Expression($expressionString, $parameters, $types);
$select->join(array('up1'=>'user_profile'), $expression1, array('value'), 'left')
->join(array('up2'=>'user_profile'), $expression2, array('value'), 'left');

Y tri to:
$select = $sql->select();
$select->from('request')
->columns(array('*', new Expression('CONCAT(up1.value,"#",up2.value) as display_user_name')));
$expressionString = '? = ? AND ? = ?';
$types = array(Expression::TYPE_IDENTIFIER, Expression::TYPE_IDENTIFIER, Expression::TYPE_IDENTIFIER, Expression::TYPE_VALUE);
$parameters1 = array('request.user_id', 'up1.user_id', 'up1.key', 'user_first_name');
$expression1 = new Expression($expressionString, $parameters1, $types);
$parameters2 = array('request.user_id', 'up2.user_id', 'up2.key', 'user_last_name');
$expression2 = new Expression($expressionString, $parameters2, $types);
$select->join(array('up1'=>'user_profile'), $expression1, array('value'), 'left')
->join(array('up2'=>'user_profile'), $expression2, array('value'), 'left');
does not work, where the error

Related

LINQ query with sub-query list

The query below should be selecting a list of information from different tables, and should also bring back a list of VehicleNames that are related to each ID coming back from db.Reservations
The query brings back data, but the list of VehicleNames only has one record, and it should bring back anywhere up to 5 records, depending on how many vehicles were reserved for that specific instance. I have tried adding a foreach to the VehicleName line in the select but I don't think I am using it right. Does anyone have any ideas as to how I can retrieve the list of values I need?
var query = from r in db.Reservations
let e = db.Employees.Where(x => r.RequestorID == x.ColleagueID).FirstOrDefault()
let rtv = db.ReservationToVehicle.Where(x => r.ID == x.ReservationID).FirstOrDefault()
let rs = db.ReservationStatus.Where(x => r.ID == x.ReservationID).FirstOrDefault()
let rst = db.ReservationStatusTypes.Where(x => rs.ReservationStatusTypeID == x.ID).FirstOrDefault()
select new
{
StartDate = r.StartDate,
EndDate = r.EndDate,
Destination = r.Destination,
PurposeOfTrip = r.PurposeOfTrip,
TransportingStudents = r.TransportStudentsFG,
EmployeeName = e.FirstName + " " + e.LastName,
ApprovalStatus = rst.StatusType,
ThemeColor = r.ThemeColor,
VehicleName = (from v in db.Vehicles
where v.ID == rtv.VehicleID
select v.VehicleName).ToList()
};
EDIT: Updated query, still uncertain how to get back list of Vehicles that have been reserved
var query = from r in db.Reservations
let e = db.Employees.Where(x => r.RequestorID == x.ColleagueID).FirstOrDefault()
let rtv = db.ReservationToVehicle.Where(x => r.ID == x.ReservationID).Select(y => y.VehicleID).ToList()
let rs = db.ReservationStatus.Where(x => r.ID == x.ReservationID).FirstOrDefault()
let rst = db.ReservationStatusTypes.Where(x => rs.ReservationStatusTypeID == x.ID).FirstOrDefault()
select new
{
StartDate = r.StartDate,
EndDate = r.EndDate,
Destination = r.Destination,
PurposeOfTrip = r.PurposeOfTrip,
TransportingStudents = r.TransportStudentsFG,
EmployeeName = e.FirstName + " " + e.LastName,
ApprovalStatus = rst.StatusType,
ThemeColor = r.ThemeColor,
VehicleName = (from v in db.Vehicles
where v.ID == rtv.VehicleID
select v.VehicleName).ToList()
};
rtv.VehicleID does not exist anymore, now rtv comes back with a list of IDs....I need to be able to get into that list to find where v.ID is IN the rtv list
Looks like people already told you this in the comments, but here's the code that ought to work:
var query = from r in db.Reservations
let e = db.Employees.Where(x => r.RequestorID == x.ColleagueID).FirstOrDefault()
let rtv = db.ReservationToVehicle.Where(x => r.ID == x.ReservationID).Select(y => y.VehicleID)
let rs = db.ReservationStatus.Where(x => r.ID == x.ReservationID).FirstOrDefault()
let rst = db.ReservationStatusTypes.Where(x => rs.ReservationStatusTypeID == x.ID).FirstOrDefault()
select new
{
StartDate = r.StartDate,
EndDate = r.EndDate,
Destination = r.Destination,
PurposeOfTrip = r.PurposeOfTrip,
TransportingStudents = r.TransportStudentsFG,
EmployeeName = e.FirstName + " " + e.LastName,
ApprovalStatus = rst.StatusType,
ThemeColor = r.ThemeColor,
VehicleName = (from v in db.Vehicles
where rtv.Contains(v.ID)
select v.VehicleName).ToList()
};
I'd also recommend looking at setting up navigation properties between your entities. Your query could be much simpler, something like this:
var query = from r in db.Reservations
let e = r.Requestor
let rs = r.ReservationStatus
let rst = rs.ReservationStatusType
select new
{
StartDate = r.StartDate,
EndDate = r.EndDate,
Destination = r.Destination,
PurposeOfTrip = r.PurposeOfTrip,
TransportingStudents = r.TransportStudentsFG,
EmployeeName = e.FirstName + " " + e.LastName,
ApprovalStatus = rst.StatusType,
ThemeColor = r.ThemeColor,
VehicleName = r.Vehicles.Select(v => v.VehicleName).ToList()
};

Views hook_views_query_alter JOIN

In hook_views_query_alter i build join query like this:
$join = new views_join();
$join->table = 'table_2';
$join->field = 'field_2';
$join->left_table = 'table_1';
$join->left_field = 'field_1';
$join->type = 'LEFT';
$join->extra = array(
array(
'table' => 'table_2',
'field' => 'field_3',
'value' => 'table_1.field_4',
),
);
The query should looks like this:
LEFT JOIN {table_2} table_2 ON table_1.field_1 = table_2.field_2 AND table_1.field_3 = table_2.field_4
My problem is here 'value' => 'table_1.field_4'. I can't set value as field. It treat it as string value. So at the and in my query i have unwanted single quotes.
So at the end my query looks like this:
LEFT JOIN {table_2} table_2 ON table_1.field_1 = table_2.field_2 AND table_1.field_3 = 'table_2.field_4'
I'm not sure if it's the best solution but this:
$join = new views_join();
$join->table = 'table_2';
$join->field = 'field_2';
$join->left_table = 'table_1';
$join->left_field = 'field_1';
$join->type = 'LEFT';
$join->extra = 'table_1.field_3 = table_2.field_4';
works for me.

count in sub-query in zend framework 2

I am new bee of Zf2, so please suggest how should I create following sql in Zend framework 2?
Select mt1.*,
(select count(mt2.parent_id)
from md_type as mt2
where mt2.parent_id = mt1.id)) as cnt
from md_type as mt1
You can try this:
$sub = new Select('md_type');
$sub->columns(array(new Expression('COUNT(mt2.parent_id) as total')))
->where(array(
new \Zend\Db\Sql\Predicate\Expression('mt2.parent_id = mt1.id')
))
;
$subquery = new \Zend\Db\Sql\Expression("({$sub->getSqlString()})");
$select = new \Zend\Db\Sql\Select('mt1');
$select->columns(array('*', 'cnt' => $subquery));
this would produce:
SELECT mt1.*,
(SELECT COUNT(mt2.parent_id) as total
FROM "md_type"
WHERE mt2.parent_id = mt1.id
) AS cnt
FROM mt1
Please try this
$sql = new Sql($this->_adapter);
$mainSelect = $sql->select()->from('mt1');
$subQry = $sql->select()
->from('md_type')
->columns(array('orderCount' => new \Zend\Db\Sql\Expression('COUNT(md_type.parent_id)')))
->where('mt2.parent_id = mt1.id');
$mainSelect->columns(
array(
'id',
'total' => new \Zend\Db\Sql\Expression('?', array($subQry)),
)
);
$statement = $sql->prepareStatementForSqlObject($mainSelect);
$comments = $statement->execute();
$resultSet = new ResultSet();
$resultSet->initialize($comments);
return $resultSet->toArray();
Reference: ZF2 - subqueries

Export products from Mysql Magento

I have some problems with Magento DB, i cannot match the attributes for my custom products export file.
I need help to get attributes, i have finished this script only with this header
But attribute_set, visibility and size_cloth is returning number not name. maybe this can be resolved with a match function.
I need to get more attributes, ex: category_ids, i cannot get this...
color, size_shoes, size_etc.
Please check my script.
'store', '_website', 'attribute_set', 'type', 'sku', 'name', 'description', 'short_description', 'visibility', 'has_option', 'price', 'special_price', 'size_cloth', 'link', 'image'
<?php
//Setup Connection information
$dbhost = 'localhost';
$dbuser = 'user';
$dbpass = 'pass';
//Connect to the database
$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die('Error connecting to mysql');
//Point to specific DB
$dbname = 'database_name';
mysql_select_db($dbname);
//Create the Query to get the products
$sql = "SELECT DISTINCT P.attribute_set_id, P.type_id, P.sku, P.has_options, V.value AS Name, T1.value AS ProdDesc, T2.value AS ShortDesc,
T5.value AS visibility, D.value AS Price, S.value AS Special_Price, SIZE_CLOTH.value AS size_cloth, CONCAT('http://www.website.com/', V1.value) AS Link,
CASE
WHEN V2.Value IS NULL
THEN NULL
ELSE CONCAT('http://www.website.com/media/catalog/product', V2.value)
END AS Image
FROM catalog_product_entity AS P INNER JOIN
catalog_product_entity_varchar AS V ON P.entity_id = V.entity_id AND V.attribute_id = 60 LEFT JOIN
catalog_product_entity_varchar AS V1 ON P.entity_id = V1.entity_id AND V1.attribute_id = 87 LEFT JOIN
catalog_product_entity_varchar AS V2 ON P.entity_id = V2.entity_id AND V2.attribute_id = 74 LEFT JOIN
catalog_product_entity_text AS T1 ON P.entity_id = T1.entity_id AND T1.attribute_id = 61 LEFT JOIN
catalog_product_entity_text AS T2 ON P.entity_id = T2.entity_id AND T2.attribute_id = 62 LEFT JOIN
catalog_product_entity_int AS T5 ON P.entity_id = T5.entity_id AND T5.attribute_id = 91 LEFT JOIN
catalog_product_entity_decimal AS D ON P.entity_id = D.entity_id AND D.attribute_id = 64 LEFT JOIN
catalog_product_entity_int AS SIZE_CLOTH ON P.entity_id = SIZE_CLOTH.entity_id AND SIZE_CLOTH.attribute_id = 122 LEFT JOIN
catalog_product_entity_decimal AS S ON P.entity_id = S.entity_id AND S.attribute_id = 65";
//Run the query
$query = mysql_query($sql);
//But after this i will prepare the csv file for export.
$file = fopen('products_export.csv', 'w');
// Custom header for csv file
$header = array('store', '_website', 'attribute_set', 'type', 'sku', 'name', 'description', 'short_description', 'visibility', 'has_option', 'price', 'special_price', 'size_cloth', 'link', 'image');
// this will arrange all data by comma
fputcsv($file, $header, ',', '"');
//Loop through and print each products info
while($row = mysql_fetch_array($query))
{
$item = array();
$value1 = ("admin");
$value2 = ("base");
$value3 = ($row['attribute_set_id']);
$value4 = ($row['type_id']);
$value5 = ($row['sku']);
$value6 = ($row['Name']);
$value7 = ($row['ProdDesc']);
$value8 = ($row['ShortDesc']);
$value9 = ($row['visibility']);
$value10 = ($row['has_options']);
$value11 = ($row['Price']);
$value111 = ($row['Special_Price']);
$value112 = ($row['size_cloth']);
$value12 = ($row['Link']);
//$value13 = ($row['Image']);
$item[] = $value1;
$item[] = $value2;
$item[] = $value3;
$item[] = $value4;
$item[] = $value5;
$item[] = $value6;
$item[] = $value7;
$item[] = $value8;
$item[] = $value9;
$item[] = $value10;
$item[] = $value11;
$item[] = $value111;
$item[] = $value112;
$item[] = $value12;
// put all data in csv file
fputcsv($file, $item, ',', '"');
}
{
// close csv file and finish.
fclose($file);
}
?>
I think that the best solution will be the data.
Example:
if ( $value112 == need to array the list of numbers, 1, 2, 3, 4, 5) {
echo "S, M, L, XL";
} else {
echo " ";
}
But i dont know how to insert this to my array items...
Interacting directly with Magento's DB wouldn't be my 1st choice.
Alternatives that actually work:
Use Magento Import/Export module
Use Magento Dataflow Import/Export
Use Magento's product collection to generate the export file
http://www.magentocommerce.com/knowledge-base/entry/magento-for-dev-part-8-varien-data-collections

dao recordset updating the wrong record

I'm trying to have a form usable for both creating a new record or updating another. Currently it is doing it through the value of a textbox (new or edit). The structure works fine, but for some reason, when it is performing the edit function, it is saving changes to the wrong record. For instance, if I am editing record 1027, when i submit it, it'll update record 1073. Its consistent, it'll always update the same, wrong record. Edit 1000, it'll update 1073; if i update 1081, it'll update 1073, and so on. Is there a way to specify which record it should be editing? yes, the record number is the primary key/id. Heres the code:
Private Sub btnSubmit_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strTable As String
Dim strField As String
Dim ID As Long
Dim newID As Long
strTable = "record_holdData"
Set db = CurrentDb
Set rs = db.OpenRecordset(strTable)
'button has 2 modes
If txtMode.Value = "NEW" Then
With rs
.AddNew
.Fields("PO_no") = txtPONum
.Fields("prodSupervisor") = cboProdSup
.Fields("qaSupervisor") = cboQASup
.Fields("labTech") = cboLabTech
.Fields("flavor") = cboFlavor
.Fields("lineNumber") = cboLineNumber
.Fields("container") = cboContainer
.Fields("package") = cboPackage
.Fields("holdQty") = txtQty
.Fields("productionDate") = txtProdDate
.Fields("dateCode") = txtDatecode
.Fields("component") = cboComponent
.Fields("nonconformance") = cboDiscrepancy
.Fields("foundDuring") = cboFoundAt
.Fields("responsibility") = cboRespCode
.Fields("comments") = txtDescription
.Fields("rootCause") = txtRootCause
.Fields("holdStatus") = 1
.Fields("dateOpened") = Now()
.Update
.Bookmark = .LastModified
newID = !ID
End With
MsgBox ("Hold information saved!")
btnPrintTag.Enabled = True
DoCmd.OpenReport "Holdtag", acViewPreview, , "[ID] = " & newID
DoCmd.Close
ElseIf txtMode.Value = "EDIT" Then
'do editing stuff
With rs
.Edit
.Fields("PO_no") = txtPONum
.Fields("prodSupervisor") = cboProdSup
.Fields("qaSupervisor") = cboQASup
.Fields("labTech") = cboLabTech
.Fields("flavor") = cboFlavor
.Fields("lineNumber") = cboLineNumber
.Fields("container") = cboContainer
.Fields("package") = cboPackage
.Fields("holdQty") = txtQty
.Fields("productionDate") = txtProdDate
.Fields("dateCode") = txtDatecode
.Fields("component") = cboComponent
.Fields("nonconformance") = cboDiscrepancy
.Fields("foundDuring") = cboFoundAt
.Fields("responsibility") = cboRespCode
.Fields("comments") = txtDescription
.Fields("rootCause") = txtRootCause
.Fields("lastEditDate") = Now()
.Update
End With
MsgBox ("Information Updated")
End If
End Sub
Sorry i caught it. Problem was I was basically redefining the recordset each time the subroutine was called. I changed the second block to the following:
ElseIf txtMode.Value = "EDIT" Then
'do editing stuff
Set rs = db.OpenRecordset("SELECT * FROM record_holdData WHERE ID=" & txtID)
With rs
.Edit
.Fields("PO_no") = txtPONum
.Fields("prodSupervisor") = cboProdSup
.Fields("qaSupervisor") = cboQASup
.Fields("labTech") = cboLabTech
.Fields("flavor") = cboFlavor
.Fields("lineNumber") = cboLineNumber
.Fields("container") = cboContainer
.Fields("package") = cboPackage
.Fields("holdQty") = txtQty
.Fields("productionDate") = txtProdDate
.Fields("dateCode") = txtDatecode
.Fields("component") = cboComponent
.Fields("nonconformance") = cboDiscrepancy
.Fields("foundDuring") = cboFoundAt
.Fields("responsibility") = cboRespCode
.Fields("comments") = txtDescription
.Fields("rootCause") = txtRootCause
.Fields("lastEditDate") = Now()
.Update
End With

Resources