join with AND id=1 with SQL::Abstract::More - sql

I'm trying to do a join using SQL::Abstract::More that has an `and and then a literal value, not on a table column.
=>{table.table_id=table_id,table_log.date>table.date,table_log.event_id=1}
gd_audit_log
the resulting output that I want
LEFT OUTER JOIN table_log ON (
table_log.date > table.date
AND table.table_id = table_log.table_id
AND table_log.event_id = 1
)
this code works except for
AND table_log.event_id = 1
the error is
... failed: Unknown column 'table_log.1' in 'on clause'
obviously it's generating the wrong SQL, what I'm trying to figure out is how to get it to generate the SQL I need.

From RT Bug 84972. To insert a literal value, you need to use the hashref syntax, instead
of the string syntax :
my $result = $sqla->join(
'table',
{ operator => '=>',
condition => { '%1$s.table_id' => {-ident => '%2$s.table_id'},
'%2$s.date' => {'>' => {-ident => '%1$s.date'}},
'%2$s.event_id' => 1}},
'table_log'
);

Seems to me that table_log.event_id = 1 isn't a valid join clause, but should be in a where clause.

Use force Luke
qw/table
=>{table.table_id=table_id,table_log.date>table.date,table_log.event_id='1'}
table_log/
need 'escape' 1 by single quote

Related

Translate this Linq into SQL

I have this linq code that I need to translate into identical SQL so I can query the database directly... I get stuck when it gets complicated. Can anyone help?
Linq
_db.BatchPaymentSplits
.Where(bps => bps.YearSetupId == i.YearSetupId)
.Where(bps => bps.CustomerIdEntered != null)
.Where(bps => _db.BatchPayments
.Where(bp => _db.Batches.Where(b => b.BatchTypeId.Equals("T"))
.Select(b => b.BatchId)
.Contains(bp.BatchId)
)
.Select(bp => bp.BatchPaymentId).Contains(bps.BatchPaymentId)
)
SQL so far
SELECT * FROM BatchPaymentSplit
WHERE YearSetupId = 1
AND CustomerIdEntered IS NOT NULL
I can't say that I think the LINQ or the resulting SQL is the best way to express this query (should be using Join I think), but this is my literal translation:
SELECT *
FROM BatchPaymentSplits bps
WHERE bps.YearSetupId = i.YearSetupId AND
bps.CustomerIdEntered IS NOT NULL AND
EXISTS (SELECT * FROM BatchPayments bp
WHERE EXISTS (SELECT * FROM Batches b
WHERE b.BatchTypeId = 'T' AND
b.BatchId = bp.BatchId) AND
bp.BatchPaymentId = bps.BatchPaymentId)
You can translate Contains when applied to an IEnumerable/IQueryable as an EXISTS query with an = expression.

Why does a UNION ALL query treat the outer ORDER column as unknown?

I'm using unionAll() and return the data perfectly, but I need ordernate the data and always return error because the column not exists.
$events = $this->Events
->find('available')
->where([
'Events.group_of_event_id IS NULL'
])
->select('Events.id')
->select('Events.name')
->select('Events.slug')
->select('Events.date_event_start')
->select([
'is_group' => 0
]);
$groups = $this->GroupOfEvents
->find('available')
->select('GroupOfEvents.id')
->select('GroupOfEvents.name')
->select('GroupOfEvents.slug')
->select('GroupOfEvents.date_event_start')
->select([
'is_group' => 1
]);
$limit = 10;
$page = 1;
if($this->request->query('limit'))
$limit = $this->request->query('limit');
if($this->request->query('page'))
$page = $this->request->query('page');
$offset = ($page - 1) * $limit;
$connection = ConnectionManager::get('default');
$union = $events->unionAll($groups)->epilog(
$connection
->newQuery()
->order(['date_event_start' => 'ASC'])
->limit($limit)
->offset($offset)
);
Return this error:
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'date_event_start' in 'order clause'
As the error states, there is no date_event_start column.
Unlinke normale SQL queries, where a non-table prefixed column would fall back to referring to one of the involved tables, similar doesn't happen for union results, with union results you have to explicity refer to the columns as they have been selected.
So you have to make sure that either the columns are selected without a table prefix, or to select and use proper aliases in the ORDER clause. In order to avoid ambiguity, I'd strongly suggest going for the latter, something like
->select(['date_event_start_alias' => 'Events.date_event_start'])
// ...
->select(['date_event_start_alias' => 'GroupOfEvents.date_event_start'])
// ...
->order(['date_event_start_alias' => 'ASC'])
It should be noted that at least with MySQL and Postgres (I'm not sure about other DBMS like SQLite or SQL Server), you actually have to set the alias only for the first SELECT. Setting it for all selects won't do any harm, so I'm including it in the example, but it's not actually necessary.
See also
Cookbook > Database Access & ORM > Query Builder > Selecting Data

Sugar query syntax error in SugarCRM

I am trying to join table prospects with leads. I am executing this query
$queryProspects = new SugarQuery();
$queryProspects->from(BeanFactory::getBean('Prospects'));
$leads = $queryProspects->joinTable('leads');
$queryProspects->select("prospects.id","prospects.lead_id");
$queryProspects->where()->equals("lead_id","117c3d5d-07d9-0ae7-5610-573ac87c9a35");
Before executing it like this.
$queryProspects->execute();
I am compiling my query like
$queryProspects->compileSql();
This query is not working after executing. query result after compiling is
SELECT prospects.id id, prospects.lead_id lead_id FROM prospects JOIN leads ON () WHERE prospects.deleted = 0 AND prospects.lead_id = '117c3d5d-07d9-0ae7-5610-573ac87c9a35'
I know the error is () WHERE which I need to remove, but unable to do changes in sugar query in order to remove these brackets and where clause (which are showing in sql generated query).
Change from and join statement like this.
$queryProspects->from(BeanFactory::getBean('Prospects'), array('team_security' => false));
$leads = $queryProspects->join('lead')->joinName();
lead in join is the link (name field) in your prospects > vardefs.php as shown below.
'lead' => array(
'name' => 'lead',
'type' => 'link',
'relationship' => 'lead_prospect',
'module' => 'Leads',
'source' => 'non-db',
'vname' => 'LBL_LEAD',
),
please execute your query like this :
$result = $queryProspects->execute();
For more details Follow this link :
Sugar Query

TYPO3 doesn't respect field names in JOIN query

I'm trying to fetch a JOIN query in TYPO3 using createQuery and $query->statement(...), but get odd results. Can someone explain to me why TYPO3 doesn't include table names as a prefix to column names in a JOIN query? Does this conflict with the ORM? Can I in anyway speed up a query of multiple 1:N-relations?
Example:
SELECT
client.name, project.name
FROM
client
LEFT JOIN
project ON project.client = client.uid
The PHP code from client repository:
$query = $this->createQuery();
$query->statement($statement);
$query->getQuerySettings()->setReturnRawQueryResult(true);
var_dump($query->execute());
The result prints out only names of the projects:
array (size=294)
0 =>
array (size=1)
'name' => string 'Projectname1' (length=21)
1 =>
array (size=1)
'name' => string 'Projectname2' (length=20)
2 =>
array (size=1)
'name' => string 'Projectname3' (length=32)
EDIT: This might be standard SQL behaviour.
Use aliases for fields:
SELECT
client.name client_name, project.name project_name
FROM
client
LEFT JOIN
project ON project.client = client.uid

Struggle with SQL Statement (Not Exists)

Hey i have some problems with a sql statement. This is the Database Scheme:(http://docs.elgg.org/wiki/DatabaseSchema), only the "entities" and the "relationship" table are important! What i'm trying to do is, select all guid's where the type of the object is "group" but this object is not a child of a other group. That means there is no record in the relationship table with the guid in the guid_two column. My first idea was this:
SELECT * FROM elgg_entities e
JOIN elgg_entity_relationships r ON e.guid = r.guid_one
WHERE e.type='group' AND NOT EXISTS (
SELECT *
FROM elgg_entity_relationships s
WHERE e.guid = s.guid_two
AND s.relationship='subgroup')
But it wont work. Also there are some other relationships in the table like member etc. I hope someone can help me, because i really frustrated right now.
Edit: This SQL query works in MyPHP, in elgg i tried to convert it into "elgg-ich":
$options = array(
'type' => 'group',
'joins' => array("JOIN elgg_entity_relationships r ON e.guid = r.guid_one"),
'wheres' => array("e.type='group' AND not exists (SELECT e.guid
FROM elgg_entity_relationships s
where e.guid = s.guid_two
AND s.relationship = 'subgroup'
)"),
'limit' => $limit,
'full_view' => FALSE,
);
$content = elgg_list_entities($options);
=> Solution was the case sensitivity and where instead of wheres in line 6.
As noted in the edited question;
Solution was the case sensitivity and where instead of wheres in line
6.