yii CDbCriteria Join Column not found - mysql

I've been struggling with converting the following SQL to CDBCriteria to be used with a CActiveDataProvider:
"SELECT PresetDeviceLink., Device. FROM PresetDeviceLink INNER JOIN Device ON Device.id = PresetDeviceLink.deviceId WHERE Device.roomId = 1"
Table structure is as follows:
mysql> describe PresetDeviceLink;
+----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| presetId | int(11) | NO | | NULL | |
| deviceId | int(11) | NO | | NULL | |
| state | int(11) | NO | | 0 | |
| value | int(11) | NO | | 32 | |
+----------+---------+------+-----+---------+----------------+
mysql> describe Device;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| ref | int(11) | NO | | NULL | |
| roomId | int(11) | NO | | NULL | |
| typeId | int(11) | NO | | NULL | |
| paired | tinyint(1) | NO | | 0 | |
| name | varchar(255) | YES | | NULL | |
| description | text | YES | | NULL | |
| dimmerPos | int(11) | NO | | 0 | |
+-------------+--------------+------+-----+---------+----------------+
My code in my controller is as follows:
$criteria = new CDbCriteria;
$criteria->select = 'PresetDeviceLink.*, Device.*';
$criteria->join = 'INNER JOIN Device ON Device.id = PresetDeviceLink.deviceId';
$criteria->condition = 'Device.roomId = 1';
$presetDeviceLink=new CActiveDataProvider('PresetDeviceLink', array(
'criteria' => $criteria,
));
When run I get the following error:
CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: <b>Column not
found</b>: 1054 Unknown column 'PresetDeviceLink.deviceId' in 'on clause'. The SQL
statement executed was: SELECT COUNT(*) FROM `PresetDeviceLink` `t` INNER JOIN
Device ON Device.id = PresetDeviceLink.deviceId WHERE Device.roomId = 1
The strange thing is, If I use 'Device' as the CActiveDataProvider source and change the join statement to join to 'PresetDeviceLink', it then complains that the Device.roomId column could not be found.
Do I just not understand how CActiveDataProvider works? It looks to me that I can only use a condition (in a join or where clause) from a field in the table that I pass to the CActiveDataProvider. Any advice?
PS - the SQL query works beautifully in the MySQL console.
Thanks in advance,
Ben

As is visible in the "The SQL statement executed was:" line, the first table was aliased to t. This is Yii's standard behaviour.
As a result of this, you should use that alias to refer to that table instead of PresetDeviceLink. Or you could try setting $criteria->alias = 'PresetDeviceLink'; before using it in the CActiveDataProvider, though I have not personally tried that option, it should work.

Related

postgresql returns null but mysql doesn't

I have an application for which I am migrating from Mysql to Psql.
I have three tables t1,t2,t3 described below . Table t3 will always have a entry as long as user is available , but both table t1 and t2 may or may not have entry if the user doesn't create DB in his account.
While executing q1 in mysql , I get result set containing values fetched from table t3, even if t1 and t2 doesn't have entry , but it returns null in psql . So I've written two queries pq1 and pq2 to be equivalent to q1 . What is the reason that mysql doesn't return null values but psql does? Is there any better solution to this than breaking down into two queries for psql ?
mysql query (q1)
select
COALESCE(sum(dr.NO_OF_QT),0),
ur.NO_OF_USERS, ur.NO_OF_DB, 0,
COALESCE(sum(dr.NO_OF_SM),0),
COALESCE(sum(dr.NO_OF_RPTS),0)
from DataBaseProps dr
left join DataBaseDetails db on dr.DB_ID=db.ID and db.STATUS=1
left join UserProps ur on db.OWNER_UID=ur.USER_UID
where ur.USER_UID='USER_UID'
Psql-query_1 (pq1)
select
COALESCE(sum(dr.NO_OF_QT),0),
0,0, 0,
COALESCE(sum(dr.NO_OF_SM),0),
COALESCE(sum(dr.NO_OF_RPTS),0)
from DataBaseProps dr
left join DataBaseDetails db on dr.DB_ID=db.ID and db.STATUS=1
left join UserProps ur on db.OWNER_UID=ur.USER_UID
where ur.USER_UID='USER_UID'
psql-query_2(pq2)
select NO_OF_USERS,NO_OF_DB from UserProps
where USER_UID='USER_UID'
Table 1 DataBaseProps (t1)
desc DataBaseProps >
+-----------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+------------+------+-----+---------+-------+
| DB_ID | bigint(19) | NO | PRI | NULL | |
| NO_OF_RPTS | int(10) | YES | | 0 | |
| NO_OF_QT | int(10) | YES | | 0 | |
| NO_OF_SM | int(10) | YES | | 0 | |
+-----------------+------------+------+-----+---------+-------+
Table 2 - DataBaseDetails(t2)
desc DataBaseDetails>
+-------------------+--------------+------+-----+-----------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+-----------------+-------+
| ID | bigint(19) | NO | PRI | NULL | |
| NAME | varchar(50) | NO | | NULL | |
| STATUS | int(10) | NO | | 1 | |
| OWNER_UID | bigint(19) | NO | | NULL | |
+-------------------+--------------+------+-----+-----------------+-------+
Table 3 UserProps(t3)
desc UserProps>
+-----------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+------------+------+-----+---------+-------+
| USER_UID | bigint(19) | NO | PRI | NULL | |
| NO_OF_DB | int(10) | YES | | 0 | |
| NO_OF_USERS | int(10) | YES | | 0 | |
+-----------------+------------+------+-----+---------+-------+

mysql UPDATE says column cannot be null. Why is it null?

I have a join table called carriers_rects that looks like this:
+------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| carrier_id | int(11) unsigned | NO | | NULL | |
| rect_id | int(11) unsigned | NO | | NULL | |
+------------+------------------+------+-----+---------+----------------+
I also have a rects table that looks like this:
+---------+-------------+------+-----+----------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+----------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(54) | NO | | new rect | |
| width | varchar(54) | NO | | NULL | |
| length | varchar(54) | NO | | NULL | |
| rounded | tinyint(1) | NO | | NULL | |
| xx | varchar(54) | NO | | NULL | |
| yy | varchar(54) | NO | | NULL | |
| height | varchar(54) | NO | | NULL | |
+---------+-------------+------+-----+----------+----------------+
I am trying to add a case_id column to rects and just make it a one-to-many relationship and kill the carriers_rects table. We are moving our DB and we never used the many-to-many relationship.
So I added the case_id column to rects:
alter table rects add case_id int(11) not null;
Then I tried to update the case_id on the rects with all the case_id's that would match from the carriers_rects table.
update rects set case_id = (select carrier_id from carriers_rects where rect_id = id);
I am getting column case_id cannot be null.
I tested to see if there where any nulls and I can't seem to find any.
select * from (select * from carriers_rects where rect_id IN(select id from rects)) `b` where id is null;
I also tried it the other way around because honestly I am a little confused.
select id from rects where id IN(select rect_id from carriers_rects)
Clearly I am not a sql genius. But would love to be schooled here.
Not sure why I am getting the error mentioned above.
What if you change to a update-join syntax rather than using subquery like
update rects r
join carriers_rects cr on cr.rect_id = r.id
set r.case_id = cr.carrier_id
where cr.carrier_id is not null;
The main reason of this error is in your inner query condition rect_id = id . They both are from carriers_rects (it means carriers_rects.rect_id = carriers_rects.id) so you get null. Change it to rect_id = rects.id
update rects set case_id =
(select carrier_id from carriers_rects where rect_id = rects.id);

Query returning multiple objects when only one is expected

I have a simple table:
+-------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+-------+
| ID | bigint(20) | NO | PRI | NULL | |
| AdmissionDateTime | datetime | NO | | NULL | |
| AdmissionEvent | varchar(255) | YES | | NULL | |
| DischargeDateTime | datetime | YES | | NULL | |
| DischargeEvent | varchar(255) | YES | | NULL | |
| DemographicId | bigint(20) | NO | MUL | NULL | |
| FacilityId | bigint(20) | YES | MUL | NULL | |
| VisitId | bigint(20) | NO | MUL | NULL | |
| WardId | bigint(20) | NO | MUL | NULL | |
+-------------------+--------------+------+-----+---------+-------+
On which I run the following JPA (Spring-data) query:
#Query("SELECT w FROM WardTransaction w WHERE w.id = (SELECT MAX(x.id) FROM
WardTransaction x WHERE w = x AND w.visit = :visit)")
public WardTransaction findCurrent(#Param("visit") Visit visit);
On occasions I get the following exception.
org.springframework.dao.IncorrectResultSizeDataAccessException: More than one
result was returned from Query.getSingleResult(); nested exception is
javax.persistence.NonUniqueResultException: More than one result was returned from
Query.getSingleResult()
I have not been able to work out why this is happening. It does not seem to make a lot of sense to me as there can only be one 'MAX' - especially on Id (I have used 'admissionDate' in the past).
Any assistance appreciated.
why are you selecting table ? you should select columns .
try this
#Query("SELECT * FROM WardTransaction w WHERE w.id in (SELECT MAX(x.id)
FROM WardTransaction x WHERE w.id = x.id AND w.visit = :visit)")
This query is simpler and I think would get you what you want:
SELECT something
FROM sometable
Where something = someotherthing
ORDER BY sometable.id DESC
LIMIT 1
Basically it returns the results with the highest IDs at the top and grabs the first one.

ERROR 1093 (HY000): You can't specify target table 'a' for update in FROM clause

I have this query
UPDATE trh_adminLoginDate SET superseded = true WHERE EXISTS
(SELECT * FROM trh_adminLoginDate AS a2 WHERE a2.adminId = a.adminId AND a2.loginDate > a.loginDate AND a2.clientPlatform = a.clientPlatform)
and table look like this.
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| dateCreated | datetime | NO | | NULL | |
| version | int(11) | NO | | NULL | |
| dateModified | datetime | NO | | NULL | |
| adminId | bigint(20) | NO | MUL | NULL | |
| clientPlatform | varchar(255) | YES | | NULL | |
| loginDate | datetime | YES | | NULL | |
| superseded | tinyint(1) | NO | | NULL | |
+----------------+--------------+------+-----+---------+----------------+
When I execute this query I get the below error:
ERROR 1093 (HY000): You can't specify target table 'a' for update in FROM clause
I can create temporary table and keep the result of the sub-query and then do the UPDATE. But I don't want to do in this way. Can someone suggest me better way of doing this?
You are using the alias "a" but you never define it.
Perhaps this would work:
UPDATE trh_adminLoginDate a
JOIN trh_adminLoginDate AS a2
ON a2.adminId = a.adminId
AND a2.loginDate > a.loginDate
AND a2.clientPlatform = a.clientPlatform
SET a.superseded = true
Or perhaps this will do the trick:
UPDATE trh_adminLoginDate a
SET superseded = true
WHERE EXISTS
(SELECT * FROM trh_adminLoginDate WHERE adminId = a.adminId AND loginDate > a.loginDate AND clientPlatform = a.clientPlatform)

Updating table using group by sum

I have two tables. One is a detail table that contains quantity info and has the following structure
> mysql> DESCRIBE summary_finished;
+---------------+---------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+---------------+---------------+------+-----+---------+
| db_id | int(11) | NO | PRI | NULL |
| finished_id | text | NO | | NULL |
| finished_name | text | NO | | NULL |
| qoh | int(11) | NO | | NULL |
| value | decimal(10,2) | NO | | NULL |
+---------------+---------------+------+-----+---------+
mysql> DESCRIBE detail_finished;
+-------------+---------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+-------------+---------------+------+-----+---------+
| db_id | int(11) | NO | PRI | NULL |
| finished_id | text | NO | | NULL |
| quantity | int(11) | NO | | NULL |
| value | decimal(10,2) | NO | | NULL |
+-------------+---------------+------+-----+---------+
In detail_finished there are many items that have the same finished_id. What I am trying to accomplish is combining items that have the same finished_id and update that sum to the summary_finished.qoh field. This is what I have so far:
function set_qty($total, $finished_id){
global $connection;
$query="UPDATE summary_finished
SET qoh={$total}
WHERE finished_id='$finished_id'";
$quantity=mysql_query($query, $connection);
confirm_query($quantity);
}
$query="SELECT finished_id, SUM(quantity) FROM detail_finished GROUP BY finished_id";
$result=mysql_query($query, $connection) or die(mysql_error());
while($row = mysql_fetch_array($result)){
set_qty($row['SUM(quantity)'], $row['finished_id']);
}
I know the sums are calculating correctly as I can echo them straight out, however I cannot get my table to update. Forgive me for the sloppy code I am very new with mysql entirely. Thank you in advance for the help.
I don't know why you use text type to store id. By the way
update summary_finished as sf
inner join (
select finished_id,
sum(quantity) as total
from detail_finished
group by finished_id )as t
set sf.qoh = t.total
where sf.finished_id = t.finished_id