I need to execute following query using phalcon framework:
"SELECT id FROM table GROUP BY id HAVING '31' = ALL(array_agg(status))"
How can I execute this query using phalcon?
When I do following:
Model::query()
->columns(['id'])
->groupBy('id')
->having('31 = ALL(array_agg(status))')
->execute();
I get this error message:
Syntax error, unexpected token ALL, near to '(array_agg(status)) ', when parsing: SELECT id FROM [SomeNameSpace\Model] GROUP BY [id] HAVING 31 = ALL(array_agg(status)) (137)
I'm not 100% sure which Postgres functions are supported, but you can try like this:
Model::query()
->columns([
'id',
'ALL(array_agg(status)) AS statusCounter'
])
->groupBy('id')
->having('31 = statusCounter')
->execute();
Notice that I moved the aggregation functions in the select, rather in having clause.
UPDATE: here is an example of very custom query. Most functions used are not supported and it's sometimes cleaner just to write a simple SQL query and bind the desired Model to it:
public static function findNearest($params = null)
{
// A raw SQL statement
$sql = '
SELECT *, 111.045 * DEGREES(ACOS(COS(RADIANS(:lat))
* COS(RADIANS(X(coords)))
* COS(RADIANS(Y(coords)) - RADIANS(:lng))
+ SIN(RADIANS(:lat))
* SIN(RADIANS(X(coords)))))
AS distance_in_km
FROM object_locations
ORDER BY distance_in_km ASC
LIMIT 0,5;
';
// Base model
$model = new ObjectLocations();
// Execute the query
return new \Phalcon\Mvc\Model\Resultset\Simple(
null,
$model,
$model->getReadConnection()->query($sql, $params)
);
}
// How to use:
\Models\ObjectLocations::findNearest([
'lat' => 42.4961756,
'lng' => 27.471543300000008
])
You need to add ALL as dialect extension. Check this topic for example https://forum.phalconphp.com/discussion/16363/where-yearcurrenttimestamp-how-to-do-this
Related
I've written this query in sparql:
SELECT ?spouse
WHERE {
dbr:Zach_Galifianakis dbp:spouse ?spouse.
}
and I have this output:
2012
""#en
"Quinn Lundberg"#en
(https://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&query=SELECT+%3Fspouse%0D%0AWHERE+%7B%0D%0Adbr%3AZach_Galifianakis+dbp%3Aspouse+%3Fspouse.%0D%0A%7D%0D%0A&format=text%2Fhtml&timeout=30000&signal_void=on&signal_unconnected=on)
I don't understand how to select only the name "Quinn Lundberg"#en. I've tried using FILTER clause but it doesn't work.
Not a generic solution, but this will fetch only the name for your case:
SELECT *
WHERE {
dbr:Zach_Galifianakis dbp:spouse ?spouse.
FILTER (strlen(str(?spouse)) > 0 && lang(?spouse) = 'en')
}
Output
I want to do the following query in Postgres using JDBC:
with things as (values(1),(2)) select * from things;
So my Java code looks like this:
String sql = "with things as (?) select * from things";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setArray(1, conn.createArrayOf("INTEGER", new Integer[]{1, 2});
But this is throwing the following error:
org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"
You can do what you need using unnest like this:
Integer[] id = {1, 2};
Array array = connection.createArrayOf("int4", id);
try (PreparedStatement stmt = connection.prepareStatement(
"with things as (select unnest((?)::integer[])) select * from things")) {
stmt.setArray(1, array);
ResultSet rs = stmt.executeQuery();
// use the result set
}
I'm using Eloquent to produce results from a query comprised of three tables:
photos (id)
photos_to_photosets (photo_id, photoset_id)
photosets (id)
My models have their many-to-many relationships defined as:
class Photo extends Model
{
public function photosets()
{
return $this->hasMany(PhotoSet::class, 'photos_to_photo_sets');
}
}
And
class PhotoSets extends Model
{
public function photos()
{
return $this->belongsToMany(Photo::class, 'photos_to_photo_sets');
}
}
Now, to fetch results I'm forced to use the following Eloquent code:
$photoData = $this->photoSets->photos()
->orWhere('photo_set_id', '=', $id)
->get();
This produces the following query:
SELECT * FROM `photos`
INNER JOIN `photos_to_photo_sets`
ON `photos`.`id` = `photos_to_photo_sets`.`photo_id`
WHERE `photos_to_photo_sets`.`photo_set_id` is null
OR `photo_set_id` = ?
This query works, but I can't seem to remove WHERE `photos_to_photo_sets`.`photo_set_id` is null from the query.
I've tried to just use ->where('photo_set_id', '=', $id) but the null clause still remains; even worse it produces the following WHERE clause:
... WHERE `photos_to_photo_sets`.`photo_set_id` IS NULL
AND `photo_set_id` = ?
Is there any way, utilizing Eloquent, to remove this null WHERE clause segment?
Ideally, I'd like to end up with the following query:
SELECT * FROM `photos`
INNER JOIN `photos_to_photo_sets`
ON `photos`.`id` = `photos_to_photo_sets`.`photo_id`
WHERE `photo_set_id` = ?
Thank you in advance for any help!
UPDATE
Based off #Jonas Staudenmeir's answer, the null WHERE clause has been removed.
To achieve this, I set the photoSet's model ID prior to running the query. The resulting code was:
$this->photoSets->id = $photoset_id;
$photoData = $this->photoSets->photos()->get();
Which produced:
SELECT * FROM `photos`
INNER JOIN `photos_to_photo_sets`
ON `photos`.`id` = `photos_to_photo_sets`.`photo_id`
WHERE `photo_set_id` = ?
The injected model doesn't have an id:
$this->photoSet->id = $id;
Then you don't need the additional constraint:
$photoData = $this->photoSets->photos;
I am learning how to do simple queries using the Yii2 framework. I use PostgreSQL.
I am trying to join two tables and get the data from both tables with a where condition.
The tables are called Admins and Persons.
The join use field called idadm.
The condition is idadm = 33. This works great but the result has data only from the Admins table and I need data from the other table.
Here is my example:
$query = \app\models\Admins::find()
->select('*')
->leftJoin('persons', 'persons.idadm = admins.idadm')
->where(['admins.idadm' => 33])
->with('persons')
->all();
I am following the Yii2 official guide: http://www.yiiframework.com/doc-2.0/guide-db-active-record.html
Update: Here I show the updated code that doesn't solve de problem:
You need to write all column name in select().
$query = \app\models\Admins::find()
->select('admin.*,persons.*') // make sure same column name not there in both table
->leftJoin('persons', 'persons.idadm = admins.idadm')
->where(['admins.idadm' => 33])
->with('persons')
->all();
And also you need to define person table attributes in Admin model.
Second way is get records as array,so you dont need to define attributes in Admin model.
$query = \app\models\Admins::find()
->select('admin.*,persons.*') // make sure same column name not there in both table
->leftJoin('persons', 'persons.idadm = admins.idadm')
->where(['admins.idadm' => 33])
->with('persons')
->asArray()
->all();
Ensure that active record has required relations, e.g. something like follows:
class Admins extends \yii\db\ActiveRecord {
public function table() {
return "admins";
}
public function getPersons()
{
return $this->hasMany(Person::className(), ['idadm' => 'idadm']);
}
}
class Person extends \yii\db\ActiveRecord {
public function table() {
return "persons";
}
}
Then use joinWith to build query:
$query = Admins::find()
->joinWith('persons')
->limit(1);
$result = $query->createCommand()->getSql();
echo $result;
Here is produced query:
SELECT `admins`.* FROM `admins`
LEFT JOIN `person` ON `admins`.`idadm` = `person`.`idadm` LIMIT 1
I'm trying to create a query that pulls information about sellers from my database, but only if their store has launched in the last 3 days. The easiest way I can think of to calculate the date for the query is using a new DateTime() object. When I output my code to test it, it's in the proper string for MySQL to query it with, but whenever I try to bind the variable, I get an error. I'm using Zend_Db to query, (PDO adapter)
action:
public function indexAction()
{
$dateMod = new DateTime();
$dateMod->modify('-2 days');
$dateMod->format('Y-m-d H:i:s');
// get sellers initialized in last 3 days
$sellerTable = new Application_Model_DbTable_Sellers();
$select = $sellerTable->select()->setIntegrityCheck(false);
$select->from(array('s' => 'seller'),array('sellerID', 'businessName'));
// select firstName, lastName, picture from user table, and businessName and sellerID from seller table.
$select->join(array('u' => 'user'), 's.userID = u.userID', array('firstName', 'lastName', 'picture'));
$select->where('s.active = 1 AND s.contentApproval = 1 AND s.paymentApproval = 1 AND s.featured = 1');
$select->where('s.launchDate > ?', $dateMod);
$select->order('s.launchDate DESC');
$newSellers = $sellerTable->fetchAll($select);
When I assign $dateMod to the view, it outputs the correct Y-m-d H:i:s format. But when I plug it into the query, I get the following error:
Message: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') ORDER BY `b`.`launchDate` DESC' at line 2
If I hardcode a value into dateMod in the mysql timestamp format, the query works fine. How can I access just the string value of the timestamp in the DateTime object? getTimestamp returns a unix formatted timestamp, even after assigning a format.
The format() function returns the formatted date, so you need to assign that to a variable for use in the query:
$dateFormatted = $dateMod->format('Y-m-d H:i:s');
$select->where('s.launchDate > ?', $dateFormatted);