Codeigniter Group by last record - codeigniter

Say i have 3 or 4 table which some table are connected with parent table. I want to show group by last record.
Table: table1
--------------------------------------------------------------------
| table1Id(AI)(PK) | date | tagid | blah3 | blah3 | blah4 |
--------------------------------------------------------------------
1 | 2016-05-01 | 101 |
2 | 2016-05-04 | 102 |
3 | 2016-05-10 | 101 |
4 | 2016-05-15 | 101 |
5 | 2016-05-04 | 103 |
6 | 2016-05-20 | 101 |
But when i do query group by tagid it will retrieve first row
--------------------------------------------------------------------
| table1Id(AI)(PK) | date | tagid | blah3 | blah3 | blah4 |
--------------------------------------------------------------------
1 | 2016-05-04 | 101 |
2 | 2016-05-04 | 102 |
5 | 2016-05-04 | 103 |
What i want to look like this
--------------------------------------------------------------------
| table1Id(AI)(PK) | date | tagid | blah3 | blah3 | blah4 |
--------------------------------------------------------------------
6 | 2016-05-20 | 101 |
2 | 2016-05-04 | 102 |
5 | 2016-05-04 | 103 |
My query like this
$this->db->select('*');
$this->db->from('tablename1');
$this->db->join('tablename2', 'tablename2.tagid= tablename1.tagid', 'left');
$this->db->group_by('tablename1.tagId, tablename2.tagId');
$this->db->order_by('tablename1.tagId','asc');

Use sub query. See below code
$this->db->select('*');
$this->db->from('tablename1');
$this->db->order_by('table1Id','DESC');
$subquery = $this->db->get_compiled_select();
$this->db->select('*');
$this->db->from('('.$subquery.') a');
$this->db->join('tablename2', 'tablename2.tagid= a.tagid', 'left');
$this->db->group_by('a.tagId, tablename2.tagId');
$this->db->order_by('a.tagId','asc');

Related

How to store data by increment by +1 every time stored

This is my product table.I want to store customer_id from 1000 and save by +1 how much data i stored
id | customer_id | name |
1 | 1000 | ABC |
2 | 1001 | Tripathi |
3 | 1002 | Leaptrig |
4 | 1003 | Falcon |
5 | 1004 | Savillan |
6 | 1005 | Molt |
7 | 1006 | Falt |
My Controller
$lastProduct=Product::pluck('customer_id')->last();
$product=new Product();
$product->name=$request->name;
if($lastProduct){
$product->customer_id=1000+($lastProduct+1);
}
$product->save();
But In this code,Customer id i increment by 1000 2001,3002 like this. so how should i avoid it ?
id | customer_id | name |
1 | 1000 | ABC |
2 | 2001 | Tripathi |
3 | 3002 | Leaptrig |
4 | 4003 | Falcon |
5 | 5004 | Savillan |
6 | 6005 | Molt |
7 | 7006 | Falt |
You can try this :-
$lastProduct=Product::pluck('customer_id')->last();
$product=new Product();
$product->name=$request->name;
if($lastProduct){
$product->customer_id=$lastProduct+1;
}
$product->save();

Laravel Eloquent groupBy orderBy gives different results in MariaDB

I have read about this already in SO and MariaDB knowledgeable about this incompatibility between Mysql and Mariadb. But I am not sure how to resolve this issue in Laravel Eloquent / DB queries.
My Problem: The groupBy orderBy query gives different results in MariaDB and MySql. It works fine in mySql by the results are in different order in MariaDB.
This is my query:
$messages = ChatMessages::select(DB::raw('t.*'))
->from(DB::raw('(SELECT * FROM chat_messages ORDER BY created_at DESC) t'))
->whereIn('message_id', $messageIds)
->groupBy('message_id')
->orderBy('created_at', 'DESC')
->paginate(3);
For example, lets say this is the chat_messages table:
+----+----------+---------------------+-----------+
| id | message_id | created_at | name |
+----+----------+---------------------+-----------+
| 1 | 1000 | 2017-01-01 06:03:40 | Anna |
+----+----------+---------------------+-----------+
| 2 | 1007 | 2017-01-02 07:13:20 | Becky |
+----+----------+---------------------+-----------+
| 3 | 1000 | 2017-01-03 08:20:12 | Christina |
+----+----------+---------------------+-----------+
| 4 | 1004 | 2017-01-03 08:20:15 | Dorothy |
+----+----------+---------------------+-----------+
| 5 | 1004 | 2017-01-04 09:25:45 | Emma |
+----+----------+---------------------+-----------+
| 6 | 1000 | 2017-01-05 10:30:10 | Fiona |
+----+----------+---------------------+-----------+
| 7 | 1007 | 2017-01-05 10:33:23 | Gigi |
+----+----------+---------------------+-----------+
| 8 | 1007 | 2017-01-06 12:46:34 | Heidi |
+----+----------+---------------------+-----------+
| 9 | 1000 | 2017-01-06 12:46:34 | Irene |
+----+----------+---------------------+-----------+
| 10 | 1007 | 2017-01-07 14:58:37 | Jane |
+----+----------+---------------------+-----------+
| 11 | 1007 | 2017-01-07 14:58:37 | Katy |
+----+----------+---------------------+-----------+
The query works fine in MySql database and the results are returned as this:
+----+----------+---------------------+-----------+
| id | message_id | created_at | name |
+----+----------+---------------------+-----------+
| 11 | 1007 | 2017-01-07 14:58:37 | Katy |
+----+----------+---------------------+-----------+
| 9 | 1000 | 2017-01-06 12:46:34 | Irene |
+----+----------+---------------------+-----------+
| 5 | 1004 | 2017-01-04 09:25:45 | Emma |
+----+----------+---------------------+-----------+
However, in MariaDB database, the results are returned incorrectly like this. It seems to group the message_id in ascending order first and then adding the orderBy to that:
+----+----------+---------------------+-----------+
| id | message_id | created_at | name |
+----+----------+---------------------+-----------+
| 4 | 1004 | 2017-01-03 08:20:15 | Dorothy |
+----+----------+---------------------+-----------+
| 2 | 1007 | 2017-01-02 07:13:20 | Becky |
+----+----------+---------------------+-----------+
| 1 | 1000 | 2017-01-01 06:03:40 | Anna |
+----+----------+---------------------+-----------+
I tried changing the query thought of using unique() instead like this:
ChatMessages::whereIn('message_id', $messageIds)
->orderBy('created_at', 'DESC')
->paginate(3)
->unique('message_id');
Although it works in MariaDB and MySql the same way, but the pagination is applied before the unique check and therefore returned lesser results:
+----+----------+---------------------+-----------+
| id | message_id | created_at | name |
+----+----------+---------------------+-----------+
| 11 | 1007 | 2017-01-07 14:58:37 | Katy |
+----+----------+---------------------+-----------+
| 9 | 1000 | 2017-01-06 12:46:34 | Irene |
+----+----------+---------------------+-----------+
How can I resolve this?
You are probabbly trying to do a "groupwise max". This can no longer be done by the trick of having a subquery with an ORDER BY.
A subquery, but definition, has no order. However, in the past, both MariaDB and MySQL would perform the ORDER BY, and that happened to be beneficial to the outer query.
MariaDB was first to ignore the inner ORDER BY; MySQL picked up on it later. Follow the tag [greatest-n-per-group] for various workarounds.

Proxysql - Please help me clarify "chains of rules" feature

I'm newbie with proxysql, this my enviroment:
Centos 7 , proxysql-1.4.13 . I define 2 host group ids : host group id 2 for mysql server that can write , host group id 3 for mysql server that can read.
All queries that begin with insert, update, delete, alter should be routed to host group id 2.
All queries that begin with select should be routed to host group id 3.
So here are my rules :
Admin> select rule_id,active,digest,match_digest,destination_hostgroup,flagIN,flagOUT,next_query_flagIN,sticky_conn,apply from mysql_query_rules;
+---------+--------+--------------------+--------------+-----------------------+--------+---------+-------------------+-------------+-------+
| rule_id | active | digest | match_digest | destination_hostgroup | flagIN | flagOUT | next_query_flagIN | sticky_conn | apply |
+---------+--------+--------------------+--------------+-----------------------+--------+---------+-------------------+-------------+-------+
| 101 | 1 | NULL | ^insert | 2 | 0 | NULL | NULL | NULL | 1 |
| 102 | 1 | NULL | ^update | 2 | 0 | NULL | NULL | NULL | 1 |
| 103 | 1 | NULL | ^delete | 2 | 0 | NULL | NULL | NULL | 1 |
| 104 | 1 | NULL | ^alter | 2 | 0 | NULL | NULL | NULL | 1 |
| 105 | 1 | NULL | ^select | 3 | 0 | NULL | NULL | NULL | 1 |
+---------+--------+--------------------+--------------+-----------------------+--------+---------+-------------------+-------------+-------+
And they works fine. By the way, are these rules ok ? Should I replace match_digest by match_pattern ?
However , my application has 1 feature that insert data into a table (create booking) then select (almost immediately) new data from that table .
So if select query fails (because new data has not replicated to host group id 3 yet), application feature will run wrong.
I want to route the select query right after insert query to host group id 2 so it will get new data successfully.
I read proxysql document https://github.com/sysown/proxysql/wiki/Main-(runtime)#mysql_query_rules and this discussion https://github.com/sysown/proxysql/pull/825 , I think this is solution for me ,isn't it ? I still don't understand about these flagIN,flagOUT,next_query_flagIN,sticky_conn stuff clearly but I will give it a try.
I know the insert query digest is 0xCDD6DB677604AFA7
The select query digest is 0x0DCD2E8ADF6A66CB
Then I add 2 new rules:
Admin> select rule_id,active,digest,match_digest,destination_hostgroup,flagIN,flagOUT,next_query_flagIN,sticky_conn,apply from mysql_query_rules;
+---------+--------+--------------------+--------------+-----------------------+--------+---------+-------------------+-------------+-------+
| rule_id | active | digest | match_digest | destination_hostgroup | flagIN | flagOUT | next_query_flagIN | sticky_conn | apply |
+---------+--------+--------------------+--------------+-----------------------+--------+---------+-------------------+-------------+-------+
| 1 | 1 | 0xCDD6DB677604AFA7 | NULL | 2 | 0 | NULL | 1 | 1 | 1 |
| 2 | 1 | 0x0DCD2E8ADF6A66CB | NULL | 2 | 1 | NULL | NULL | NULL | 1 |
| 101 | 1 | NULL | ^insert | 2 | 0 | NULL | NULL | NULL | 1 |
| 102 | 1 | NULL | ^update | 2 | 0 | NULL | NULL | NULL | 1 |
| 103 | 1 | NULL | ^delete | 2 | 0 | NULL | NULL | NULL | 1 |
| 104 | 1 | NULL | ^alter | 2 | 0 | NULL | NULL | NULL | 1 |
| 105 | 1 | NULL | ^select | 3 | 0 | NULL | NULL | NULL | 1 |
+---------+--------+--------------------+--------------+-----------------------+--------+---------+-------------------+-------------+-------+
They work fine, the select query right after insert query is route to host group id 2 so it gets new data successfully and application feature runs ok.
But am I doing right ?
I'm confused because stats_mysql_query_rules result:
Before application feature run:
Admin> select * from stats_mysql_query_rules;
+---------+------+
| rule_id | hits |
+---------+------+
| 1 | 20 |
| 2 | 20 |
| 101 | 33 |
| 102 | 0 |
| 103 | 2 |
| 104 | 0 |
| 105 | 903 |
+---------+------+
After application feature run (10 bookings):
Admin> select * from stats_mysql_query_rules;
+---------+------+
| rule_id | hits |
+---------+------+
| 1 | 30 |
| 2 | 30 |
| 101 | 43 |
| 102 | 0 |
| 103 | 2 |
| 104 | 0 |
| 105 | 1313 |
+---------+------+
Why rule_id 101 hits rate increase from 33 --> 43 ? So rule_id 101 (match_digest ^insert) also match insert query in application feature ? Does it mean I'm doing wrong ?

Laravel Select unique count with groupBy

I am trying to get the count of unique batches in gift_code table for each campaign. The gift_code table is joined to campaign table by campaign_id.
Here is some sample data for campaign table.
--------------+--------------
|campaign_id | name |
--------------+--------------
| 1 | abc |
--------------+--------------
| 2 | xyz |
--------------+--------------
Below is some sample data for gift_code table.
--------------+------------------------+--------------+
|gift_code_id | campaign_id | batch | unique_code |
--------------+-------------+----------+---------------
| 1 | 1 | 1 | zxc23 |
--------------+-------------+----------+--------------+
| 2 | 1 | 2 | rtc26 |
--------------+-------------+----------++-------------+
| 3 | 2 | 1 | z8723 |
--------------+-------------+----------+--------------+
| 4 | 2 | 2 | h7c26 |
--------------+-------------+----------++-------------+
| 5 | 2 | 2 | rrcf6 |
--------------+-------------+----------++-------------+
| 6 | 2 | 3 | r7y28 |
--------------+-------------+----------++-------------+
| 7 | 2 | 3 | bnc26 |
--------------+-------------+----------++-------------+
$campaign = DB::table('campaign')
->select('campaign.*', DB::raw('count(gift_code.batch) as batch_count')->groupBy('gift_code.campaign_id')->groupBy('gift_code.batch'))
->leftjoin('gift_code', 'campaign.campaign_id', '=', 'gift_code.campaign_id')
->get();
My expected results are:
--------------+-------------------------+
|campaign_id | name |batch_count|
--------------+-------------+-----------+
| 1 | abc | 2 |
--------------+-------------+-----------+
| 2 | xyz | 3 |
--------------+-------------+-----------+
Try below query
$data = \DB::table('campaign as c')
->leftJoin('gift_code as gc','c.campaign_id','=','gc.campaign_id')
->select('c.*',\DB::raw('COUNT(distinct(gc.batch)) as batch_count'))
->groupBy('c.campaign_id')
->get();

Determinate unique values from oracle join?

I need a way to avoid duplicate values from oracle join, I have this scenario.
The first table contain general information about a person.
+-----------+-------+-------------+
| ID | Name | Birtday_date|
+-----------+-------+-------------+
| 1 | Byron | 12/10/1998 |
| 2 | Peter | 01/11/1973 |
| 4 | Jose | 05/02/2008 |
+-----------+-------+-------------+
The second table contain information about a telephone of the people in the first table.
+-------+----------+----------+----------+
| ID |ID_Person |CELL_TYPE | NUMBER |
+-------+- --------+----------+----------+
| 1221 | 1 | 3 | 099141021|
| 2221 | 1 | 2 | 099091925|
| 3222 | 1 | 1 | 098041013|
| 4321 | 2 | 1 | 088043153|
| 4561 | 2 | 2 | 090044313|
| 5678 | 4 | 1 | 092049013|
| 8990 | 4 | 2 | 098090233|
+----- -+----------+----------+----------+
The Third table contain information about a email of the people in the first table.
+------+----------+----------+---------------+
| ID |ID_Person |EMAIL_TYPE| Email |
+------+- --------+----------+---------------+
| 221 | 1 | 1 |jdoe#aol.com |
| 222 | 1 | 2 |jdoe1#aol.com |
| 421 | 2 | 1 |xx12#yahoo.com |
| 451 | 2 | 2 |dsdsa#gmail.com|
| 578 | 4 | 1 |sasaw1#sdas.com|
| 899 | 4 | 2 |cvcvsd#wew.es |
| 899 | 4 | 2 |cvsd#www.es |
+------+----------+----------+---------------+
I was able to produce a result like this, you can check in this link http://sqlfiddle.com/#!4/8e326/1
+-----+-------+-------------+----------+----------+----------+----------------+
| ID | Name | Birtday_date| CELL_TYPE| NUMBER |EMAIL_TYPE|EMAIL|
+-----+-------+-------------+----------+----------+----------+----------------+
| 1 | Byron | 12/10/1998 | 3 | 099141021|1 |jdoe#aol.com |
| 1 | Byron | 12/10/1998 | 2 | 099091925|2 |jdoe1#aol.com |
| 1 | Byron | 12/10/1998 | 1 | 099091925| | |
| 2 | Peter | 01/11/1973 | 1 | 088043153|1 |xx12#yahoo.com |
| 2 | Peter | 01/11/1973 | 2 | 090044313|2 |dsdsa#gmail.com |
| 4 | Jose | 05/02/2008 | 1 | 092049013|1 |sasaw1#sdas.com |
| 4 | Jose | 05/02/2008 | 2 | 098090233|2 |cvcvsd#wew.es |
+-----+-------+-------------+----------+----------+----------+----------------+
If you check the data in table Email for user with ID_Person = 4 only present two of the three emails that have, the problem for this case is the person have more emails that cellphone numbers and only will present the same number of the cellphone numbers.
The result i expected is something like this.
+-----+-------+-------------+----------+----------+----------+----------------+
| ID | Name | Birtday_date| CELL_TYPE| NUMBER |EMAIL_TYPE|EMAIL|
+-----+-------+-------------+----------+----------+----------+----------------+
| 1 | Byron | 12/10/1998 | 3 | 099141021|1 |jdoe#aol.com |
| 1 | Byron | 12/10/1998 | 2 | 099091925|2 |jdoe1#aol.com |
| 1 | Byron | 12/10/1998 | 1 | 099091925| | |
| 2 | Peter | 01/11/1973 | 1 | 088043153|1 |xx12#yahoo.com |
| 2 | Peter | 01/11/1973 | 2 | 090044313|2 |dsdsa#gmail.com |
| 4 | Jose | 05/02/2008 | 1 | 092049013|1 |sasaw1#sdas.com |
| 4 | Jose | 05/02/2008 | 2 | 098090233|2 |cvcvsd#wew.es |
| 4 | Jose | 05/02/2008 | | |2 |cvsd#www.es |
+-----+-------+-------------+----------+----------+----------+----------------+
This is the way that i need to present the data.
I could not understand why your query was so complex, thus, added the simple full outer join and it seems to be working:
select distinct p.id, p.name,
case when Lag(CELL) over(partition by p.id order by p.id,pe.id) = CELL then null else cell_type end as cell_type,
case when Lag(CELL) over(partition by p.id order by p.id,pe.id) = CELL then null else CELL end as CELL,
EMAIL_TYPE as EMAIL_TYPE, EMAIL as EMAIL
from person p full outer join phones pe on p.id = pe.id
full outer join emails e
on p.id = e.id and pe.cell_type = e.email_type;

Resources