MDX queries. How can to solve "IN" in "where" part - where-clause

I have sql query and i need this query execute in olap cube .
select count(distinct mi.id) from [MTD_DEV].[dbo].[MenuItemAttributes] as m
inner join [dbo].[MenuItemOlds] as mi
on mi.id = m.MenuItemId
inner join [dbo].[RestaurantlistItems] as rl
on rl.RestaurantId = mi.RestaurantId
where m.AttributeId = 31 and rl.RestaurantListId = 69 and mi.PeriodId = 99 and m.MenuItemId in (select MenuItemId from [MTD_DEV].[dbo].[MenuItemAttributes] where AttributeId = 6
and i have working mdx query and I need to add operator 'IN' or something another solution for this query
SELECT CROSSJOIN(
{[Measures].[Menu Item Olds Count],[Measures].[Restaurantlist Items Count]},
{[Periods].[Id].[99],[Periods].[Id].[93],[Periods].[Id].[75]}) ON COLUMNS,
{[Menu Item Olds].[id]} ON ROWS
FROM [MTD DEV]
where (
{[Restaurant Lists].[Id].[69]},
{[Attributes].[Id].[6]} ,
{[Attribute Categories].[Id].[5]} -- or can use the same parameter {[Attributes].[Id].[31]}
)
for better understanding:
https://drive.google.com/file/d/0B3rw0YPItJIIa3FfNEtrVC04SVU/view?usp=sharing
Additional Comments to question
In ms sql I have to slice MenuItemOlds by some parameter m.AttributeId = 31
annd then from result I have to slice again for parameter AttributeId = 6.
In Sql it looks like this:
select count(distinct mi.id) from [MTD_DEV].[dbo].[MenuItemAttributes] as m
inner join [dbo].[MenuItemOlds] as mi on mi.id = m.MenuItemId
where m.AttributeId = 31 and m.MenuItemId in (select MenuItemId from [MTD_DEV].[dbo].[MenuItemAttributes] where AttributeId = 6
I have problem in OLAP Cube.
How I see to solve this problem :
1.I get all data where AttributeId = 31
SELECT CROSSJOIN(
{[Measures].[Menu Item Olds Count],[Measures].[Restaurantlist Items Count]},
{[Periods].[Id].[99],[Periods].[Id].[93],[Periods].[Id].[75]}) ON COLUMNS,
{[Menu Item Olds].[id]} ON ROWS
FROM [MTD DEV]
where ({[Attributes].[Id].[31]})
the result of this - all catering menu items
After this , in this collection of Menu Items, I need to find all menu items where {[Attributes].[Id].[6]} (kids menu)
When i am trying to execute such query :
SELECT CROSSJOIN(
{[Measures].[Menu Item Olds Count],[Measures].[Restaurantlist Items Count]},
{[Periods].[Id].[99],[Periods].[Id].[93],[Periods].[Id].[75]}) ON COLUMNS,
{[Menu Item Olds].[id]} ON ROWS
FROM [MTD DEV]
where (
{[Attributes].[Id].[6]} ,
{[Attributes].[Id].[31]}
)
I get result , in which i have Menu items with AttributeId.[6] + menuItem with attributeId.[31]
for example:
count of menu items with AttributeId.[6] = 11000 items
count of menu items with AttributeId.[31] = 724000items
and result is 724000+11000 = 735000 but i don`t need it
i need to find all items with AttributeId.[31], and in this collection i need to find items with AttributeId.[6]
The right result of query must be less than 11000 items

Does NonEmpty with intersect work as an alternative?
SELECT
{
[Measures].[Menu Item Olds Count]
,[Measures].[Restaurantlist Items Count]
}
*
{
[Periods].[Id].[99]
,[Periods].[Id].[93]
,[Periods].[Id].[75]
} ON COLUMNS
,Intersect
(
NonEmpty
(
[Menu Item Olds].[id].[id].MEMBERS
,(
[Attributes].[Id].[31]
,{
[Measures].[Menu Item Olds Count]
,[Measures].[Restaurantlist Items Count]
}
)
)
,NonEmpty
(
[Menu Item Olds].[id].[id].MEMBERS
,(
[Attributes].[Id].[6]
,{
[Measures].[Menu Item Olds Count]
,[Measures].[Restaurantlist Items Count]
}
)
)
) ON ROWS
FROM [MTD DEV];

This would be a classical case for Exists, slightly complicated as you have a many-to-many relationship between Menu Item Olds and Attributes:
SELECT CROSSJOIN(
{[Measures].[Menu Item Olds Count],[Measures].[Restaurantlist Items Count]},
{[Periods].[Id].[99],[Periods].[Id].[93],[Periods].[Id].[75]})
ON COLUMNS,
Exists(Exists([Menu Item Olds].[id].[id].Members,
{[Attributes].[Id].[31]}
),
{[Attributes].[Id].[6]}
)
ON ROWS
FROM [MTD DEV]

Related

Power BI - Using Dax to Filter Based on a Group By

I am new to DAX.
Let's pretend I have a table that looks like this:
Table A:
status delivered sold
late 10 50
late 20 300
early 5 500
Let's pretend I am using this SQL query:
with cte_1 as (
select
status, count(*) as [row_count]
from [table a]
group by [status]
having count(*) > 1
)
select *
from [table a] as p1
inner join [cte_1] as p2
on p1.[status] = p2.[status]
What would be the dax equivalent of this?
The SQL query return the Table A rows with the status that occurrs at least twice in the table, adding the count of the number of rows with the same status. In Power BI we can write a calculated table that adds the count of the rows of the same status and then filter out those with a count less than 2
Result =
FILTER(
ADDCOLUMNS(
'Table A',
"row_count",
CALCULATE(
COUNTROWS( 'Table A' ),
ALLEXCEPT( 'Table A', 'Table A'[Status] )
)
),
[row_count] > 1
)

Get Items with smallest vote count including 0 in postgresql

I am working on a project where I need to get the 2 items with the least amount of votes where I have 2 tables an item table and a votes table with a forgienkey of ItemId.
I have this query:
SELECT id FROM (
SELECT "ItemId" AS id,
count("ItemId") AS total
FROM "Votes"
WHERE "ItemId" IN (
SELECT id FROM "Items"
WHERE date("Items"."createdAt") = date('2015-05-26 18:30:00.565+00')
AND "Items"."region" = 'west'
)
GROUP BY "ItemId" ORDER BY total LIMIT 2
) x;
Which in some respects is fine but it doesn't include the Items with the count being null or 0. Is there a better way to do this?
Thanks. Please let me know if you need more info.
Postgresql: 9.4
something like this should work:
SELECT id,
coalesce((SELECT count(*) FROM "Votes" WHERE "ItemId" = "Items".id), 0) as total
FROM "Items"
WHERE date("Items"."createdAt") = date('2015-05-26 18:30:00.565+00')
AND "Items"."region" = 'west'
ORDER BY total LIMIT 2
If an item has not been voted for, then the "Votes" table will not return anything for it and therefore the main query does not display the item at all.
You need to select from "Items" and then LEFT JOIN to "Votes" grouped by "ItemId" and the count of votes for it. Like this, all the items will be considered, also those for which no votes have been cast. Use the coalesce() function to convert NULLs to 0:
SELECT "Items".id, coalesce(x.total, 0) AS cnt
FROM "Items"
LEFT JOIN (
SELECT "ItemId" AS id, count("ItemId") AS total
FROM "Votes"
GROUP BY "ItemId") x USING (id)
WHERE date("Items"."createdAt") = '2015-05-26'::date
AND "Items"."region" = 'west'
ORDER BY cnt
LIMIT 2;

MDX filter data

WITH
MEMBER [Measures].[ParameterCaption] AS [Estate].[Week].CURRENTMEMBER.MEMBER_CAPTION
MEMBER [Measures].[ParameterValue] AS [Estate].[Week].CURRENTMEMBER.UNIQUENAME
MEMBER [Measures].[ParameterLevel] AS [Estate].[Week].CURRENTMEMBER.LEVEL.ORDINAL
SELECT
{[Measures].[ParameterCaption], [Measures].[ParameterValue], [Measures].[ParameterLevel]} ON COLUMNS
,
NON EMPTY (
ORDER (
EXCEPT( [Estate].[Week].[ALL].CHILDREN
, { [Estate].[Week]})
, ( [Estate].[Week].MEMBERVALUE)
, ASC
)
) ON ROWS
From [EstateRpt]
WHERE Filter([V Estate Weekly Rpt].[Week].CHILDREN, [V Estate Weekly Rpt].[Week].MEMBERVALUE = 'NONE')
Hi, i am new to the MDX. I want to filter the week which is not equal to "NONE"? by default, week is set the "NONE", so it will appear the NONE data in cube. I want to filter this NONE.
I do try the WHERE clause but it show the error to me which i do not figure out what is the problem
If you want to filter out 'NONE' then you need to use this in your filter:
<> 'NONE'
Also you need to use CurrentMember within your filter like this example:
SELECT
{
[Date].[Calendar].[Month].&[2006]&[7]
,[Date].[Calendar].[Date].&[20050220]
}
*
{[Measures].[Reseller Sales Amount]} ON COLUMNS
,
{[Product].[Category].Children}
*
{[Geography].[Geography].[Country].MEMBERS} ON ROWS
FROM [Adventure Works]
WHERE
Filter
(
[Geography].[State-Province].MEMBERS
,
[Geography].[State-Province].CurrentMember.Member_Caption <> 'California'
);

SQL query for adding column value to compare with other column

I have two tables
table_inventory
List item
inventory_rack_key(primarykey)
node_key
rack_id
inventory_item_key
in_coming_qty,locked_qty
quantity
table_item
inventory_item_key(primary key)
item_id,product_zone
The table example are provided here DB TABLES
I need query to find out those items for which (net_qty) i.e difference b/w sum of in_coming_qty & quantity & locked_qty is negative. arranged by node_key,rack_id, item_id,net_qty
Note: each distinct set {node_key,rack_id, item_id,net_qty} will have only 1 row in output.
For ex :{node_key,rack_id, item_id} = {ABD101,RK-01,562879} has 4 rows in table_inventory
but in output net_qty= -78(single row) .
The query I made is giving me result but can we do it in some other way?
SELECT l.node_key,
l.rack_id,
i.item_id,
( SUM(l.quantity + l.in_coming_qty) - SUM(l.locked_qty) ) AS net_qty
FROM table_inventory l,
table_item i
WHERE l.inventory_item_key = i.inventory_item_key
GROUP BY l.node_key,
l.rack_id,
i.item_id
HAVING SUM(l.quantity + l.in_coming_qty) - SUM(l.locked_qty) < 0
Not really. There is this minor variant:
select v.* from (
SELECT l.node_key,
l.rack_id,
i.item_id,
SUM(l.quantity + l.in_coming_qty - l.locked_qty) AS net_qty
FROM table_inventory l,
table_item i
WHERE l.inventory_item_key = i.inventory_item_key
GROUP BY l.node_key,
l.rack_id,
i.item_id
) v
where net_qty < 0
- which means that the SUM calculation only needs to be coded once, but you do still need to do a SUM.

SQL latest/top items in category

What is a scalable way to select latest 10 items from each category.
I have a schema list this:
item category updated
so I want to select 10 last update items from each category. The current solution I can come up with is to query for categories first and then issue some sort of union query:
categories = sql.execute("select categories from categories_table")
query = ""
for cat in categories:
query += "union select top 10 from table where category=cat order by updated"
result = sql.execute(query)
I am not sure how efficient this will be for bigger databases (1 million rows).
If there is a way to do this in one go - that would be nice.
Any help appreciated.
This will not compile but you'll have the general idea:
from i in table
group i by i.category into g
select new { cat = g.Key, LastTens = g.OrderByDescending(o => o.Updated).Take(10).Select(...) }
EDIT: the question asked for SQL:
SELECT * FROM
(
SELECT
ROW_NUMBER() OVER (PARTITION BY categoryId ORDER BY somedate) AS PartNum,
categoryId,
[...]
FROM
category
) AS Partitionned
WHERE PartNum <= 10