How can I UPDATE Table A in MySQL joining another table? - mysql

I have a stats table that has a user_id.
I have a users table with an id that corresponds to the above user_id. I also have an employee flag in the users table.
I want to update all records in the stats table where the user_id is not that of an employee.
Ideally, I'd like to do this via the CodeIgniter Active Record, but I'm fine with a raw query as well.
Thanks!
EDIT My attempt
if($employee == false) {
$this->db->where('(default_profiles.opid = 0 OR default_profiles.opid IS NULL)');
} else {
$this->db->where('default_profiles.opid > 0');
}
$this->db->join('weekly_stats', 'default_weekly_stats.user_id = default_profiles.user_id');
$this->db->update('default_weekly_stats', $data);
However, this just yields:
UPDATE `default_weekly_stats` SET `rank` = 1 WHERE `default_weekly_stats`.`week` = '1' AND `default_weekly_stats`.`correct_picks` = '4' AND (default_profiles.opid = 0 OR default_profiles.opid IS NULL)

Haven't tried it but maybe it should be like this:
$this->db->where_not_in('users.employee_flag', '0')->join('users', 'users.user_id = stats.user_id')->update('stats', $data);
EDIT: ( based on #dianuj answer )
$this->db->set('rank', $rank );
if($employee == false) {
$this->db->where('(default_profiles.opid = 0 OR default_profiles.opid IS NULL)');
} else {
$this->db->where('default_profiles.opid > 0');
}
$this->db->update('weekly_stats ON default_weekly_stats.user_id = default_profiles.user_id');

update stats s
inner join users u on u.id = s.user_id
and u.employee = 0
set some_column = 'some_value'

Related

Yii2 user profile

ok so one time i use yii2 with 1 table of user and 1 table of profile(admin,user) and was easy when i connected to the DB, but now i have 3 table of user and when i try to connect it to the DB i have problem...with the function findIdentity
public static function findIdentity($id)
{
$users = Administrador::find()->where(['id_admin'=>$id])->one();
if(!count($users)){
return null;
}
else{
//this->password=$users->passwd;
return new static($users);
}
//return isset(self::$users[$id]) ? new static(self::$users[$id]) : null;
}
as you can see in $users = Administrador::find() i have the name of the table "Administrador" but i want to search the id of the others table too, help please
btw my other 2 table are "contador" and "mecanico" which the id is "id_cont" for contador and "id_mec" for mecanico
Option 1
Add libraries to top of script file:
use someloc/model/Administrator;
use someloc/model/Contador;
use someloc/model/Mecanico
Then:
$users1 = Administrador::find()->where(['id_admin'=>$id])->one();
$users2 = Contador::find()->where(['id_admin'=>$id])->one();
$users3 = Mecanico::find()->where(['id_admin'=>$id])->one();
if (count($users1)) {
return $user1;
} elseif (count($users2)) {
return $user2;
} elseif (count($users3)) {
return $user3;
} else {
....
}
Option 2
Use createCommand in order to use custome SQL statement.
Note: the following query joins results of two tables together.
$sql = "
SELECT
userid
, field2
FROM
(
SELECT
t1.user_id AS userid
, anotherfield AS field2
FROM
table1 t1
UNION
SELECT
t1.user_id AS userid
, anotherfield AS field2
FROM
table2 t2
) x
WHERE
user_id = :user_id
";
$params = [':user_id' => $user_id];
$data = Yii::$app->db->createCommand($sql)->bindValues($params)->queryAll();

How to convert this query to doctrine DQL

SELECT apntoken,deviceid,created
FROM `distribution_mobiletokens` as dm
WHERE userid='20'
and not exists (
select 1
from `distribution_mobiletokens`
where userid = '20'
and deviceid = dm.deviceid
and created > dm.created
)
What this query does is selects all mobiletokens where the user id is equal to 20 and the deviceid is the same but chooses the newest apntoken for the device.
My database looks like below.
For more information on this query, I got this answer from another question I asked here(How to group by in SQL by largest date (Order By a Group By))
Things I've Tried
$mobiletokens = $em->createQueryBuilder()
->select('u.id,company.id as companyid,user.id as userid,u.apntoken')
->from('AppBundle:MobileTokens', 'u')
->leftJoin('u.companyId', 'company')
->leftJoin('u.userId', 'user')
->where('u.status = 1 and user.id = :userid')
->setParameter('userid',(int)$jsondata['userid'])
->groupby('u.apntoken')
->getQuery()
->getResult();
//#JA - Get the list of all the apn tokens we need to send the message to.
foreach($mobiletokens as $tokenobject){
$deviceTokens[] = $tokenobject["apntoken"];
echo $tokenobject["apntoken"]."\n";
}
die();
This gives me the incorrect response of
63416A61F2FD47CC7B579CAEACB002CB00FACC3786A8991F329BB41B1208C4BA
9B25BBCC3F3D2232934D86A7BC72967A5546B250281FB750FFE645C8EB105AF6
latestone
Any help here is appreciated!
Other Information
Data with SELECT * FROM
Data after using the SQL I provided up top.
You could use a subselect created with the querybuilder as example:
public function selectNewAppToken($userId)
{
// get an ExpressionBuilder instance, so that you
$expr = $this->_em->getExpressionBuilder();
// create a subquery in order to take all address records for a specified user id
$sub = $this->_em->createQueryBuilder()
->select('a')
->from('AppBundle:MobileTokens', 'a')
->where('a.user = dm.id')
->andWhere('a.deviceid = dm.deviceid')
->andWhere($expr->gte('a.created','dm.created'));
$qb = $this->_em->createQueryBuilder()
->select('dm')
->from('AppBundle:MobileTokens', 'dm')
->where($expr->not($expr->exists($sub->getDQL())))
->andWhere('dm.user = :user_id')
->setParameter('user_id', $userId);
return $qb->getQuery()->getResult();
}
I did this for now as a temporary fix, not sure if this is best answer though.
$em = $this->em;
$connection = $em->getConnection();
$statement = $connection->prepare("
SELECT apntoken,deviceid,created
FROM `distribution_mobiletokens` as dm
WHERE userid=:userid
and not exists (
select 1
from `distribution_mobiletokens`
where userid = :userid
and deviceid = dm.deviceid
and created > dm.created
)");
$statement->bindValue('userid', $jsondata['userid']);
$statement->execute();
$mobiletokens = $statement->fetchAll();
//#JA - Get the list of all the apn tokens we need to send the message to.
foreach($mobiletokens as $tokenobject){
$deviceTokens[] = $tokenobject["apntoken"];
echo $tokenobject["apntoken"]."\n";
}

How to update array of records if not exist insert, without id?

i tried to do like this:
INSERT INTO hlr_client_country
(perform_hlr, client_id, mcc, dial_code)
VALUES
(1,2,202,30),(1,2,204,31)
ON DUPLICATE KEY UPDATE
id = 'id',
client_id = 'client_id',
mcc = 'mcc'
but query always inserts new and new records.
I want to update first and if record not exists insert one
Help please
try this code
$result = mysql_query("SELECT * FROM table WHERE title_1 ='$title_1' ");
if( mysql_num_rows($result) > 0) {
mysql_query("UPDATE table SET column = '$value' WHERE title_1 = '$title_1' ");
}
else
{
mysql_query("INSERT INTO table (title_1) VALUES ('$title_1') ");
}
^_^

MySQL 2 Tables, query before insert

I'm perplexed, here is what I have.
Two tables, one is temporary, one is permanent.
table Temptable:
city , state //- has a list of 20 citys and states
table Permtable:
city , state //- has hundreds of citys and states
I want to do two things:
I want to use city and state from Temptable and query the Permtable to see if it already contains
that city and state. If it doesn't I want it to add it.
IF it has a match in city and state, I want it to play c:\sound.wav and then I want it add it to the
permtable.
I am lost as to how to do this.
This will tell you which records exist or don't exist from your TempTable:
SELECT T.City, T.State, CASE WHEN P.State IS NULL THEN 'DOES NOT EXIST' ELSE 'DOES EXIST' END
FROM TempTable T
LEFT JOIN PermTable P ON T.City = P.City AND T.STate = P.State
You can INSERT those records that don't exists in the PermTable like such:
INSERT INTO PermTable
SELECT T.City, T.State
FROM TempTable T
LEFT JOIN PermTable P ON T.City = P.City AND T.STate = P.State
WHERE P.State IS NULL
Not sure about your requirement to play a sound and it doesn't make sense to then add it (since it already exists).
Since we have no code to run with here, query temptable for city and state, then query SELECT COUNT(id) FROM permtable WHERE city='$tempcity' AND state='$tempstate'.
Then user mysqli_num_rows on your query to see if any matches were found.
$q= "SELECT COUNT(*) FROM temptable WHERE city='$tempcity' AND state='$tempstate'";
$r = #mysqli_query($dbc, $q);
if(mysqli_num_rows($r) != 0) {
echo "<embed src =\"sound.wav\" hidden=\"true\" autostart=\"true\"></embed>";
}
else {
//Do your other stuff.
}
It really depends on how you have your table set up. If you have column 'State' and column 'City' where 'City' is something like 'Dallas-Austin-Houstin-San Antonio' then you will have to query for 'State', explode the value of 'City' into an array, run a while to check for $tempcity in the array, which would look like the following:
$q = "SELECT city FROM permtable WHERE state='$tempstate'";
$r = #mysqli_query($dbc, $q);
$row = mysqli_fetch_array($r, MYSQLI_ASSOC);
if (mysqli_num_rows($r) == 1) { //STATE MATCH
$cityCheck = explode("-", $row['city']);
$i = 0;
$count = count($cityCheck);
$goodMatch = 0;
while ($i < $count) { //find out if user already voted on post
if ($cityCheck[$i] == $tempcity) {
$goodMatch = 1;
} //City State match
else { } //City does not match with state, continue while loop.
$i++;
} //END WHILE
else { } //STATE DID NOT MATCH
if ($goodmatch) {
echo "<embed src =\"sound.wav\" hidden=\"true\" autostart=\"true\"></embed>";
}
else {}

get me the latest Change from Select Query in below given condition

I have a Table structure as
id, trackid, table_name, operation,
oldvalue, newvalue, field,
changedonetime
Now if I have 3 rows for the same "trackid" same "field", then how can i select the latest out of the three?
i.e. for e.g.:
id = 100 trackid = 152 table_name
= jos_menu operation= UPDATE oldvalue = IPL newvalue = IPLcccc
field = name live = 0 changedonetime =
2010-04-30 17:54:39
and
id = 101 trackid = 152 table_name =
jos_menu operation= UPDATE oldvalue
= IPLcccc newvalue = IPL2222 field = name live = 0 changedonetime =
2010-04-30 18:54:39
As u can see above the secind entry is the latest change,
Now what query I should use to get the only one and Latest row out of many such rows...
$distupdqry = "select DISTINCT trackid,table_name from jos_audittrail where live = 0 AND operation = 'UPDATE'";
$disupdsel = mysql_query($distupdqry);
$t_ids = array();
$t_table = array();
while($row3 = mysql_fetch_array($disupdsel))
{
$t_ids[] = $row3['trackid'];
$t_table[] = $row3['table_name'];
//$t_table[] = $row3['table_name'];
}
//echo "<pre>";print_r($t_table);echo "<pre>";
//exit;
for($n=0;$n<count($t_ids);$n++)
{
$qupd = "SELECT * FROM jos_audittrail WHERE operation = 'UPDATE' AND trackid=$t_ids[$n] order by changedone DESC ";
$seletupdaudit = mysql_query($qupd);
$row4 = array();
$audit3 = array();
while($row4 = mysql_fetch_array($seletupdaudit))
{
$audit3[] = $row4;
}
$updatefield = '';
for($j=0;$j<count($audit3);$j++)
{
if($j == 0)
{
if($audit3[$j]['operation'] == "UPDATE")
{
//$insqry .= $audit2[$i]['operation']." ";
//echo "<br>";
$updatefield .= "UPDATE `".$audit3[$j]['table_name']."` SET ";
}
}
if($audit3[$j]['operation'] == "UPDATE")
{
$updatefield .= $audit3[$j]['field']." = '".$audit3[$j]['newvalue']."', ";
}
}
/*echo "<pre>";
print_r($audit3);
exit;*/
$primarykey = "SHOW INDEXES FROM `".$t_table[$n]."` WHERE Key_name = 'PRIMARY'";
$prime = mysql_query($primarykey);
$pkey = mysql_fetch_array($prime);
$updatefield .= "]";
echo $updatefield = str_replace(", ]"," WHERE ".$pkey['Column_name']." = '".$t_ids[$n]."'",$updatefield);
}
In the above code I am fetching ou the distinct IDs in which update operation has been done, and then accordingly query is fired to get all the changes done on different fields of the selected distinct ids...
Here I am creating the Update query by fetching the records from the initially described table which is here mentioned as audittrail table...
Therefore I need the last made change in the field so that only latest change can be selected in the select queries i have used...
please go through the code.. and see how can i make the required change i need finally..
This is another question of the greatest-n-per-group category, which comes up several times per week on Stack Overflow.
Here's how I'd solve it in your case:
SELECT j1.*
FROM jos_audittrail j1 LEFT OUTER JOIN jos_audittrail j2
ON (j1.trackid = j2.trackid AND j1.field = j2.field
AND j1.changedonetime < j2.changedonetime)
WHERE j2.id IS NULL;