How do I show a timestamp member as a date in SQL Server MDX queries - sql-server

I have a scenario where I the dimension has a series of date / time members but instead I want to show it grouped to the day, how do I do that?
Example cube query:
select {[Measures].[Count]} on columns,
[Date].[Date].[Date] on rows
from [Cube]
and this query returns:
| count
2014-03-03 15:50:24.000 | 1
2014-03-03 16:05:10.000 | 1
2014-03-03 16:05:21.000 | 1
2014-03-02 16:30:13.000 | 1
I want to be able to show
| count
2014-03-03 | 3
2014-03-02 | 1
I'm using Microsoft Analysis Services 2008 R2 and the MDX queries for that

Maybe this is a little similar to what you're trying to achieve:
WITH
MEMBER [Measures].[countDays] AS
Count((EXISTING [Date].[Calendar].[Date]))
SELECT
{[Measures].[countDays]} ON COLUMNS
,[Date].[Calendar].[Month] ON ROWS
FROM [Adventure Works];
It returns the following:

Related

SQL Server - same table for multiple customers

I have a need to manage a dataset for multiple customers - each customer manages a small table to update procedure volumes for the next five years. The table is structured like so:
+-------------+--------+--------+--------+--------+--------+
| | Year 1 | Year 2 | Year 3 | Year 4 | Year 5 |
+-------------+--------+--------+--------+--------+--------+
| Procedure A | 5 | 10 | 14 | 12 | 21 |
+-------------+--------+--------+--------+--------+--------+
| Procedure B | 23 | 23 | 2 | 3 | 4 |
+-------------+--------+--------+--------+--------+--------+
| Procedure C | 5 | 6 | 7 | 8 | 12 |
+-------------+--------+--------+--------+--------+--------+
The values in this table will be managed by each customer via MS PowerApps.
This same structure exists for every single customer. What is the best way to put all of these in one dataset?
Should I just add a column for CUSTOMER ID and just put all the data in there?
The process:
Utilizing PowerApps, a new customer deal will be generated and a row will be added for them in the SQL DB in a customer records table.
Simultaneously, the blank template of the above table should be generated for them.
Now, the customer can interface with this SQL table within PowerApps and add their respective procedure volumes.
The question isn't explained well but:
I would assume all of the customer specific data has at least one column that is the same. For instance CustomerName. You could create your own table with CustomerId, CustomerName, (any other fields you would like to see). If there isn't a concept of CustomerId on the customer's tables, you would have to join them on CustomerName. You could populate your own CustomerId for the new table.
I would be happy to help more if you could clarify the question and show a few examples.

How to forecast count based on a day?

I am new to SQL Server world. I have a table as below:
alert_id | create_date | Status
---------+-------------+---------
1231 | 4/15/2017 | Open
1232 | 4/15/2017 | Open
1234 | 4/15/2017 | Closed
1235 | 4/16/2017 | Open
All of these alerts should be closed in 30 days. I need to get a forecast report which shows how many alerts are open for past 30 days.
I would like to write a select query whose output would be 2 columns. First would be Date and 2nd would be count. The date column should display all the dates for next 30 days and Count column should display the number of records which are due to expire on that day. Something like below would work. Please assist.
date | Count
----------+---------
5/15/2017 | 2
5/16/2017 | 3
5/17/2017 | 0
5/18/2017 | 0
.
.
.
6/14/2017 | 0
This is a job for GROUP BY and date arithmetic. In MySQL:
SELECT DATE(create_date) + INTERVAL 30 DAY expire_date, COUNT(*) num
FROM tbl
WHERE status = 'Open'
GROUP BY DATE(create_date)
DATE(create_date) + INTERVAL 30 DAY gets you the create date values with thirty days added.
GROUP BY(create_date) groups your data by values of your create date, truncated to midnight.
And, COUNT(*) goes with GROUP BY to tell you how many records in each group.
Edit In recent versions of SQL Server (MS)
SELECT DATEADD(day, 30, CAST(create_date AS DATE)) expire_date, COUNT(*) num
FROM tbl
WHERE status = 'Open'
GROUP BY CAST(create_date AS DATE)
Notice, please, that date arithmetic varies between make and model of SQL server software. That's why you get hassled by Stack Overflow users in comments when you use more than one tag like [oracle] [mysql] [sql-server] on your questions.
Cool, huh? You should read up on aggregate queries, sometimes called summary queries.
You're not going to get the missing dates with zeros by them. That's quite a bit harder to do with SQL.

GROUP BY to flatten each group member in a separate column

I am trying to generate a report in SSRS.
I have 2 tables as below:
Address table:
AddressId | AddressLine
AddressCountEachMonth
ID | AddressId | Date | Count
For each date(Year-Month) there is an entry in AddressCountEachMonth table with the count value.
What I would like to do is to be able to query AddressCountEachMonth to output the result as below
For example If I provide a start date: 2014-01-01 and and date: 2014-05-01
Query result should be:
Address | 2016-01 | 2016-02 | 2016-03 | 2016-04 | 2016-05|
x 5 1 0 2 4
y 2 3 4 0 2
...
...
is there any function in SQL Server that would help? I looked into STUFF but could not generate the result.
Luckily SSRS provides the ability to pivot dynamically so you will not have to hard code a query or build dynamic sql. Check out this article that shows step by step how to do this.
https://msdn.microsoft.com/en-us/library/ms157334%28v=sql.100%29.aspx?f=255&MSPPError=-2147217396
Another good one:
https://www.simple-talk.com/sql/reporting-services/advanced-matrix-reporting-techniques/

select all rows that have more than one ID in a specific date

My table:
Items | Price | UpdateAt
1 | 2000 | 02/02/2015
2 | 4000 | 06/04/2015
3 | 2150 | 07/05/2015
4 | 1800 | 07/05/2015
5 | 5540 | 08/16/2015
4 | 1700 | 12/24/2015
5 | 5200 | 12/26/2015
2 | 3900 | 01/01/2016
4 | 2000 | 06/14/2016
As you can see, this is a table that keeps items' price as well as their old price before the last update.
Now I need to find the rows which :
UpdateAt is more than 1 year ago from now
Must have updated price at least once ever since
Aren't the most up-to-date price
So with those conditions, the result from the above table should be :
Items | Price | UpdateAt
2 | 4000 | 06/04/2015
4 | 1800 | 07/05/2015
I can achieve what I need with this
Declare #LastUpdate date set #LastUpdate = DATEADD(YEAER, -1, GETDATE())
select Items, UpdateAt from ITEM_PRICE where Items in (
select Items from (
select Items, count(Items) as C from ITEM_PRICE group by Items) T
where T.C > 1)
and UpdateAt < #LastUpdate
But since I am still a newbie in sqlserver, and this need to be done in vb.net, passing along that query with lots of select in it seems sloppy and hard to maintain.
So, I would like to ask if anyone can give me a simpler solution ?
Sorry, i edited my question as I need one more condition to be met after trying #Tim Biegeleisen's answer, which is indeed the correct one for the question before edit. And I can't figure this out anymore.
Why I need all those condition, it's because I'm having to clean up the table: Clearing off the data that's older than 1 year, while still keeping the most up-to-date item price.
In my answer below, I use a subquery to identify all items which appear in the table during the last year. This is the requirement of having an updated price "at least once ever since." In the outer query, I restrict to only records which are older than one year from now, which is the other part of the requirement. An INNER JOIN is used, because we want to filter off records which do not meet both criteria.
SELECT t1.Items, t1.Price, t1.UpdateAt
FROM ITEM_PRICE t1
INNER JOIN
(
SELECT DISTINCT Items
FROM ITEM_PRICE
WHERE UpdateAt > DATEADD(year, -1, GETDATE())
) t2
ON t1.Items = t2.Items
WHERE t1.UpdateAt <= DATEADD(year, -1, GETDATE())
Once again, SQL Fiddle is having problems simulating SQL Server. But I went ahead and created a Fiddle in MySQL, which looks nearly identical to my SQL Server answer. You can verify that the logic and output are correct.
SQLFiddle

Pivottable on SSAS cube: hide rows without result on measure

I'm having trouble hiding rows that have no data for certain dimension members for the selected measure, however there are rows for that member in the measuregroup.
Consider the following datasource for the measuregroup:
+---------+----------+----------+----------+--------+
| invoice | customer | subtotal | shipping | total |
+---------+----------+----------+----------+--------+
| 1 | a | 12.95 | 2.50 | 15.45 |
| 2 | a | 7.50 | | 7.50 |
| 3 | b | 125.00 | | 125.00 |
+---------+----------+----------+----------+--------+
When trying to create a pivottable based on a measuregroup in a SSAS-cube, this might result in the following:
However, I would like to hide the row for Customer b, since there are no results in the given pivottable. I have tried using Pivottable Options -> Display -> Show items with no data on rows but that only works for showing/hiding a Customer that's not at all referenced in the given measuregroup, say Customer c.
Is there any way to hide rows without results for the given measure, without creating a seperate measuregroup WHERE shipping IS NOT NULL?
I'm using SQL-server 2008 and Excel 2013
Edit:
For clarification, I'm using Excel to connect to the SSAS cube. The resulting pivottable (in Excel) looks like the given image.
In the DSV find the table with the shipping column and add a calculated column with expression:
Case when shipping <> 0 then shipping end
Please go to the properties window for the Shipping measure in the cube designer in BIDS and change the NullHandling property to Preserve. Change the source column to the new calculated column. Then redeploy and I am hopeful that row in your pivot will disappear.
And ensure Pivottable Options -> Display -> Show items with no data on rows is unchecked.
If that still doesn't do it connect the Object Explorer window of Management Studio to SSAS and tell us what version number it shows in the server node. Could be you aren't on the latest service pack and this is a bug.
Go in your pivot table in Excel, click on the dropdown on your customer column. In the dropdown menu you will find an option called Value Filters. There you can set something like Shipping greater than 0.1.
This filters your Customer dimension column based on the measure values.
Maybe something like this (but I don't see the pivot...)
DECLARE #tbl TABLE(invoice INT,customer VARCHAR(10),subtotal DECIMAL(8,2),shipping DECIMAL(8,2),total DECIMAL(8,2));
INSERT INTO #tbl VALUES
(1,'a',12.95,2.50,15.45)
,(2,'a',7.50,NULL,7.50)
,(3,'b',125.00,NULL,125.00);
SELECT customer, SUM(shipping) AS SumShipping
FROM #tbl
GROUP BY customer
HAVING SUM(shipping) IS NOT NULL

Resources