My $condition in find() cannot make use of virtualfield.
I have this virtualfield on my Employee model:
var $virtualFields = array(
'AgentFullName' => "CONCAT(Employee.id, ' ', Employee.emp_ape_pat, ' ', Employee.emp_ape_mat, ' ', Employee.name)"
);
I'm using this condition to look on two fields, one regular, one virtual (
$idconditions = array(
'OR' => array(
'Employee.id LIKE' => $this->passedArgs['valsearch'],
'Employee.AgentFullName LIKE' => $this->passedArgs['valsearch']
));
My find returns no record when looking for a valid text that can be found on the virtual field:
$theid = $this->Horario->Employee->find('first', array(
'fields' => array('Employee.emp_appserial', 'Employee.AgentFullName'),
'conditions' => $idconditions,
));
However, the sql_dump seems correct:
When find() looks for an id number:
SELECT `Employee`.`emp_appserial`, (CONCAT(`Employee`.`id`, ' ', `Employee`.`emp_ape_pat`, ' ', `Employee`.`emp_ape_mat`, ' ', `Employee`.`name`)) AS `Employee__AgentFullName` FROM `devopm0_5`.`employees` AS `Employee` WHERE ((`Employee`.`id` LIKE 1005) OR ((CONCAT(`Employee`.`id`, ' ', `Employee`.`emp_ape_pat`, ' ', `Employee`.`emp_ape_mat`, ' ', `Employee`.`name`)) LIKE '1005')) LIMIT 1
And the find() using last name (returns no record)
SELECT `Employee`.`emp_appserial`, (CONCAT(`Employee`.`id`, ' ', `Employee`.`emp_ape_pat`, ' ', `Employee`.`emp_ape_mat`, ' ', `Employee`.`name`)) AS `Employee__AgentFullName` FROM `devopm0_5`.`employees` AS `Employee` WHERE ((`Employee`.`id` LIKE 'SMITH') OR ((CONCAT(`Employee`.`id`, ' ', `Employee`.`emp_ape_pat`, ' ', `Employee`.`emp_ape_mat`, ' ', `Employee`.`name`)) LIKE 'SMITH')) LIMIT 1
I wonder why the virtualfield cannot be subject to search.
Can you help?
Thank a lot !
You cannot use VirtualFields as SQL Conditions.
The virtual fields are added to the results after the find is performed, and this is why you cannot condition on them.
The Cookbook says:
These fields cannot be saved, but will be treated like other model fields for read operations. They will be indexed under the model’s key alongside other model fields.
Related
I have a statement on DB2 using the TRANSLATE function:
,TRANSLATE( FIELD1, ' ', x'042021222324282A3638FF') FIELD1A
How to I modify the statement for a question mark character in data
Thank you.
ihope that i understood youright. You want to replace a '?' by ' ' is that true? in this case translate works like this:
VALUES translate('sdnfojs?sdmf', ' ', x'6F'),
translate('sdnfojs?sdmf', ' ', '?');
--result: 'sdnfojs sdmf'
I have the following situation:
I have a script consisting of 6 selects joined by "UNION ALL".
From the CLP DB2 console, this script fails. Curiously, each query independently work, and even come to work if grouped in pairs. However, when I try with three or more, it fails.
So, my question is: is there is a limit for more that one UNION ALL?
My environment is:
Client. DB2 Connect server 10.1
zOS 390 (no idea what is the DB2 version on that side)
AIX 7.1
The query is like this (but three times )
SELECT
,'GG'
,varchar(right( '000000000000000' || rtrim(ltrim(eeee.zzzz)), 15), 15)
,substr(char(right('**********'||char(left(replace(eeee.yyyy,' ','*')||'**********',10),10),10),10),1,7)
,eeee.kkkkk
,eeee.hhhhhh
,CASE WHEN hhhhhh='A5 ' THEN 'ARS' WHEN hhhhhh='A6 ' THEN 'AUD' WHEN hhhhhh='B5 ' THEN 'BRL' WHEN hhhhhh='U1 ' THEN 'GBP' WHEN hhhhhh='B9 ' THEN 'BND' WHEN hhhhhh='B6 ' THEN 'BNG' WHEN hhhhhh='C1 ' THEN 'CAD' WHEN hhhhhh='C3 ' THEN 'CLP' WHEN hhhhhh='C4 ' THEN 'CNY' WHEN hhhhhh='C5 ' THEN 'COP' WHEN hhhhhh='C7 ' THEN 'CRC' WHEN hhhhhh='L5 ' THEN 'HRK' WHEN hhhhhh='C9 ' THEN 'CYP' WHEN hhhhhh='X0 ' THEN 'CZK' WHEN hhhhhh='D0 ' THEN 'DKK' WHEN hhhhhh='D1 ' THEN 'DOP' WHEN hhhhhh='U0 ' THEN 'EGP' WHEN hhhhhh='E3 ' THEN 'EUR' WHEN hhhhhh='G5 ' THEN 'GTQ' WHEN hhhhhh='H0 ' THEN 'HTG' WHEN hhhhhh='H3 ' THEN 'HUF' WHEN hhhhhh='I1 ' THEN 'INR' WHEN hhhhhh='I2 ' THEN 'IDR' WHEN hhhhhh='K2 ' THEN 'WON' WHEN hhhhhh='L6 ' THEN 'LVL' WHEN hhhhhh='L7 ' THEN 'LTL' WHEN hhhhhh='M2 ' THEN 'MYR' WHEN hhhhhh='M6 ' THEN 'MXN' WHEN hhhhhh='I8 ' THEN 'ILS' WHEN hhhhhh='N2 ' THEN 'NZD' WHEN hhhhhh='N4 ' THEN 'NIO' WHEN hhhhhh='N6 ' THEN 'NOK' WHEN hhhhhh='T4 ' THEN 'XPF' WHEN hhhhhh='P0 ' THEN 'PKR' WHEN hhhhhh='P1 ' THEN 'PAB' WHEN hhhhhh='P3 ' THEN 'PEN' WHEN hhhhhh='P4 ' THEN 'PHP' WHEN hhhhhh='P5 ' THEN 'PLN' WHEN hhhhhh='R2 ' THEN 'RON' WHEN hhhhhh='U3 ' THEN 'RUB' WHEN hhhhhh='S0 ' THEN 'SAR' WHEN hhhhhh='R6 ' THEN 'RSD' WHEN hhhhhh='S2 ' THEN 'SGD' WHEN hhhhhh='K5 ' THEN 'SKK' WHEN hhhhhh='S4 ' THEN 'ZAR' WHEN hhhhhh='C2 ' THEN 'LKR' WHEN hhhhhh='S8 ' THEN 'SEK' WHEN hhhhhh='S9 ' THEN 'CHF' WHEN hhhhhh='T2 ' THEN 'THB' WHEN hhhhhh='T6 ' THEN 'TRL' WHEN hhhhhh='U4 ' THEN 'USD' WHEN hhhhhh='U6 ' THEN 'UAH' WHEN hhhhhh='U5 ' THEN 'AED' WHEN hhhhhh='U2 ' THEN 'UYU' WHEN hhhhhh='V0 ' THEN 'VEB' WHEN hhhhhh='V1 ' THEN 'VND' WHEN hhhhhh='J1 ' THEN 'JPY' ELSE '###' END
, case when eeee.FCRCIDF='Y' then 1 else 0 end
,
CASE
WHEN SUBSTR(eeee.yyyy,7,1) = 'X' THEN 'X'
WHEN SUBSTR(eeee.yyyy,4,2) = 'O' THEN 'O'
WHEN SUBSTR(eeee.yyyy,4,2) = 'C' THEN 'C'
WHEN SUBSTR(eeee.yyyy,4,2) = 'R' THEN 'R'
WHEN eeee.lll = 'F' THEN 'F'
WHEN eeee.ppp <> '' THEN 'D'
WHEN eeee.rrr = 0 THEN '0'
WHEN eeee.rrr <> eeee.ACINTOT THEN 'P'
WHEN eeee.rrr = eeee.ACINTOT THEN '1'
ELSE '*'
END
,1
,eeee.DCINISS
,0
from (SELECT ori.*,oric.tttt FROM www.SK1V01_CUSTOMER ori left OUTER JOIN www.SK1V01A_CUSTCUF oric
ON ori.bbbb=oric.bbbb and ori.ICUSCNO=oric.ICUSCNO ) as aaaa
,www.SK1V02_OPENBILL eeee,www.SK1V41_OPENBILL kkkk
where aaaa.bbbb=eeee.bbbb
and aaaa.cagllic=eeee.cagllic
and aaaa.icuscno=eeee.icuscno
Without the entire statement its pretty hard to determine exact reasons. An given that just one portion is so long & poorly formatted, I'm not sure we'd want to dig through it all. But I can suggest a few approaches that may help resolve your problem.
Simplest part first. In practically any computer language, well formatted code helps you see the structure of what's going on. It may also help you spot the differences between your queries. (Perhaps you know this, & your code merely lost its formatting when you tried to post it.)
When trying to UNION multiple complex queries, it's not uncommon to have column inconsistencies among the queries. You might have missing or extra columns, or columns out of order. But it's possible some of your column expressions are evaluating to different types. You might want to cast() those expressions, or use type conversion functions, just to be sure.
There's so much going on here. Try testing with a version where you comment out large chunks of code, same on each major subquery, until you find which part is causing the problem.
You have a ridiculously long CASE expression on hhhhhh. Why don't you put these value pairs into a lookup table that you can join to.
Try using a module approach, just as you should when writing a large program. You could create a view for each of the major queries, then UNION them together. (Some developers use layers of views like layers of modular code).
Metadata about your views is available in the database catalog views. This means you could write a query to compare the attributes of the columns in your set of union views.
I'm trying to group a query's response by day, month, or year based on user input.
To do this I'm extracting the day, month, or year from the log_time column AS when and then trying to GROUP BY when but CakePHP says:
SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "when" LINE 1: ...2-31' GROUP BY "Passenger"."route_id", "Route"."name", when ^
Here's an example of my function call where the grouping is 'month'.
$fields = array(
"CONCAT(DATE_PART('year', \"Passenger\".\"log_time\"), '-', DATE_PART('month', \"Passenger\".\"log_time\")) AS when",
"Passenger.route_id",
"Route.name",
"SUM(Passenger.embarked) AS embarked"
);
$conditions = array(
"Passenger.log_time >=" => $start,
"Passenger.log_time <=" => $end
);
$group = array("Passenger.route_id", "Route.name", "\"when\"");
return $this->find('all', array('fields' => $fields, 'conditions' => $conditions, 'group' => $group));
This is using Postgres on Cake 2.3.5. Has anyone else figured out how to do this?
when is a keyword that is used with CASE. Looks like PostgreSQL can figure out that the when in your select is just an identifier but there isn't enough context to figure it out in the GROUP BY. I'd quote it in both places:
"CONCAT(DATE_PART('year', \"Passenger\".\"log_time\"), '-', DATE_PART('month', \"Passenger\".\"log_time\")) AS \"when\"",
and:
$group = array("\"when\"", "Passenger.route_id", "Route.name");
I got stuck during database migration on PostgreSQL and need your help.
I have two tables that I need to join: drzewa_mateczne.migracja (data I need to migrate) and ibl_as.t_adres_lesny (dictionary I need to join with migracja).
I need to join them on replace(drzewa_mateczne.migracja.adresy_lesne, ' ', '') = replace(ibl_as.t_adres_lesny.adres, ' ', ''). However my data is not very regular, so I want to join it on first good match with the dictionary.
I've created the following query:
select
count(*)
from
drzewa_mateczne.migracja a
where
length(a.adresy_lesne) > 0
and replace(a.adresy_lesne, ' ', '') = (select substr(replace(al.adres, ' ', ''), 1, length(replace(a.adresy_lesne, ' ', ''))) from ibl_as.t_adres_lesny al limit 1)
The query doesn't return any rows.
It does successfully join empty rows if ran without
length(a.adresy_lesne) > 0
The two following queries return rows (as expected):
select replace(adres, ' ', '')
from ibl_as.t_adres_lesny
where substr(replace(adres, ' ', ''), 1, 16) = '16-15-1-13-180-c'
limit 1
select replace(adresy_lesne, ' ', ''), length(replace(adresy_lesne, ' ', ''))
from drzewa_mateczne.migracja
where replace(adresy_lesne, ' ', '') = '16-15-1-13-180-c'
I'm suspecting that there might be a problem in sub-query inside the 'where' clause in my query. If you guys could help me resolve this issue, or at least point me in the right direction, I'd be very greatful.
Thanks in advance,
Jan
You can largely simplify to:
SELECT count(*)
FROM drzewa_mateczne.migracja a
WHERE a.adresy_lesne <> ''
AND EXISTS (
SELECT 1 FROM ibl_as.t_adres_lesny al
WHERE replace(al.adres, ' ', '')
LIKE (replace(a.adresy_lesne, ' ', '') || '%')
)
a.adresy_lesne <> '' does the same as length(a.adresy_lesne) > 0, just faster.
Replace the correlated subquery with an EXISTS semi-join (to get only one match per row).
Replace the complex string construction with a simple LIKE expression.
More information on pattern matching and index support in these related answers:
PostgreSQL LIKE query performance variations
Difference between LIKE and ~ in Postgres
speeding up wildcard text lookups
What you're basically telling the database to do is to get you the count of rows from drzewa_mateczne.migracja that have a non-empty adresy_lesne field that is a prefix of the adres field of a semi-random ibl_as.t_adres_lesny row...
Lose the "limit 1" in the subquery and substitute the "=" with "in" and see if that is what you wanted...
I had a problem with scraping info from a web page, which was solved by someone, but i would also like to get the data from that structure and put it into normal string variables, i commented saying this and was told to create a new question, so here it is!
code:
use Web::Query 'wq';
my $football_matches = wq($mech->content)
->find('tr.match')
->map(sub {
my (undef, $e) = #_;
return 'v' eq $e->find('td.score')->text
? [
$e->attr('id'),
map { $e->find("td.$_")->text }
(qw(tournament dateTime homeTeam score awayTeam prices))
]
: ();
});
use Data::Dumper; print Dumper $football_matches;
output:
$VAR1 = [
['tn7gc635476', '', ' Mo 12Mar 2012 ', 'Arsenal', 'v', 'Newcastle', ' '],
['tn7gc649937', '', ' Tu 13Mar 2012 ', 'Liverpool', 'v', 'Everton', ' '],
['tn7gc635681', '', ' Sa 17Mar 2012 ', 'Fulham', 'v', 'Swansea', ' '],
['tn7gc635661', '', ' Sa 17Mar 2012 ', 'Wigan', 'v', 'West Brom', ' '],
['tn7gc635749', '', ' Su 18Mar 2012 ', 'Wolves', 'v', 'Man Utd', ' '],
['tn7gc635556', '', ' Su 18Mar 2012 ', 'Newcastle', 'v', 'Norwich', ' ']
];
What i would like to do is take each date, home team and away team and put them into normal variables/arrays.
Thanks in advance!
You may want to check perldsc and perlref. Look for the part arrays-of-arrays and arrayref