I want to create a new calculated member in OLAP Cube to count the number of distinct clients, I'm trying to write this expression, but i don't know how to make it in MDX:
Distinct count ([DIM.Clients].[CuNumber], where Sum([Measures].[QQT - FACT Ventes] >=1)
Any help please !
Thanks!
Hi thank you for replies,
I spent couple of days trying to make the query work, but without big progress.
First, I ran an SQL query on my datawarehouse to know what result should I get on my OLAP Cube,
this is my SQL query:
use [Warehouse]
select count(*) as count_row
From
(Select F.FaCunumberX
from [dbo].[Dim_FaClients] F
inner join [dbo].[FACT_Ventes] V on F.[SK_FAClients] = V.SK_FaClients
inner join [dbo].[Dim_Date] D on D.SK_Date = V.SK_Date
where
D.Year = '2014'
Group by F.FaCunumberX
having SUM(V.QQT) >= 1) test
the result I got is : 26026
On my OLAP Cube I tried several queries, but I didn't get the same result
this is some of the expressions that I tried :
WITH SET MySet AS
(Filter({[DIM FA Clients].[FaCuNumberX].[FaCuNumberX]}*{([Dim Date].[Year].&[2014],[Measures].[QQT - Fact Ventes])},[Measures].[QQT - Fact Ventes]>1 or [Measures].[QQT - Fact Ventes]=1)
MEMBER MEASURES.SETDISTINCTCOUNT AS
DISTINCTCOUNT(MySet)
SELECT {MEASURES.SETDISTINCTCOUNT} ON 0
FROM [CubeAll]
the result I got with this one is : 31575
I tried also this expression :
DistinctCount(Filter([DIM.Clients].[CuNumber].[CuNumber].Members,
[Measures].[QQT - FACT Ventes] >= 1
)
)
the same result : 31575
sincerely, I don't see what I'm missing on my expressions.
Thank's for your help !
This would be something like
DistinctCount(Filter([DIM.Clients].[CuNumber].[CuNumber].Members,
[Measures].[QQT - FACT Ventes] >= 1
)
)
See the documentation of Filter and DistinctCount for details.
Related
i have been trying to find an answer but the things i found and tried does not seem to work, or i am doing something wrong.
As an example we have 2 tables:
Table Messages:
Int: id
Date: create_timestamp
String: join_number
Table Map:
String: entity_name
String: join_number
I am trying to count create_timestamps and group them by Entity_name, so the query is:
select count(create_timestamp) as count , entity_name from Messages left join Map on Messages.join_number = Map.join_number group by entity_name
The query is working fine except of one problem it does not return entity with result 0 if no timestamps were found. I need it to return the entity_name and result 0 if it found nothing.
I tried query with COALESCE like this:
select COALESCE(count(create_timestamp), 0) as count , entity_name from Messages left join Map on Messages.join_number = Map.join_number group by entity_name
But it still does not return 0 values. Please keep in mind this is a DB2 Database, any comments, questions, or answers are really welcome here.
It turns out answer by Mark is correct. I did a mistake on query as i also included the condition "where timestamp > timestamp (xxxx)" which caused the query not to include those 0 results. In case someone can find it helpful, the correct query if you want to choose the timestamp is:
select count(timestamp) as count, entity_name from Map left join Messages on timestamp > timestamp('2020-01-01') and Messages.join_number = Map.join_number group by entity_name
Thanks a lot again!
I tried to apply the solution in Google BigQuery - Updating a nested repeated field to the field hits.transaction.transactionRevenue, but I receive error message:
Scalar subquery produced more than one element
I have tried to run the following query:
UPDATE `project_id.dataset_id.table`
SET hits = ARRAY(
SELECT AS STRUCT * REPLACE (
(SELECT AS STRUCT transaction.* REPLACE (1 AS transactionRevenue)) AS transaction
)
FROM UNNEST(hits) as transactionRevenue
)
WHERE (select h.transaction.transactionId from unnest(hits) as h) LIKE 'ABC123XYZ'
Are there any obvious mistakes on my part? Would be great if anyone could share some tips or experiences that could help me with this.
What I basically want to do is to set the revenue of a specific transaction to 1.
Many thanks in advance,
David
This is the problem:
WHERE (select h.transaction.transactionId from unnest(hits) as h) LIKE 'ABC123XYZ'
If there is more than one hit in the array, this will cause the error that you are seeing. You probably want this instead:
WHERE EXISTS (select 1 from unnest(hits) as h WHERE h.transaction.transactionId LIKE 'ABC123XYZ')
But note that your UPDATE will now replace all elements of the array for any row where this condition is true. What you may want is to move the condition inside the ARRAY function call instead:
UPDATE `project_id.dataset_id.table`
SET hits = ARRAY(
SELECT AS STRUCT * REPLACE (
(SELECT AS STRUCT transaction.* REPLACE (1 AS transactionRevenue)) AS transaction
)
FROM UNNEST(hits) as h
WHERE h.transaction.transactionId LIKE 'ABC123XYZ'
)
WHERE true
Now the replacement will only apply to hits with a transaction ID matching the pattern.
I have a query that was given to me that I modified for my use.
I'm having issue with the double of total billed amounts. However some accounts the aggregation is correct while in other accounts its double.
my sql is this.
SELECT DISTINCT
CNT.ACCT_ID,
COUNT(DISTINCT CNT.BILL_ID) AS BILLS,
TO_CHAR(SUM(CNT.CUR_AMT),'9,999,999') as TOTAL_BILLED,
TO_CHAR(SUM(CNT.CUR_AMT)/COUNT (DISTINCT CNT.BILL_ID),'999,999') as AVG_BILL
FROM
(SELECT
LC.ACCT_ID,
BILL.BILL_ID,
FT.CUR_AMT,
BILL.BILL_DT
FROM table1.CUSTOMER_DEPOSITS LC,
table2.PS_CI_BSEG BSEG,
table3.PS_CI_BILL BILL,
table4.PS_CI_FT FT
WHERE
LC.ACCT_ID =BILL.ACCT_ID
AND LC.CUST_CLASS NOT IN ('PPAY-R','TAFT','C-TAFT','SP3','C-NPAY')
AND FT.BILL_ID = BILL.BILL_ID
AND FT.FT_TYPE_FLG = 'BS'
AND BSEG.BILL_ID = BILL.BILL_ID
AND BSEG.BSEG_STAT_FLG = '50'
AND FT.ARS_DT > '01-JUN-2015'
AND FT.ARS_DT < '01-JUL-2016'
)CNT
GROUP BY CNT.ACCT_ID
I ran this against two accounts.
One account had the correct total_billed amount
while the second account had doubled the total_billed amount
I missing something but I honestly don't know how to resolve this.
Any help would be greatly appreciated.
(Using Oracle 11.2)
I have a rather complicated SQL with something like
wm_concat( distinct abc )
that is expected to return some varchar2(4000) compatible result.
It causes ORA-00932: inconsistent datatypes in my select used in some coalesce( some_varchar_col, wm_concat( ... ) ).
So I tried casting it via two different methods:
dbms_lob.substr( ..., 4000 ) -- L) tried even with 3000 in case of "unicode byte blow-up"
cast( ... as varchar2(4000)) -- C) tried even with 3000 in case of "unicode byte blow-up"
(The are used in a view, but playing around with it suggests, it is not related to the views)
Depending on the column and other operators I either get N) no result or O) ORA-22922:
select * from view_with_above_included where rownum <= 100
N) My Eclipse Data Explorer JDBC connection returns without any result (no columns without results, no (0 rows effected), only the query time statistics). (It could be an internal exception not treated as such?)
O)
ORA-22922: nonexistent LOB value
ORA-06512: in "SYS.DBMS_LOB", line 1092
ORA-06512: in line 1
Strangely the following test queries work:
-- rownum <= 100 would already cause the above problems
select * from view_with_above_included where rownum <= 10
or
select * from view_with_above_included
but looking at the actual aggregated data does not show aggregated data that would exceed 1000 characters in length.
Luckily, it works with the listagg( ... ) function provided since 11.2 (we are already running on), so we did not have to investigate further:
listagg( abc, ',' ) within group ( order by abc )
(Where wm_concat(...) is, as one should know, some internal and officially unsupported function.)
a rather nice solution (because it is not so bloated) to implement the distinct functionality is via self-referencing regexp functionality which should work in many cases:
regexp_replace(
listagg( abc, ',' ) within group ( order by abc )
, '(^|,)(.+)(,\2)+', '\1\2' )
(Maybe/Hopefully we will see some working listagg( distinct abc ) functionality in the future, which would be very neat and cool like the wm_concat syntax. E.g. this is no problem since a long time with Postgres' string_agg( distinct abc )1 )
-- 1: postgres sql example:
select string_agg( distinct x, ',' ) from unnest('{a,b,a}'::text[]) as x`
If the list exceeds 4000 characters, one cannot use listagg anymore (ORA-22922 again).
But luckily we can use the xmlagg function here (as mentioned here).
If you want to realize a distinct on a 4000-chars-truncated result here, you could outcomment the (1)-marked lines.
-- in smallercase everything that could/should be special for your query
-- comment in (1) to realize a distinct on a 4000 chars truncated result
WITH cfg AS (
SELECT
',' AS list_delim,
'([^,]+)(,\1)*(,|$)' AS list_dist_match, -- regexp match for distinct functionality
'\1\3' AS LIST_DIST_REPL -- regexp replace for distinct functionality
FROM DUAL
)
SELECT
--REGEXP_REPLACE( DBMS_LOB.SUBSTR( -- (1)
RTRIM( XMLAGG( XMLELEMENT( E, mycol, listdelim ).EXTRACT('//text()')
ORDER BY mycol ).GetClobVal(), LIST_DELIM )
--, 4000 ), LIST_DIST_MATCH, LIST_DIST_REPL ) -- (1)
AS mylist
FROM mytab, CFG
I have the following dql SELECT query, which works:
SELECT q AS question, AVG(r.score) AS average
FROM MyBundle:Question q
JOIN q.ratings r
WHERE q.deleted IS NULL
GROUP BY q.id
ORDER BY q.id ASC
What I'd like to do is make it return 0 if AVG(r.score) is either 0 or null. I'm just not sure how to do it. Is it possible to do something like:
SELECT q AS question, (AVG(r.score) OR 0) AS average FROM....
Since you can't use aggregate function in a WHERE clause, you must use HAVING instead. That should do the trick:
SELECT q AS question, AVG(r.score) AS average
FROM MyBundle:Question q
JOIN q.ratings r
WHERE q.deleted IS NULL
GROUP BY q.id
HAVING average IN (0, NULL)
ORDER BY q.id ASC
Are you looking for an alternative of mysql IFNULL to a doctrine query builder. Look at this question.
Changing my (INNER) JOIN to a LEFT OUTER JOIN gave me the results I was looking for.