Mdx calculate count distinct - count

I want to write a mdx script that displays the count rows I have for a member.
This is my initial script:
SELECT NON EMPTY { [Measures].[I_OPC_ATTEINT]
and 6 measures } ON COLUMNS
, NON EMPTY { ([Axe_Temps].[MOIS_ANNEE].[MOIS_ANNEE].ALLMEMBERS
* [Axe_ORGANISATION].[Structure].[EQUIPE].ALLMEMBERS
* [Axe_OPC].[TYPE_REGROUPEMENT].[TYPE_REGROUPEMENT].ALLMEMBERS
* [Axe_OPC].[COMPOSITION].[COMPOSITION].ALLMEMBERS
* [Axe_OPC].[OPC].[OPC].ALLMEMBERS ) } DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME ON ROWS
FROM ( SELECT ( STRTOMEMBER('[Axe_ORGANISATION].[CODE_EQUIPE].&[E_1001]') ) ON COLUMNS
FROM ( SELECT ( STRTOMEMBER('[Axe_ORGANISATION].[CODE_PLATEAU].&[D_1000]') ) ON COLUMNS
FROM ( SELECT ( STRTOMEMBER('[Axe_ORGANISATION].[CODE_UNITE].&[U_107864]') ) ON COLUMNS
FROM ( SELECT ( STRTOMEMBER('[Axe_ORGANISATION].[CODE_CANAL].&[AVSC]') ) ON COLUMNS
FROM ( SELECT ( STRTOMEMBER('[Axe_Temps].[MOIS_ANNEE].&[201306]') ) ON COLUMNS
FROM [PVC_Reporting])))))
I want to display 2 calculated measures:
The count of rows of my result ( count distinct ( [Axe_OPC].[COMPOSITION].[COMPOSITION].ALLMEMBERS )
The count of rows where [Measures].[I_OPC_ATTEINT] <> 0
Thank you.

I would create a measure of type 'distinct count' within the cube and create a simple dimension (oui|non) for I_OPC_ATTEINT.

Related

Quicksight Countover with Conditional

I have a table with order information. It is broken down by OrderID, Item Name. How can I get the count of all orders with multiple x and y items. For example, how many orders have more than 1 dumplings and more than 1 water?
You can use the Countif function like:
countIf (
Revenue,
# Conditions
CalendarDay >= ${BasePeriodStartDate} AND
CalendarDay <= ${BasePeriodEndDate} AND
SourcingType <> 'Indirect'
)
Documentation

Error in concatenation of `LISTAGG` function[Not a duplicate question] [duplicate]

I have the following table TEMP
I want to create a pivot view using SQL, Ordered by CATEGORY ASC ,by LEVEL DESC and SET ASC and fill in the value .
Expected output:
I have tried the following code but unable to get a workaround the aggregate part which is throwing an error:
SELECT *
FROM
(SELECT
SET, LEVEL, CATEGORY, VALUE
FROM
TEMP
ORDER BY
CATEGORY ASC, LEVEL DESC, SET ASC) x
PIVOT
(value(VALUE) FOR RISK_LEVEL IN ('X','Y','Z') AND CATEGORY IN ('ABC', 'DEF', 'GHI', 'JKL')) p
Furthermore I want to know if there can be any method for dynamically adding the columns and arriving at this view for any table having the same columns (so that hardcoding can be avoided).
I know we can do this in Excel and transpose it, but I want the data to be stored in the db in this format.
A stored function(or procedure) might be created in order to create a SQL for Dynamic Pivoting, and the result set is loaded into a variable of type SYS_REFCURSOR :
CREATE OR REPLACE FUNCTION Get_Categories_RS RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
v_sql VARCHAR2(32767);
v_cols_1 VARCHAR2(32767);
v_cols_2 VARCHAR2(32767);
BEGIN
SELECT LISTAGG( ''''||"level"||''' AS "'||"level"||'"' , ',' )
WITHIN GROUP ( ORDER BY "level" DESC )
INTO v_cols_1
FROM (
SELECT DISTINCT "level"
FROM temp
);
SELECT LISTAGG( 'MAX(CASE WHEN category = '''||category||''' THEN "'||"level"||'" END) AS "'||"level"||'_'||category||'"' , ',' )
WITHIN GROUP ( ORDER BY category, "level" DESC )
INTO v_cols_2
FROM (
SELECT DISTINCT "level", category
FROM temp
);
v_sql :=
'SELECT "set", '|| v_cols_2 ||'
FROM
(
SELECT *
FROM temp
PIVOT
(
MAX(value) FOR "level" IN ( '|| v_cols_1 ||' )
)
)
GROUP BY "set"
ORDER BY "set"';
OPEN v_recordset FOR v_sql;
RETURN v_recordset;
END;
in which I used two levels of pivoting : the first is within the inner query involving PIVOT Clause, and the second is in the outer query having the conditional aggregation logic. Notice that the order of levels should be in the descending order( Z, Y, X ) within the expected result as conforming to the description.
And then invoke
VAR rc REFCURSOR
EXEC :rc := Get_Categories_RS;
PRINT rc
from SQL Developer's Command Line in order to get the result set
Btw, avoid using reserved keywords such as set and level as in your case. I needed to quote them in order to be able to use.

Select specified row from multiple rows returned by select

I have a select statement which returns multiple rows. I need to select a particular one of these rows. I would like to write something like
SELECT * FROM ( SELECT * FROM table WHERE x IS y ) WHERE row_in_selected_rows IS n;
Is this possible?
Note that I cannot use the rowid from the original table, because i have the index of the required row in the rows returned from the first select statement, not the index in the original table.
You can use ROW_NUMBER() window function:
select col1, col2, ....
from (
SELECT *, row_number() over() rn
FROM table
WHERE x IS y
) t
where t.rn = 4
but this way the order of the rows returned from the query is not defined, so the 4th row could be any row.
The correct way would be:
select col1, col2, ....
from (
SELECT *, row_number() over(order by somecolumn) rn
FROM table
WHERE x IS y
) t
where t.rn = 4
You could also use OFFSET with LIMIT:
SELECT * FROM ( SELECT * FROM table WHERE x IS y )
LIMIT 1 OFFSET 3;
which skips the first 3 rows and returns only the 4th, but again LIMIT and OFFSET should be used with ORDER BY, like:
SELECT * FROM ( SELECT * FROM table WHERE x IS y )
ORDER BY somecolumn
LIMIT 1 OFFSET 3;

How to use a select query results in an update query?

I have two tables:
films(id,marksNum)
marks(id,film_id,mark)
I'd like to save number of marks for each film in films.marksNum.
My attempt is:
UPDATE films
SET marksNum=
(
SELECT count(id)
FROM marks
WHERE marks.film_id=films.id
GROUP BY marks.film_id
)
WHERE films.id=marks.film_id
but I'v got an error: no such column: marks.film_id
What am I doing wrong?
Thank you in advance!
Well, this is not an elegan solve but any way:
1)
CREATE TABLE `grp_marks` ( `film_id` INTEGER, `marks_num` INTEGER )
2)
INSERT INTO grp_marks(film_id,marks_num)
SELECT film_id,count(id)
FROM marks
GROUP BY film_id
3)
UPDATE films
SET marksNum=
(
SELECT marks_num
FROM grp_marks
WHERE (film_id=films.id)
)
WHERE EXISTS
(SELECT * FROM grp_marks WHERE grp_marks.film_id=films.id
)

The query performance is very low + correlated subquery

The query's aim is to get reserved rooms status is 3 or going to reserve in 30 to 45 minutes status in 2 or unreserved status in 1. reservation rooms are in RESEENH table and each reservation is in ORD_NOARCHIVE table which has begintime and endtime of reservation. So for each reservation room this query checks whether reservation is available at current time also its checks the meeting room parents and children. if children is reserved then parents are are blocked.
it takes 10 secs to fetch first 50 records.
with cte as
(
SELECT DISTINCT R.syscode,
R.behcode,
R.syscode AS FK_RESERVATIONUNIT, (
CASE
WHEN R.TYPE = 3 THEN '1'
WHEN R.TYPE = 1 THEN '2'
ELSE NULL
END ) AS LOCATION_TYPE,
R.sysobjalg AS FK_PROPERTY,
MP.syscode AS FK_MEASUREMENTPOINT,
MP.fk_plc_occupancy_state AS FK_PLC_OCCUPANCY_STATE,
F.syscode AS FK_FLOOR,
R.transitiontime,
r.type,
r.is_compoundreservationunit,
r.is_archived,
MP.fk_person,
os.transitionperiod
FROM reseenh R
--left outer join ordtrantbl RSS
--ON RSS.reservationunisyscode = R.syscode
left outer join objond F
ON F.syscode = R.fk_floor
left outer join pln_measurementpoint MP
ON MP.fk_reservationunit = R.syscode
AND MP.is_primary_measurement_point = 'T',
pln_ordersetting os
)
select cte.syscode,cte.behcode,cte.FK_RESERVATIONUNIT,
(CASE
WHEN O.begindatetime_user IS NULL THEN '1' --GREEN
WHEN O.begindatetime_user - (Nvl(cte.transitiontime, ( cte.transitionperiod ))/1440 ) > current_date THEN '2' -- ORANGE
WHEN O.begindatetime_user + (Nvl(cte.transitiontime, ( cte.transitionperiod )) /1440 ) > current_date THEN '3' -- RED
ELSE '3'
END ) AS LOCAVAILABILITY_STATUS_CODE,
cte.LOCATION_TYPE,
cte.FK_PROPERTY,
Coalesce(O.sysmelder, cte.fk_person) AS FK_PERSON,
O.syscode AS FK_ORDER,
O.ref_bostate_userdefined AS FK_ORDER_STATE_USER,
O.fk_bostate AS FK_ORDER_STATE_SYSTEM,
FK_MEASUREMENTPOINT,FK_PLC_OCCUPANCY_STATE,FK_FLOOR
from cte left outer join ord_noarchive O on O.syscode in
( SELECT MAX(ord.syscode) KEEP (DENSE_RANK FIRST ORDER BY ord.begindatetime_user) OVER (PARTITION BY ord.sysreseenh )
FROM ord_noarchive ORD
WHERE ( ( (
current_date >= ( ORD.begindatetime_user - ( Nvl(cte.transitiontime, ( cte.transitionperiod ))/1440) )
AND (
current_date - ( Nvl(cte.transitiontime, (cte.transitionperiod )) / 1440 ) ) <=ORD.enddatetime_user )
OR ( (
current_date + ( (
CASE
WHEN (
cte.TYPE = 1 ) THEN 30
ELSE 45
END ) / 1440 ) ) >= ( ORD.begindatetime_user - (Nvl(cte.transitiontime, ( cte.transitionperiod))/1440 ) )
AND (
current_date - ( Nvl(cte.transitiontime, ( cte.transitionperiod )) / 1440 ) ) < ORD.enddatetime_user ) )
AND ORD.sysreseenh IN
(
SELECT fk_reservationunit_parent
FROM pln_reservationunit_rut
WHERE fk_reservationunit_child IN
(
SELECT fk_reservationunit_child
FROM pln_reservationunit_rut
WHERE cte.is_compoundreservationunit = 'T'
AND fk_reservationunit_parent = cte.syscode)
UNION
SELECT cte.syscode
FROM dual
UNION
SELECT
CASE
WHEN cte.is_compoundreservationunit = 'T' THEN fk_reservationunit_child
ELSE fk_reservationunit_parent
END
FROM pln_reservationunit_rut
WHERE (
cte.is_compoundreservationunit = 'T'
AND fk_reservationunit_parent = cte.syscode )
OR (
cte.is_compoundreservationunit = 'F'
AND fk_reservationunit_child = cte.syscode ))
AND ORD.fk_bostate IN
(
SELECT syscode
FROM pln_bostate
WHERE pnname IN ( 'Requested',
'Made',
'AdministrativelyCompleted' )
AND fk_bodefinition = ref_bodefinition)
AND ORD.sysreseenh = O.sysreseenh
))
WHERE cte.is_archived = 'F'
AND cte.TYPE IN ( 1,
3 )
AND cte.fk_floor=495
No time to analyze the details of a very complex query, but my overall sense is that you are trying to do too many things at once. Separate the tasks. Check on room availability in one query, and check on the children/parent thing in a separate query.
Also, you could analyze the execution plan for the query and see what it bogging it down. My suspicion (again without time to really try to understand your query) is that at some point the mixing of tasks is translating into a many-to-many relationship where you have an intermediate result that is a cross product of rows between some of the tables in your query.

Resources