how to add another column to query result? - mysql

i need some help.
so i have one table like this.
| id_num | payment | dollar |
| 889 | 1/2/2022 | 500 |
| 889 | 3/2/2022 | 400 |
| 789 | 1/2/2022 | 350 |
| 123 | 2/1/2022 | 200 |
I want to count how many unique Id_num with their payment date.
i'm using this query
select id_num, count(*) as count from tabletesting Group By id_num ;
And the result was
| id_num | count |
| 889 | 2 |
| 789 | 1 |
| 123 | 1 |
What i want is something like this
| id_num | payment | count |
| 889 | 1/2/2022 | 2 |
| 889 | 3/2/2022 | 2 |
| 789 | 1/2/2022 | 1 |
| 123 | 2/1/2022 | 1 |
how could i achieve that result ?
Many Thanks.

u can try this query
select id_num, payment,
(
select count(*) as count
from tabletesting b
where b.id_num = a.id_num
group by id_num
) as 'count'
from tabletesting a
group by id_num, payment
I hope it help

Related

MySQL list all records in left table with Join

I have two tables, one includes vehicle data & other includes fuel data as follows:
tbl_vehicle
+------------+--------+
| vehicle_id | reg_no |
+------------+--------+
| 1 | ABC |
| 2 | DEF |
| 3 | GHI |
| 4 | JKA |
| 5 | LMN |
| 6 | OPQ |
+------------+--------+
tbl_direct_fuel
+---------+------------+----------+------------+
| fuel_id | vehicle_id | fuel_qty | date |
+---------+------------+----------+------------+
| 100 | 1 | 10 | 2019-10-01 |
| 101 | 1 | 12 | 2019-10-02 |
| 102 | 2 | 20 | 2019-10-03 |
| 103 | 3 | 15 | 2019-10-03 |
| 104 | 2 | 25 | 2019-10-04 |
+---------+------------+----------+------------+
I tried to get all records of left table with relevant records of right table. Used following Query.
select("reg_no,sum(fuel_qty) as total")
->from('tbl_direct_fuel')
->join('tbl_vehicle', 'tbl_direct_fuel.vehicle=tbl_vehicle.vehicle_id', 'left')
->group_by ('reg_no')
The above code shows only the following output.
+--------+----------+
| reg_no | total |
+--------+----------+
| ABC | 22 |
| DEF | 45 |
| GHI | 15 |
+--------+----------+
But I need all the vehicles with un-fueled vehicles as follows.
Desired output
+--------+----------+
| reg_no | total |
+--------+----------+
| ABC | 22 |
| DEF | 45 |
| GHI | 15 |
| JKA | 0 |
| LMN | 0 |
| OPQ | 0 |
+--------+----------+
You would to invert the tables in the left join, so that vehicules with no fueling do appear in the resultset (as it is, your left join allows for fueling without vehicules, which does not look like a relevant use case).
I would also recommend prefixing the column names with the table they come from to avoid ambiguity.
Finally, to return 0 (instead of null) for the vehicules that had no fueling, you can use coalesce().
select("tbl_vehicle.reg_no, coalesce(sum(fuel_qty), 0) fuel_qty")
->from('tbl_vehicle')
->join('tbl_direct_fuel', 'tbl_direct_fuel.vehicle = tbl_vehicle.vehicle_id', 'left')
->group_by ('tbl_vehicle.vehicle_id')
Try:
select t1.reg_no, t2.fuel_total
from tbl_vehicle t1
left join (
select vehicle_id, sum(fuel_qty) fuel_total
from tbl_direct_fuel
group by vehicle_id
) t2 on t1.vehicle_id = t2.vehicle_id

Summarize the total of a specified item all together

I have the following table
MySQL [distributor]> select * from orderitems;
+-----------+------------+---------+----------+------------+
| order_num | order_item | prod_id | quantity | item_price |
+-----------+------------+---------+----------+------------+
| 20005 | 1 | BR01 | 100 | 5.49 |
| 20005 | 2 | BR03 | 100 | 10.99 |
| 20006 | 1 | BR01 | 20 | 5.99 |
| 20006 | 2 | BR02 | 10 | 8.99 |
| 20006 | 3 | BR03 | 10 | 11.99 |
| 20007 | 1 | BR03 | 50 | 11.49 |
| 20007 | 2 | BNBG01 | 100 | 2.99 |
| 20007 | 3 | BNBG02 | 100 | 2.99 |
| 20007 | 4 | BNBG03 | 100 | 2.99 |
| 20007 | 5 | RGAN01 | 50 | 4.49 |
| 20008 | 1 | RGAN01 | 5 | 4.99 |
| 20008 | 2 | BR03 | 5 | 11.99 |
| 20008 | 3 | BNBG01 | 10 | 3.49 |
| 20008 | 4 | BNBG02 | 10 | 3.49 |
| 20008 | 5 | BNBG03 | 10 | 3.49 |
| 20009 | 1 | BNBG01 | 250 | 2.49 |
| 20009 | 2 | BNBG02 | 250 | 2.49 |
| 20009 | 3 | BNBG03 | 250 | 2.49 |
+-----------+------------+---------+----------+------------+
18 rows in set (0.098 sec)
I am able to summarize the total price of a specified order as;
MySQL [distributor]> select order_num, sum(quantity*item_price)
as total_price from orderitems where order_num = 20008;
+-----------+-------------+
| order_num | total_price |
+-----------+-------------+
| 20008 | 189.60 |
+-----------+-------------+
1 row in set (0.026 sec)
How could I aggregate the total-price of each order and display them all together?
A SELECT statement clause that divides the query result into groups of rows, usually for the purpose of performing one or more aggregations on each group. The SELECT statement returns one row per group.
So in your all things are fine just need group by order_num
select order_num, sum(quantity*item_price) as total_price from orderitems
group by order_num
Use GROUP BY:
select order_num, sum(quantity*item_price) as total_price
from orderitems group by order_num
If you want to show total price of all orders which order details, you can remove order num from select:-
select sum(quantity*item_price) as total_price from orderitems;
However, if you are looking to show total price of all orders against each order, you can use below query :-
select order_num, sum(sum(quantity*item_price)) OVER() as total_price
from orderitems
group by order_num;

Getting required rows in mysql using GROUPBY

I have a table named travel which is as follows:
+-------+-----+----------+
| Name | Day | Distance |
+-------+-----+----------+
| Ravi | 1 | 10 |
| Ravi | 2 | 21 |
| Ravi | 3 | 23 |
| Hari | 1 | 12 |
| Hari | 2 | 32 |
| Kiran | 1 | 12 |
| Kiran | 2 | 32 |
| Kiran | 3 | 21 |
| Kiran | 4 | 43 |
+-------+-----+----------+
using group in sql for this table as
select name, day, distance, sum(distance) as total_dist
from travel
group by name;
I get the result as follows
+-------+-----+----------+------------+
| Name | Day | Distance | total_dist |
+-------+-----+----------+------------+
| Ravi | 1 | 10 | 54 |
| Hari | 1 | 12 | 44 |
| Kiran | 1 | 12 | 108 |
+-------+-----+----------+------------+
That is mysql gives the top row by default for columns which are not aggregated. But I would prefer to get all the rows with aggregated values or rows with bottom row in the group like as follows:
+-------+-----+----------+------------+
| Name | Day | Distance | total_dist |
+-------+-----+----------+------------+
| Ravi | 3 | 23 | 54 |
| Hari | 2 | 32 | 44 |
| Kiran | 4 | 43 | 108 |
+-------+-----+----------+------------+
or either in this way:
+-------+-----+----------+------------+
| Name | Day | Distance | total_dist |
+-------+-----+----------+------------+
| Ravi | 1 | 10 | 54 |
| Ravi | 2 | 21 | 54 |
| Ravi | 3 | 23 | 54 |
| Hari | 1 | 12 | 44 |
| Hari | 2 | 32 | 44 |
| Kiran | 1 | 12 | 108 |
| Kiran | 2 | 32 | 108 |
| Kiran | 3 | 21 | 108 |
| Kiran | 4 | 43 | 108 |
+-------+-----+----------+------------+
I am new to using mysql and confused with using group by, please guide me if any of the above two results are possible to get.
To get the entire list with the sum for each group, you can use a subquery and join the total back to the original table:
select t.name, t.day, t.distance, t2.total_dist
from travel t
join (select name, sum(distance) total_dist
from travel
group by name) t2 on t.name = t2.name
SQL Fiddle Demo
Or to get the max day per group, just include max(day) in the subquery:
select t.name, t.day, t.distance, t2.total_dist
from travel t
join (select name, sum(distance) total_dist, max(day) max_day
from travel
group by name) t2 on t.name = t2.name and t.day = t2.max_day
More Fiddle
it will work for you
select name,max(day),max(distance)
from tablename
group by name
and other case
select name,max(day),max(distance),(select sum(distance) from table) as total_dist
from tablename
group by name

MySQL, ordering GROUP BY

I have a table that has some values in it, along with the time that value was taken against an associated ID from another table.
I am looking to retrieve the latest value for every item in that table, and then order by those latest values.
Here is an SQL fiddle, http://www.sqlfiddle.com/#!2/0be99
And here is text output.
'hist' table
| HIST_ID | HIST_ITEM_ID | HIST_VALUE | HIST_TIME |
|---------|--------------|------------|------------|
| 1 | 1 | 1 | 1420291000 |
| 2 | 1 | 2 | 1420292000 |
| 3 | 1 | 3 | 1420293000 |
| 4 | 1 | 5 | 1420294000 |
| 5 | 1 | 10 | 1420295000 |
| 6 | 1 | 50 | 1420296000 |
| 7 | 1 | 60 | 1420297000 |
| 8 | 1 | 77 | 1420298000 |
| 9 | 1 | 90 | 1420299000 |
| 10 | 1 | 101 | 1420300000 |
| 11 | 2 | 1 | 1420291000 |
| 12 | 2 | 3 | 1420292000 |
| 13 | 2 | 7 | 1420293000 |
| 14 | 2 | 9 | 1420294000 |
| 15 | 2 | 15 | 1420295000 |
| 16 | 2 | 21 | 1420296000 |
| 17 | 2 | 33 | 1420297000 |
| 18 | 2 | 35 | 1420298000 |
| 19 | 2 | 55 | 1420299000 |
| 20 | 2 | 91 | 1420300000 |
'items' table
| ITEM_ID | ITEM_TITLE |
|---------|------------|
| 1 | ABCD |
| 2 | XYZ123 |
So, I can do something like...
select * from hist
inner join items on hist_item_id = item_id
group by hist_item_id
order by hist_value desc
However this returns me a grouping that I cannot order. How can I order this grouping? I had a look at other similar questions on here but was unable to apply their solutions successfully to my query to produce the desire result.
The desired result here would be to return.
HIST_ITEM_ID | ITEM_TITLE | HIST_VALUE |
|------------|------------|------------|
| 1 | ABCD | 101 |
| 2 | XYZ123 | 91 |
You can use a join to get the most recent history item. Then you can join back to the history table and the item table to get additional information:
select h.*, i.item_title
from (select hist_item_id, max(hist_id) as max_hist_id
from hist
group by hist_item_id
) hh join
hist h
on h.hist_id = hh.max_hist_id join
items i
on i.item_id = hh.hist_item_id;
Here is a SQL Fiddle.
You should use MAX function and group by the item id. That would look like this:
SELECT i.item_id, i.item_title, MAX(h.hist_value)
FROM items AS i
INNER JOIN hist AS h
ON i.item_id = h.hist_item_id
GROUP BY i.item_id

how to decide the Order of records as a Result of join query

The tables (from http://www.tutorialspoint.com/sql/sql-using-joins.htm)
1)Customers table:
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
| 7 | Muffy | 24 | Indore | 10000.00 |
+----+----------+-----+-----------+----------+
2) Orders table :
+-----+---------------------+-------------+--------+
|OID | DATE | CUSTOMER_ID | AMOUNT |
+-----+---------------------+-------------+--------+
| 102 | 2009-10-08 00:00:00 | 3 | 3000 |
| 100 | 2009-10-08 00:00:00 | 3 | 1500 |
| 101 | 2009-11-20 00:00:00 | 2 | 1560 |
| 103 | 2008-05-20 00:00:00 | 4 | 2060 |
+-----+---------------------+-------------+--------+
the inner join query is :
SELECT ID, NAME, AGE, AMOUNT
FROM CUSTOMERS, ORDERS
WHERE CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
The result shown is :
+----+----------+-----+--------+
| ID | NAME | AGE | AMOUNT |
+----+----------+-----+--------+
| 3 | kaushik | 23 | 3000 |
| 3 | kaushik | 23 | 1500 |
| 2 | Khilan | 25 | 1560 |
| 4 | Chaitali | 25 | 2060 |
+----+----------+-----+--------+
My question : the resultant table is clearly ordered according to the "ORDERS" table i.e the oredering in ID column in result table is 3,3,2,4 acc. to ORDERS table. Why is the ordering of IDs not according to the CUSTOMERS table i.e why is the result not
ID
2
3
3
4
and the corresponding values .Is there some sort of rule for that ?
You should use order by like below
SELECT ID, NAME, AGE, AMOUNT
FROM CUSTOMERS, ORDERS
WHERE CUSTOMERS.ID = ORDERS.CUSTOMER_ID order by ID asc;
The order of a query result is not defined until you define it. Use an ORDER BY clause when you are interested in a particular order.
That being said...
Don't use old style joins anymore. Every RDBMS supports SQL-92 join syntax.
Get into the habit of prefixing columns with the table name. Use a table alias to save typing.
.
SELECT
c.ID, c.NAME, c.AGE, o.AMOUNT
FROM
CUSTOMERS c
INNER JOIN ORDERS o ON c.ID = o.CUSTOMER_ID
ORDER BY
c.ID;