Related
I am trying to get the remaining number of working units for each month, of a sum between a bought number of working unit, and a consumed number of working unit.
I tried two possibilities, but both have flaws :
In the first test, I created a "Months" table that contains every month and every year, in order to show all months in the final matrix I wish to create with these data. With this one, I get the closing whenever there is a consumed working unit, but when there is not, the column is "empty", because it does not get the last closing.
USE OTRS_Revised
SELECT [Customer], CASE WHEN [Year] < 2016 THEN 1 ELSE [Year] END AS [Year], CASE WHEN [Year] < 2016 THEN 0 ELSE [Month] END AS [Month], [Closing] AS Total, SUM([Closing])
OVER (PARTITION BY [Customer] ORDER BY [Year], [Month] ROWS UNBOUNDED PRECEDING) AS Closing
FROM [dbo].[WU_Closing_View]
WHERE [Customer] IN ('CustomerList')
GROUP BY [Customer], [Year], [Month], [Closing]
UNION ALL
SELECT '' AS Customer, CASE WHEN [Year] < 2016 THEN 1 ELSE [Year] END AS [Year], CASE WHEN [Year] < 2016 THEN 0 ELSE [Month] END AS [Month], '' AS Total, '' AS Sum_bought
FROM [dbo].Months
WHERE [Year] <= 2016
GROUP BY Year, Month
ORDER BY Customer, Year, Month
I also tried to do it "month by month", with the below query. It works for one month, but I can't find any way to use this to get the results for each month of the year 2016.
SELECT
(SELECT SUM(Closing) AS Expr1
FROM OTRS_Revised.dbo.WU_Bought_View
WHERE (Customer LIKE 'SomeCustomer') AND (DATEADD(Year, Year - 1900, DATEADD(Month, Month - 1, DATEADD(day, 0, 0))) <= DATEADD(Year, 2016 - 1900, DATEADD(Month, 5 - 1, DATEADD(day, 0, 0))))
GROUP BY Customer)
+
(SELECT SUM(Closing) AS Expr1
FROM OTRS_Revised.dbo.WU_Consumed_View
WHERE (Customer LIKE 'SomeCustomer') AND (DATEADD(Year, Year - 1900, DATEADD(Month, Month - 1, DATEADD(day, 0, 0))) <= DATEADD(Year, 2016 - 1900, DATEADD(Month, 5 - 1, DATEADD(day, 0, 0))))
GROUP BY Customer) AS Expr1,
[Month]
FROM OTRS_Revised.dbo.Months
GROUP BY [Month]
SELECT b.*
FROM
( SELECT CASE WHEN [Year] < 2016 THEN 1 ELSE [Year] END AS [Year], CASE WHEN [Year] < 2016 THEN 0 ELSE [Month] END AS [Month]
FROM [dbo].Months
WHERE [Year] <= 2016
GROUP BY Year, Month
ORDER BY Customer, Year, Month ) AS a
LEFT OUTER JOIN
(SELECT [Customer], CASE WHEN [Year] < 2016 THEN 1 ELSE [Year] END AS [Year], CASE WHEN [Year] < 2016 THEN 0 ELSE [Month] END AS [Month], [Closing] AS Total, SUM([Closing])
OVER (PARTITION BY [Customer] ORDER BY [Year], [Month] ROWS UNBOUNDED PRECEDING) AS Closing
FROM [dbo].[WU_Closing_View]
WHERE [Customer] IN ('CustomerList')
GROUP BY [Customer], [Year], [Month], [Closing]) AS b
ON a.Month = b.Month )
In your approach when you do union the rows that don't have matching months is getting removed. Since you want the months that does not have closing match as well, you need to use the left outer join
Something like this perhaps
DECLARE #T TABLE (ID INT, ProductID INT, TrDate DATE,InOut VARCHAR(10),Amount INT)
INSERT INTO #T VALUES
(1 ,1, '2016-01-01', 'I', 100),
(2 ,2, '2016-01-01', 'I', 100),
(3 ,3, '2016-02-01', 'I', 100),
(4 ,4, '2016-03-01', 'I', 100),
(5 ,1, '2016-03-01', 'I', 100),
(6 ,2, '2016-04-01', 'O', 10),
(7 ,3, '2016-05-01', 'I', 100),
(8 ,5, '2016-05-01', 'I', 100),
(9 ,5, '2016-05-01', 'O', 100),
(10 ,6, '2016-05-01', 'I', 100)
declare #m table (id int, menddate date)
insert #m values
(1,'2015-12-31'),(2,'2016-01-31'),(3,'2016-02-29'),(4,'2016-03-31'),
(5,'2016-04-30'),(6,'2016-05-31'),(7,'2016-06-30'),(4,'2016-07-31')
Select *
from
(
select -- t.*
x.xproductid , x.xyyyymm,
SUM(t.total) OVER (partition by x.xproductid
ORDER BY x.xyyyymm
ROWS UNBOUNDED PRECEDING) AS CumulativeTotal
from
(
SELECT t.ProductID tproductid, year(t.trdate) * 100 + month(t.trdate) tyyyymm,
sum(case when t.Inout = 'I' then t.Amount else t.amount * -1 end) as total
FROM #T t
group by ProductID, year(t.trdate) * 100 + month(t.trdate)
) t
right outer join
(select distinct productid as xproductid,year(m.menddate) * 100 + month(m.menddate) xyyyymm from #t t, #m m) x on x.xproductid = t.tproductid and x.xyyyymm = t.tyyyymm
) z
where z.xyyyymm >= 201601
order by z.xProductID,z.xyyyymm
Note the use of a right outer join to get all the month ends for all products
I have a SELECT Statement that shows details on Orders.
It uses the below code
SELECT Orders.OrderID, Orders.invoiceID, Items.itemName AS 'Item Name', Orders.quantity, DATENAME(mm, Orders.OrderDate) + ' ' + DATENAME(dd, Orders.OrderDate) + ', ' + DATENAME(yyyy, Orders.OrderDate) AS 'Order Date', (Orders.price * Orders.quantity) AS 'Total', Orders.delivered
FROM Orders
INNER JOIN Items
ON Orders.itemID = Items.itemID
ORDER BY Orders.orderID, Items.itemID ASC
Everything works fine, however I'm not sure how to get a "$" to show up to the left of the numbers in the "total" field.
All help will be appreciated.
Thanks,
Bryan
try this
SELECT Orders.OrderID,
Orders.invoiceID,
Items.itemName AS 'Item Name',
Orders.quantity,
DATENAME(mm, Orders.OrderDate) + ' ' + DATENAME(dd, Orders.OrderDate) + ', ' + DATENAME(yyyy, Orders.OrderDate) AS 'Order Date',
'$' + Convert(VARCHAR(50), Orders.price * Orders.quantity) AS 'Total',
Orders.delivered
FROM Orders
INNER JOIN Items ON Orders.itemID = Items.itemID
ORDER BY Orders.orderID, Items.itemID ASC
You could just explicitly concat it:
SELECT Orders.OrderID,
Orders.invoiceID,
Items.itemName AS 'Item Name',
Orders.quantity,
DATENAME(mm, Orders.OrderDate) + ' ' + DATENAME(dd, Orders.OrderDate) + ', ' + DATENAME(yyyy, Orders.OrderDate) AS 'Order Date',
'$' + (CAST (Orders.price * Orders.quantity) AS VARCHAR(100)) AS 'Total',
Orders.delivered
FROM Orders
INNER JOIN Items ON Orders.itemID = Items.itemID
ORDER BY Orders.orderID, Items.itemID ASC
This is untested, but this is the same answer but casting the numeric value.
SELECT Orders.OrderID,
Orders.invoiceID,
Items.itemName AS 'Item Name',
Orders.quantity,
DATENAME(mm, Orders.OrderDate) + ' ' + DATENAME(dd, Orders.OrderDate) + ', ' + DATENAME(yyyy, Orders.OrderDate) AS 'Order Date',
'$' + CAST((Orders.price * Orders.quantity) as varchar(90))
AS 'Total',
Orders.delivered
FROM Orders
INNER JOIN Items ON Orders.itemID = Items.itemID
ORDER BY Orders.orderID, Items.itemID ASC
here is my query and result;
select
DATEADD(dd, DATEDIFF(dd, 0, PostDate), 0) as Date,
Stores.Name StoreName,
SUM(PosCash + PosCredit + PosBillCash + PosBillCredit) as Revenue
from StoreRevenue
inner join Stores on Stores.ID = StoreRevenue.StoreID
group by DATEADD(dd, DATEDIFF(dd, 0, PostDate), 0), Stores.Name
result : http://prntscr.com/zaele
I want to create a table (result) that must be group by date and store names.
Date, Avcılar Mağaza, Ataşehir Mağaza
2013-03-04, 150, 200
2013-03-05, 200, 250
2013-03-06, 300, 150
rows of sub-group (these ones: 2013-03-04, 150, 200) are date and incomes of each stores
I want to get that kind of result
I have also tried "pivot" in sql but It doesnt work for me
sorry for my english. -Thanks
You can use the PIVOT function to transform the data from rows to columns:
select *
from
(
select
DATEADD(dd, DATEDIFF(dd, 0, PostDate), 0) as Date,
Stores.Name StoreName,
(PosCash + PosCredit + PosBillCash + PosBillCredit) as Revenue
from StoreRevenue
inner join Stores
on Stores.ID = StoreRevenue.StoreID
) d
pivot
(
sum(Revenue)
for StoreName in ([Avcılar Mağaza], [Ataşehir Mağaza]..)
) piv;
Or you can use an aggregate function with a CASE:
select DATEADD(dd, DATEDIFF(dd, 0, PostDate), 0) as Date,
sum(case when Stores.Name = 'Avcılar Mağaza'
then PosCash + PosCredit + PosBillCash + PosBillCredit end) as [Avcılar Mağaza],
sum(case when Stores.Name = 'Ataşehir Mağaza'
then PosCash + PosCredit + PosBillCash + PosBillCredit end) as [Ataşehir Mağaza]
from StoreRevenue
inner join Stores
on Stores.ID = StoreRevenue.StoreID
group by DATEADD(dd, DATEDIFF(dd, 0, PostDate), 0)
If you have an unknown number fo stores, then you can use dynamic sql:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(name)
from Stores
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT Date, ' + #cols + '
from
(
select
DATEADD(dd, DATEDIFF(dd, 0, PostDate), 0) as Date,
Stores.Name StoreName,
(PosCash + PosCredit + PosBillCash + PosBillCredit) as Revenue
from StoreRevenue
inner join Stores
on Stores.ID = StoreRevenue.StoreID
) x
pivot
(
sum(Revenue)
for StoreName in (' + #cols + ')
) p '
execute(#query)
Try this:
WITH CTE
AS
(
select
DATEADD(dd, DATEDIFF(dd, 0, PostDate), 0) as Date,
Stores.Name StoreName,
PosCash + PosCredit + PosBillCash + PosBillCredit as Revenue
from StoreRevenue
inner join Stores on Stores.ID = StoreRevenue.StoreID
)
SELECT *
FROM CTE AS c
PIVOT
(
SUM(Revenue)
FOR StoreName IN ([Avcılar Mağaza], [Ataşehir Mağaza], ...)
) AS p
I am having trouble outputting an SQL Select Statement to my XML to be used for my Graph
I have these results
December 2011 470 FRESENIUS
January 2012 434 FRESENIUS
February 2012 278 FRESENIUS
February 2012 2 STORESID
I need to output them like this so I can loop my Code and generate the XML
Month Year FRESNIUS STORESID
December 2011 470 0
January 2012 434 0
February 2012 278 2
take note i did not include the headers, these are all column results.
and also, STORESID and FRESNIUS are not STATIC Values. Multiple Storers Exists so I needed to Expand my number of Columns also , Dynamically.
I kinda need to output the second one to generate the XML properly thru PHP which I already have. Or are there any other proper way.
Thanks.
query below for the output i was talking about
SELECT
DATENAME(month, orderdate) + ' ' + CAST(Year(orderdate) AS VARCHAR(4)) AS 'Month Year' ,
count(*) 'Number of Orders',
storerkey
FROM orders
GROUP BY
storerkey,
DATENAME(month, orderdate) + ' ' + CAST(Year(orderdate) AS VARCHAR(4)),
CAST(Year(orderdate) AS VARCHAR(4)) + RIGHT('0' + CAST(Month(orderdate) AS VARCHAR(2)),2)
ORDER BY
storerkey,
CAST(Year(orderdate) AS VARCHAR(4)) + RIGHT('0' + CAST(Month(orderdate) AS VARCHAR(2)),2)
I am not 100% certain of the XML output you need but you can take advantage of SQL-Servers FOR XML clause and PIVOT function. This should get you started:
CREATE TABLE #Test (GraphDate DATETIME, Value INT, Type VARCHAR(50))
INSERT #Test VALUES
('01/12/2011', 470, 'FRESENIUS'),
('01/01/2012', 434, 'FRESENIUS'),
('01/12/2012', 278, 'FRESENIUS'),
('01/02/2012', 2, 'STORESID')
SELECT DATEPART(YEAR, GraphDate) [Year],
DATENAME(MONTH, GraphDate) [Month],
ISNULL(FRESENIUS, 0) [FRESENIUS],
ISNULL(STORESID, 0) [STORESID]
FROM #Test
PIVOT
( SUM(Value)
FOR Type IN ([FRESENIUS], [STORESID])
) PivotTable
FOR XML PATH('row'), ROOT
DROP TABLE #Test
EDIT
The below is the basic query you have asked for based on the query you have given.
SELECT DATENAME(MONTH, OrderDate) + ' ' + DATENAME(YEAR, OrderDate) [MonthYear],
ISNULL(FRESENIUS, 0) [FRESENIUS],
ISNULL(STORESID, 0) [STORESID]
FROM Orders
PIVOT
( COUNT(StorerKey)
FOR StorerKey IN ([FRESENIUS], [STORESID])
) PivotTable
ORDER BY DATEPART(YEAR, OrderDate), DATEPART(MONTH, OrderDate)
EDIT 2
I don't think PIVOT is supported by SQL-Server 2000. You will need to use aggregate functions:
SELECT DATENAME(MONTH, OrderDate) + ' ' + DATENAME(YEAR, OrderDate) [MonthYear],
COUNT(CASE WHEN StorerKey = 'FRESENIUS' THEN 1 END) [FRESENIUS],
COUNT(CASE WHEN StorerKey = 'STORESID' THEN 1 END) [STORESID]
FROM Orders
GROUP BY DATEPART(YEAR, OrderDate), DATEPART(MONTH, OrderDate), DATENAME(YEAR, OrderDate), DATENAME(MONTH, OrderDate)
ORDER BY DATEPART(YEAR, OrderDate), DATEPART(MONTH, OrderDate)
I think some FOR XML functionality is still available though so you may still be able to output your XML directly from SQL.
EDIT 3
DECLARE #SQL NVARCHAR(2000)
SELECT #SQL = ISNULL(#SQL, '') + ', COUNT(CASE WHEN StorerKey = ''' + StorerKey + ''' THEN 1 END) [' + StorerKey + ']'
FROM ( SELECT DISTINCT StorerKey
FROM Orders
) Keys
SET #SQL = 'SELECT DATENAME(MONTH, OrderDate) + '' '' + DATENAME(YEAR, OrderDate) [MonthYear]' + #SQL +
' FROM Orders
GROUP BY DATEPART(YEAR, OrderDate), DATEPART(MONTH, OrderDate), DATENAME(YEAR, OrderDate), DATENAME(MONTH, OrderDate)
ORDER BY DATEPART(YEAR, OrderDate), DATEPART(MONTH, OrderDate)'
EXECUTE SP_EXECUTESQL #SQL
You could join the table to itself. If I make assumptions about the column names, assume that either the FRESNIUS or STORESID could be absent, and use common table expressions (untested!):
WITH date_fresnius AS (
SELECT [Month Year], FRESNIUS
FROM original_table
)
, date_storesid AS (
SELECT [Month Year], STORESID
FROM original_table
)
SELECT
ISNULL( f.[Month Year], s.[Month Year]) AS [Month Year]
, ISNULL( f.FRESNIUS, 0 ) AS FRESNIUS
, ISNULL( s.STORESID, 0 ) AS STORESID
FROM
date_fresnius f
FULL OUTER JOIN date_storesid s ON (f.[Month Year] = s.[Month Year])
If you always have a FRESNIUS record you can use a LEFT JOIN instead.
Based on your query:
SELECT
DATENAME(MONTH, orderdate) + ' ' + CAST(YEAR(orderdate) AS VARCHAR(4)) AS [Month Year]
COUNT(CASE storerkey WHEN 'FRESNIUS' THEN 1 END) AS FRESNIUS,
COUNT(CASE storerkey WHEN 'STORESID' THEN 1 END) AS STORESID
FROM orders
GROUP BY YEAR(orderdate), MONTH(orderdate), DATENAME(MONTH, orderdate)
ORDER BY YEAR(orderdate), MONTH(orderdate)
Output:
Month Year FRESNIUS STORESID
December 2011 470 0
January 2012 434 0
February 2012 278 2
I need to select the last 12 months of rolling demand from a table that contains the following fields:
Item,
Year,
Month,
Demand Qty
I have tried the following:
Select Item, [Year], [Month],[Demand QTY]
FROM [table1]
Where
(
[Year] >= Year(getdate())-'1'
and [Month] >= Month(getdate())
)
and
(
[Year] < year(getdate())+'1'
and [Month] <= month(getdate())
)
but I am only getting the records for last year and this year of the current month.
Item Year Month Demand Qty
CD051 2011 3 8800
CD051 2012 3 0
I'm still a rookie so I could be making obvious mistakes. Could someone please help me?
Try:
Select Item, [Year], [Month],[Demand QTY]
FROM [table1]
Where ( [Year] = Year(getdate())-'1' and [Month] >= Month(getdate()) ) or
( [Year] = year(getdate()) and [Month] <= month(getdate()) )
The best way to do this:
Select * from TableName where (([Year] * 100) + [Month]) >= ((Year(DateAdd(mm, -12, GetDate())) * 100) + (Month(DateAdd(mm, -12, GetDate()))))
This will only give you between 12 months ago and today
Select * from TableName where (([Year] * 100) + [Month]) between ((Year(DateAdd(mm, -12, GetDate())) * 100) + (Month(DateAdd(mm, -12, GetDate())))) and (Year(GetDate()) * 100 + Month(GetDate()))
For an average, you should be able to add
Select [Year], [Month], Avg([Demand QTY]) AvgDemand from TableName where (([Year] * 100) + [Month]) between ((Year(DateAdd(mm, -12, GetDate())) * 100) + (Month(DateAdd(mm, -12, GetDate())))) and (Year(GetDate()) * 100 + Month(GetDate()))
Group by [Year], [Month]
Just remember that if you have other columns in your query that would make the row unique, you Avg wont give you what you expect