I have the following MDX query
SELECT
NON EMPTY
{
[Measures].[Date]
,[Measures].[count]
,[Measures].[Growth]
,[Measures].[Growth percentage]
}
ON COLUMNS,
NON EMPTY
(
NONEMPTY(
[Business Unit].[BU Number].[BU Number])
,[Department].[Deptnumber].[Deptnumber]
,SelectedPeriod
)
ON ROWS
FROM Cube
As result I get
Bu Number DeptNumber Period Date count Growth Growth percentage
1 a 1/1 null null null null
1 a 1/1 null null null null
1 b 1/1 1 null null null
I only want where at least one field is filled
( count
Growth
Growth percentage
)
so when I see all nulls that row should be deleted
The non empty does not do that in this example
So how to fix that
thanks
Try this:
SELECT
{
[Measures].[Date]
,[Measures].[count]
,[Measures].[Growth]
,[Measures].[Growth percentage]
}
ON COLUMNS,
NONEMPTY(
[Business Unit].[BU Number].[BU Number].Members
*[Department].[Deptnumber].[Deptnumber].Members
*SelectedPeriod,
{
[Measures].[count]
,[Measures].[Growth]
,[Measures].[Growth percentage]
}
)
ON ROWS
FROM Cube
I added a member to make the measure.date null if any other where null
that works, but now the performance is not existing. It works for some filters of the data, but 98% it does not gives results after a long time waiting
MEMBER [Measures].[Date calc] AS
(
IIF( [Measures].[Date] = null
AND [Measures].[count] = null
AND [Measures].[Growth] = null
AND [Measures].[Growth percentage] = null, Null, [Measures].[Date] )
)
And I used
NON EMPTY
CrossJoin(
Hierarchize(),
Hierarchize(),
SelectedPeriode
)
ON ROWS
and that solved the performance problem
Related
Using Microsoft SQL Server 2012
I've been trying for weeks to get this sorted over my original question for getting a query to work, it does but not correctly. What I want to achieve from this is on the old questions table I'm getting data from has a "filepath" column that the question data refers to from a folder on the local machine this is structured as an example like this: (some columns I haven't included)
Old question table
QuizQuestionID MasterQuestionID MasterQuestionGUID MasterTypeID MasterDifficultyID MasterCategoryID MasterDecadeID QuizQuestionTypeID QuizQuestionDifficultyID QuizQuestionCategoryID QuizQuestionDecadeI D QuestionText AnswerText FilePath IsEditable IsDeletable IsDeleted IsDifficultyOverridden CreatedDate ModifiedDate AUTO_UseCount AUTO_TieBreakerUsageCount AUTO_TieBreakerLastUsed
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1222 1755 0bee472592ce78e7457d87d7a172ff7b 3 2 7 3 3 2 7 3 Name the singer. David Essex /Sounds/CHORUS David Essex - Tahiti.mp3 False True False False 2014-01-18 12:53:59.000 2014-02-07 12:28:55.000 0 NULL NULL
1223 1756 1df7bd191ef5e31b854c7de5f18982d0 1 2 11 NULL 1 2 11 NULL What is this savoury item? Green Chili /Images/General/Greeen Chili.png False True False False 2014-01-18 15:17:39.000 2014-01-26 19:46:00.000 0 NULL NULL
Now in the new question table, a column uses another table called media2 to find the local filepath of files these are structured:
New question table
id uuid type question answer media created_date modified_date created_user modified_user master_category master_decade master_difficulty is_editable is_deletable multiple_choice choice_1 choice_2 choice_3 choice_4 blur_effect related square_1 square_2 square_3 square_4 tie_breaker
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
8033 07B3D24A-6FFA-40AF-B723-B78C9899D4B4 Audio Name the singer. David Essex 21488 2015-03-23 11:51:31.000 2016-03-08 15:21:48.697 NULL NULL 7 2 1 False False False NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
17395 48E555BD-52D6-4358-89E5-8FEE0F0F3AFD Text What is this savoury item? Green chili 19459 2013-09-10 23:51:35.460 2013-09-13 12:51:53.963 NULL NULL 12 NULL 1 False False NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
Media2 table
id UUID name Path Mime/type directory used for Category folder import folder
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
21488 c25183d2-aad7-4c16-8869-9eac711cc39b CHORUS David Essex - Tahiti Quiz C:\media\audio\c25183d2-aad7-4c16-8869-9eac711cc39b.mp3 audio/mp3 Audio Quiz Audio NULL NULL
19459 642db3c3-c531-4818-9b0d-4d7ccd35e0f9 Green chili C:\media\images\642db3c3-c531-4818-9b0d-4d7ccd35e0f9.png image/png Images Quiz Images NULL NULL
Just need to add that "UUID" is a random set of numbers the table uses to identify the file name in their folders so we don't get any duplicated files that may be named the same but don't have the same content and are also used by other software apart from the quiz so I can't use this as a reference to create a query.
This is the whole code that converts the "old questions table" to the "new questions table" the substring is the part that converts the format from old to new which works fine but to clarify it returns null to the "media" column on any image or sound questions, its supposed to convert the filepath column from the old table against the "media2" table and then import all rows to the new question table with the "media" column referencing the "media2" table for filepaths.
--Specify the database, table and columns we want to insert into
INSERT INTO NewDatabase.dbo.quizquestions (uuid, [type], question, answer, created_date, modified_date, master_category, master_decade, master_difficulty, is_editable, is_deletable, media)
--Get the data from the old database (old_database) and map the media filename to the media2 table in the new database
select
questions.uuid,
questions.newtype,
questions.QuestionText,
questions.AnswerText,
questions.CreatedDate,
questions.ModifiedDate,
questions.master_category,
questions.master_decade,
questions.master_difficulty,
questions.IsEditable,
questions.IsDeletable,
media.id as mediaid from
(
select NEWID() as uuid,
CASE
WHEN qqt.TypeName = 'Sound' THEN 'Audio'
ELSE qqt.TypeName
END AS newtype,
qq.QuestionText, qq.AnswerText,
CASE
WHEN qq.createdDate is not NULL THEN qq.createdDate
ELSE GETDATE()
END as createdDate,
CASE
WHEN qq.ModifiedDate is not NULL THEN qq.ModifiedDate
ELSE GETDATE()
END as ModifiedDate,
CASE
WHEN cat.id is NOT NULL THEN cat.id
ELSE 1
END as master_category,
qqdc.QuizQuestionDecadeID as master_decade,
qd.id as master_difficulty,
qq.IsEditable, qq.IsDeletable,
qq.FilePath,
SUBSTRING(
qq.FilePath,
(len(qq.FilePath) - charindex('/', reverse(qq.FilePath)) + 2),
(len(qq.FilePath) - charindex('.', reverse(qq.FilePath))) - (len(qq.FilePath) - charindex('/', reverse(qq.FilePath))) -1 ) as fpath
-- (len(qq.FilePath) - charindex('.', reverse(qq.FilePath)) as positionoflastdot),
--(len(qq.FilePath) - charindex('/', reverse(qq.FilePath)) as positionoflastslash),
from Olddatabase.dbo.QuizQuestion qq
left join Olddatabase.dbo.QuizQuestionType qqt on qq.QuizQuestionTypeID = qqt.QuizQuestionTypeID
left join Olddatabase.dbo.QuizQuestionDifficulty qqd on qq.QuizQuestionDifficultyID = qqd.QuizQuestionDifficultyID
left join Olddatabase.dbo.QuizQuestionCategory qqc on qq.QuizQuestionCategoryID = qqc.QuizQuestionCategoryID
left join Olddatabase.dbo.QuizQuestionDecade qqdc on qq.QuizQuestionDecadeID = qqdc.QuizQuestionDecadeID
left join Olddatabase.dbo.QuizQuestionCategory qqmc on qq.MasterCategoryID = qqmc.MasterQuestionCategoryID
left join Newdatabase.dbo.QuizCategories cat on qqc.CategoryName = cat.name
left join Newdatabase.dbo.QuizDifficulties qd on qd.id = qq.MasterDifficultyID
where qq.MasterCategoryID is not null
) as questions
left join Newdatabase.dbo.Media2 media on media.name = replace(fpath, 'quiz','')
i cant really change to structure of the tables as the software relies heavily on it, and changing it manually would be painful and time consuming as there are over 2000 audio/images questions
i'm just getting my head around SQL databases and queries but this has stopped me dead from progressing.
any help changing this above query or creating something entirely different would be greatly appreciated.
Just looking at it, the code seems properly structured. Faced with something like this, I’d “cut down” the query to only the relevant parts, and debug from there, tossing in extra lines like those you currently have commented out to review the parts of the function calls being returned. Pick it part, look at all th details, and you’ll eventually figure out what’s not lining up. The following should work as an initial "minimum query":
select
qquestions.FilePath
,questions.fpath
,media.id as mediaid
from (-- Build the necessary filepath. Running just the subquery can help figure things out too
select
qq.FilePath
,SUBSTRING(
qq.FilePath
,(len(qq.FilePath) - charindex('/', reverse(qq.FilePath)) + 2)
,(len(qq.FilePath) - charindex('.', reverse(qq.FilePath))) - (len(qq.FilePath) - charindex('/', reverse(qq.FilePath))) -1 ) as fpath
from Olddatabase.dbo.QuizQuestion qq
where qq.MasterCategoryID is not null
) as questions
left join Newdatabase.dbo.Media2 media
on media.name = replace(fpath, 'quiz','')
Mess with this and it should be easier to figre things out.
Bonus advice: code like
CASE
WHEN qq.createdDate is not NULL THEN qq.createdDate
ELSE GETDATE()
END as createdDate,
can be replaced with the shorter and more legible form
isnull(qq.createdDate, getdate()) createdDate,
I have a question regarding handling NULL value in a column in ORACLE Table.
So, when i query a table, i get this error message in every NULL value occurences
Notice: Undefined index: STATUS in C:\xampp\htdocs\WeltesInformationCenter\AdminLTE\pages\tables\assignmenttable.php on line 481
my query is like this
SELECT MASTER_DRAWING.*, (SELECT PREPACKING_LIST.PACKING_STATUS FROM PREPACKING_LIST WHERE MASTER_DRAWING.HEAD_MARK = PREPACKING_LIST.HEAD_MARK) STATUS FROM MASTER_DRAWING WHERE PROJECT_NAME = :PROJNAME
My question is, how to handle NULL value so that when it sees a null value, it can return some value such as 0 or any string.
Thanks
Try
SELECT MASTER_DRAWING.*,
NVL((SELECT PREPACKING_LIST.PACKING_STATUS
FROM PREPACKING_LIST
WHERE MASTER_DRAWING.HEAD_MARK = PREPACKING_LIST.HEAD_MARK),'N/A'
) STATUS
FROM MASTER_DRAWING WHERE PROJECT_NAME = :PROJNAME
I want to filter out dimensions if the metric values not exist over that dimension, but I have some metric containing some raw data ie, Infinity, 1.#NN.
I am using NON EMPTY() but it is not filtering data correctly as it filter the dimension if all metrics are null but in my case it fetch 'Infinity' dimensions too:
Mdx Query:
SELECT
{
[Measures].[1],
[Measures].[2],
[Measures].[3]
} DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS
, NON EMPTY Hierarchize (
{
DrilldownLevel ( { [Roles].[Dimension].[All] } )
}
) DIMENSION PROPERTIES PARENT_UNIQUE_NAME
, [Roles].[Roster Role].[Roster Role].[Roster Role - Enterprise]
, [Roles].[Roster Role].[Roster Role].[Roster Role - Group] ON ROWS
FROM [Cuve]
WHERE ( [Dates].[Calendar].[Calendar Year].&[2013], [Markets].[Market].&[1], [Areas]. [Area].&[8], [Roles].[Enterprise Role].&[2] )
I can not NONEMPTY() as it remove dimension if any of metric is null while I want to remove if all are null.
I want that I can filter out dimension, ie if metric value is not an integer (eg, "Infinity" or other data) or filter it out by NOT IN() kind of function.
Thanks
First, it sounds like you are dividing by 0 in the calculations for your measures. If you can, I would rewrite them to return null where the denominator is 0.
This would look something like:
IIF([Measures].[denominator] = 0, Null, [Measures].[Numerator/[Measures].[Denominator])
Then you can use Filter. I'm not quite sure I know enough about your cube's structure to write your query, but try something like this:
Select {
[Measures].[1],
[Measures].[2],
[Measures].3]} on COLUMNS,
{ Filter([Roles].[Dimension].[Dimension].members, CoalesceEmpty([Measures].[1],[Measures].[2],[Measures].[3], 0) <> 0)
* ({[Roles].[Roster Role].[Roster Role].[Roster Role - Enterprise], [Roles].[Roster Role].[Roster Role].[Roster Role - Group]})} on ROWS
FROM [Cuve]
WHERE ( [Dates].[Calendar].[Calendar Year].&[2013], [Markets].[Market].&[1], [Areas]. [Area].&[8], [Roles].[Enterprise Role].&[2] )
I have been working on creating a kpi that compares the rank of a customer on a specific date compared to the previous day. In turn you would be able to see if that customer has went up in rank or down in rank in terms of whatever the list was generated by. In my situation they are ordered by revenue.
I am able to rank my customers via the rank function easily enough and provide the report but when it comes to creating the kpi of comparing these ranks across days I am struggling in figuring out how this should be approached. The rank itself is not something stored as data it is something that I will need to create on the fly via the rank function.
Here is an example of my mdx query that I am using to create my initial starting report that provides me with rank of customers without a date splice:
WITH SET [RevRank] AS
ORDER (
[Customer].[Customer Id].CHILDREN ,
[Measures].[Revenue], BDESC)
MEMBER [Measures].[RANKRevenue] AS RANK([Customer].[Customer Id].CurrentMember, [RevRank] )
SELECT NON EMPTY { [Measures].[Revenue], [Measures].[Fact Order Count], [Measures].[RANKRevenue] } ON COLUMNS,
NON EMPTY TopCount( { ([RevRank] ) } , 100, [Measures].[Revenue]) ON ROWS
FROM [DW]
From this I am attempting to splice in a specific date (day) and then compare that rank to a previous day within a kpi. So, starting off I am working on breaking this query up. I created a pre calculated set and pre calculated member to help me do this more easily. Now I am just trying to figure out how to create this set and member by a day and then I can at least produce a comparison between one day and the next.
01/26/2012 Update: Ok, I am a bit further down the road on this, but I am still having issues with getting the rank to pull into my query, the query below has nulls for the rankings. Hopefully someone can see the issue with this query.
WITH MEMBER [Measures].[PrevDayRevenue] AS
( [Measures].[Revenue], ParallelPeriod ([Date Link].[PK Date].[PK Date],1))
SET [RevRankPrevOrder] AS
ORDER (
[Customer].[Customer Id].Members ,
[Measures].[PrevDayRevenue],
BDESC)
MEMBER [Measures].[RANKRevenuePrevOrder] AS RANK([Customer].CurrentMember, [RevRankPrevOrder])
SET [RevRankCurrOrder] AS
ORDER (
[Customer].[Customer Id].Members ,
[Measures].[Revenue],
BDESC)
MEMBER [Measures].[RANKRevenueCurrOrder] AS RANK([Customer].CurrentMember, [RevRankCurrOrder])
SELECT NON EMPTY { [Measures].[Revenue], [Measures].[PrevDayRevenue], [Measures].[RANKRevenuePrevOrder], [Measures].[RANKRevenueCurrOrder] } ON COLUMNS,
NON EMPTY { ( [RevRankCurrOrder] ) } ON ROWS
FROM [DW]
WHERE {[Date Link].[PK Date].&[2012-01-08T00:00:00]}
You can use the ParallelPeriod function to calculate the rank for the prior day. This will also need to be done on the fly.
Then you can just compare the two in your KPI value...
CASE
WHEN [Customer Rank Yesterday] - [Customer Rank Today] > 0 THEN 1
WHEN [Customer Rank Yesterday] - [Customer Rank Today] = 0 THEN 0
ELSE -1
END
Here is my finished query, hope this helps someone else. :
WITH MEMBER [Measures].[PrevDayRevenue] AS
( [Measures].[Revenue], ParallelPeriod ([Date Link].[PK Date].[PK Date],1))
SET [RevRankPrevOrder] AS
ORDER (
[Customer].[Customer Id].CHILDREN ,
[Measures].[PrevDayRevenue],
BDESC)
MEMBER [Measures].[RANKRevenuePrevOrder] AS
RANK(
[Customer].[Customer Id].CurrentMember,
[RevRankPrevOrder])
SET [RevRankCurrOrder] AS
ORDER (
[Customer].[Customer Id].CHILDREN,
[Measures].[Revenue],
BDESC)
MEMBER [Measures].[RANKRevenueCurrOrder] AS RANK([Customer].[Customer Id].CurrentMember, [RevRankCurrOrder])
SELECT NON EMPTY { [Measures].[Revenue], [Measures].[PrevDayRevenue], [Measures].[RANKRevenuePrevOrder], [Measures].[RANKRevenueCurrOrder] } ON COLUMNS,
NON EMPTY { ( [RevRankCurrOrder] ) } ON ROWS
FROM [DW]
WHERE {[Date Link].[PK Date].&[2012-01-10T00:00:00]}
When I execute a certain stored procedure (which selects from a non-indexed view) with a non-null parameter, it's lightning fast at about 10ms. When I execute it with a NULL parameter (resulting in a FKColumn = NULL query) it's much slower at about 1200ms.
I've executed it with the actual execution plan and it appears the most costly portion of the query is a clustered index scan with the predicate IS NULL on the fk column in question - 59%! The index covering this column is (AFAIK) good.
So what can I do to improve the performance here? Change the fk column to NOT NULL and fill the nulls with a default value?
SELECT top 20 dbo.vwStreamItems.ItemId
,dbo.vwStreamItems.ItemType
,dbo.vwStreamItems.AuthorId
,dbo.vwStreamItems.AuthorPreviewImageURL
,dbo.vwStreamItems.AuthorThumbImageURL
,dbo.vwStreamItems.AuthorName
,dbo.vwStreamItems.AuthorLocation
,dbo.vwStreamItems.ItemText
,dbo.vwStreamItems.ItemLat
,dbo.vwStreamItems.ItemLng
,dbo.vwStreamItems.CommentCount
,dbo.vwStreamItems.PhotoCount
,dbo.vwStreamItems.VideoCount
,dbo.vwStreamItems.CreateDate
,dbo.vwStreamItems.Language
,dbo.vwStreamItems.ProfileIsFriendsOnly
,dbo.vwStreamItems.IsActive
,dbo.vwStreamItems.LocationIsFriendsOnly
,dbo.vwStreamItems.IsFriendsOnly
,dbo.vwStreamItems.IsDeleted
,dbo.vwStreamItems.StreamId
,dbo.vwStreamItems.StreamName
,dbo.vwStreamItems.StreamOwnerId
,dbo.vwStreamItems.StreamIsDeleted
,dbo.vwStreamItems.RecipientId
,dbo.vwStreamItems.RecipientName
,dbo.vwStreamItems.StreamIsPrivate
,dbo.GetUserIsFriend(#RequestingUserId, vwStreamItems.AuthorId) as IsFriend
,dbo.GetObjectIsBookmarked(#RequestingUserId, vwStreamItems.ItemId) as IsBookmarked
from dbo.vwStreamItems WITH (NOLOCK)
where 1 = 1
and vwStreamItems.IsActive = 1
and vwStreamItems.IsDeleted = 0
and vwStreamItems.StreamIsDeleted = 0
and (
StreamId is NULL
or
ItemType = 'Stream'
)
order by CreateDate desc
When it's not null, do you have
and vwStreamItems.StreamIsDeleted = 0
and (
StreamId = 'xxx'
or
ItemType = 'Stream'
)
or
and vwStreamItems.StreamIsDeleted = 0
and (
StreamId = 'xxx'
)
You have an OR clause there which is most likely the problem, not the IS NULL as such.
The plans will show why: the OR forces a SCAN but it's manageable with StreamId = 'xxx'. When you use IS NULL, you lose selectivity.
I'd suggest changing your index make StreamId the right-most column.
However, a view is simply a macro that expands so the underlying query on the base tables could be complex and not easy to optimise...
The biggest performance gain would be for you to try to loose GetUserIsFriend and GetObjectIsBookmarked functions and use JOIN to make the same functionality. Using functions or stored procedures inside a query is basically the same as using FOR loop - the items are called 1 by 1 to determine the value of a function. If you'd use joining tables instead, all of the items values would be determined together as a group in 1 pass.