I am attempting to add a blank row and subtotal into a grid view of a table. I have managed to add the subtotal row, but no luck on the blank row. The blank row is to separate the months. My code is as below, if anyone can help I would appreciate it. If you could also tell me how to bold the subtotal row (if it's possible) that would also be great.
There is quite a lot of data, but in brief some sample data and output would look like:
DATA
Period Production
31-Jul-15 15
31-Jul-15 8
31-Jul-15 7
31-Jul-15 9
31-Aug-15 10
31-Aug-15 5
31-Aug-15 12
31-Aug-15 18
OUTPUT REQUIRED
Period Production
31-Jul-15 15
31-Jul-15 8
31-Jul-15 7
31-Jul-15 9
***Monthly Total 39
31-Aug-15 10
31-Aug-15 5
31-Aug-15 12
31-Aug-15 18
***Monthly Total 45
Code currently is:
select
d.period,
CASE WHEN d.period is null then 'Grand Total'
ELSE coalesce (d.description,'MONTHLY TOTAL') end AS Description,
sum(d.Prod_Qty) as 'Production Made',
round(sum(d.TotalTonnes),2) as Tonnes,
sum(d.TotalHrs) as Hours,
round(sum(d.TotalTonnes)/sum(d.TotalHrs),2) as 'Tonnes per Hour',
sum(d.ProdTime) as 'Production Time',
round(sum(d.TotalTonnes)/sum(d.ProdTime),2) as 'Prod Time per Tonne'
from
(
SELECT DISTINCT
EOMONTH(FWT_DAILYPRODUCTION.TransDate) AS Period,
FWT_DAILYPRODUCTION.Prod_Qty,
FWT_PROD_MACHINES.Description,
STOCK_ITEMS.CUBIC,
STOCK_ITEMS.X_BEATS,
STOCK_ITEMS.Weight,
FWT_DAILYPRODUCTION.Prod_Qty * STOCK_ITEMS.Weight / 1000 as TotalTonnes,
(select sum(FWT_LABOUR_LINES.ProdTime) from FWT_LABOUR_LINES where
FWT_DAILYPRODUCTION.SEQNO = FWT_LABOUR_LINES.HDR_SEQNO) as ProdTime,
(select sum(FWT_LABOUR_LINES.TotalHrs) from FWT_LABOUR_LINES where
FWT_DAILYPRODUCTION.SEQNO = FWT_LABOUR_LINES.HDR_SEQNO) as TotalHrs
FROM FWT_DAILYPRODUCTION FWT_DAILYPRODUCTION
FULL OUTER JOIN FWT_LABOUR_LINES FWT_LABOUR_LINES ON
(FWT_LABOUR_LINES.HDR_SEQNO = FWT_DAILYPRODUCTION.SEQNO)
FULL OUTER JOIN FWT_JOB_COST_HDR FWT_JOB_COST_HDR ON
(FWT_JOB_COST_HDR.SEQNO = FWT_DAILYPRODUCTION.JOBNO)
FULL OUTER JOIN FWT_PROD_MACHINES FWT_PROD_MACHINES ON
(FWT_PROD_MACHINES.SEQNO = FWT_JOB_COST_HDR.PROD_MACHINE)
FULL OUTER JOIN FWT_JOB_TYPE FWT_JOB_TYPE ON
(FWT_JOB_TYPE.SEQNO = FWT_JOB_COST_HDR.JOB_TYPE)
FULL OUTER JOIN FWT_JOB_STATUS FWT_JOB_STATUS ON
(FWT_JOB_STATUS.SEQNO = FWT_JOB_COST_HDR.STATUS)
FULL OUTER JOIN FWT_BILLOMAT FWT_BILLOMAT ON
(FWT_BILLOMAT.BILLCODE = FWT_JOB_COST_HDR.BILLCODE)
FULL OUTER JOIN STOCK_ITEMS STOCK_ITEMS ON
(STOCK_ITEMS.STOCKCODE = FWT_BILLOMAT.OUTPUT)
FULL OUTER JOIN STOCK_LOCATIONS STOCK_LOCATIONS ON
(STOCK_LOCATIONS.LOCNO = FWT_JOB_COST_HDR.LOCNO)
WHERE
( EOMONTH(FWT_DAILYPRODUCTION.TransDate) >= DATEADD(MM, DATEDIFF(MM, 0, GETDATE())-13, 0))
AND FWT_JOB_COST_HDR.PROD_MACHINE IN (24,19,20,21,22,23,12)
)d
Group by
rollup(d.period,d.description)
ORDER BY
d.period desc,
d.description desc
Related
I am new with mysql and working to change a store application to make it have two stock. I created a table to store stock quantity:
Then I plan to create a view with stock quantity, per store, per SKU. I using the following query:
SELECT
`stockList`.`sku`,
SUM(A.`stockQty`) AS 'store1',
SUM(B.`stockQty`) AS 'store2',
SUM(`stockList`.`stockQty`) AS 'total'
FROM `stockList`
LEFT JOIN (
SELECT * FROM `stockList` WHERE `idStock`=1
) AS A
ON `stockList`.`sku`=A.`sku`
LEFT JOIN (
SELECT * FROM `stockList` WHERE `idStock`=2
) AS B
ON `stockList`.`sku`=B.`sku`
GROUP BY `stockList`.`sku`
Per resulting table, calculation is not proper and I could not identify the logic:
SKU 43 should show for store1 = 9 and for store2 = 10, total = 19. This is what they show if I execute the select queries alone. Please, let me know if I misunderstood how this sum logic works.
You might to use SUM on subquery to calculate Totle price by sku
LEFT JOIN may make some fields not match causing NULL so use IFNULL to preset value 0
You can try this.
SELECT
T.sku,
SUM(T.stockQty) as totle,
IFNULL(A.`store1`,0) AS `store1`,
IFNULL(B.`store2`,0) AS `store2`
FROM `stockList` AS T
LEFT JOIN
(
SELECT sku,SUM(`stockQty`) as `store1`
FROM `stockList`
WHERE `idStock`=1
GROUP BY sku
) as A ON A.sku = T.sku
LEFT JOIN
(
SELECT sku,SUM(`stockQty`) as `store2`
FROM `stockList`
WHERE `idStock`=2
GROUP BY sku
) AS B ON T.sku =B.sku
GROUP BY T.sku
sqlfiddle
Your query is much more complicated than it needs to be. You can just do this:
SELECT
sku,
SUM(stockQty) as total,
SUM(IF(idStock=1,stockQty,0)) AS `store1`,
SUM(IF(idStock=2,stockQty,0)) AS `store2`
FROM `stockList`
GROUP BY sku
Output:
sku total store1 store2
36 10 10 0
37 3 3 0
38 4 4 0
39 3 3 0
40 10 10 0
41 12 12 0
42 12 12 0
43 19 9 10
I have created the below SQL query to calculate the total income from leases within the next 12 months .
SELECT DISTINCT apartment.addressLine1, lease.monthlyRent, lease.duration, lease.roomNumber, lease.monthlyRent*lease.duration AS totalLeaseRent
FROM `lease`
INNER JOIN apartment on (lease.roomNumber) = (apartment.roomNumber)
left Join tenantLease on tenantLease.leaseID = lease.leaseID
WHERE tenantLease.live = 1 AND lease.duration <= 12
This returns the following result:
AddressLine1 monthlyRent Duration(months) roomNumber totalLeaseRent
Chlorine Gardens1200 9 GF02 10800
May Road 800 12 GF03 9600
Beech Hill 900 8 BG06 7200
Ash Avenue 1000 12 AA04 12000
I now want to be able to have another row to include the total of the totalLeaseRent. Like this:
AddressLine1 monthlyRent Duration(months) roomNumber totalLeaseRent
Chlorine Garden1200 9 GF02 10800
May Road 800 12 GF03 9600
Beech Hill 900 8 BG06 7200
Ash Avenue 1000 12 AA04 12000
TOTAL *total*
I have tried the following code but keep getting the error code:
1222 - The used SELECT statements have a different number of columns
SELECT DISTINCT apartment.addressLine1, lease.monthlyRent, lease.duration, lease.roomNumber, lease.monthlyRent*lease.duration AS totalLeaseRent
FROM `lease`
INNER JOIN apartment on (lease.roomNumber) = (apartment.roomNumber)
left Join tenantLease on tenantLease.leaseID = lease.leaseID
WHERE tenantLease.live = 1 AND lease.duration <= 12
UNION ALL
SELECT 'Total', SUM(lease.monthlyRent * lease.duration)
FROM lease
How do I get this query to run?
Thanks
TRY THIS: We have to follow following three points while working with set operation
1- Each SELECT statement within UNION must have the same number of columns
2- The columns must also have similar data types
3- The columns in each SELECT statement must also be in the same order
SELECT DISTINCT apartment.addressLine1,
lease.monthlyRent,
lease.duration,
lease.roomNumber,
lease.monthlyRent*lease.duration AS totalLeaseRent
FROM `lease`
INNER JOIN apartment on (lease.roomNumber) = (apartment.roomNumber)
left Join tenantLease on tenantLease.leaseID = lease.leaseID
WHERE tenantLease.live = 1 AND lease.duration <= 12
UNION ALL
SELECT 'Total', NULL, NULL, NULL, SUM(lease.monthlyRent * lease.duration)
FROM lease
I have been stuck in a recent problem with a SQL Query. What I'm trying to archieve is to get each product in the store and show how many of them has been sold each month. However, sometimes there are some months where these products were not sold, which means they won't be displayed.
For instance, this is the result I'm getting right now
Article Month Sold
CN140027 6 312
CN140027 7 293
CN140027 12 122
CN140186 1 10
CN140186 4 2
While I want to get something more like this
Article Month Sold
CN140027 6 312
CN140027 7 293
CN140027 8 0
CN140027 9 0
CN140027 10 0
CN140027 11 0
CN140027 12 122
CN140186 1 10
CN140186 2 0
CN140186 3 0
CN140186 4 2
And here is the query I'm using at the moment
SELECT k.artikelnr, Months.datefield as `Months`, IFNULL(SUM(k.menge),0) as `Quantity`
FROM store_shop_korb as k LEFT OUTER JOIN office_calendar AS Months
ON Months.datefield = month(k.date_insert)
WHERE k.date_insert BETWEEN "2014-12-01" AND "2015-12-31"
group by k.artikelnr, Months.datefield
What am I missing? Or what am I doing wrong? Any help is really appreciated.
Thanks in advance.
EDIT:
Additional information:
office_calendar is the calendar table. It only contains the months as registry, from 1 to 12.
Additionally, I'm taking the article/product ID from a table called 'store_shop_korb', which contains all the lines of a made order (so it contains the article ID, its price, the quantity for each order..)
This works for me:
SELECT k.artikelnr, c.datefield AS `Month`, COALESCE(s.Quantity, 0) AS Sold
FROM (
SELECT artikelnr
FROM store_shop_korb
GROUP BY artikelnr
) k
JOIN office_calendar c
LEFT JOIN (
SELECT artikelnr, MONTH(date_insert) AS monthfield, SUM(menge) AS Quantity
FROM store_shop_korb
GROUP BY artikelnr, MONTH(date_insert)
) s ON k.artikelnr = s.artikelnr AND c.datefield = s.monthfield
ORDER BY k.artikelnr, c.datefield
If you have a table of articles, you can use it in the place of subquery k. I'm basically normalizing on the fly.
Explanation:
There's basically 3 sets of data that get joined. The first is a distinct set of articles (k), the second is a distinct set of months (c). These two are joined without restriction, meaning you get the cartesian product (every article x every month). This result is then left-joined to the sales per month (s) so that we don't lose 0 entries.
Add another where condition , i think it will solve your problem
SELECT k.artikelnr, Months.datefield as `Months`, IFNULL(SUM(k.menge),0) as `Quantity`
FROM store_shop_korb as k LEFT OUTER JOIN office_calendar AS Months
ON Months.datefield = month(k.date_insert)
WHERE IFNULL(SUM(k.menge),0)>0 AND k.date_insert BETWEEN "2014-12-01" AND "2015-12-31"
group by k.artikelnr, Months.datefield
I have tried this in MSAccess and it seems to work OK
SELECT PRODUCT, CALENDAR.MONTH, A
FROM CALENDAR LEFT JOIN (
SELECT PRODUCT, MONTH(SALEDTE) AS M, SUM(SALEAMOUNT) AS A
FROM SALES
WHERE SALEDTE BETWEEN #1/1/2015# AND #12/31/2015#
GROUP BY PRODUCT, MONTH(SALEDTE) ) AS X
ON X.M = CALENDAR.MONTH
If you already have a calender table then use this.
SELECT B.Article,
A.Month,
COALESCE(c.Sold, 0)
FROM (SELECT DISTINCT Months.datefield --Considering this as months feild
FROM office_calendar AS Months) A
CROSS JOIN (SELECT DISTINCT article
FROM Yourtable) B
LEFT OUTER JOIN Yourtable C
ON a.month = c.Month
AND b.Article = c.Article
Else you need a months table. Try this.
SELECT *
FROM (SELECT 1 AS month UNION
SELECT 2 UNION
SELECT 3 UNION
SELECT 4 UNION
SELECT 5 UNION
SELECT 6 UNION
SELECT 7 UNION
SELECT 8 UNION
SELECT 9 UNION
SELECT 10 UNION
SELECT 11 UNION
SELECT 12) A
CROSS JOIN (SELECT DISTINCT article
FROM Yourtable) B
LEFT OUTER JOIN Yourtable C
ON a.month = c.Month
AND b.Article = c.Article
I have a table for terminal
Id status
1 Online
2 Offline
3 Offline
and I have a separate table where I can find the total hours/date of the up and downtime.
total_time
Id up down
1 10 14
2 20 4
3 15 9
1 5 19
2 4 20
3 10 14
I want to display the terminal id, status and the TOTAL up and downtime(1 = 15(up), 2 = 24(up), 3 = 25(up). I'm using inner join and I have no idea how i will be able to get the sum of the up and downtime..
SELECT terminal.Id, terminal.status, total_time.Id, SUM(total_time.up),SUM(total_time.down)
FROM terminal
INNER JOIN total_time
ON terminal.Id = total_time.Id
WHERE terminal.Id = total_time.Id
Something like this should do the trick. I am interpreting your question as asking for only the sum of the time of the current status. If this is not what you want (and maybe you want the sum of both times), please let me know.
SELECT t.id, t.status, IF(t.status = 'Online', ttlTime.upTime, ttlTime.downTime) as totalTime
FROM terminal t
JOIN
(SELECT tt.id, SUM(tt.up) as upTime, SUM(tt.down) AS downTime
FROM total_time tt
GROUP BY tt.id) ttlTime ON t.id = ttlTime.id
See the SQLFiddle
You get "inner sums" by using the GROUP BY clause.
Try:
SELECT terminal.Id, SUM(total_time.up), SUM(total_time.down)
FROM terminal
INNER JOIN total_time
ON terminal.Id = total_time.Id
GROUP BY terminal.Id
SELECT DISTINCT terminal.Id, terminal.status, total_time.Id, SUM(total_time.up),SUM(total_time.down)
FROM terminal
INNER JOIN total_time
ON terminal.Id = total_time.Id
Should do it. The DISTINCT clause acts as a filter to remove duplicate records from a result set.
How can I write this.. I have table 'Company' with a column 'Size'. The size references enums. I need to display the average company size as alias AS 'AverageEstimatedCompanySize' by substituting column 'Size' when column 'Size' is:
1 = 15
2 = 30
3 = 50
4 = 100
5 = 250
In other words, my table shows company size as either 1, 2, 3, 4 or 5. While 1 is actually a company size of 15.
This is all part of a bigger query:
SELECT COUNT(DISTINCT(ID)) AS 'Total # of Opps', AVG(Size*?) AS 'AverageEstimatedCompanySize'
FROM persontable AS POJT INNER JOIN opportunity
ON POJT.ID = opportunity.id
WHERE opportunity.TimeStamp >= '2012-01-01' AND opportunity.TimeStamp <= '2012-12-31' AND POJT.JobTitleID IN
(SELECT Id
FROM job
WHERE CategoryID IN
(SELECT id
FROM job_category
WHERE name IN ('Sc', 'Ma', 'Co', 'En', 'Tr')))
Sounds like something solvable with a case statement. The following is untested but should point you in the right direction.
SELECT
COUNT(DISTINCT(ID)) AS 'Total # of Opps',
AVG(
CASE Size
WHEN 1 THEN 15
WHEN 2 THEN 30
WHEN 3 THEN 50
WHEN 4 THEN 100
WHEN 5 THEN 250
END
) AS 'AverageEstimatedCompanySize'
FROM persontable AS POJT INNER JOIN opportunity
ON POJT.ID = opportunity.id
WHERE opportunity.TimeStamp >= '2012-01-01' AND opportunity.TimeStamp <= '2012-12-31' AND POJT.JobTitleID IN
(SELECT Id
FROM job
WHERE CategoryID IN
(SELECT id
FROM job_category
WHERE name IN ('Sc', 'Ma', 'Co', 'En', 'Tr')))
I'm thinking that one approach might be to modify the query to JOIN to the Company table appropriately (that's something you'll need to work out), and then modify the AVG statement:
... AVG(CASE `Size`
WHEN 1 THEN 15
WHEN 2 THEN 30
WHEN 3 THEN 50
WHEN 4 THEN 100
WHEN 5 THEN 250 END) AS 'AverageEstimatedCompanySize'
where Size is from the Company table.
Now, a more dynamic approach would be to create a new field, or even a new table, that maps those sizes and just JOIN the Company table and say the new table in the query and just grab the appropriate field per row then. That would get rid of the CASE statement.