Sort array in PHP or MySQL - mysql

i have a problem.
i want to sort array follow max value in colum feed_id with every user_id,
then loop.
this is array start :
$array_start = array(
array("user_id"=>1,"feed_id"=>10),
array("user_id"=>1,"feed_id"=>11),
array("feed_id"=>2,"user_id"=>25),
array("feed_id"=>9,"user_id"=>26),
array("feed_id"=>2,"user_id"=>30),
array("feed_id"=>7,"user_id"=>33),
);
then sort array_start, i want to return array_result :
$array_result = array(
//loop 1
array("user_id"=>1,"feed_id"=>37),
array("feed_id"=>2,"user_id"=>30),
array("feed_id"=>9,"user_id"=>26),
array("feed_id"=>7,"user_id"=>33),
//loop 2
array("user_id"=>1,"feed_id"=>11),
array("feed_id"=>2,"user_id"=>25),
);
please help me, thank your reading !

Here you go!
I am writing the query based on a random table name. Please change it accordingly.
select user_id, max(feed_id) from MyTable
group by user_id
order by feed_id DESC;
The above query will result both the columns and the sorting will be done on feed_id and in descending order.

Related

How can I get the sum of the same id values in Laravel?

I am trying to find the sum of the same id values.
$tournament = Tournament::find($id);
$topTen = DB::table('match_scoreboard_batting')
->join('matches','match_scoreboard_batting.match_id','=','matches.id')
->where('matches.tournament_id',$id)
->select('match_scoreboard_batting.player_id','match_scoreboard_batting.runs')
->sum('match_scoreboard_batting.runs');
echo "<pre>";
print_r($topTen);
I know how to get the sum of all id values. But how can I get the sum of the same id values?
Please try this query.
$topTen = DB::table('match_scoreboard_batting')
->join('matches','match_scoreboard_batting.match_id','=','matches.id')
->where('matches.tournament_id',$id)
->select('match_scoreboard_batting.player_id', \DB::raw(' sum(match_scoreboard_batting.runs) as runs'));
You can use :
from laravel docs
DB::raw('SUM(price) as total_sales')
hope it will work for you.
Use sum() would cause to group by primary key (I guess here is player_id) automatically. If you want to get sum() of each match, tournament, or player you are supposed to add ->groupBy('some_id') in your query.

Selecting specific row from database .net core 2

I want to retrieve a specific row from the database.
so I'm using this command to retrieve it :
UserOwner userowner =_context.User.FromSql("SELECT * FROM db.user WHERE name = 'username'").FirstOrDefault();
return Ok(user);
the thing is this returns a list and I return the first on the list, but isn't there a way to return straight from the SQL command one row?
try use labda function on FirstOrDefault.
UserOwner userowner =_context.User.FirstOrDefault(o=> o.name == "username" );
return Ok(user);
but if you need use an SQL script, for MYSQL use:
"SELECT * FROM db.user WHERE name = 'username' LIMIT 1"
If I'm understanding your question correctly, you can do this using a "with" clause to get all of the rows and add a counter/index column then add a where clause to get the specific row. This would give you the 5th row from the original query.
with mainqry as (select t.*, rownum as myindex from db.user t where t.name ='username') select * from mainqry q where q.myindex=5;

Compare two dates in a database table are equal

I'm new here. So, be easy on me. I have a table called 'data' in which one of the columns is 'date' stored in YYYY-MM-DD format. Here is the code that I have been working on. Basically, what I want to do is compare if two dates stored in my table are equal. But, each time I run the code, I keep getting error: Undefined offset right where the code says $lisdate[$i+1]. How do I compare the dates stored in a table? Thank you.
My code
$sth2 = mysql_query("SELECT * FROM data WHERE dest_name='www.myren.net.my'");
while($rowstemp = mysql_fetch_assoc($sth2))
{
$lisdate[] = $rowstemp['date'];
$lisaverage[] = $rowstemp['avg_rtt'];
}
$rows = mysql_num_rows($sth2);
$addAverage[0] = $lisaverage[0];
$numbers = 0;
$j = 0;
for($i = 0; $i<$rows; $i++)
{
if($lisdate[$i] == $lisdate[$i+1])
{
$addAverage[$j] = $addAverage[$j] + $lisaverage[$i+1];
}
else
{
$j++;
$numbers = $numbers +1;
}
}
Gordon has it right. Your for loop is overrunning the end of your array because you're working with consecutive pairs of rows. Change it to read ; $i < $rows - 1; to correct this problem.
But, you have another problem. SQL rows in result sets have an unpredictable order unless your query includes an ORDER BY clause. If these rows, without that clause, appear in ascending order by date, it's dumb luck. Put ORDER BY date in your query.
It's not entirely clear what that code in the question is attempting to achieve.
(As Ollie pointed out in his answer, it bears repeating: the order that MySQL returns the rows is guaranteed ONLY if there's an ORDER BY clause on the query. The result from a "duplicate date" check that's being performed in the code is only going to detect a "duplicate" date value if it appears on contiguous rows.)
We see the code loading a couple of arrays, using the date and avg_rtt column values returned by the query. Then there's some manipulation on the array... the end result will be another it's not clear what the actual intent of that rigmarole is, what it's actually trying to achieve.
If there are any rows It looks like there's going to be another array... if there are no "duplicate" date values found, it's going to have a single element (with the value of rtt_avg from the first row), and $numbers will be set to the number of elements in the original array.
If there is a "duplicate" date values found, the results from the code seem very odd to me, a sparsely populated array. Why?
Personally, I'd be looking to get an actual statement of the specification, and have the database do that processing for me, rather than mucking through two arrays.
If what we want is set of values with no duplicated date values, I'd use a GROUP BY and some aggregation, for example:
SELECT d.dest_name
, d.date
, AVG(d.avg_rtt) AS avg_avg_rtt
, MAX(d.avg_rtt) AS max_avg_rtt
, MIN(d.avg_rtt) AS min_avg_rtt
, SUM(d.avg_rtt) AS sum_avg_rtt
, COUNT(1) AS cnt
, COUNT(d.avg_rtt) AS cnt_avg_rtt
, COUNT(DISTINCT d.avg_rtt) AS cnt_distinct_avg_rtt
FROM data d
WHERE d.dest_name = 'www.myren.net.my'
GROUP
BY d.dest_name
, d.date
ORDER
BY d.dest_name
, d.date
If I was looking for just a count of distinct date values, like what $numbers is going to contain, then just:
SELECT d.dest_name
, COUNT(DISTINCT d.date) AS cnt_distinct_date
FROM data d
WHERE d.dest_name = 'www.myren.net.my'
GROUP BY d.dest_name
ORDER BY d.dest_name
The "looping through array" that the original query just looks like an odd way to achieve a result, whatever that result is supposed to be.

Yii2 select by max date?

Suppose I have table A with its active record in yii2, What is the best way to can load the record with max created date to the model.
This is the query :
select *
from A
where created_date = (
select max(created_date) from A
)
Now I am getting the max date first then use it in another access to database ie:
$max = A::find()->select("created_date)")->max();
$model = A::find()->where("created_date = :date",[":date"=>$max])->one();
I am sure that this can be done with one access to database , but I don't know how.
please any help.
Your query is the equivalent of:
SELECT * FROM A ORDER BY created_date DESC LIMIT 1;
You can order your records by created_date in descending order and get the first record i.e:
$model = A::find()->orderBy('created_date DESC')->limit(1)->one();
Why limit(1)? As pointed out by nicolascolman, according to the official Yii documentation:
Neither yii\db\ActiveRecord::findOne() nor yii\db\ActiveQuery::one() will add LIMIT 1 to the generated SQL statement. If your query may return many rows of data, you should call limit(1) explicitly to improve the performance, e.g., Customer::find()->limit(1)->one().
$maxdate=A::find()->max('created_date');
Try this
$model = A::find()->orderBy("created_date DESC")->one();

How to make a 1 column query by choosing from two columns mysql

I have a messaging system (very basic) that has a table like this:
**MESSAGE_ID** **RUSER_ID** **SUSER_ID** **MESSAGE_DATA** **DATE**
RUSER is the receiving user, and SUSER is the sending user. If I wanted to output a query that would output a certain users messages, I would currently do:
Select * from PRIVATE_MESG where RUSER_ID=$USER_ID or SUSER_ID=$USER_ID
That would give me all message_id's that are associated with that USER_ID. What I would like, is to create a column that would produce only the ID associated with RUSER_ID or SUSER_ID associated with a specific user. I need it to choose the messages that RUSER_ID or SUSER_ID are equal to a USER_ID but only display the one that isn't USER_ID
I would then like to do a group by the output of that query.
Any help is greatly appreciated!
Thanks!
update I am not really looking for a message_id, I am just looking for a list of users who that person has written to or received from.
UPDATE
Just so everyone knows, I recieved the answer to this question perfectly! I tweaked it later on so that it would also display them by date from newest to oldest. I did this by spliting the DATETIME into DATE and TIME USING the DATE() and TIME() Function. Here was my final query:
SELECT
IF(RUSER_ID = $USER, SUSER_ID, RUSER_ID) as THE_OTHER_GUY, DATE(DATE) as DAY, TIME(DATE) as TIME
FROM PRIVATE_MESG
WHERE RUSER_ID = $USER
OR SUSER_ID = $USER;
group by THE_OTHER_GUY ORDER BY DAY DESC, TIME DESC
Hope this helps the next person!
You can query:
SELECT
*,
IF(RUSER_ID = $USER_ID, SUSER_ID, RUSER_ID) as THE_OTHER_GUY
FROM PRIVATE_MESG
WHERE RUSER_ID = $USER_ID
OR SUSER_ID = $USER_ID;
SELECT SUSER_ID FROM PRIVATE_MESG WHERE RUSER_ID=$USER_ID
UNION
SELECT RUSER_ID FROM PRIVATE_MESG WHERE SUSER_ID=$USER_ID
It retrieves:
- the list of user IDs who sent messages to $USER_ID
- the list of user IDs who received messages from $USER_ID
And UNION groups the 2 lists in a single result set.