Good day. I am really in big trouble as I can't figure what is wrong with my statement. It is as follows:
$sumitem = mysqli_query($conn,"SELECT SUM(AMOUNT) AS TOTAL FROM sum_query WHERE MAIN_ID = 1 GROUP BY ITEM_ID");
$sum = mysqli_fetch_assoc($sumitem);
I am trying to print $sum['TOTAL'] but what it shows the first column only. Below is my sample table:
MAIN_ID | ITEM_ID | AMOUNT | DESC | OTHER_DETAILS
1 | 1 | 500 | Item 1 | a
1 | 2 | 5000 | Item 2 | a
1 | 2 | 5000 | Item 2 | b
My desired result should be 5500 but it only returns 500.
Thank you very much.
If you want ans as 6500 then remove group by clause
SELECT SUM(AMOUNT) AS TOTAL FROM sum_query WHERE MAIN_ID = 1
SELECT SUM(g.AMOUNT) AS TOTAL
FROM sum_query g
WHERE g.MAIN_ID = 1
GROUP BY g.ITEM_ID
This query is working plase try out this
You are having 2 records for Item 2. and i don't know why you are keeping 'a and b' in OTHER_DETAILS.
Your requirement is not clear
If you want to take only the records matching with OTHER_DETAILS 'a',then use the following query
SELECT SUM(AMOUNT) AS TOTAL FROM sum_query WHERE MAIN_ID = 1 and OTHER_DETAILS = 'a'
Related
I have a huge number of rows that I'd like to get say, last 5 records inserted in that database from 10 different users. If the same user inserted the last 3 rows into database, we must get one row, skip the others two and move to get a row per user, until it count up to 5.
A database like that:
user_id | news_id | title
1 | 1 | foo-1
2 | 2 | foo-2
3 | 3 | foo-3
1 | 4 | baa
4 | 5 | baa0
5 | 6 | baa1
5 | 7 | baa2
6 | 8 | baa3
7 | 9 | baa4
Should return:
user_id | news_id | title
1 | 1 | foo-1
2 | 2 | foo-2
3 | 3 | foo-3
4 | 5 | baa0
5 | 6 | baa1
The current filter was done by PHP, like this:
$used = array();
while ($data = mysql_fetch_array($query)) {
$uid = $data['user_id'];
if(in_array($uid, $used))
continue;
array_push($used, $uid);
// do something with data
}
But I want to refactor it, and do the filter purely by mysql, if possible. I don't know much MySql and that's why I'm having problem to archive this...
Here's what I've tried
select DISTINCT(user_id), news_id, title from XXX
WHERE GROUP BY (news_id) DESC
LIMIT 0,5
How can I do that?
1 way you can do it is to generate a partitioned row number per user and then select 5 records where RowNumber = 1.
SELECT *
FROM
(
SELECT
d.user_id
,d.news_id
,d.title
,(#rn:= if(#uid = user_id, #rn + 1,
if(#uid:=user_id,1,1)
)
) as RowNumber
FROM
Data d
CROSS JOIN (SELECT #uid:=-1, #rn:=0) vars
ORDER BY
user_id
,news_id
) t
WHERE
t.RowNumber = 1
ORDER BY news_id
LIMIT 5;
http://rextester.com/JRIZI7402 - example to show it working
Note you can change the row order by simply changing the ORDER BY statement of the derived table so if you have a column that will signify the latest record e.g. an identity column or a datetime column you can use that, but user_id must be the first criteria to be partitioned correctly.
Do it from your query.
"SELECT * FROM table GROUP BY user_id ORDER BY news_id DESC LIMIT 5"
well, i think this will achieve what you are after.
select user_id, news_id, title from tableName
GROUP BY user_id
ORDER BY news_id DESC
LIMIT 0,5
Hope this helps!
Hello I am trying to make a Select where the uses chooses department and would like to have clause WHERE this department is first, let's say we select 10 results from department: Taxes and then make a SUM SELECT of fee WHERE status = 1. Which results be selected based on the first select All the results are coming from the same table.
| id | department | status | fee |
----------------------------------
| 1 | tax | 1 | 20 |
| 2 | tax | 2 | 20 |
| 3 | tax | 1 | 20 |
| 4 | accounting | 1 | 20 |
So I would like to select if department is choose as tax, and status is 1 the sum of FEE columns which should be 40
So far my Select query looks like this:
SELECT P.id, P.fee, (SELECT SUM(P.fee) FROM cases P WHERE status = 1) as fee_USD
FROM cases P WHERE 1";
if (!empty($department)) { $sql .= " AND P.department = '$department'"; }
the last line is checking if department is given as select option. there are other options as well but to make it simple I have pasted only this part of it. Any help is welcome.
In the Current Selection Fee is = 80
You have to add correlation to your query:
SELECT P1.id, P1.fee,
(SELECT SUM(P2.fee)
FROM cases P2
WHERE P2.department = P1.department AND status = 1) as fee_USD
FROM cases P1
WHERE 1 ...
This way the subquery will return the SUM of only those records which are related to the current record of the main query.
In a blog-like website, all the users can "star" a news (= bookmark it, mark it as "favourite").
I have a mysql table for stats.
table_news_stats
id_news
total_stars (int) //Total number of users who starred this news
placement (int)
The placement field is intuitive: if you order all the news by the total_stars field you get each news placement. So, the news with most stars will be number 1, and so on.
So, suppose I have 700 records in my table_news_stats, and for each one I have the id and the total_stars count, how can I update the placement field automatically for each record? Which query is faster/better?
Example of the table_news_stats content:
First record (A):
1-3654-?
Second record (B):
2-2456-?
Third record (C):
3-8654-?
If you order the record by stars count:
the sequence of records is C - A - B
So... the result will be:
First record (A):
1-3654-2
Second record (B):
2-2456-3
Third record (C):
3-8654-1
Clarification:
why would I ever need the placement field at all?
It's pretty simple... the placement field will be populated by a cronjob the first day of every month. Basically it will provide a 'snapshot' of the rank of each news in terms of popularity (as it was at the beginning of the current month). As a consequence, thanks to the placement field, I will have the following information:
"The 1st day of this month the 'top starred' news list was like this:
1- News C
2- NewsA
3- News B "
Then, with a query "SELECT * FROM table_news_stats ORDER BY total_stars DESC" I can obtain the new ranking (in real-time).
As a consequence, I will have the following information:
"At the time the page is loaded, the 'top starred' news list is like this:
1- News A
2- News C
3- News B "
Finally, by comparing the two rankings, I obtain the last piece of information:
"News A has gained a position" +1
"News C has lost a position" -1
"News B has no change in position" +0
If there is a better way of doing this, let me know.
I guess you don't need to update the table just:
SELECT *
FROM table_news_stats
ORDER BY total_stars DESC
But if you want to know the place of each one you can:
SELECT *, IF(#idx IS NULL,#idx:= 1,#idx:= #idx+1)
FROM table_news_stats
ORDER BY total_stars DESC
And if you still need to update something like:
UPDATE table_news_stats
SET placement = FIND_IN_SET(id_news,(SELECT GROUP_CONCAT(t.id_news) FROM (SELECT id_news
FROM table_news_stats
ORDER BY total_stars DESC) t ))
SQLFiddle
Consider the following
mysql> select * from test ;
+------+-------------+-----------+
| id | total_stars | placement |
+------+-------------+-----------+
| 1 | 3 | 0 |
| 2 | 6 | 0 |
| 3 | 7 | 0 |
| 4 | 2 | 0 |
| 5 | 9 | 0 |
| 6 | 2 | 0 |
| 7 | 1 | 0 |
+------+-------------+-----------+
Now using the following you can update the placement as
update test t1 join
(
select *,
#rn:= if(#prev = total_stars,#rn,#rn+1) as rank ,
#prev:= total_stars
from test,(select #rn:=0,#prev:=0)r
order by total_stars desc
)t2
on t2.id = t1.id
set t1.placement = t2.rank ;
mysql> select * from test order by placement ;
+------+-------------+-----------+
| id | total_stars | placement |
+------+-------------+-----------+
| 5 | 9 | 1 |
| 3 | 7 | 2 |
| 2 | 6 | 3 |
| 1 | 3 | 4 |
| 4 | 2 | 5 |
| 6 | 2 | 5 |
| 7 | 1 | 6 |
+------+-------------+-----------+
Note that in case of tie will have the same placement.
plan_id | elementclass | table_no | ress_id | UserID | Status
1 | elementclass1 | 1 | 0 | 0006100022 | N
1 | elementclass1 | 1 | 2 | 0006100022 | N
1 | elementclass2 | 2 | 0 | 0006100021 | N
1 | elementclass4 | 3 | 0 | 0006100023 | N
in above row I am expecting as this
if row is having same elementclass,table_no but different ress_id in that condition only take that row which is non zero.If with above condition tow rows having 0 it can take any row .if both rows have non zero then also it can take any one.
Now
for rest of others it can take values with 0.We can use group by to plan_id as there may be multiple plans.
Desired result
plan_id | elementclass | table_no | ress_id | UserID | Status
1 | elementclass1 | 1 | 2 | 0006100022 | N
1 | elementclass2 | 2 | 0 | 0006100021 | N
1 | elementclass4 | 3 | 0 | 0006100023 | N
Please help.
thanks
SELECT * FROM TableName a
WHERE a.ress_id = (SELECT MAX(b.ress_id) FROM TableName b WHERE b.table_no = a.table_no)
GROUP BY a.plan_id,a.table_no
This gives you:
1 result per plai_id and table_no
each result has biggest ress_id in it
First get the maximum ress id per element class. Then select the related records. There may be duplicates. Hence group by element class and ress id.
The following statement does not precisely do what you asked for, but maybe it suffices. In case of a tie you won't get one of the records, but one of the records' plan ids, one of the records' table nos, one of the records' user ids and one of the records' statusses. So the user id may be taken from one record and the status from another when elementclass and ress_id are equal.
select plan_id, mytable.elementclass, table_no, mytable.ress_id, userid, status
from mytable
join
(
select elementclass, max(ress_id) as max_ress_id
from mytable
group by elementclass
) agg on agg.elementclass = mytable.elementclass and agg.max_ress_id = mytable.res_id
group by mytable.elementclass, mytable.ress_id;
(It is possible to write a statement to access complete records in case of ties, but this is much more complicated - at least in MySQL.)
Try this:
SELECT T1.*
FROM TableName T1 JOIN
(SELECT elementclass,table_no,MAX(ress_id) as ress_id
FROM TableName
GROUP BY elementclass,table_no
)T2 ON T1.elementclass=T2.elementclass AND T1.table_no=T2.table_no AND T1.ress_id=T2.ress_id
Explanation:
Here, we are creating a temporary table T2 with maximum of ress_id for each elementclass and table_no. Then we join this table with the original table with these 3 fields and select all records from the original table T1.
Result:
PLAN_ID ELEMENTCLASS TABLE_NO RESS_ID USERID STATUS
-------------------------------------------------------------------
1 elementclass1 1 2 0006100022 N
1 elementclass2 2 0 0006100021 N
1 elementclass4 3 0 0006100023 N
See result in SQL Fiddle.
I have the following table and want to know how to set up a column total to calculate the sum of the row. I want the total column to calculate first_bid - second_bid.
id | First Bid | Second Bid | Total
0 | 7 | 1 | (first_bid)-(second_bid)
1 | 8 | 2 |
2 | 5 | 3 |
3 | 4 | 4 |
4 | 5 | 5 |
5 | 5 | 6 |
I need to display to the user all previous bids and total on a page. The total should be in descending order also.
SELECT id, First_Bid, Second_Bid, First_Bid - Second_Bid AS Total
For the grand total, you'd have to run a second query with SUM() aggregate functions. Which is somewhat redundant, since you can just do the summation in your client as you retrieve the data. e.g.
$total = 0;
while($row = fetch_from_db($result)) {
$total += $result['Total'];
... display row data ...
}
... display total ...
You can just calculate the total when you are querying the database.
SELECT first_bid, second_bid, (first_bid - second_bid) as total FROM table ORDER BY 3 DESC
Something along these lines
Try this query:
SELECT *, (First Bid-Second Bid) as total from TABLE