Count Low, Median, Average, High using MySql query - php

I have following records in my table:
Name Status Price
Product 1 Active 110
Product 2 Active 165
Product 3 Expire 256
Product 4 Pending 154
Product 5 Active 856
Product 6 Expire 523
Product 7 Pending 220
Product 8 Active 321
Product 9 Pending 478
Product 10 Expire 210
and I need output by mysql query as follow:
Status Low Median Average High
Active ? ? ? ?
Expire ? ? ? ?
Pending ? ? ? ?
I don't know how to do this by mysql query.
Thanks in advance.

SELECT status, MIN(price) as Low, MAX(price) as High, AVG(price) as Average
FROM your_table
GROUP BY status

try following code:
<?php
$arr = array( 'Active', 'Expire', 'Pending');
foreach($arr as $status) {
$stmt = "SELECT a.max, a.min, a.avg, price AS med, IF(price > a.avg, price - a.avg, a.avg-price ) AS diff FROM tbl_report_address_lists, ( SELECT ROUND(AVG(price),2) as avg, MAX(price) AS max, MIN(price) AS min FROM tbl_report_address_lists WHERE `report_id` = 13 AND `status` = '$status') AS a WHERE `report_id` = 13 AND `sales_code` = '$status' ORDER BY diff ASC LIMIT 1";
// execute query, get result data and use it
}
?>

I have prepared following query to calculate High, Low, Med and Avg, but this query calculate prices only for single status at a time:
SELECT STATUS , a.max AS High, a.min AS Low, a.avg AS Avg, Price AS Med, IF( Price > a.avg, Price - a.avg, a.avg - Price ) AS diff
FROM Table, (
SELECT ROUND( AVG( Price ) , 2 ) AS avg, MAX( Price ) AS max, MIN( Price ) AS min
FROM Table
WHERE STATUS = 'Pending'
) AS a
WHERE STATUS = 'Pending'
ORDER BY diff ASC
LIMIT 1
If I removed WHERE STATUS = 'Pending' condition, return inaccurate result.

Related

SQL multiple rows in single row

Hi everyone I have this table and I want to show result in single row group by client id and show availability for stock 1 and 2.
Here is my table
id client stock material quantity availability date
62 56 1 0 0 100 2017-12-16 23:55:01
63 56 2 0 0 900 2017-12-16 23:55:01
64 56 1 100 -20 80 2017-12-16 23:55:20
65 56 1 80 100 180 2017-12-16 23:56:06
66 56 1 180 200 380 2017-12-16 23:56:21
67 56 1 380 500 880 2017-12-16 23:58:11
68 56 1 880 -580 300 2017-12-16 23:58:38
69 56 2 900 -90 810 2017-12-17 23:59:18
Outcome I want is get result from last date, group by client id and combine stock 1 and stock 2 to single row
client availability1 availability2
56 300 810
I try this query
SELECT
historys.id
,(CASE WHEN historys.stock = 1 THEN availability END) AS availability1
,(CASE WHEN historys.stock = 2 THEN availability END) AS availability2
FROM historys
GROUP BY historys.client
ORDER by historys.id
The result is
id availability1 availability2
56 NULL 810
I will be grateful if someone help me. Thanks.
You need to filter to the right rows before the aggregation. Here is one method:
SELECT h.client,
MAX(CASE WHEN h.stock = 1 THEN h.availability END) AS availability1
MAX(CASE WHEN h.stock = 2 THEN h.availability END) AS availability2
FROM historys h
WHERE h.date = (SELECT MAX(h2.date) FROM historys h2 WHERE h2.stock = h.stock)
GROUP BY h.client
Use a union
SELECT
client, max(availability1) AS availability1, max(availability2) AS availability2
FROM
(
SELECT
client
,availability AS availability1
,0 AS availability2
FROM historys hist
WHERE id = (select max(id) from historys where client = hist.client and stock = 1)
UNION ALL
SELECT
client
,0 AS availability1
,availability AS availability2
FROM historys hist2
WHERE id = (select max(id) from historys where client = hist2.client and stock = 2)
) a
GROUP by client
ORDER by client
The NULL you have is because your selecting data from lines of historys that cannot contain the availability for stock = 1 and stock = 2 at the same time.
You can bypass that using historys both times like above :
In the subrequest (as d) we get max dates by client, then we join history two times to get both availability in a row.
select d.client,
h1.availability availability1,
h2.availability availability2
from
(
select client,
max(case when stock = 1 then date end) d1,
max(case when stock = 2 then date end) d2
from historys
group by client
) d
join historys h1 on (h1.stock = 1
and h1.date = d.d1
and h1.client = d.client)
join historys h2 on (h2.stock = 2
and h2.date = d.d2
and h2.client = d.client)
You can find an SQLFiddle here : http://sqlfiddle.com/#!9/d1ea4/5
Thanks
This may help you :
SELECT T.client client ,
SUM(CASE WHEN T.Stock = 1 THEN T.availability
END) availability1 ,
SUM(CASE WHEN T.Stock = 2 THEN T.availability
END) availability2
FROM historys T
INNER JOIN ( SELECT MAX(date) Max_Date ,
stock
FROM historys
GROUP BY stock
) T1 ON T1.Max_Date = T.date
AND T1.stock = T.stock
GROUP BY T.client
Depending on your MySQL version, you should be able to do this with a window function & a common table expression:
-- Build derived src table with "latest date" rows
WITH src AS (
SELECT id, client, stock, material, quantity, availability, date
FROM (
SELECT
id, client, stock, material, quantity, availability, date,
ROW_NUMBER() OVER(PARTITION BY client, stock ORDER BY date DESC) ClientStockRank -- For each (client, stock) pair, rank each row by date
FROM historys a
) src
WHERE ClientStockRank = 1 -- Only get rows with "latest date"
)
SELECT
client,
MAX(CASE WHEN stock = 1 THEN availability ELSE NULL) END AS Availability1, -- Get "max" value for "stock 1"
MAX(CASE WHEN stock = 2 THEN availability ELSE NULL) END AS Availability2 -- Get "max" value for "stock 2"
FROM src
GROUP BY client
I think you need MySQL 8+. If not, there should be other ways to do it too. Let me know if that works.
Update
Actually, this should also suffice:
SELECT DISTINCT
client,
MAX(CASE WHEN stock = 1 THEN availability ELSE NULL) OVER(PARTITION BY client ORDER BY date DESC) AS Availability1,
MAX(CASE WHEN stock = 2 THEN availability ELSE NULL) OVER(PARTITION BY client ORDER BY date DESC) AS availability2
FROM historys

How to fetch two tables and sort the data by date?

I need a query that fetches data fron two tables and sort them by date.
Table 1: Invoice
<?php
$query = mysql_query("select * from invoice where customer = 95");
?>
ID Customer Amount Date
1 95 1500 01-Apr-2017
2 95 5500 09-Apr-2017
3 95 22000 10-Apr-2017
4 95 35000 11-Apr-2017
Table 2: Payments
<?php
$query = mysql_query("select * from Payments where customer = 95");
?>
ID Customer Amount Date
1 95 10000 02-Apr-2017
2 95 11000 09-Apr-2017
3 95 22000 11-Apr-2017
4 95 1200 15-Apr-2017
I need output as below:
ID Date InvoiceDR InvoiceCR
1 01-Apr-2017 1500 -
2 02-Apr-2017 - 10000
3 09-Apr-2017 5500 -
4 09-Apr-2017 - 11000
$query = mysql_query("SELECT * FROM (
(SELECT invoice.id, NULL AS invoiceDR, invoice.InvoiceCR, invoice.Date FROM invoice)
UNION ALL
(SELECT NULL AS id, paymentd.InvoiceCR, NULL AS InvoiceDR, payments.Date FROM Payments)
) results ORDER BY Date ASC");
put order by date in end of the query
and change order of date as per your need
You can use "order by" for this purpose. You can set order by ascending and descending (ASC or DESC). Use this query.
select * from Invoice,Payments where '{condition}' order by Invoice.Date ASC , Payemnts.Date ASC
This query will firstly sort the data according to first table(Invoice) and then sorted data will sorted with second table(Payemnts)

query to find data based on max of one field and specific value of another

My SQL skills are minimal so I hope someone will help me. I am writing a PHP script in which I need to do some SQL queries:
I have a table called product_status, which has three 4 columns:
id
prod_id
status_date
status_code
So if we consider a product with id 1000, the table would have entries like:
id prod_id status_date status_code
1 1000 2015-09-01 08:20:35 100
2 1000 2015-09-01 09:22:40 200
3 1000 2015-09-01 09:35:51 300
4 1000 2015-09-01 09:42:55 400
Now, considering that say 300 is the status code for 'out-of-stock'. I want to write a query, where for a given date, it gives me all products that were NOT out-of-stock at the end of that day. In other words it should give me products 1000 if I query it for date '2015-09-01' since 300 is NOT the LAST entry for that product for that date in this table.
I am unable to write a query that works for this :( My query is:
select prod_id, status from product_status
where status_code != 300
group by prod_id, status
having date(max(status_date)) = '2015-09-01'
This returns me products which have statuses other than 300 as final status for the given day as well... Can anyone help correct my SQL?
Try this query
SELECT prod_id,
SUBSTRING_INDEX(GROUP_CONCAT(status_date ORDER BY status_date DESC), ',', 1) as max_date,
SUBSTRING_INDEX(GROUP_CONCAT(status_code ORDER BY status_date DESC), ',', 1) as recent_code
FROM product_status
GROUP BY prod_id
HAVING recent_code != '300' AND date(max_date) = '2015-09-01'
you want to filter by status, not group by it in this query, like this:
select prod_id, status from product_status
where status_code != 300
group by prod_id
having date(max(status_date)) = '2015-09-01'

sql query to sum of amount column

my table has data like below...
Now there are 18 rows in my below table...but receipt no are same.
but i need to display sum of amount of unique receipt no only.
plz help me to make sql query.
SELECT SUM(Amount) FROM `receipt_entry` group by receipt_no,amount
receipt_no amount
10 100
10 100
10 100
10 100
10 100
10 100
11 100
11 100
11 100
11 100
11 100
11 100
12 100
12 100
12 100
12 100
12 100
12 100
SUM of Amount = 300
FOR Above ex - i need to sum amount like below =100+100+100= 300
Use distinct clause before sum data.
Do like this:
$query = "SELECT sum(amount) AS total_amount, receipt_no
FROM receipt_entry
GROUP BY receipt_no"
You can get more detail on DISTINCT from here
Let me know for more help !!
Can you check this query:
SELECT SUM (A.AmountTotal) FROM (
SELECT SUM(DISTINCT amount) AS AmountTotal, receipt_no
FROM receipt_entry
GROUP BY receipt_no ) A
This block returns the result of:
SELECT SUM(DISTINCT amount) AS AmountTotal, receipt_no
FROM receipt_entry
GROUP BY receipt_no
AmountTotal receipt_no
----------- ----------
100 10
100 11
100 12
Again add sum of the block, gives the result.
UPDATE:
SELECT SUM(`AmountTotal`) FROM (
SELECT SUM(DISTINCT `amount`) AS AmountTotal, `receipt_no`
FROM `receipt_entry`
GROUP BY `receipt_no`) AS T1;
Can you check this query.
Working example of this scenario: SQL Fiddle

Get the most near value mysql

I have 3 tables:
PRICE
id price date
1 50 20130716
2 30 20130717
TVA
id val start end
1 7 20080101 20103112
2 8 20110101
MARGIN
id qty marg
1 500 25
2 600 20
3 800 15
4 1000 13
5 1250 11
...
Now I have this query which doesn't works:
$quantity = '557';
$link->query("
SELECT (
(price+marg)*((val+100)/100)
)
FROM PRICE
JOIN TVA
JOIN MARGIN
WHERE date = '20130717'
AND end = ''
AND qty = '$quantity'
");
The problem is that there isn't a qty = '557' on the table.
What I'd like to do is to select the most near quantity to (in this case) '557'.
So if:
$quantity = '557' the query should select 600
$quantity = '701' the query should select 800
$quantity = '1238' the query should select 1250
etc.
Is this possible?
If you put it into a procedure, you can use something like this (sort-of pseudocode):
CREATE PROCEDURE pDoStuff(#target INTEGER)
AS
DELCARE #qty INTEGER
-- Get closest qty
#qty = SELECT TOP 1 qty
FROM table
ORDER BY ABS(#target - qty) ASC
-- use that "actual" qty in your query
SELECT ((price+marg)*((val+100)/100)
FROM price
JOIN TVA
JOIN MARGIN
WHERE date = 'thedate'
AND end = ''
AND qty = #qty
GO
The syntax is incorrect, but it gives you an idea. This will allow you to select ALL rows from your original query with the closest quantity value. Most of the other answers here will limit your final results to one row (which may or may not be what you actually want).
...
AND `qty` <= $quantity
ORDER BY `qty` DESC
LIMIT 1
You can get value bigger than yours, ordered ascending and limit to 1 result. so you can firt value bigger or equal yours
SELECT (
(price+marg)*((val+100)/100)
)
FROM PRICE
JOIN TVA
JOIN MARGIN
WHERE date = '20130717'
AND end = ''
AND qty >= '$quantity'
ORDER BY qty ASC LIMIT 1
With same method you can get value lower than your number and see which one is closer to your qty

Categories