New To Yii And 2 Mysql Questions

Hello all - total noob to yii

have not a clue where to place mysql code to attempt this using Active Record

currently have written raw mysql/php report generator for static pages that

generates google visualization bar-format charts that widgets consume,

but before attempting to convert to AR was wondering are the following doable

case 1: Automation

need to run 2 similar mysql queries 

[sql]/* get external inbound calls

example of output of query which is consumed by barFormat chart

google barFomat gridchart along with get outbound calls

[’<==outbound - inbound==>’,11,‘dur’,‘avg’],

[‘816 ==> Kansas City, MO’,11,‘00:01:39’,‘00:00:09’],

[‘812 ==> Evansville, IN’,2,‘00:01:18’,‘00:00:39’],

*/

SELECT concat("[’",

		case 


		   when length(src) = 10 then left(src,3) 


		   when length(src) = 11 then mid(src,2,3) 


		end,  


		&quot; ==&gt; &quot;,


		concat(t2.city, &quot;, &quot;,t2.st),


		&quot;',&quot;,


		count(src),


		&quot;,'&quot;,


		SEC_TO_TIME(sum(duration)),


		&quot;','&quot;,


		SEC_TO_TIME(avg(duration)),


		&quot;'],&quot;) as areacodes

FROM cdr8

join ac as t2

on  t2.acs = 


		 case 


		   when length(src) = 10 then left(src,3) 


		   when length(src) = 11 then mid(src,2,3) 


		 end  

WHERE length(src) > 9

group by

case 


   when length(src) = 10 then left(src,3) 


   when length(src) = 11 then mid(src,2,3) 


end[/sql] 	

results then will be consumed by widget that displays google visualization barFormat grid

i’m running this offline and cut’n’paste (8 different tables 2 queries each table ).

case 2: Forensic filters for tables with excess of 500,000 rows

while search generated by gii crud admin and extended filtering for range is somewhat helpful need real WHERE clause. User needs to supply ranges as well as NOT ranges and dates and field lengths to test after render

[sql]WHERE

field2 BETWEEN ‘8000’ AND ‘8100’

AND field2 REGEXP ‘^-?[0-9]+$’

AND LENGTH(field2) = 4

AND ((LENGTH(field4) != 4

AND field4 NOT BETWEEN ‘8000’ AND ‘8100’)

OR (field4 REGEXP ‘^-?[0-9]+$’

AND LENGTH(field4) > 6))

AND LEFT(field0,11) between ‘2012-12-10’ and ‘2012-12-13’ [/sql]

Hope i’ve explain this enough for a response, even if it is run-away and stick to straight SQL queries and forget AR/yii entirely :unsure:

Sorry for long post, but could not find any post that even reference BETWEEN a and b ranges or more complex searches.

Thanks

hey andy welcome to the forum should not be to hard just assign you query to a variable and run findbysql


$sql = 'SELECT * FROM tableName LIMIT 10'; // some complex sql 

$result=ModelName::model()->findBySql($sql);



http://www.yiiframework.com/doc/guide/1.1/en/database.ar

Thanks for quick reply

Tried this on case 1:

instead of a js array of summary (113 javascript array)

[‘string’,number,‘hh:mm:ss’,‘hh:mm:ss’],

it returned 573,000 plus paginated records in about 4 minutes, each was empty row in a division case 1: returns expected results in non yii framework a js array with 113 rows

setting limit is not a option, must gather the formated js queries(src and dst) before rendering could have a potential of total US area codes*2

the 2 cases are totally unrelated in target group, case 1: is for management charts generating static page(s) generated each month,

while case 2: is for interactively read-only forensic type queries to the detail mysql table

Hi andy, welcome to the forum.

I would like to recommend you to read "CDbCriteria" and "CDbCommand" sections of the reference.

http://www.yiiframework.com/doc/api/1.1/CDbCriteria

http://www.yiiframework.com/doc/api/1.1/CDbCommand

You may find there how you can do a database access with more abstract way than using plain SQL.

But as for the cases that you posted, I’d rather second alirz23. Yii’s DAO and AR permits you to use a plain SQL, and they seem to be the cases that you should use it.

Or, I might want to create database views for them and create readonly CActiveRecord classes that read those views.

Can you show us your code for retrieving the data with your SQL? How did you define your AR class for it?

trying 2nd time, had google links for charting

yii query

[sql]$sql=‘SELECT concat("[\’",’

	.'	case' 


	.'	   when length(src) = 10 then left(src,3)'


	.'	   when length(src) = 11 then mid(src,2,3)'


	.'	end,'  


	.'	&quot; ==&gt; &quot;,'


	.'	concat(t2.city, &quot;, &quot;,t2.st),'


	.'	&quot;&#092;',&quot;,'


	.'	count(src),'


	.'	&quot;,&#092;'&quot;,'


	.'	SEC_TO_TIME(sum(duration)),'


	.'	&quot;&#092;',&#092;'&quot;,'


	.'	SEC_TO_TIME(avg(duration)),'


	.'	&quot;&#092;'],&quot;) as areacodes '

.'FROM cdr8

.’ join ac as t2’

.’ on t2.acs = ’

.’ case ’

.’ when length(src) = 10 then left(src,3) ’

.’ when length(src) = 11 then mid(src,2,3) ’

.’ end ’

.'WHERE length(src) > 9 ’

.'group by ’

.’ case ’

.’ when length(src) = 10 then left(src,3) ’

.’ when length(src) = 11 then mid(src,2,3) ’

.’ end’;

// echo "<pre>$sql</pre>";

$result=Cdr8::model()->findBySql($sql); [/sql]

yii result snippet

[html]<h1>Cdr8s</h1>

<div id="yw0" class="list-view">

<div class="summary">Displaying 1-50 of 573243 results.</div>

<div class="items">

<!-- div class="view" -->

<!-- /div–>

<!-- div class="view" -->

<!-- /div–>

<!-- div class="view" -->

<!-- /div–>

<!-- div class="view" -->[/html]

orig sql

[sql]SELECT concat("[’",

		case 


		   when length(src) = 10 then left(src,3) 


		   when length(src) = 11 then mid(src,2,3) 


		end,  


		&quot; ==&gt; &quot;,


		concat(t2.city, &quot;, &quot;,t2.st),


		&quot;',&quot;,


		count(src),


		&quot;,'&quot;,


		SEC_TO_TIME(sum(duration)),


		&quot;','&quot;,


		SEC_TO_TIME(avg(duration)),


		&quot;'],&quot;) as areacodes

FROM cdr8

join ac as t2

on  t2.acs = 


		 case 


		   when length(src) = 10 then left(src,3) 


		   when length(src) = 11 then mid(src,2,3) 


		 end  

WHERE length(src) > 9

group by

case 


   when length(src) = 10 then left(src,3) 


   when length(src) = 11 then mid(src,2,3) 


end [/sql]

Results externally of yii snippet 113 rows


['202 ==> District Of Columbia, DC',1,'00:00:52','00:00:52'],

['208 ==> Boise City, ID',1,'00:01:15','00:01:15'],

['209 ==> Stockton, CA',8,'00:10:37','00:01:20'],

['213 ==> Los Angeles, CA',679,'12:53:29','00:01:08'],

['218 ==> Duluth, MN',1,'00:01:29','00:01:29'],

['219 ==> Gary, IN',1,'00:00:47','00:00:47'],

['231 ==> Muskegon, MI',4,'00:00:48','00:00:12'],

['239 ==> Bokeelia, FL',6,'00:14:26','00:02:24'],

['240 ==> Gaithersburg, MD',3,'00:02:02','00:00:41'],

['252 ==> Greenville, NC',8,'00:12:51','00:01:36'],

['254 ==> Waco, TX',1,'00:00:13','00:00:13'],

google visulization script


<script> 

    google.load('visualization', '1', {packages: ['table']});

    function drawVisualization() {

      // Create and populate the data table.

      var data = google.visualization.arrayToDataTable([

['<==outbound  -  inbound==>','Answered Calls','Tot Time','AVG Call'],

['000 ==> Bad000, zz',1,'00:00:58','00:00:58'],

['202 ==> District Of Columbia, DC',1,'00:00:52','00:00:52'],

...

['972 <== Dallas, TX',5,'00:12:45','00:02:33'],

['973 <== Newark, NJ',2,'00:01:15','00:00:38']

      ]);


thc="google-visualization-table-th";

c2 =0;

c3 =0;

var x1 = data.getNumberOfRows();

for (var i = 1; i < x1; i++) {

	c2 = c2+data.getValue(i, 1);

//	c3 = c3+data.getValue(i, 2);  

} 

tdiv = document.getElementById('totals');

tc="<table id=tot><tr><td  align='right' width='120px'></td><td  align='right' width='420px'>Calls = "+c2+

"</td><td align='right' width='20px'> <!-- hours=+c3.toFixed(2) -->"+

"</td><td align='right' width='20px'></td></tr></table>";

tdiv.innerHTML=tc;


    

      // Create and draw the visualization.

      var table = new google.visualization.Table(document.getElementById('visualization'));

    

      var formatter = new google.visualization.TableBarFormat({width: 420});

      formatter.format(data, 1); // Apply formatter to second column

    

      table.draw(data, {allowHtml: true, showRowNumber: true});

    }

    

    google.setOnLoadCallback(drawVisualization);

  </script>

</head>

<body style="font-family: Arial;border: 0 none;">

<center><h1>Area Codes Answered<br>Dec 2012 QAF - Upland</h1>

<h3>external calls</h3>

<div id=totals></div>

<div id="visualization" style="width: 900px; height: 1400px;font-size:20%;line-height:10px;"></div>


</center>


</body>

<style>

* {line-height:80%;}

tr {line-height:80%;}

.google-visualization-table-td:nth-of-type(1) {color:black;font-size:9px;text-align: left;}


table tr td span {height:8px;font-size:9px}

</style>



model


class RmDbCriteria extends CDbCriteria

{

    public function compare($column, $value, $partialMatch=false, $operator='AND', $escape=true, $nullSign='null', $betweenSign='-')

        {

                if(is_array($value))

                {

                        if($value===array())

                                return $this;

                        return $this->addInCondition($column,$value,$operator);

                }

                else

                        $value="$value";


                if(preg_match('/^(?:\s*([\w\d\s]*)(<>|<=|>=|<|>|=|'.$betweenSign.'))?(.*)$/',$value,$matches))

                {

                        $value1=$matches[1];

                        $value=$matches[3];            

                        $op=$matches[2];

                }

                else

                        $op='';


                if($value==='')

                        return $this;


                if($partialMatch)

                {

                       if($value==$nullSign)

                        {

                            $this->addCondition($column.' is null');

                           return $this;

                        }

                        if($op==='')

                                return $this->addSearchCondition($column,$value,$escape,$operator);

                        if($op==='<>')

                                return $this->addSearchCondition($column,$value,$escape,$operator,'NOT LIKE');

                        

                }

                else if($op==='')

                        $op='=';

        

        if($op==$betweenSign)

        {

            $this->addBetweenCondition($column,$value1,$value); 

            return $this;

        }

        

        

        if($value==$nullSign && $nullSign!='0')

        {

            $this->addCondition($column.' is null');

            return $this;

        }

        

        if($nullSign=='0')

        {

                $column='IFNULL('.$column.',0)';

        }

            

                $this->addCondition($column.$op.self::PARAM_PREFIX.self::$paramCount,$operator);

                $this->params[self::PARAM_PREFIX.self::$paramCount++]=$value;


                return $this;

        }

    

} 

class Cdr8 extends CActiveRecord

{

	/**

	 * Returns the static model of the specified AR class.

	 * @param string $className active record class name.

	 * @return Cdr8 the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 'cdr8';

	}


	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('calldate, channel, src, clid, dst, dstchannel, disposition, duration', 'required'),

			array('duration', 'numerical', 'integerOnly'=>true),

			array('calldate, channel, src, clid, dst, dstchannel, disposition', 'length', 'max'=>50),

			

			// The following rule is used by search().

			// Please remove those attributes that should not be searched.

			array('cdrid, calldate, channel, src, clid, dst, dstchannel, disposition, duration', 'safe', 'on'=>'search'),

		);

	}


	/**

	 * @return array relational rules.

	 */

	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

		);

	}


	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'cdrid' => 'Cdrid',

			'calldate' => 'Calldate',

			'channel' => 'Channel',

			'src' => 'Src',

			'clid' => 'Clid',

			'dst' => 'Dst',

			'dstchannel' => 'Dstchannel',

			'disposition' => 'Disposition',

			'duration' => 'Duration',

		);

	}


	/**

	 * Retrieves a list of models based on the current search/filter conditions.

	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.

	 */

	public function search()

	{




		// Warning: Please modify the following code to remove attributes that

		// should not be searched.


		$criteria=new RmDbCriteria; //CDbCriteria;

// $criteria->limit = 25;


		$criteria->compare('cdrid',$this->cdrid);

		$criteria->compare('calldate',$this->calldate,true);

		$criteria->compare('channel',$this->channel,true);

		$criteria->compare('src',$this->src,true);

		$criteria->compare('clid',$this->clid,true);

		$criteria->compare('dst',$this->dst,true);

		$criteria->compare('dstchannel',$this->dstchannel,true);

		$criteria->compare('disposition',$this->disposition,true);

		$criteria->compare('duration',$this->duration);


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}

}

hi andy why dont you pull the data first and then construct an array of object, some caching would help perhaps

currently doing that externally to yii so static pages are generated by loading my generator

was trying to see if this could be done with AR in yii framework

my automated report generator includes the following sql in the arrays middle

1st runs a query off my rpttable recusively

generating and saving this type of barCharts based on teleExt, staff name joined to the details. providing all the variables this query

[sql]$sql = “SELECT concat(\”[’\","

. &quot; concat(&quot;


.&#036;table2


.&quot;.ext,	&#092;&quot; &#092;&quot;,	&quot;


.&#036;table2


.&quot;.name&quot;


.&quot;),&quot;


. &quot;&#092;&quot;',&#092;&quot;,&quot;


. &quot; count(&quot;.&#036;sd.&quot;), &#092;&quot; &#092;&quot;,&quot;


. &quot;&#092;&quot;,&#092;&quot;, &quot;


. &quot; (sum(`duration`)/3600), &quot;


. &quot;&#092;&quot;,&#092;&quot;, &quot;


. &quot;round((avg(`duration`)/60),2),&quot;


. &quot;&#092;&quot;],&#092;&quot;) as &#092;&quot;['Staff','&quot;.&#036;io.&quot; calls','Hours','avg Minutes'],&#092;&quot;&quot;


. &quot;FROM `&#036;table1` &quot;


. &quot; LEFT OUTER JOIN &#036;table2 &quot;


. &quot;ON &#036;sd = &#036;table2.Ext &quot;


. &quot;WHERE &#092;n&quot;


. &quot;left(`calldate`,7) = '&quot;.&#036;rmy.&quot;' and &quot;


. &quot;`disposition` = 'ANSWERED' and &quot;


. &quot;duration &#036;dur and &quot;


. &quot;length(&quot;.&#036;sd.&quot;)= 4 and &quot;


. &quot;length(&quot;.&#036;ds.&quot;) &gt; 6 and &quot;


. &quot;dst REGEXP '^-?[0-9]+&#036;' and &quot;


. &#036;sd.&quot; between '&quot;.&#036;Ext1.&quot;' and '&quot;.&#036;Ext2.&quot;' &quot;


. &quot;group by &quot;.&#036;sd


. &quot; order by &quot;.&#036;sd. &quot; asc&quot;; 	 	


&#036;data   = mysql_query(&#036;sql,&#036;conn); 


&#036;num    = mysql_num_rows(&#036;data);


for (&#036;i = 0; &#036;i &lt; &#036;num; &#036;i++) {


 &#036;row = mysql_fetch_row(&#036;data);


 echo &#036;row[0].'

';

}

[/sql]

supplies report headings/duration info/ date selections as well as html title and filename and writes staic pages with this bit of code


  $page = ob_get_contents();

   ob_end_clean();

   $cwd = getcwd();

   $file = "$cwd/rpts/$rptHead.html";

  @chmod($file,0755);

   $fw = fopen($file, "w");

   fputs($fw,$page, strlen($page));

   fclose($fw);

   $rptid++;

   $me=$_SERVER['PHP_SELF']."?rptid=$rptid&rptcnt=$rptcnt";

  echo ">$me<";

  if ($rptid <= $rptcnt){

      echo ">$me<";

      header("Location: $me");}

  else { die();

  }