I have this problem using Zend and I think its db related at all:
I have two tables, one contains:
id, ..., file, desc, date
and the second table contains:
id, ..., file_1, desc_1, file_2, desc_2, date
What I need as a result is:
id, ..., file, desc, date
From both tables, which means I need to have coresponding file, desc and file_1 ->file, desc_1->desc and file_2->file, desc_2->desc in this one table.
Any idea how to do this with Zend 1.12?
You need to use JOIN in Zend ORM
for exmaple
public function getPendingProjects($owner){
$data = $this ->getAdapter()
->select()
->from('campaign' , array('title', 'id'))
->joinLeft('job', 'campaign.id = job.campaign_id', array('count(user_id)'))
->where('campaign.employer_id = ' . (int)$owner . ' AND job.status = 3' );
return $data->query()->fetchAll();
}
taked from here http://zend-frameworks.com/en/articles/zend_db_zend_mysql.html
Related
I'm currently using PHP and MySQL to retrieve a set of 100,000 records in a table, then iterate over each of those records to do some calculations and then insert the result into another table. I'm wondering if I'd be able to do this in pure SQL and make the query run faster.
Here's what I"m currently using:
$stmt= $pdo->query("
SELECT Well_Permit_Num
, Gas_Quantity
, Gas_Production_Days
FROM DEP_OG_Production_Import
ORDER
BY id ASC
");
foreach ($stmt as $row) {
$data = array('well_id' => $row['Well_Permit_Num'],
'gas_quantity' => $row['Gas_Quantity'],
'gas_days' => $row['Gas_Production_Days'],
'gas_average' => ($row['Gas_Production_Days']);
$updateTot = $pdo->prepare("INSERT INTO DEP_OG_TOTALS
(Well_Permit_Num,
Total_Gas,
Total_Gas_Days,
Total_Gas_Avg)
VALUES (:well_id,
:gas_quantity,
:gas_days,
:gas_average)
ON DUPLICATE KEY UPDATE
Total_Gas = Total_Gas + VALUES(Total_Gas),
Total_Gas_Days = Total_Gas_Days + VALUES(Total_Gas_Days),
Total_Gas_Avg =(Total_Gas + VALUES(Total_Gas)) / (Total_Gas_Days + VALUES(Total_Gas_Days))");
}
I'd like to see if this can be done in pure MySQL instead of having to use PHP just for the fact of using it to hold the variables.
My Result should be 1 record that is a running total for each Well. The source table may house 60-70 records for the same well, but over a few thousand different Wells.
It's a constant import process that has to be run, so it's not like there is a final table which you can just do SUM(Gas_Quantity)... etc.. on
As commented by Uueerdo, you seem to need an INSERT ... SELECT query. The role of such query is to INSERT insert the resultset returned by an inner SELECT. The inner select is an aggregate query that computes the total sum of gas and days for each well.
INSERT INTO DEP_OG_TOTALS (Well_Permit_Num, Total_Gas, Total_Gas_Days, Total_Gas_Avg)
SELECT
t.Well_Permit_Num,
SUM(t.Gas_Quantity) Total_Gas,
SUM(t.Gas_Production_Days) Total_Gas_Days
FROM DEP_OG_Production_Import t
GROUP BY t.Well_Permit_Num
ON DUPLICATE KEY UPDATE
Total_Gas = Total_Gas + t.Total_Gas,
Total_Gas_Days = Total_Gas_Days + t.Total_Gas_Days,
Total_Gas_Avg =(Total_Gas + t.Total_Gas) / (Total_Gas_Days + t.Total_Gas_Days)
<?php
select1($conn);
function select2 ($conn,$id ,$name)
{
$stmt = $conn->prepare("SELECT def FROM define WHERE wordkey = ?");
mysqli_stmt_bind_param($stmt, 'i', $id);
$stmt->execute();
$stmt->bind_result($def);
while($stmt->fetch()) {
echo "here"; // for testing
$wordArray += $def;
//I will make a call to the js function here sending id, name and wordArray
}
//$stmt->close();
}
function select1 ($conn){
$stmt2 = $conn->prepare("SELECT id , name FROM words");
$stmt2->execute();
$stmt2->bind_result($id, $name);
while($stmt2->fetch()) {
select2 ($conn,$id ,$name);
}
}
?>
I want to ask question I have words table and def table. in def table i have multiple definitions for the same words.id. Is it possible to select them in one query statement ?
words table have id , name
def table have id, wordkey , definition
I want to retrieve name and for each name select all its definitions so that I will then call a javascript function (id, name, defArray)
to display each name with the array of its definitions.
I thought of doing it through 2 select statement, but the problem is the select2 function is not working.
As I can assume from the very limited details from your question.
Try
select a.name, b.definition from words a, def b where a.id=b.word_id
In the above query we are simply accessing the data from multiple tables.
Please supply some more explanation (possibly with code) for precise bug fixings.
Hope it helps, All the best!
Assuming the following:
words
ID | Word
definitions
ID | WordID | Definition
SELECT D.Definition AS definition, W.Word AS word
FROM definitions D, words W
WHERE W.ID = D.WordID
ORDER BY W.Word ASC
This will display rows of definitions, ordered by the word they correspond to.
I have a MySQL script like this: SELECT id, name FROM users WHERE id IN (6,4,34)
The sequence in the IN(...) array is very important. Is it possible to get them in the given sequence?
You can use the MySQL FIELD function to keep it compact;
SELECT id, name
FROM users
WHERE id IN (6, 4, 34)
ORDER BY FIELD(id, 6, 4, 34);
Try
SELECT id, name FROM users WHERE id IN (6,4,34) order by FIELD(id,6,4,34)
You can use any expression in the ORDER BY clause, including a 'CASE':
ORDER BY CASE id
WHEN 6 THEN 1
WHEN 4 THEN 2
WHEN 34 THEN 3
END ASC
If your list comes from the application programming layer, you might build this with the following (PHP here):
$sortVal = 1;
foreach($ids as $id_val) {
$cases[] = sprintf('WHEN %i THEN %i', $id_val, $sortVal++);
}
$order_by = 'ORDER BY CASE id ' . implode($cases) . ' END ASC';
However, I'll mention that Joachim's answer is quite elegant :-)
A complete example based on Chris Trahey answer.
$ids = array("table1", "table2", "table3");
$sortVal = 1;
foreach ($ids as $id_val) {
$cases[] = sprintf("WHEN '%s' THEN %u ", $id_val, $sortVal++);
}
$order_by = 'ORDER BY CASE `tableName` ' . implode($cases) . ' END ASC';
$result = mysqli_query( $con, "
SELECT DISTINCT tableName
FROM `table`
$order_by");
I have this mysql query:
SELECT
freeAnswers.*,
(SELECT `districtCode`
FROM `geodatas`
WHERE `zipCode` = clients.zipCode
GROUP BY `zipCode`
LIMIT 0, 1) as districtCode,
clients.zipCode,
clients.gender,
clients.startAge,
clients.endAge,
clients.mail,
clients.facebook,
surveys.customerId,
surveys.activityId,
surveys.name as surveyName,
customers.companyName,
activities.name as activityName
FROM freeAnswers,
clients,
surveys,
customers,
activities
WHERE freeAnswers.surveyId = surveys.id
AND surveys.customerId = customers.id
AND activities.id = surveys.activityId
AND clients.id = freeAnswers.clientId
AND customers.id = 1
ORDER BY activityName asc
LIMIT 0, 10
the query is correct on my mysql server but when I try to use it in Zend Framework 1.11 model
I get this error: Mysqli prepare error: Operand should contain 1 column(s)
Please, could anyone help me to make it run well?
Best Regards,
Elaidon
Here is some code that should work. Zend_Db_Select doesn't really provide a way to select from multiple tables in the FROM clause without using a JOIN so this feels a bit hackish to me in regards to one small part of the query. Your best bet will probably be to rewrite the query using JOINs where appropriate.
$subselect = $db->select()
->from('geodatas', 'districtCode')
->where('zipCode = clients.zipCode')
->group('zipCode')
->limit(1, 0);
$from = $db->quoteIdentifier('freeAnswers') . ', ' .
$db->quoteIdentifier('clients') . ', ' .
$db->quoteIdentifier('surveys') . ', ' .
$db->quoteIdentifier('customers') . ', ' .
$db->quoteIdentifier('activities');
$select = $db->select()
->from(array('activities' => new Zend_Db_Expr($from)),
array('freeanswers.*',
'districtCode' =>
new Zend_Db_Expr('(' . $subselect . ')'),
'clients.zipCode', 'clients.gender', 'clients.startAge',
'clients.endAge', 'clients.mail', 'clients.facebook',
'clients.customerId', 'clients.activityId',
'surveyName' => 'surveys.name', 'customers.companyName',
'activityName' => 'activities.name'))
->where('freeAnswers.surveyId = surveys.id')
->where('surveys.customerId = customers.id')
->where('activities.id = surveys.activityId')
->where('clients.id = freeAnswers.clientId')
->where('customers.id = ?', 1)
->order('activityName ASC')
->limit(10, 0);
The only reason I say it is hackish is because of the line:
->from(array('activities' => new Zend_Db_Expr($from)),
Since from() really only works with one table, I create a Zend_Db_Expr and specify the correlation as the last table name in the expression. If you don't pass a Zend_Db_Expr, it will either quote your comma separated table name incorrectly, or if you pass an array of table names, it just uses the first. When you pass a Zend_Db_Expr with no name, it defaults to use AS t which also doesn't work in your case. That is why I put it as is.
That returns the exact SQL you provided except for the last thing mentioned. Here is actually what it returns:
SELECT
`freeanswers`.*,
(SELECT `geodatas`.`districtCode`
FROM `geodatas`
WHERE (zipCode = clients.zipCode)
GROUP BY `zipCode`
LIMIT 1) AS `districtCode`,
`clients`.`zipCode`,
`clients`.`gender`,
`clients`.`startAge`,
`clients`.`endAge`,
`clients`.`mail`,
`clients`.`facebook`,
`clients`.`customerId`,
`clients`.`activityId`,
`surveys`.`name` AS `surveyName`,
`customers`.`companyName`,
`activities`.`name` AS `activityName`
FROM `freeAnswers`,
`clients`,
`surveys`,
`customers`,
`activities` AS `activities`
WHERE (freeAnswers.surveyId = surveys.id)
AND (surveys.customerId = customers.id)
AND (activities.id = surveys.activityId)
AND (clients.id = freeAnswers.clientId)
AND (customers.id = 1)
ORDER BY `activityName` ASC
LIMIT 10
So that will work but eventually you will want to rewrite it using JOIN instead of specifying most of the WHERE clauses.
When dealing with subqueries and Zend_Db_Select, I find it easy to write each subquery as their own queries before writing the final query, and just insert the subqueries where they need to go and Zend_Db handles the rest.
Hope that helps.
Is it possible to get the column names using a query in MySQL? For example, I have a SELECT query:
SELECT name AS 'name', surname AS 'col1', last_name AS 'col2' FROM tb_people;
So, I want to get "Only with one SQL query" like:
Columns or alias of my query
--------
name
col1
col2
I try something similar to:
SHOW COLUMNS (SELECT name AS 'name', surname AS 'col1', last_name AS 'col2' FROM tb_people)
And with
DESCRIBE (SELECT name AS 'name', surname AS 'col1', last_name AS 'col2' FROM tb_people)
But these return SQL errors.
Why don't you do this in your application? MySql API in most languages provide functions to fetch all sorts of field information including name from the results returned by MySql. For example in PHP you can use mysql_fetch_field() on the results returned by mysql_query() to fetch field information.
This is how it is done in PHP, there must be equivalent functions in the language you are using:
$res = mysql_query( "SELECT name AS 'name', surname AS 'col1', last_name AS 'col2' FROM tb_people" );
for( $i = 0; $i < mysql_num_fields( $res ); ++$i ) {
$fieldInfo = mysql_fetch_field( $res, $i );
echo $fieldInfo[ 'name' ].'<br />';
}
results:
name
col1
col2
Hey I have used this successfully in the past, but I don't know if it compatible with all versions:
SELECT name FROM syscolumns
WHERE id = (SELECT id FROM sysobjects
WHERE name= 'MyTableName')
ORDER by colorder
If you installed MySQL server 5, you may get around this problem easily:
use information_schema
SELECT * FROM information_schema.`COLUMNS` C limit 5
WHERE table_name = 'your_table_name'
Cheers!