MySQL insert multiple row select in other table - mysql

I have small database with couple of tables for some small PHP project. One of my SELECTs (given bellow table) gives result like this:
+-------+------+------+
| idpart | qty |IMEI |
+-------+------+------+
| 2 | 4 | xxx |
| 6 | 1 | yyyy |
| 8 | 2 | zzzz |
|10 | 3 | ssss |
+-------+------+------+
Number of rows changes it can be 1 or n, but its never less then 1. idpart is not repeating it self as result of this query - it can be show only once. This is the actual query:
select odel_part.idpart as idpart, model_part.qtyused as qty, reparationorders.IMEI as IMEI
from reparation orders
inner join order model on order_model.idreparationorder=reparationorders.idreparationorder
inner join models on order_model.idmodel = models.idmodel
inner join model_part on models.idmodel = model_part.idmodel
inner join parts on model_part.idpart = parts.idpart
where reparationorders.idreparationorder = 1
Result of this query along with some additional data which is fixed has to be inserted in to other table. Other table has following fields:
+-----------+-----------+-------+--------+-----+-------+
| idtrans | idpart | qty | date | tt | IMEI |
+-----------+-----------+-------+--------+-----+-------+
idtrans - int which autoincrements
idpart - from query (idpart)
qty - from query (qty)
date - entered manualy
tt - entered manualy
IMEI - from query (IMEI)
in this 2nd table idtrans is unique, idpart can repeat it self thorough rows (this is intended behaviour, because this table will track usage of this parts for different dates).
Can you help me with doing this insert to 2nd table (name of 2nd table is transactions)?
Thank you in advance

You would just do:
insert into transactions(idpart, qty, date, tt, IMEI)
select idpart, qty, now(), #tt, imei
from reparations orders . . .;
The . . . is just the rest of your query. I am guessing that you want the current date/time inserted for "date"; now() provides that information.

Related

Find multiple totals by adding values from mysql table

I need to create a number adding all the values i can find in the db related to a specific customer.
Ex.
| Cust. | Value |
| 1 | 3 |
| 2 | 1 |
| 1 | 1 |
| 2 | 1 |
| 3 | 5 |
The result i want is : Customer #1 = 4, Customer #2 = 2; Customer #3 = 5.
There is a way to do that right into the mysql query?
Try Below query.
Select CONCAT('Customer #' , cust) as customer , sum(Value)
FROM customer_table
Group By cust
You want to SUM the values with a specific GROUP BY clause. Think of the GROUP BY as dividing rows into buckets and the SUM as aggregating the contents of those buckets into something useful.
Something like:
SELECT SUM(Value) FROM table GROUP BY Cust

SQL query to get SUM from more dependent tables

I have the following MySQL DB structure:
table sales_order - id, name, ...
id | name
------------------
1 | Order Test
table sales_order_item - id, order_id, name, amount_dispatched ...
id | order_id | name | amount_dispatched
------------------------------------------
1 | 1 | Item 1 | 5
2 | 1 | Item 2 | 10
table sales_order_item_invoice - id, item_id, amount, ...
id | item_id | amount
---------------------
1 | 1 | 3
2 | 2 | 5
3 | 2 | 5
These three tables are in chain via the foreign keys. Table "invoice" can have more rows for one row in "item". Table "item" can have more rows for one row in "order".
Now, I need to create SQL query that returns all rows from table sales_order and appends there some data from the other tables - amount_dispatched and amount_invoiced:
dispatched = sum of all order's items' amount_dispatched
invoiced = sum of all invoices' amount (or 0 if no invoice exists)
Such query seems to be straightforward:
SELECT
`sales_order`.*,
SUM(`sales_order_item`.`amount_dispatched`) AS dispatched,
SUM(`sales_order_item_invoice`.`amount`) AS invoiced,
FROM `sales_order`
LEFT JOIN `sales_order_item` ON `sales_order`.`id` = `sales_order_item`.`order_id`
LEFT JOIN `sales_order_item_invoice` ON `sales_order_item`.`id` =`sales_order_item_invoice`.`item_id`
GROUP BY `sales_order`.`id`
The result contains all orders - ok
The result contains sum of invoices amount - ok
The result of "amount_dispatched" is invalid - if the item has more rows in item_invoice, the item's amount is summed several times, so for the example above, I get:
id | name | dispatched | invoiced
---------------------------------------
1 | Order Test | 25 | 13
Amount_dispatched is 25, but I would expect it to be 15.
Any idea how to correct my SQL query?
Thank you.
Firstly, use subquery do aggregation for invoice amount in sales_order_item_invoice, then left join.
SELECT
`sales_order`.*,
SUM(`sales_order_item`.`amount_dispatched`) AS dispatched,
SUM(t.`amount`) AS invoiced
FROM `sales_order`
LEFT JOIN `sales_order_item` ON `sales_order`.`id` = `sales_order_item`.`order_id`
LEFT JOIN (
SELECT item_id, SUM(amount) AS amount
FROM `sales_order_item_invoice`
GROUP BY item_id
) t ON `sales_order_item`.`id` = t.`item_id`
GROUP BY `sales_order`.`id`

SQL Query - Getting Sum Of Multiple Column with Id in Table Using Inner Join

Good day,
I'm creating a query where I can throw inside the data grid view.
Suppose I have 2 table namely table A and table B. Table A has StaffId column and while Table B has StaffId too. Table B can have multiple value of cost with foreign key of StaffId. What I'm trying to do is, get all the sum value inside the Table B with the same StaffId.
Here's the sample table definitions and contents.
// Table A
| StaffId | Name |
| 1 | Dummmy |
// Table B
| Id | StaffId | Cost |
| 1 | 1 | 10.00 |
| 2 | 1 | 10.00 |
| 3 | 1 | 10.00 |
I already tried this query, but I can't get the correct answer.
SELECT A.Name, Sum(B.Cost) FROM B INNER JOIN A ON A.StaffId=B.StaffId
The answer should be like this
Dummy | 30.00
but my query doesn't work. How can I get the value of all the cost in the table B?
Any help would be much appreciate. Thank you in advance.
Try like this,
To find sum of cost for each and every StaffId's you should use this.
SELECT A.StaffId
,A.NAME
,Sum(B.Cost) as Total
FROM B
INNER JOIN A ON A.StaffId = B.StaffId
GROUP BY A.StaffId
,A.NAME
To find all the cost for all the StaffId's you should use this.
SELECT Sum(B.Cost)
FROM B
INNER JOIN A ON A.StaffId = B.StaffId

Query to Find Duplicate entries

I am looking for an SQL query to give me a list of duplicate entries in a table. However, there are 3 different columns to take into account. First is an ID, Second is a Name, and third is a Date. The situation is that there are multiple Names that are assigned with the same ID, and there are multiple records of those in a day, which makes THOUSANDS of different records per day.
I already filtered it so that only results for the past 7 days will show, but the amount of records is still too much for me to extract. I just want to decrease the number of rows in the output order to properly extract the results.
Sample
|--id-|--name--|-------date------|
| 1 | a |5-9-2015, 10:00am|
| 1 | a |5-8-2015, 10:02am|
| 1 | a |5-8-2015, 11:00am|
| 1 | b |5-8-2015, 10:00am|
| 1 | b |5-8-2015, 10:02am|
| 1 | c |5-8-2015, 10:00am|
| 2 | d |5-8-2015, 10:00am|
expected output
|--id-|--name--|
| 1 | a |
| 1 | b |
| 1 | c |
| 2 | d |
Inclusion of entries without any duplicates are fine. The important thing is to only return a single record of a unique id-name combination for a day.
Thanks in advance for any help that you can give.
You can get the combinations as:
select distinct id, name
from sample;
If you want duplicates, using group by and having:
select id, name
from sample
group by id, name
having count(*) > 1;
EDIT:
If you want this by date, then add date(date) to the group by and perhaps select clauses.
To return single id-name data per day you can use this:
select id, name
from tab
group by id, name, date(date)
The DATE() function extracts the date part of a date or date/time expression.
select id,name
from sample
group by id,name,DATE(date)
having count(*)>1;

MySQL conditionally populate column 3 based on DISTINCT involving 2 other columns in one table

Had a good read through similar topics but I can't quite a) find one to match my scenario, or b) understand others enough to fit / tailor / tweek to my situation.
I have a table, the important fields being;
+------+------+--------+--------+
| ID | Name | Price |Status |
+------+------+--------+--------+
| 1 | Fred | 4.50 | |
| 2 | Fred | 4.50 | |
| 3 | Fred | 5.00 | |
| 4 | John | 7.20 | |
| 5 | John | 7.20 | |
| 6 | John | 7.20 | |
| 7 | Max | 2.38 | |
| 8 | Max | 2.38 | |
| 9 | Sam | 21.00 | |
+------+------+--------+--------+
ID is an auto-incrementing value as records get added throughout the day.
NAME is a Primary Key field, which can repeat 1 to 3 times in the whole table.
Each NAME will have a PRICE value, which may or may not be the same per NAME.
There is also a STATUS field that need to be populated based on the following, which is actually the part I am stuck on.
Status = 'Y' if each DISTINCT name has only one price attached to it.
Status = 'N' if each DISTINCT name has multiple prices attached to it.
Using the table above, ID's 1, 2 and 3 should be 'N', whilst 4, 5, 6, 7, 8 and 9 should be 'Y'.
I think this may well involve some form of combination of JOINs, GROUPs, and DISTINCTs but I am at a loss on how to put that into the right order for SQL.
In order to get the count of distinct Price values per name, we must use a GROUP BY on the Name field, but since you also want to display all names ungrouped but with an additional Status field, we must first create a subselect in the FROM clause which groups by the name and determines whether the name has multiple price values or not.
When we GROUP BY Name in the subselect, COUNT(DISTINCT price) will count the number of distinct price values for each particular name. Without the DISTINCT keyword, it would simply count the number of rows where price is not null.
In conjunction with that, we use a CASE expression to insert N into the Status column if there is more than one distinct Price value for the particular name, otherwise, it will insert Y.
The subselect only returns one row per Name, so to get all names ungrouped, we join that subselect to the main table on the condition that the subselect's Name = the main table's Name:
SELECT
b.ID,
b.Name,
b.Price,
a.Status
FROM
(
SELECT Name, CASE WHEN COUNT(DISTINCT Price) > 1 THEN 'N' ELSE 'Y' END AS Status
FROM tbl
GROUP BY Name
) a
INNER JOIN
tbl b ON a.Name = b.Name
Edit: In order to facilitate an update, you can incorporate this query using JOINs in the UPDATE like so:
UPDATE
tbl a
INNER JOIN
(
SELECT Name, CASE WHEN COUNT(DISTINCT Price) > 1 THEN 'N' ELSE 'Y' END AS Status
FROM tbl
GROUP BY Name
) b ON a.Name = b.Name
SET
a.Status = b.Status
Assuming you have an unfilled Status column in your table.
If you want to update the status column, you could do:
UPDATE mytable s
SET status = (
SELECT IF(COUNT(DISTINCT price)=1, 'Y', 'N') c
FROM (
SELECT *
FROM mytable
) s1
WHERE s1.name = s.name
GROUP BY name
);
Technically, it should not be necessary to have this:
FROM (
SELECT *
FROM mytable
) s1
but there is a mysql limitation that prevents you to select from the table you're updating. By wrapping it in parenthesis, we force mysql to create a temporary table and then it suddenly is possible.