Insert in to a new table results from multiple queries - mysql

I have these queries and I want to insert these results in to a single temporary table. How Can I do that?
select date(max(created_date)) AS 'Last Shipped Date',
sum(item_count) AS 'Last Shipped Units'
from order
where is_shipped = 1
AND date(shipped_date) = (select date(max(shipped_date)) from order);
select
count(distinct o.key) AS 'ACTIVE ',
count(od.ean) AS 'Active_ Units'
from order o
left join order_details od on o.id = od. order_details
Where o.is_active = 1;
select count(distinct order_key) AS 'Total_Orders_Shipped_Yesterday',
sum(item_count) AS 'Total_units_Shipped_yesterday'
from order
where datediff(curdate(), modified_date)=1
AND is_shipped =1;
select count(distinct liquidation_order_id) AS 'orders cancelled',
count(ean) AS 'Units cancelled'
from order_details
where datediff(curdate(), modified_date)=1
AND order_details_status_ =4;

There may be a way to do it in one query, but it will be complicated. It's easier to just do a series of UPDATE queries that fill in the appropriate columns in the table by joining with the other queries that calculate the values.
CREATE TEMPORARY TABLE tempTable (
`Last Shipped Date` DATE,
`Last Shipped Units` INT,
Active INT,
Active_Units INT,
Total_Orders_Shipped_Yesterday INT,
Total_units_Shipped_yesterday INT,
`orders cancelled` INT,
`Units cancelled` INT);
INSERT INTO tempTable (`Last Shipped Date`, `Last Shipped Units`)
select date(max(created_date)) AS 'Last Shipped Date',
sum(item_count) AS 'Last Shipped Units'
from order
where is_shipped = 1
AND date(shipped_date) = (select date(max(shipped_date)) from order);
UPDATE tempTable AS t
JOIN order o
left join order_details od on o.id = od. order_details
SET t.Active = count(distinct o.key), t.Active_Units = count(od.ean)
Where o.is_active = 1;
UPDATE tempTable AS t
JOIN order
SET t.Total_Orders_Shipped_Yesterday = count(distinct order_key),
t.Total_units_Shipped_yesterday = SUM(item_count)
where datediff(curdate(), modified_date)=1
AND is_shipped =1;
UPDATE tempTable AS t
JOIN order_details
SET t.`orders cancelled` = count(distinct liquidation_order_id),
t.`Units cancelled` = COUNT(ean)
where datediff(curdate(), modified_date)=1
AND order_details_status_ =4;

Related

SQL query for Update table using Join & Group By

I have used this to get Data
SELECT customers.*, COUNT(invoice.payment_status) AS pending_invoices,sum(invoice.total ) AS total_pending_amount
FROM customers JOIN invoice ON (invoice.customer_id = customers.id)
WHERE invoice.payment_status = 'P' AND invoice.status = 'A' AND payment_followup_date IS NOT NULL AND payment_followup_date <= '2022-03-24 23:59'
GROUP BY invoice.customer_id
ORDER By payment_followup_date DESC
Now I am looking for a Query to perform an update on customers to add the current DateTime into payment_payment_followup_date and payment status = P for those customers who have more than 3 pending invoices
Try this:
UPDATE customers c
INNER JOIN (
SELECT
customer_id, COUNT(payment_status) pending_invoices
FROM invoice
WHERE payment_status = 'P' AND status = 'A'
GROUP BY customer_id
HAVING COUNT(payment_status) > 3
) i ON c.customer_id = i.customer_id
SET c.payment_payment_followup_date = CURRENT_TIMESTAMP()
c.payment_status = 'P'
WHERE c.payment_followup_date IS NOT NULL
AND c.payment_followup_date <= '2022-03-24 23:59'

SQL Recursion with Parent / Child for Employees

I have a little question:
I have a view and want to make a small recursive (my approach) call to a table called employee. There are the employees and a column "reportsTo", which gives the EmployeeId of the respective superior or parent.
There is also an invoice table with all purchases made by customers. The customers have a direct contact person / seller (SupportRepId). Now the annual sales of the employees are to be listed, as well as those of the direct employees. (Reverse ReportTo!)
create view employee_sales_v as
select employee.LastName, employee.ReportsTo, sum(invoice.total) sales,
year(invoice.InvoiceDate) year
from employee
join customer on customer.SupportRepId = employee.EmployeeId
join invoice on invoice.CustomerId = customer.CustomerId
group by employee.LastName, year(invoice.InvoiceDate);
How can I get these sales?
SampleData:
CREATE TABLE `Customer`
(
`CustomerId` INT NOT NULL AUTO_INCREMENT,
`SupportRepId` INT,
CONSTRAINT `PK_Customer` PRIMARY KEY (`CustomerId`)
);
CREATE TABLE `Employee`
(
`EmployeeId` INT NOT NULL AUTO_INCREMENT,
`LastName` NVARCHAR(20) NOT NULL,
`FirstName` NVARCHAR(20) NOT NULL,
`ReportsTo` INT,
CONSTRAINT `PK_Employee` PRIMARY KEY (`EmployeeId`)
);
CREATE TABLE `Invoice`
(
`InvoiceId` INT NOT NULL AUTO_INCREMENT,
`CustomerId` INT NOT NULL,
`InvoiceDate` DATETIME NOT NULL,
`Total` NUMERIC(10,2) NOT NULL,
CONSTRAINT `PK_Invoice` PRIMARY KEY (`InvoiceId`)
);
INSERT INTO `Employee` (`LastName`, `FirstName`, `ReportsTo`) VALUES (N'HGF', N'POI', 0);
INSERT INTO `Employee` (`LastName`, `FirstName`, `ReportsTo`) VALUES (N'XYZ', N'ABC', 1);
INSERT INTO `Customer` (`SupportRepId`) VALUES (2);
INSERT INTO `Customer` (`SupportRepId`) VALUES (2);
INSERT INTO `Invoice` (`CustomerId`, `InvoiceDate`, `Total`) VALUES (1, '2013/1/1', 1.98);
INSERT INTO `Invoice` (`CustomerId`, `InvoiceDate`, `Total`) VALUES (2, '2009/10/2', 3.96);
INSERT INTO `Invoice` (`CustomerId`, `InvoiceDate`, `Total`) VALUES (2, '2010/5/3', 5.94);
... as well as those of the direct employees.
Since only the sales total of the direct employees are needed, recursion is not required in this case.
SQL:
WITH CTE AS
(SELECT SupportRepId, year(i.InvoiceDate) AS YEAR, sum(i.total) total
FROM Customer c
INNER JOIN Invoice i on i.CustomerId = c.CustomerId
GROUP BY year(i.InvoiceDate), SupportRepId) ---CREATE CTE
SELECT
e1.LastName,
e1.ReportsTo,
t1.year,
IFNULL(cte1.total,0.00) AS `My Sales`,
IFNULL(t2.total,0.00) AS `Reportees Sales`
FROM Employee e1
INNER JOIN (SELECT DISTINCT year(i.InvoiceDate) AS year from Invoice i) t1 on 1 = 1 --- ALL DISTINCT YEARS
LEFT JOIN CTE cte1 on e1.EmployeeId = cte1.SupportRepId and t1.year = cte1.year
LEFT JOIN
(SELECT
e2.ReportsTo, cte2.year, sum(cte2.total) total
FROM Employee e2
INNER JOIN CTE cte2 ON e2.EmployeeId = cte2.SupportRepId
GROUP BY e2.ReportsTo, cte2.year) t2 --- GET EMPLOYEE DETAILS
ON t2.ReportsTo = e1.EmployeeId AND t1.year = t2.year
--- WHERE cte1.year is not null || t2.year is not null
ORDER by e1.LastName, t1.year
Details:
--- CREATE CTE : Fetch employees and their sales for each year. Created this subquery as cte since it needs to be reused
--- ALL DISTINCT : Fetch all the distinct year the invoice is generated. This will allow us to generate report for employees even if they have not made any sales on a year. (If that is not required, uncomment WHERE cte1.year is not null || t2.year is not null to filter out employees and reportes with no sales for a year).
--- GET EMPLOYEE DETAILS : This subquery fetches the sales details of the reportees.
Demo:
Fiddle Link over here. I have added additional test cases for validation.
Update: Query update for pre MySQL 8
SELECT
e1.LastName,
e1.ReportsTo,
t1.year,
IFNULL(cte1.total,0.00) AS `My Sales`,
IFNULL(t2.total,0.00) AS `Reportees Sales`
FROM Employee e1
INNER JOIN (SELECT DISTINCT year(i.InvoiceDate) AS year from Invoice i) t1 on 1 = 1 --- ALL DISTINCT YEARS
LEFT JOIN
(SELECT SupportRepId, year(i.InvoiceDate) AS YEAR, sum(i.total) total
FROM Customer c
INNER JOIN Invoice i on i.CustomerId = c.CustomerId
GROUP BY year(i.InvoiceDate), SupportRepId) cte1 on e1.EmployeeId = cte1.SupportRepId and t1.year = cte1.year
LEFT JOIN
(SELECT
e2.ReportsTo, cte2.year, sum(cte2.total) total
FROM Employee e2
INNER JOIN ((SELECT SupportRepId, year(i.InvoiceDate) AS YEAR, sum(i.total) total
FROM Customer c
INNER JOIN Invoice i on i.CustomerId = c.CustomerId
GROUP BY year(i.InvoiceDate), SupportRepId)) cte2
ON e2.EmployeeId = cte2.SupportRepId
GROUP BY e2.ReportsTo, cte2.year) t2 --- GET EMPLOYEE DETAILS
ON t2.ReportsTo = e1.EmployeeId AND t1.year = t2.year
--- WHERE cte1.year is not null || t2.year is not null
ORDER by e1.LastName, t1.year
Fiddle link: https://www.db-fiddle.com/f/td8RaWwYr7AKp1wWGfJ8yK/3

get record in sql

I have a table with the following fields:
SELECT `sms_id`,
`u_id`,
`sender_id`,
`mobile_no`,
`message`,
`campaign_name`,
`status`,
`request_id`,
`route_id`,
`totalnumber`,
`msgcreadit`,
`date1`,
`deductbal`,
`submited`
FROM `send_sms`
WHERE 1
I want to select u_id whose status ="pending", but I want the latest pending status according to the [date1] date field and I also want the count of individual u_ids with status ="pending".
How can I do it?
In MySQL you can do:
SELECT s.*
FROM `send_sms` s
WHERE s.status = 'pending' AND
s.date1 = (SELECT MAX(s2.date1) FROM send_sms s2 WHERE s2.u_id = s.u_id and s2.status = 'pending');
Just another approach:
SELECT s.*
FROM `send_sms` s
LEFT JOIN `send_sms` s2
ON s.date1 < s2.date1
AND s2.u_id = s.u_id
AND s2.status = 'pending'
WHERE s.status = 'pending'
AND s2.status IS NULL

sql select all if column has only two particular values

orders (
o_id INT AUTO_INCREMENT,
o_status TINYINT,
o_description VARCHAR(50),
)
orders_products (
op_id INT AUTO_INCREMENT,
op_order_id INT(11),
op_product_id INT(11),
op_price DECIMAL(19, 2),
)
How to select all orders that have ONLY products with id = 1 and id = 2.
Thank you and sorry from my English...
There are different ways to get the desired result, this utilizes conditional aggregation:
select *
from orders
where o_id in
(
select op_order_id
from orders_products
having count(case when op_product_id = 1 then 1 end) > 0 -- at least one row with 1
and count(case when op_product_id = 2 then 1 end) > 0 -- at least one row with 2
and count(case when op_product_id not in (1,2) then 1 end) = 0 -- no other value
)
Depending on indexes/selectivity EXISTS/NOT EXISTS might be faster:
select o_id
from orders as o
where exists (select *
from orders_products as op
where op.op_order_id = o.o_id
and op.op_product_id = 1) -- at least one row with 1
and exists (select *
from orders_products as op
where op.op_order_id = o.o_id
and op.op_product_id = 2) -- at least one row with 2
and not exists (select *
from orders_products as op
where op.op_order_id = o.o_id
and op.op_product_id not in (1,2)) -- no other value
You could first find all the distinct order and product combination for product 1 or 2 or both, and then look for orders that have both.
create table orders (o_id INT);
create table orders_products (op_order_id INT(11), op_product_id INT(11));
insert into orders values (1), (2);
insert into orders_products values (1, 1), (1, 2), (2, 2);
select o_id from (
select distinct o_id, op_product_id
from orders o
inner join orders_products op on op.op_order_id = o.o_id
where op.op_product_id in (1,2)
) main
group by o_id
having count(*) = 2
Result:
1
Another way to write the query could be like this:
select o_id
from orders o
where exists (select 1 from orders_products where op_order_id = o.o_id and op_product_id = 1)
and exists (select 1 from orders_products where op_order_id = o.o_id and op_product_id = 2)
I would do this using aggregation and having:
select order_id
from order_products op
group by order_id
having sum(product_id = 1) > 0 and
sum(product_id = 2) > 0 and
sum(product_id not in (1, 2)) = 0;
If you want additional information about the order, then just join in the orders table.
Your question is what I call a "set-within-set" query . . . looking for patterns in a hierarchy (that is products within an order). There are several ways to solve this, but the having clause turns out to be quite general.

view select cannot contain from clause

I have a SQL Query. When I run it executes successfully, but when i was trying to create a view with the query it shows create a view with each subquery.
SOS.
SELECT `product_category_vendor_id`,
ct1.category_id,
ct1.category_name,
c1.`product_id`,
p1.product_name,
c1.`vendor_id`,
v1.vendor_name,
c1.`product_purchase_price`,
c1.product_vendor_qty,
d1.available
FROM (SELECT `product_category_vendor_id`,
a1.`product_id`,
a1.`vendor_id`,
a1.`product_purchase_price`,
b2.product_vendor_qty
FROM (SELECT `product_category_vendor_id`,
`product_id`,
`vendor_id`,
`product_purchase_price`
FROM tbl_inksand_product_category_vendor
WHERE product_category_vendor_id IN
(SELECT
Max(product_category_vendor_id) AS
`Product_Category_Vendor_Id`
FROM
tbl_inksand_product_category_vendor
WHERE (
product_category_vendor_status =
'A' )
GROUP BY product_id,
`vendor_id`
ORDER BY `product_id`))
AS a1
JOIN (SELECT `product_id`,
`vendor_id`,
Sum(`product_vendor_qty`) AS Product_Vendor_Qty
FROM tbl_inksand_product_category_vendor
GROUP BY product_id,
`vendor_id`
ORDER BY `product_id`) b2
ON a1.`product_id` = b2.`product_id`
AND a1.`vendor_id` = b2.`vendor_id`) c1
JOIN (SELECT `product_id`,
`vendor_id`,
Count(`item_id`) AS Available
FROM `tbl_inksand_item_dtls`
WHERE `product_item_status` = 'Not Sale'
GROUP BY `product_id`,
`vendor_id`) d1
ON c1.`product_id` = d1.`product_id`
AND c1.`vendor_id` = d1.`vendor_id`
JOIN tbl_inksand_vendor AS v1
ON c1.`vendor_id` = v1.`vendor_id`
JOIN tbl_inksand_product p1
ON p1.product_id = c1.`product_id`
JOIN tbl_inksand_category ct1
ON ct1.category_id = p1.category_id
Subqueries cannot be used in the FROM clause of a view.
Source: https://dev.mysql.com/doc/refman/5.0/en/view-restrictions.html
So yeah it was the right reccomendation to create seperate views.