Using this query,
SELECT company, YEAR( date ) as year, COUNT( * ) as total
FROM table
WHERE company = "Medtronic"
OR company = "Private"
GROUP BY YEAR( date )
I get a table like this:
Company year total
Medtronic 1998 6
Private 1998 5
Medtronic 1999 5
Private 1999 1
How do I calculate the % that is contributed by each company for each year?
For example, the percentage contributed by Medtronic in year 1998 is
6 / (6+5) = 54.5%
I have been trying to make a MySQL query to calculate the percentages.
Thanks guys.
Use:
SELECT x.company,
x.year,
x.annual_total
x.annual_total / y.total AS percentage
FROM (SELECT t.company,
YEAR(t.date) as year,
COUNT( * ) as annual_total
FROM TABLE t
WHERE t.company IN ('Medtronic', 'Private')
GROUP BY YEAR( t.date ) ) x
JOIN (SELECT t.company,
COUNT(*) 'total'
FROM TABLE t
WHERE t.company IN ('Medtronic', 'Private')
GROUP BY t.company) y ON y.company = x.company
If you want the percentage with particular decimal places, use:
CAST(x.annual_total / y.total AS DECIMAL(2,2)) AS percentage
Check that this gives the count per company you expect:
SELECT t.company,
COUNT(*) 'total'
FROM TABLE t
WHERE t.company IN ('Medtronic', 'Private')
GROUP BY t.company
My SQL query:
SELECT x.company, x.year, x.annual_total, CAST( x.annual_total / y.total AS DECIMAL( 2, 2 ) ) AS percentage
FROM (
SELECT t.company, YEAR( t.date ) AS year, COUNT( * ) AS annual_total
FROM my_patents AS t
WHERE t.company = 'Private'
GROUP BY YEAR( t.date )
)x
JOIN (
SELECT t.company, COUNT( * ) AS total
FROM my_patents AS t
WHERE t.company = 'Medtronic'
OR t.company = 'Private'
GROUP BY t.company
)y ON y.company = x.company
my results:
Private 1998 5 0.04
when i run this query:
SELECT t.company, YEAR( date ) , COUNT( * ) AS total
FROM my_patents AS t
WHERE t.company = 'Medtronic'
OR t.company = 'Private'
GROUP BY t.company, YEAR( date )
I get
Medtronic 1998 6
Private 1998 5
Related
I'd like to be able to output the following fields from the query below:
AddedById,AddedByName,HoursWorked,CurrentYearlyFlexiAvailable
However where I have WHERE addedby=1, I'd like to replace this with the field name AddedById as I do not want to hard code this value as the overall query should and will return more than one person, I want to get this value from the rpt_timesheet_data view, which is there. The CurrentYearlyFlexiAvailable field should be telling me how much time they have left for the current year to date by doing the calculation between the SELECT SUM(ttl) and from the FROM (SELECT SUM(worked)-420 as ttl
SELECT AddedById,AddedByName,SUM(HoursWorked) AS HoursWorked
,(SELECT SUM(ttl) - (
SELECT SUM(worked)
FROM vwtimesheet
WHERE addedby=AddedById
AND entrydate BETWEEN '2017-01-01' AND '2017-04-13'
AND activityid=3192
GROUP BY addedby ) AS flexihours
FROM (
SELECT SUM(worked)-420 AS ttl
FROM vwtimesheet
WHERE addedby=1 <!--HERE IS THE ISSUE
AND entrydate BETWEEN '2017-01-01' AND '2017-04-13'
AND projectid<>113 AND activityid<>3192
GROUP BY entrydate
HAVING SUM(worked)>420
) AS s) AS CurrentYearlyFlexiAvailable
FROM rpt_timesheet_data
WHERE entrydate BETWEEN '2017-04-02' AND '2017-04-13 23:59:59'
AND ActivityId=3192
GROUP BY AddedById,AddedByName
ORDER BY AddedByName
but I keep getting:
Error Code: 1054. Unknown column 'AddedById' in 'where clause'
Just in that one location. I've tried various queries to sort this, but just cannot figure it out. Sorry not to good at explaining this, can see it in my head what I want to do...
Here is a query that does something very similar in that it returns the results for a single user, where as the one above is meant to loop through all users and give me the results:-
SELECT addedbyname, SUM(ttl) -
(SELECT SUM(worked)
FROM vwtimesheet
WHERE addedby=1
AND entrydate BETWEEN '2017-01-01' AND '2017-04-13'
AND activityid=3192
GROUP BY addedby ) AS CurrentYearlyFlexiAvailable
,(SELECT SUM(worked) FROM vwtimesheet
WHERE addedby=1
AND entrydate BETWEEN '2017-01-01' AND '2017-04-13'
AND activityid=3192
GROUP BY addedby ) AS flexiused
,(SELECT sum(worked) FROM vwtimesheet
WHERE addedby=1
AND entrydate BETWEEN DATE_FORMAT(NOW() ,'%Y-%m-01') AND curdate()
AND activityid=3192
GROUP BY addedby ) as fleximonthused
FROM ( SELECT entrydate,addedbyname,SUM(worked)-420 AS ttl FROM vwtimesheet
WHERE addedby=1
AND entrydate BETWEEN '2017-01-01' AND '2017-04-13'
AND projectid<>113
AND activityid<>3192
GROUP BY entrydate,addedbyname
HAVING SUM(worked)>420
) AS s
Please try the following...
SELECT AddedById,
AddedByName,
SUM( HoursWorked ) AS HoursWorked,
SUM( ttl ) - sumWorked AS CurrentYearlyFlexiAvailable
FROM ( SELECT AddedById AS AddedById,
AddedByName AS AddedByName
FROM rpt_timesheet_data
GROUP BY AddedById
) AS AddedByFinder
JOIN ( SELECT addedby AS addedby,
entrydate AS entrydate,
SUM( worked ) - 420 AS ttl
FROM vwtimesheet
WHERE entrydate BETWEEN '2017-01-01' AND '2017-04-13'
AND projectid <> 113
AND activityid <> 3192
GROUP BY addedby,
entrydate
HAVING SUM( worked ) > 420
) AS ttlFinder ON AddedByFinder.AddedById = ttlFinder.addedby
JOIN ( SELECT addedby AS addedby,
SUM( worked ) AS sumWorked
FROM vwtimesheet
WHERE entrydate BETWEEN '2017-01-01' AND '2017-04-13'
AND activityid = 3192
GROUP BY addedby
) sumWorkedFinder ON AddedByFinder.AddedById = sumWorkedFinder.addedby
WHERE entrydate BETWEEN '2017-04-02' AND '2017-04-13 23:59:59'
AND ActivityId = 3192
GROUP BY AddedById,
AddedByName
ORDER BY AddedByName;
(Explanation to follow...)
If you have any questions or comments, then please feel free to post a Comment accordingly.
I'm trying to get from database information about orders grouped by date.
I have table sales_flat_order, where I have it's id, order creation date, total_paid for order, and order item count. And I have table sales_flat_order_item where are orders items with it prices.
I created script to get order information by day:
SELECT
DATE( sales_flat_order.created_at ) AS date,
SUM( sales_flat_order.total_paid ) AS sales,
SUM( sales_flat_order.total_item_count ) AS items
FROM
sales_flat_order,
sales_flat_order_payment
WHERE
sales_flat_order.status = 'complete'
AND sales_flat_order.entity_id = sales_flat_order_payment.parent_id
AND sales_flat_order_payment.method = 'checkmo'
GROUP BY DATE( sales_flat_order.created_at )
WITH ROLLUP
I get:
DATE SALES ITEMS
2013-03-05 72 3
2013-03-06 100 5
And I have script to count median price:
SELECT
avg(t1.price) as median_val
FROM
(
SELECT
#rownum:=#rownum+1 as `row_number`,
d.price
FROM
sales_flat_order_item d,
(SELECT #rownum:=0) r
WHERE 1
ORDER BY d.price
) as t1,
(
SELECT
count(*) as total_rows
FROM
sales_flat_order_item d
WHERE 1
) as t2
WHERE 1
AND t1.row_number>=total_rows/2
and t1.row_number<=total_rows/2+1;
Now I'm trying to combine this two script to get:
DATE SALES ITEMS median_item_price
2013-03-05 72 3 19
2013-03-06 100 5 10.5
Combined script:
SELECT
DATE( sales_flat_order.created_at ) AS date,
SUM( sales_flat_order.total_paid ) AS sales,
SUM( sales_flat_order.total_item_count ) AS items,
sales_flat_order_item.price as median_item_price
FROM
sales_flat_order,
sales_flat_order_payment,
(
SELECT
avg(t1.price) as median_val
FROM
(
SELECT
#rownum:=#rownum+1 as `row_number`,
d.price
FROM
sales_flat_order_item d,
(SELECT #rownum:=0) r
WHERE 1
ORDER BY d.price
) as t1,
(
SELECT
count(*) as total_rows
FROM
sales_flat_order_item d
WHERE 1
) as t2
WHERE 1
AND t1.row_number>=total_rows/2
and t1.row_number<=total_rows/2+1
) as sales_flat_order_item
WHERE
sales_flat_order.status = 'complete'
AND sales_flat_order.entity_id = sales_flat_order_payment.parent_id
AND sales_flat_order_payment.method = 'checkmo'
AND DATE(sales_flat_order_item.created_at) = DATE(sales_flat_order.created_at)
GROUP BY DATE( sales_flat_order.created_at )
WITH ROLLUP
and get error: #1248 - Every derived table must have its own alias
here is database: http://sqlfiddle.com/#!2/7dfec
Can anyone help?
Solution:
SELECT
DATE( sales_flat_order.created_at ) AS date,
SUM( sales_flat_order.total_paid ) AS sales,
SUM( sales_flat_order.total_item_count ) AS items,
MAX( median.median_val ) as median_item_price
FROM
sales_flat_order,
sales_flat_order_payment,
(
SELECT DATE(sq.created_at) as median_date, avg(sq.price) as median_val FROM (
SELECT t1.row_number, t1.price, t1.created_at FROM(
SELECT IF(#prev!=d.created_at, #rownum:=1, #rownum:=#rownum+1) as `row_number`, d.price, #prev:=d.created_at AS created_at
FROM sales_flat_order_item d, (SELECT #rownum:=0, #prev:=NULL) r
ORDER BY d.price
) as t1 INNER JOIN
(
SELECT count(*) as total_rows, created_at
FROM sales_flat_order_item d
GROUP BY created_at
) as t2
ON t1.created_at = t2.created_at
WHERE 1=1
AND t1.row_number>=t2.total_rows/2 and t1.row_number<=t2.total_rows/2+1
)sq
group by DATE(sq.created_at)
) as median
WHERE
sales_flat_order.status = 'complete'
AND sales_flat_order.entity_id = sales_flat_order_payment.parent_id
AND sales_flat_order_payment.method = 'checkmo'
AND median.median_date = DATE( sales_flat_order.created_at )
GROUP BY DATE( sales_flat_order.created_at )
WITH ROLLUP
I have a database that contains member information for a club. Each member at any time can be one of three distinct statuses (active, veteran, associate). I have it broken down into three tables. The member table, with all the member information, the status table with the status_name and status_id and a grid table which includes the member_id, status_id, date_from and date_to.
I am trying to calculate the amount of time a member has spent at each status. I am currently calculating the total time that the member has spent in the "active" status via the following query:
SELECT first_name, last_name,
(DATE_FORMAT( FROM_DAYS( SUM( DATEDIFF( IFNULL( q.date_to, NOW() ) , q.date_from ) ) ) , "%Y" ) +0) as service_years
FROM member a
LEFT JOIN member_status q on a.id = q.member_id AND q.status_id = 1
GROUP BY a.id
I know that I can pull the total time that the person has been a member by leaving off the AND in the left join, however I can't figure out a way to calculate the time for each status in a single query.
My ideal result would be along the lines of:
-----------------------------------------------------------
|member_name | active_years | veteran_years | total_years |
-----------------------------------------------------------
|name | 5 | 5 | 10 |
-----------------------------------------------------------
Is there a way to accomplish what I'm looking for in a single query?
Assuming 1=active and 2=veteran, something like this should work:
SELECT first_name, last_name,
(DATE_FORMAT( FROM_DAYS( SUM( case when q.status_id = 1 then DATEDIFF( IFNULL( q.date_to, NOW() ) , q.date_from ) ) else 0 end ) , "%Y" ) +0) as active_years,
(DATE_FORMAT( FROM_DAYS( SUM( case when q.status_id = 2 then DATEDIFF( IFNULL( q.date_to, NOW() ) , q.date_from ) ) else 0 end ) , "%Y" ) +0) as veteran_years,
(DATE_FORMAT( FROM_DAYS( SUM( DATEDIFF( IFNULL( q.date_to, NOW() ) , q.date_from ) ) ) , "%Y" ) +0) as total_years
FROM member a
LEFT JOIN member_status q on a.id = q.member_id AND q.status_id in (1,2)
GROUP BY a.id
Another option is to join the member_status table more than once.
You should be able to do something like this which uses a CASE statement to determine the status name and then calculates the total number of years based on the status:
SELECT first_name,
last_name,
CASE WHEN status_name = 'active'
then (DATE_FORMAT( FROM_DAYS( SUM( DATEDIFF( IFNULL( q.date_to, NOW() ) , q.date_from ) ) ) , "%Y" ) +0) end as active_years,
CASE WHEN status_name = 'veteran'
then (DATE_FORMAT( FROM_DAYS( SUM( DATEDIFF( IFNULL( q.date_to, NOW() ) , q.date_from ) ) ) , "%Y" ) +0) end as active_years,
(DATE_FORMAT( FROM_DAYS( SUM( DATEDIFF( IFNULL( q.date_to, NOW() ) , q.date_from ) ) ) , "%Y" ) +0) as total_years,
FROM member a
LEFT JOIN member_status q
on a.id = q.member_id
AND q.status_id = 1
GROUP BY a.id, a.first_name, a.last_name
if you post some sample data it will be easier to determine the proper query
I am actually stuck in merging the result of this two queries:
first query:
SELECT c.code, c.name, pc.sku, pc.cat_code, pp.title
FROM `cat_parent` cp, cat c, prod_cat pc, products pp
WHERE c.code = cp.cat_code
AND cp.cat_code = pc.cat_code
AND pp.sku = pc.sku
AND cp.parent_code = 01110
AND hide =0
The result I get is:
Second query:
SELECT `sku` , `update_date` , `description` , count( * ) AS total_sold
FROM `orderline`
WHERE `update_date` >= ( DATE_ADD(CURDATE( ) , INTERVAL -14 DAY ) )
AND `update_date` <= ( DATE_ADD(CURDATE( ) , INTERVAL -7 DAY ) )
GROUP BY left( sku, 7 )
ORDER BY total_sold DESC
The result:
The question I want to ask that how can I get the result by filtering the sku available in both tables.
Just bit confused on that part....any ideas will be appreciated.
This is only part of the data. there is heaps of data. Yes, I want to merge the both tables and want to find the common sku available in both tables.
My expected result will be sku, title, total sold.
Thanks, anyway I managed to get around to get the result.
My final query:
SELECT * FROM (
SELECT sku , update_date , description FROM orderline WHERE
update_date >= '2012-03-06' AND update_date <= '2012-03-07' )g
JOIN (
SELECT c.code, c.name, pc.sku, pc.cat_code FROM cat_parent cp, cat
c, prod_cat pc, products pp WHERE c.code = cp.cat_code AND cp.cat_code
= pc.cat_code AND pp.sku = pc.sku AND cp.parent_code =01110 AND hide =0 )p ON left( g.sku, 7 ) = left( p.sku, 7 )
Something like this -
SELECT
`c`.`code`, `c`.`name`, `pc`.`sku`, `pc`.`cat_code`, `pp.title`,
`ol`.`sku`, `ol`.`update_date`, `ol`.`description`, COUNT(*) AS `total_sold`
FROM `cat_parent` `cp`
INNER JOIN `cat` `c`
ON `c`.`code` = `cp`.`cat_code`
INNER JOIN `prod_cat` `pc`
ON `cp`.`cat_code` = `pc`.`cat_code`
INNER JOIN `products` `pp`
ON `pp`.`sku` = `pc`.`sku`
INNER JOIN `orderline` `ol`
ON LEFT(`pc`.`sku`, 7) = LEFT(`ol`.`sku`, 7)
WHERE `cp`.`parent_code` = 01110
AND `hide` = 0
AND `ol`.`update_date` >= ( DATE_ADD(CURDATE( ) , INTERVAL -14 DAY ) )
AND `ol`.`update_date` <= ( DATE_ADD(CURDATE( ) , INTERVAL -7 DAY ) )
GROUP BY left( `ol`.`sku`, 7 )
ORDER BY `total_sold` DESC
Here's my query:
SELECT
FROM_UNIXTIME( date_added, '%m-%d-%Y' ) AS formatted_date,
SUM( tb =1 ) AS sum_users,
SUM( tb =2 ) AS sum_links,
SUM( tb =3 ) AS sum_ads,
SUM( tb =4 ) AS sum_actions
FROM (
SELECT date_added, 1 AS tb
FROM users_list WHERE 1=1
UNION ALL
SELECT date_added, 2
FROM users_links WHERE 1=1
UNION ALL
SELECT date_served, 3
FROM ads_served WHERE 1=1
UNION ALL
SELECT date_served, 4
FROM actions WHERE 1=1
) AS t
GROUP BY formatted_date
ORDER BY formatted_date DESC
Here's my table data:
users_list
id date_added
1 1234567890
2 1334567890
3 1434567890
users_links
id date_added
1 1244567890
2 1354567890
3 1464567890
ads_served
id date_served revenue
1 1234567891 0.01
2 1334567892 0.02
3 1434567893 0.02
actions
id date_served
1 1234561890
2 1334562890
3 1434563890
I am trying to sum the revenue for formatted_date in the ads_served table as a 6th column for the output query. I am lost as to where to start. If I add the sum(revenue) to the union select I get a "column mismatch" error.
Column revenue belongs to ads_served but you are selecting from a sub query where revenue is not present. Add it to the subquery:
SELECT
FROM_UNIXTIME( date_added, '%m-%d-%Y' ) AS formatted_date,
SUM( tb =1 ) AS sum_users,
SUM( tb =2 ) AS sum_links,
SUM( tb =3 ) AS sum_ads,
SUM( tb =4 ) AS sum_actions,
SUM( revenue ) As sum_revenue
FROM (
SELECT date_added, 1 AS tb, 0 As revenue
FROM users_list WHERE 1=1
UNION ALL
SELECT date_added, 2, 0
FROM users_links WHERE 1=1
UNION ALL
SELECT date_served, 3, revenue
FROM ads_served WHERE 1=1
UNION ALL
SELECT date_served, 4, 0
FROM actions WHERE 1=1
) AS t
GROUP BY formatted_date
ORDER BY formatted_date DESC
Try in this way. Why do you use 1=1 ?
SELECT
FROM_UNIXTIME( date_added, '%m-%d-%Y' ) AS formatted_date,
SUM( tb =1 ) AS sum_users,
SUM( tb =2 ) AS sum_links,
SUM( tb =3 ) AS sum_ads,
SUM( tb =4 ) AS sum_actions,
sum(total) as tot_rev
FROM (
SELECT date_added,'' as total, 1 AS tb
FROM users_list WHERE 1=1
UNION ALL
SELECT date_added,'', 2
FROM users_links WHERE 1=1
UNION ALL
SELECT date_served,revenue, 3
FROM ads_served WHERE 1=1
UNION ALL
SELECT date_served,'', 4
FROM actions WHERE 1=1
) AS t
GROUP BY formatted_date
ORDER BY formatted_date DESC