i need to get the latest order (from our custon admin panel). here's my query:
select *
from order
left join customer
on (customer.id = order.fk_cid)
where date = curdate()
order by time desc
limit 1;
this output everything from orders and customers which i need except 1 therefore that is why i use the *
here's my table structure:
order table:
id, fk_cid, date, time
customer table:
id, name, lastname, street, city, zip, country, phone, email, lastlogin
now, in my php i have:
$result = mysql_query("
select *
from `order`
left join customer
on (customer.id = order.fk_cid)
where date = curdate()
order by time desc
limit 1");
$row = mysql_fetch_assoc($result, MYSQL_ASSOC);
at this point my order is not correct, why?
Your customers.id is overwriting the order.id because you are using the same column name.
select *
from `order`
left join customer on (customer.id = order.fk_cid)
where date = curdate() order by time desc limit 1;
+------+--------+------------+----------+------+-------+------
| id | fk_cid | date | time | id | name | ....
+------+--------+------------+----------+------+-------+------
| 1 | 2 | 2011-11-30 | 07:01:23 | 2 | asasd | ....
+------+--------+------------+----------+------+-------+------
1 row in set (0.03 sec)
As you can see in this example you have two id, so PHP when retrieve the data using mysql_fetch_assoc it overwrites the second id because it's the same key in the array. To fix this, you will have to specify the columns in your query:
select `order`.id AS order_id, customer.id AS customer_id, customer.name /* etc... */
This will output:
Also, I recommend to use different name for your tables and fields. order, date, time since they are reserved word (in case you forget for use the ` ).
Array
(
[order_id] => 1
[customer_id] => 2
// etc...
)
Also here's a topic you should read: Why is SELECT * considered harmful?
Related
I have the table:
id | date_submitted
1 | 01/01/2017
1 | 01/02/2017
2 | 01/03/2017
2 | 01/04/2017
I'm looking for the correct SQL to select each row, limited to one row per id that has the latest value in date_submitted.
So the SQL should return for the above table:
id | date_submitted
1 | 01/02/2017
2 | 01/04/2017
The query needs to select everything in the row, too.
Thanks for your help.
You can find max date for each id in subquery and join it with the original table to get all the rows with all the columns (assuming there are more columns apart from id and date_submitted) like this:
select t.*
from your_table t
inner join (
select id, max(date_submitted) date_submitted
from your_table
group by id
) t2 on t.id = t2.id
and t.date_submitted = t2.date_submitted;
Note that this query will return multiple rows for an id in case there are multiple rows with date_submitted equals to max date_submitted for that id. If you really want only one row per id, then the solution will be a bit different.
If you just need id and max date use:
select id, max(date_submitted) date_submitted
from your_table
group by id
I am currently working with MySQL creating a view that would return the following:
NAME | EMAIL | LAST_SEEN
abby | a#l.d | 2015-10-31 14:36:26
abby | a#l.d | 2015-11-28 13:30:37
I then apply the GROUP BY name to the select query and it returns the following
NAME | EMAIL | LAST_SEEN
abby | a#l.d | 2015-10-31 14:36:26
I want to know how can I fix this query so that it returns the following:
NAME | EMAIL | LAST_SEEN
abby | a#l.d | 2015-11-28 13:30:37
the actual code is as follows:
CREATE VIEW v_user_last_seen
AS
SELECT concat_ws(' ', u.first_name, u.middle_name, u.last_name) AS user_name
,c.email
,l.in_when AS last_seen
FROM user AS u
INNER JOIN check_here_first AS c ON c.email = u.email
INNER JOIN log AS l ON l.u_id = c.username
GROUP BY user_name
ORDER BY user_name ASC
simply use max(last_seen)
select name, email, max(last_seen)
from yourtable,
group by name, email;
Try to sort your table before grouping, this should do for simple cases such as this one:
SELECT *
FROM ( SELECT *
FROM `tablename`
ORDER BY `LAST_SEEN` DESC
) temp
GROUP BY `name`
If this fails, you can do something like:
SELECT tmp1.*
FROM `tablename` tmp1
LEFT JOIN `tablename` tmp2
ON (tmp1.`name` = tmp2.`name`
AND tmp1.`LAST_SEEN` < tmp2.`LAST_SEEN`)
WHERE tmp2.`name` IS NULL
The idea here is matching the table's rows with itself, where the matched values have a higher values. for that ones that don't match, we will get a null, as we use LEFT JOIN. These should be the highest in the group.
I have a table which stores information on standings in multiple leagues, think of this as a fantasy site. The structure is as follows in terms of columns.
league_id | user_id | total_points | prediction_difference | current_position | last_position
In order to calculate the current standings I am issuing the following query:
SELECT
*
FROM f_u_standings
WHERE league_id = 1
ORDER BY total_points DESC,
prediction_difference DESC
My question is, now I have this result set, how can I then perform an UPDATE based on the SELECT query which updates the current_position column? My programming language of choice on this project is PHP.
you can update with a select.. this assumes you have an ID for each row
UPDATE TABLE f_u_standings fs,
(
SELECT
*
----- do what you want to change current_position -----
FROM f_u_standings
WHERE league_id = 1
ORDER BY total_points DESC,
prediction_difference DESC
) temp
SET fs.current_position = temp.current_position WHERE fs.id = temp.id
This may be closer to what you need:
UPDATE f_u_standings fs,
(SELECT #rownum:=#rownum+1 rownum, id
FROM f_u_standings, (SELECT #rownum := 0) init
WHERE league_id = 1
ORDER BY total_points DESC,
prediction_difference DESC) temp
SET fs.current_position = temp.rownum
WHERE fs.id = temp.id
I'm having problems constructing a select query.
I have a table which I have shown in a simplified version below. There are many more columns than those I have shown, but I have ommitied those not relevent to this query.
ID ReceiptNo TransactionType
--------------------------------
1 | 2SJ1532 | SALE
2 | 8UG7825 | SALE
3 | 0619373 | SALE
4 | 8UG7825 | RFND
5 | | TEST
I want to select only those rows that have a transaction type "SALE" where the ReceiptNo for the selected row also appears in a row with transaction type RFND.
So in the above example I would want to select Row 2. Because it has Transaction Type SALE
and its ReceiptNo also appears in a row with transaction type RFND.
I have the following query to select all the SALE type transaction types, but I think I need a subquery to make the select work as descriped above. If anyone could help that would be great.
SELECT * FROM $table_name WHERE RecieptNo IS NOT NULL AND TRIM(RecieptNo) <> '' AND TransactionType = 'SALE'
Try this:
SELECT *
FROM $table_name
WHERE RecieptNo IN(SELECT RecieptNo
FROM tablename
WHERE TransactionType IN('Sale', 'RFND')
GROUP BY RecieptNo
HAVING COUNT( DISTINCT TransactionType) = 2);
This will ensure that the selected RecieptNo have both transaction types Sale, RFND.
SELECT t.*
FROM your_table t
JOIN your_table t2 ON t2.TransactionType = 'RFND' AND t2.ReceiptNo=t.ReceiptNo
GROUP BY t.ID
SELECT *
FROM $table_name X1
WHERE X1.TransactionType = 'SALE'
AND EXISTS (
SELECT X2.ReceiptNo
FROM $table_name X2
WHERE X1.ReceiptNo=X2.ReceiptNo
AND X2.TransactionType = 'RFND'
)
Lets say I have 3 columns and 3 rows, the first column is for ID, the second is names, third is votes. like:
+----+------+-------+
| id | name | votes |
+----+------+-------+
| 1 | bob | 7 |
| 2 | jill | 2 |
| 3 | jake | 9 |
+----+------+-------+
How can I have PHP compare the values in the votes field and sort it by whichever had the highest number, and attach a rank of #1,2,3, etc. depending on how many votes it had?
Each value will be displayed on a separate page. For example, if I went to 'bob's page' with the ID of 1, I would need it to display '#2 bob' since he would be ranked 2nd by votes.
You can make a separate column rank and update it by running the following code whenever your vote changes. This method will make you more efficient as in this you wont be sorting the table again and again when user visits his page:
$q = "select * from tableName order by votes DESC";
$a = mysql_query($q);
$count = 1;
while($arr = mysql_fetch_array($a){
$up = "update tableName set(rank) VALUES($count) WHERE name=$arr['name']";
$aq = mysql_query($up);
$count++;
}
Now on individual pages, you can just retrieve the rank value and show
$user = "Bob";
$q = "select rank from tableName where name=$user";
$a = mysql_query($q);
$arr = mysql_fetch_array($a);
echo $arr[0];
Also this(a slight modification in other answer) should work for you :-
SELECT #rownum:=#rownum+1 AS rank, name, vote FROM table, (SELECT #rownum:=0) as P ORDER BY vote DESC
You could read the values returned by your query into an array and then sort said array.
You want a SELECT query doing an ORDER BY votes, and create a special variable to handle the rank of a row:
SELECT #rownum:=#rownum+1 AS rank, name, vote FROM table, (SELECT #rownum:=0) ORDER BY vote DESC
This query should let you fetch an array with the rank, name, and number of votes of each person of your table.
Alternatively, you can just sort by vote, and add the rank value yourself with PHP.
You can use the MySQL 'ORDER BY' and display those ranks using PHP:
For this example:
<?php
//connection
//DB selection
$query = "SELECT * FROM table_votes ORDER BY votes DESC";
$result = mysql_query($query);
for(int $i=1; $row = mysql_fetch_array($result);i++)
{
echo "#".$i.$row['name']."<br/>";
}
?>