Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 months ago.
Improve this question
Query Result
date_created
sub_total
total_amount
budget_id
10000
2022-09-25
700
9300
1
2022-09-21
500
8800
1
2022-09-15
900
7900
1
2022-09-01
500
7400
1
7400
Budget Table
id
budget
1
10000
Here's my query
SELECT date_created, sub_total,
budget - LAG(sub_total) OVER (ORDER BY date_created DESC)
as total_amount
FROM sales
LEFT JOIN budget_table ON budget.id = sales.budget_id
WHERE budget_id = 1
ORDER BY date_created DESC
Union to get start and end position and subtract cumulative sum from budget to get detail (lag is inappropriate here). prepend a seq to assist ordering
DROP TABLE IF EXISTS T,T1;
CREATE TABLE T
(date_created DATE,SUB_TOTAL INT,BUDGET_ID INT);
INSERT INTO T VALUES
('2022-09-25' ,700, 1),
('2022-09-21' ,500, 1),
('2022-09-15' ,900, 1),
('2022-09-01' ,500, 1);
CREATE TABLE T1(BUDGET_ID INT,BUDGET INT);
INSERT INTO T1 VALUES (1,10000);
SELECT 2 SEQ,T.BUDGET_ID,date_created, sub_total,
BUDGET - SUM(sub_total) OVER (ORDER BY date_created DESC) TOTAL_AMOUNT
FROM T
LEFT JOIN T1 ON T1.budget_id = T.budget_id
WHERE T.budget_id = 1
UNION ALL
SELECT 1 AS SEQ, T1.BUDGET_ID,NULL,NULL,T1.BUDGET FROM T1
UNION ALL
SELECT 3 AS SEQ, T.BUDGET_ID,NULL,NULL,
BUDGET - SUM(sub_total) TOTAL_AMOUNT
FROM T
LEFT JOIN T1 ON T1.budget_id = T.budget_id
WHERE T.budget_id = 1
ORDER BY BUDGET_ID,SEQ,date_created DESC
+-----+-----------+--------------+-----------+--------------+
| SEQ | BUDGET_ID | date_created | sub_total | TOTAL_AMOUNT |
+-----+-----------+--------------+-----------+--------------+
| 1 | 1 | NULL | NULL | 10000 |
| 2 | 1 | 2022-09-25 | 700 | 9300 |
| 2 | 1 | 2022-09-21 | 500 | 8800 |
| 2 | 1 | 2022-09-15 | 900 | 7900 |
| 2 | 1 | 2022-09-01 | 500 | 7400 |
| 3 | 1 | NULL | NULL | 7400 |
+-----+-----------+--------------+-----------+--------------+
6 rows in set (0.002 sec)
Related
im new in sql. I cannot get data with format what i want in one step. Now i'm using more sql commands. I want to get all data in one command because i cant to connect them in subquery with group by. Somebodys can help me?
example of Table i have:
id
order_id
order_status
1
1
0
2
1
0
3
1
0
4
1
1
5
1
1
6
2
0
7
2
0
8
2
1
Table i want to have after sql query:
order_id
count
of
progress(%)
1
2
5
40
2
1
3
33
queries i use:
SELECT order_id, COUNT(status) as count
FROM `orders`
WHERE status = 1
GROUP by order_id;
SELECT order_id, COUNT(status) as of
FROM `orders`
GROUP by order_id;
SELECT order_id,
CAST((SELECT COUNT(status) FROM `orders` WHERE status = 1) /
(SELECT COUNT(status) FROM `orders`) *100 as int) AS progress FROM orders
group by order_id;
but last working properly only if i use where to single order id.
I want to make this data in one sql query to format i showed up.
Thanks a lot guys!
You don't need subqueries to do this, SQL's ordinary aggregate functions already work as you want with your group by clause:
SELECT order_id,
SUM(order_status) AS `count`,
COUNT(*) AS `of`,
SUM(order_status) / COUNT(order_status) * 100 as `progress`
FROM orders
group by order_id;
See example at http://sqlfiddle.com/#!9/d1799db/4/0
you need to use multiple subqueries
here's a query that I used and worked on your example on the onecompiler.com website
-- create
CREATE TABLE EMPLOYEE (
order_id INTEGER,
order_status INTEGER
);
-- insert
INSERT INTO EMPLOYEE VALUES (1,0 );
INSERT INTO EMPLOYEE VALUES (1, 0);
INSERT INTO EMPLOYEE VALUES (1, 0);
INSERT INTO EMPLOYEE VALUES (1, 1);
INSERT INTO EMPLOYEE VALUES (1,1 );
INSERT INTO EMPLOYEE VALUES (2, 0);
INSERT INTO EMPLOYEE VALUES (2, 0);
INSERT INTO EMPLOYEE VALUES (2, 1);
select *
from EMPLOYEE;
SELECT order_id, count, off , count/off
from(
select distinct order_id as order_id,
(select count(order_id) from EMPLOYEE C WHERE A.order_id=C.order_id AND order_status =1) as 'count',
(select count(order_id) from EMPLOYEE B WHERE A.order_id=B.order_id ) as 'off'
FROM EMPLOYEE A
) AA
;
You need to use sum and count with group by.
create table orders(
id int,
order_id int,
order_status int);
insert into orders values
(1,1,0),
(2,1,0),
(3,1,0),
(4,1,1),
(5,1,1),
(6,2,0),
(7,2,0),
(8,2,1);
select
order_id,
sum(order_status) count,
count(order_id) "of",
(100 * sum(order_status))
/ count(order_id) progress
from orders
group by order_id
order by order_id;
order_id | count | of | progress
-------: | ----: | -: | -------:
1 | 2 | 5 | 40.0000
2 | 1 | 3 | 33.3333
db<>fiddle here
i was described my problem without some details, w i want to join with other table but i see only record with status
oders_details
| id | order_describe | order_date |
|:----:|:--------------:|:----------:|
| 1 | sample 1 | 2022-02-28 |
| 2 | sample 2 | 2022-02-28 |
| 3 | sample 3 | 2022-03-01 |
| 4 | sample 4 | 2022-03-02 |
orders_status
| id | order_id |order_status|
|:---:|:---------------:|:----------:|
| 1 | 1 | 0 |
| 2 | 1 | 0 |
| 3 | 1 | 0 |
| 4 | 1 | 1 |
| 5 | 1 | 1 |
| 6 | 2 | 0 |
| 7 | 2 | 0 |
| 8 | 2 | 1 |
table i want after query
orders_view
| id |order_id|order_describe| order_date | count | of | progress |
|-----|--------|--------------|------------|-------|----|:--------:|
| 1 | 1 | sample 1 | 2022-02-28| 2 | 5 | 40 |
| 2 | 2 | sample 2 | 2022-02-28| 1 | 3 | 33 |
| 3 | 3 | sample 3 | 2022-03-01| null |null| null |
| 4 | 4 | sample 4 | 2022-03-02| null |null| null |
i want to get some hint what i have todo, to get finally table or view, not complete solution, to better understand sql lang
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Scenario:
A factory producing steel pipes every day in various sizes and gauges (swg), are logged and stored in the pipe_production table (pipe_id foreign key to pipe table). The factory also has clients to which it regularly sells pipes, upon request an invoice is created and logged in the invoices table. Subsequently, the related pipes relative to each invoice are stored in the pipe_invoices table. When a member of the sales team authorises the invoice, the authorised column switches from false to true (0 => 1 in) in the invoices table and signals that that these pipes will be sold and should be removed from the stock.
I'm looking for a query to produce a stock table to accurately assess the pipe onsite. However I'm only looking to find only the difference between pipes produced and AUTHORISED invoice pipes.
The application is being built on the Laravel framework.
Table: pipes
id | description | swg | min_weight | max_weight
1 | 2" X 2" | 16 | 10 | 11
2 | 2" X 2" | 18 | 8 | 19
3 | 1" X 2" | 18 | 4 | 6
Table: pipe_productions
id | pipe_id | quantity | production_date
1 | 1 | 1000 | 2020-10-1
2 | 2 | 2000 | 2020-10-1
3 | 3 | 5500 | 2020-10-1
Table: invoices
id | client_id | authorised | loaded | invoice_date
1 | 1 | 0 | 0 | 2020-10-09
2 | 2 | 1 | 0 | 2020-10-09
3 | 2 | 1 | 1 | 2020-10-09
Table: pipe_invoices
id | invoice_id | pipe_id | quantity
1 | 1 | 3 | 2000
2 | 1 | 1 | 1000
3 | 2 | 2 | 1000
Edit:
My Current query which only gets the difference between pipe_production and pipe_invoices. It does not account for the case where the invoice is not authorised and should not be removed.
SELECT *, coalesce(a.quantity, 0)-coalesce(b.quantity, 0) as diff
FROM
(SELECT pipe_id, sum(quantity) as quantity
FROM pipe_productions
GROUP BY pipe_id) a
LEFT JOIN
(SELECT pipe_id, sum(quantity) as quantity
FROM pipe_invoices
GROUP BY pipe_id) b
on a.pipe_id = b.pipe_id
LEFT JOIN pipes
on a.pipe_id = pipes.id
WHERE coalesce(a.quantity, 0)-coalesce(b.quantity, 0) != 0
ORDER BY swg asc, pipe_description desc
I assume that you only need to a small adaption to your query and join invoices in your b statement:
SELECT *, coalesce(a.quantity, 0)-coalesce(b.quantity, 0) as diff
FROM
(
SELECT pipe_id, sum(quantity) as quantity
FROM pipe_productions
GROUP BY pipe_id
) a
LEFT JOIN
(
SELECT pipe_id, sum(quantity) as quantity
FROM pipe_invoices pi
JOIN invoices i ON pi.invoice_id = i.id
WHERE i.authorised = 1
GROUP BY pipe_id
) b
on a.pipe_id = b.pipe_id
LEFT JOIN pipes
on a.pipe_id = pipes.id
WHERE coalesce(a.quantity, 0)-coalesce(b.quantity, 0) != 0
ORDER BY swg asc, pipe_description desc
I have a table tmp_addit which looks like this
addition_id allowance_id sal_id amount
--------------------------------------------
1 4 1 300
2 5 1 400
3 6 1 200
4 4 2 300
5 5 2 250
6 6 2 150
I want to update the table such that the amount with allowance_id in (5,6) must be added to allowance_id = 4. Eg: I want to get 900 as amount for (sal_id = 1 and allowance_id = 4).
I tried this code but it's not working
update tmp_addit set amount =(select sum(amount) from tmp_addit
where allowance_id in(5,6)
group by salary_id) where allowance_id=4;
Any help?
With this query:
select salary_id, sum(amount) amount
from tmp_addit
where allowance_id in (5, 6)
group by salary_id
you get the sums that you want to add to the column amount.
Then you need to join this query to the table in an UPDATE statement:
update tmp_addit t
inner join (
select salary_id, sum(amount) amount
from tmp_addit
where allowance_id in (5, 6)
group by salary_id
) g on g.salary_id = t.salary_id
set t.amount = t.amount + g.amount
where t.allowance_id = 4;
See the demo.
Result:
| addition_id | allowance_id | salary_id | amount |
| ----------- | ------------ | --------- | ------ |
| 1 | 4 | 1 | 900 |
| 2 | 5 | 1 | 400 |
| 3 | 6 | 1 | 200 |
| 4 | 4 | 2 | 700 |
| 5 | 5 | 2 | 250 |
| 6 | 6 | 2 | 150 |
I'd use a join on the aggregated query by the sal_id:
UPDATE tmp_addit t
JOIN (SELECT sal_id, SUM(amount) AS sum_amount
FROM tmp_addit
WHERE allowance_id IN (5, 6)) s ON t.sal_id = s.sal_id
SET t.amount = t.amount + s.sum_amount
WHERE allowance_id = 4
Hi I am a PHP Developer weak in MySQL Medium complex queries make my head fired.
The below is the table vulnerability.
+-----------------------------------------------------------------------------------------------+
| id | webisite_id | low_count| high_count | medium_count | date_time | vul_date |
+-----------------------------------------------------------------------------------------------+
| 20 | 6 | 1 | 1 | 1 | 2018-07-04 09:14:04 | 2018-02-01 |
| 19 | 6 | 30 | 30 | 30 | 2018-07-04 09:13:38 | 2018-01-30 |
| 18 | 6 | 1 | 1 | 1 | 2018-07-04 09:13:16 | 2018-01-01 |
+-----------------------------------------------------------------------------------------------+
This table represent count of low, medium, high - vulnerability count for each website in database. We can enter as many entries for each websites. But the only relevant entry for a website is the latest entry in each month (based on vul_date).
Here I need help I want query which fetch sum of counts low, high, medium of each websites of each month of last 1 year, for example if -> website with id 1 has 1, 2, 3 low, high, medium number of vulnerabilities, on month June and
-> that of with id 2 has 7, 8, 9 respectively the result should be for June 8, 10, 12. And like last 1 year's each month result should be get. If no entry it should be 0.
Note that the entries should be the maximum value of vul_date and if a site has multiple entries on the same vul_date get the latest date_time entry.
I tried to write question as much as simple. hope the question is understood.
Please help me on this
Thanks in advance.
I think below query will work for you.
SELECT
SUM(low_count),
SUM(medium_count),
SUM(high_count),
MONTH(vul_date)
FROM
(SELECT
low_count, medium_count, high_count, vul_date, date_time
FROM
test
WHERE
(website_id , vul_date) IN (SELECT website_id, MAX(vul_date)
FROM test GROUP BY website_id , MONTH(vul_date))) t
WHERE
date_time IN (SELECT MAX(date_time) FROM test GROUP BY website_id , vul_date)
GROUP BY MONTH(vul_date);
What it does is, first finds the latest entry month wise for each website id which is your max vul_date.
SELECT website_id, MAX(vul_date)
FROM test GROUP BY website_id , MONTH(vul_date)
If there are more than one entry for a vul_date, it uses date_time to select maximum value from them. Finally it sums all website date after grouping it month wise.
You can change the above query to get 0 value for those months where there is no entry for any websites.
DROP TABLE IF EXISTS T;
CREATE TABLE T(id INT, website_id INT, low_count INT, high_count INT, medium_count INT, date_time DATETIME, vul_date DATE);
INSERT INTO T VALUES
( 20 , 6 , 1 , 1 , 1, '2018-07-04 09:14:04' , '2018-02-01'),
( 19 , 6 , 30, 30, 30, '2018-07-04 09:13:38' , '2018-01-30'),
( 18 , 6 , 2 , 2 ,2 , '2018-07-04 09:13:16' , '2018-01-01'),
( 17 , 6 , 2 , 2 ,2 , '2018-07-04 09:12:01' , '2018-01-01'),
( 90 , 1,1,2,3,'2017-07-05 01:00:00',' 2017-07-06'),
( 90 , 2,8,9,10,'2017-07-05 01:00:00',' 2017-07-06');
select coalesce(c.yyyymm,d.yyyymm) yyyymm,
coalesce(c.lo,0) lo,
coalesce(c.hi,0) hi,
coalesce(c.med,0) med
from
(
SELECT concat(year(a.vul_date),'-',month(a.vul_date)) yyyymm,
SUM(LOW_COUNT) lo,SUM(HIGH_COUNT) hi,sum(medium_count) med
from
(
select website_id,date_time,vul_date
from t
where date_time = (select max(date_time) from t t1 where t1.website_id = t.website_id and t1.vul_date = t.vul_date)
) a
join
(select website_id, date_time,vul_date,
LOW_COUNT,HIGH_COUNT,medium_count
from t) b
on b.website_id = a.website_id and b.date_time = a.date_time
group by concat(year(a.vul_date),'-',month(a.vul_date))
) c
right join
(select distinct concat(year(dte),'-',month(dte)) yyyymm from dates d
where dte between date_sub(now(), interval 1 year) and now()
) d on d.yyyymm = c.yyyymm
;
Sub query a get the vul_date with the most recent data_time which is then self joined, aggregated and then infilled with missing dates using a right join to a dates/calender table. If you don't have a dates/calender it would be useful for this kind of exercise nut there are alternatives which you can find in SO.
Result
+---------+------+------+------+
| yyyymm | lo | hi | med |
+---------+------+------+------+
| 2017-7 | 9 | 11 | 13 |
| 2017-8 | 0 | 0 | 0 |
| 2017-9 | 0 | 0 | 0 |
| 2017-10 | 0 | 0 | 0 |
| 2017-11 | 0 | 0 | 0 |
| 2017-12 | 0 | 0 | 0 |
| 2018-1 | 32 | 32 | 32 |
| 2018-2 | 1 | 1 | 1 |
| 2018-3 | 0 | 0 | 0 |
| 2018-4 | 0 | 0 | 0 |
| 2018-5 | 0 | 0 | 0 |
| 2018-6 | 0 | 0 | 0 |
| 2018-7 | 0 | 0 | 0 |
+---------+------+------+------+
13 rows in set (0.04 sec)
I have a table:
ID | User | Amount
1 | 1 | 50
2 | 1 | 80
3 | 2 | 80
4 | 2 | 100
5 | 1 | 90
6 | 1 | 120
7 | 2 | 120
8 | 1 | 150
9 | 2 | 300
I do a query:
SELECT * FROM TABLE ORDER BY amount DESC group by userid
I'm getting this:
ID | User | Amount
1 | 1 | 50
2 | 1 | 80
But I was expecting:
ID | User | Amount
9 | 2 | 300
8 | 1 | 150
What is wrong with my sql?
When grouping you have to use aggregate functions like max() for all columns that are not grouped by
select t.*
from table t
inner join
(
SELECT userid, max(amount) as total
FROM TABLE
group by userid
) x on x.userid = t.userid and x.total = t.amount
ORDER BY t.amount DESC
Another solution.Check SQL Fiddle
Using FIND_IN_SET clause
SELECT
ua.*
FROM user_amount ua
WHERE FIND_IN_SET(ua.amount,(SELECT
MAX(ua1.amount)
FROM user_amount ua1
WHERE ua1.user = ua.user)) > 0
ORDER BY amount desc;
Using IN clause
SELECT
ua.*
FROM user_amount ua
WHERE ua.amount IN (SELECT
MAX(ua1.amount)
FROM user_amount ua1
WHERE ua1.user = ua.user)
ORDER BY amount desc