I'm trying to calculate a percentage in my SQL query.
This is what I have right now:
SELECT
DATE(processed_at) AS day,
(
SELECT
COUNT(*) FROM return_items
WHERE return_id IN (SELECT id FROM returns WHERE DATE(processed_at) = day)
) as products_returned,
COUNT(*) as return_count,
(
SELECT
COUNT(*) as co_returns
FROM returns
WHERE return_method = 'mondial_relais'
AND DATE(processed_at) = day
) as return_rate_mr
FROM returns
WHERE MONTH(processed_at) = 10
AND YEAR(processed_at) = 2011
GROUP BY day;
Basically I need the return_rate_mr to be a percentage value.
I tried doing something like return_rate_mr * 100 / return_count as perc_value but this doesn't work. (I don't actually need the current return_rate_mr value, just the percentage.
Any ideas?
Assuming your original query returns the desired results, you can wrap it as a subquery:
SELECT
day,
return_rate_mr * 100 / return_count as perc_value,
... any other columns ...
FROM
( ... your original query here ...) as myalias;
Basically, the subquery creates a result set where the columns are renamed. Then, the outer query is free to use those new column names.
Are you looking for this?
SELECT
`day`,
`products_returned`,
(`return_rate_mr` * 100) / `return_count` AS `percentage`
FROM (
SELECT
DATE(processed_at) AS day,
(
SELECT
COUNT(*) FROM return_items
WHERE return_id IN (SELECT id FROM returns WHERE DATE(processed_at) = day)
) as products_returned,
COUNT(*) as return_count,
(
SELECT
COUNT(*) as co_returns
FROM returns
WHERE return_method = 'mondial_relais'
AND DATE(processed_at) = day
) as return_rate_mr
FROM returns
WHERE MONTH(processed_at) = 10
AND YEAR(processed_at) = 2011
GROUP BY day) AS `ss`
Did you try something like:
SELECT (`return_rate_mr` * 100 ) / `return_count` as "yourValue", OthersFields
FROM SELECT
DATE(processed_at) AS day,
(
SELECT
COUNT(*) FROM return_items
WHERE return_id IN (SELECT id FROM returns WHERE DATE(processed_at) = day)
) as products_returned,
COUNT(*) as return_count,
(
SELECT
COUNT(*) as co_returns
FROM returns
WHERE return_method = 'mondial_relais'
AND DATE(processed_at) = day
) as return_rate_mr
FROM returns
WHERE MONTH(processed_at) = 10
AND YEAR(processed_at) = 2011
GROUP BY day;
Hope this helps
Try:
SELECT DATE(processed_at) AS day,
count(distinct id) as products_returned,
COUNT(*) as return_count,
100* sum(case return_method when 'mondial_relais' then 1 end) / COUNT(*)
as return_perc_mr
FROM returns
WHERE MONTH(processed_at) = 10
AND YEAR(processed_at) = 2011
GROUP BY day;
I suspect that products_returned should be counting distinct item_id values (or something similar), but this should duplicate the logic in the original query.
Related
I was on the "hospital_payment_data" table.
I want to call up the data of the number of data, the cache_account_received sum, and the total_medical_bills sum, and then bring up the mount sum value from the cash_recipit_rowtable to express. What should I do?
hospital_payment_data
cash_receipt_row
I want result
However, sending the following queries results in the following:
SELECT
COUNT(*) as total,
SUM(cash_amount_received) AS sum_cash_amount_received,
COUNT(
IF(total_medical_bills >= 100000 AND
cash_amount_received , total_medical_bills, NULL)
) as obligatory_issue,
SUM(
IF(total_medical_bills >= 100000 AND
cash_amount_received , cash_amount_received, NULL)
) as sum_obligatory_issue,
SUM(amount) AS sum_amount
FROM (
SELECT total_medical_bills, cash_amount_received, amount
FROM hospital_payment_data, cash_receipt_row
) AS a
wrong result
Try this.
SELECT
COUNT(*) as total,
SUM(cash_amount_received) AS sum_cash_amount_received,
COUNT(
IF(total_medical_bills >= 100000 AND
cash_amount_received , total_medical_bills, NULL)
) as obligatory_issue,
SUM(
IF(total_medical_bills >= 100000 AND
cash_amount_received , cash_amount_received, NULL)
) as sum_obligatory_issue,
SUM(amount) AS sum_amount
FROM (
SELECT total_medical_bills, cash_amount_received, amount
FROM hospital_payment_data, cash_receipt_row
WHERE hospital_payment_data.id = cash_receipt_row.id
) AS a
Never use commas in the FROM clause. Always use proper, explicit, standard, readable JOIN syntax.
You can also simplify your counting logic in MySQL. There is no need for IF() or a subquery:
SELECT COUNT(*) as total,
SUM(cash_amount_received) AS sum_cash_amount_received,
SUM( total_medical_bills >= 100000 AND
obligatory_issue <> 0
) as obligatory_issue,
SUM(CASE WHEN total_medical_bills >= 100000
THEN cash_amount_received
END) as sum_obligatory_issue,
SUM(amount) AS sum_amount
FROM hospital_payment_data hpd JOIN
cash_receipt_row crr
ON hpd.id = crr.id;
You'll notice that where conditional logic is needed, then this uses the standard SQL construct, CASE, rather than IF.
I am trying to get this query...
SELECT `Num_1`, COUNT(`Num_1`) AS `value_occurrence` FROM numbers WHERE MONTH(`Dates`) = 1 AND YEAR(`Dates`) = 1995 GROUP BY `Num_1` ORDER BY `value_occurrence` DESC
But for multiple columns as in 'Num_1', 'Num_2', 'Num_3', 'Num_4', 'Num_5' and return with the occurrence of each column such as 'num_1_occurrence', 'num_2_occurrence', 'num_3_occurrence', 'num_4_occurrence', 'num_5_occurrence' and all within the date specified.
numbers table
Example output
I had tried using...
SELECT `Num_1`,`Num_2`, `Num_3`,`Num_4`,`Num_5`,COUNT(`Num_1`,`Num_2`,`Num_3`,`Num_4`,`Num_5`) AS `num_1_occurrence`,`num_2_occurrence`,`num_3_occurrence`, `num_4_occurrence`,`num_5_occurrence`FROM numbers WHERE MONTH(`Dates`) = 1 AND YEAR(`Dates`) = 1995
but just threw errors, I have searched extensively for days and have not found the correct way to do it.
I'd do it like this:
SELECT n.num
, MAX(IF(n.q='n1',n.cnt,NULL)) AS num_1_occurrence
, MAX(IF(n.q='n2',n.cnt,NULL)) AS num_2_occurrence
, MAX(IF(n.q='n3',n.cnt,NULL)) AS num_3_occurrence
FROM (
SELECT 'n1' AS q
, n1.Num_1 AS num
, COUNT(n1.Num_1) AS cnt
FROM numbers n1
WHERE n1.Dates >= '1995-01-01'
AND n1.Dates < '1995-01-01' + INTERVAL 1 MONTH
GROUP BY n1.Num_1
UNION ALL
SELECT 'n2' AS q
, n2.Num_2 AS num
, COUNT(n2.Num_2) AS cnt
FROM numbers n2
WHERE n2.Dates >= '1995-01-01'
AND n2.Dates < '1995-01-01' + INTERVAL 1 MONTH
GROUP BY n2.Num_2
UNION ALL
SELECT 'n3' AS q
, n3.Num_3 AS num
, COUNT(n3.Num_3) AS cnt
FROM numbers n3
WHERE n3.Dates >= '1995-01-01'
AND n3.Dates < '1995-01-01' + INTERVAL 1 MONTH
GROUP BY n3.Num_3
) n
GROUP BY n.num
ORDER BY GREATEST(num_1_occurrence,num_2_occurrence,num_3_occurrence) DESC
I'm only doing Num_1 and Num_2 here, but I think it's what you're looking for, or close. This will give you the list in "tall" format, with the original column name, the value in that column, and the count of that value in that column going across...
SELECT 'Num_1' AS field_name, Num_1 AS value, value_count
FROM (SELECT Num_1, COUNT(Num_1) AS value_count
FROM numbers
GROUP BY Num_1) AS num1_counts
WHERE MONTH(`Dates`) = 1 AND YEAR(`Dates`) = 1995
UNION
SELECT 'Num_2' AS field_name, Num_2 AS value, value_count
FROM (SELECT Num_2, COUNT(Num_2) AS value_count
FROM numbers
GROUP BY Num_2) AS num2_counts
WHERE MONTH(`Dates`) = 1 AND YEAR(`Dates`) = 1995
I have 100 records from 3 users. I want to show the most recent record from each user. I have the following query:
SELECT *
FROM Mytable
WHERE Dateabc = CURRENT DATE
AND timeabc =
(
SELECT MAX(timeabc)
FROM Mytable
)
It returns the most recent record for everyone, and I need it to return most recent record from every user.
Should the solution support both DB2 and mysql?
SELECT * FROM Mytable as x
WHERE Dateabc = CURRENT_DATE
AND timeabc = (SELECT MAX( timeabc ) FROM Mytable as y where x.user = y.user)
If it's only DB2 more efficient solutions exists:
SELECT * from (
SELECT x.*, row_number() over (partition by user order by timeabc desc) as rn
FROM Mytable as x
)
WHERE rn = 1
I assume somewhere in your table you have a userID...
select userID, max(timeabc) from mytable group by userID
SELECT *
FROM Mytable as a
WHERE Dateabc = CURRENT_DATE
AND timeabc =
(
SELECT MAX( timeabc )
FROM Mytable as b
WHERE a.uId = b.uId
)
What I am trying to get is to send a request to DB that will:
1 count all rows
2 return 10 rows
SELECT count( * ) AS 'total'
FROM stuff
WHERE usr = '65'
LIMIT 10
So it is supposed to return 10 results PLUS 'total' with the number of all rows.
So far it returns the counted amount of rows only....
-- count records first
SET #total = (
SELECT count( * ) AS 'total'
FROM `stuff`
WHERE `usr` = '65'
);
-- then, select your ten records and include the total from previous operation
SELECT *, #total
FROM `stuff`
WHERE `usr` = '65'
LIMIT 10
You'll need to split the 2 concerns out, and then recombine them:
SELECT s.col1, s.col2, s.col3, x.total
FROM `stuff` s
CROSS JOIN
(
SELECT count(*) AS total
FROM `stuff`
WHERE `usr` = '65'
) x
WHERE s.`usr` = '65'
LIMIT 10;
Fiddle here
RDBMs like SqlServer and Oracle allow for CTE's which would allow you to DRY up the repeated select ... where. Some options in MySql here
If you want all rows to be counted and limit the result to 10 then you can do it the following way
SELECT SQL_CALC_FOUND_ROWS * FROM `stuff` WHERE `usr` = '65' LIMIT 10
SELECT FOUND_ROWS();
I have two SELECT statements that give the values "TotalSales" and "VendorPay_Com". I want to be able to subtract VendorPay_Com from TotalSales within the one MySQL statement to get the value "Outstanding_Funds" but I haven't found a reliable way to do so.
These are my two statements:
Query 1:
SELECT SUM(Price) AS TotalSales
FROM PROPERTY
WHERE Status = 'Sold';
Query 2:
SELECT SUM(AC.Amount) AS VendorPay_Comm
FROM (
SELECT Amount FROM lawyer_pays_vendor
UNION ALL
SELECT CommissionEarned AS `Amount` FROM COMMISSION AS C WHERE C.`status` = 'Paid') AS AC
Any help on this matter would be greatly appreciated :)
You can do it as follows :
select (select ...) - (select ...)
In your example, simply :
select
(
SELECT SUM(Price) AS TotalSales
FROM PROPERTY
WHERE Status = 'Sold'
)
-
(
SELECT SUM(AC.Amount) AS VendorPay_Comm
FROM (
SELECT Amount FROM lawyer_pays_vendor
UNION ALL
SELECT CommissionEarned AS `Amount` FROM COMMISSION AS C WHERE C.`status` = 'Paid') AS AC
) AS Outstanding_Funds
Try
SELECT TotalSales-VendorPay_Comm AS Outstanding_Funds
FROM
(SELECT SUM(Price) AS TotalSales
FROM PROPERTY
WHERE Status = 'Sold') t1,
(SELECT SUM(Amount) AS VendorPay_Comm
FROM (SELECT Amount FROM lawyer_pays_vendor
UNION ALL
SELECT CommissionEarned AS Amount
FROM COMMISSION
WHERE Status = 'Paid') t0) t2
Here is sqlfiddle