A shorter way of specifying a set in MDX - mdx

Is there a briefer way of specifying a set in MDX?
I know I can do something like :
{[Debtor].[TRADING DEBTOR CODE].&[AU-000013],[Debtor].[TRADING DEBTOR CODE].&[AU-000020]}
but once you get over a few members, it becomes incredibly verbose.
I'm looking for something like
MagicFunctionToMakeASet([Debtor].[TRADING DEBTOR CODE],'AU-000013,AU-000015,AU-000013,AU-000015,...')

Are they in sequence at all? If so, could you do
{
[Debtor].[TRADING DEBTOR CODE].&[AU-000013] :
[Debtor].[TRADING DEBTOR CODE].&[AU-000020]
}
To give you a set of codes 13 though to 20 inclusive?
Failing that, take a look at InStr and see if it can help, it looks like it might - Or you could create some subsets using it and then combine into your final set?
http://msdn.microsoft.com/en-us/library/ms145487.aspx
From the above MSDN:
WITH SET [ChardonnayChablis] AS
'Filter([Product].Members, (InStr(1, [Product].CurrentMember.Name, "chardonnay") <> 0) OR (InStr(1, [Product].CurrentMember.Name, "chablis") <> 0))'
SELECT
[ChardonnayChablis] ON COLUMNS,
{Measures.[Unit Sales]} ON ROWS
FROM Sales

There are various shortcuts. If you just want all the 'children' of a certain member, use Descendants() or .children. Or get all the members at one level with .members. You can specify a range between two members, or use a filter to match some sort of critera.
What were you after? I'll try to give a more specific example...

Related

Access SQL GROUP BY problem (eg. tbl_Produktion.ID not part of the aggregation-function)

I want to group by two columns, however MS Access won't let me do it.
Here is the code I wrote:
SELECT
tbl_Produktion.Datum, tbl_Produktion.Schichtleiter,
tbl_Produktion.ProduktionsID, tbl_Produktion.Linie,
tbl_Produktion.Schicht, tbl_Produktion.Anzahl_Schichten_P,
tbl_Produktion.Schichtteam, tbl_Produktion.Von, tbl_Produktion.Bis,
tbl_Produktion.Pause, tbl_Produktion.Kunde, tbl_Produktion.TeileNr,
tbl_Produktion.FormNr, tbl_Produktion.LabyNr,
SUM(tbl_Produktion.Stueckzahl_Prod),
tbl_Produktion.Stueckzahl_Ausschuss, tbl_Produktion.Ausschussgrund,
tbl_Produktion.Kommentar, tbl_Produktion.StvSchichtleiter,
tbl_Produktion.Von2, tbl_Produktion.Bis2, tbl_Produktion.Pause2,
tbl_Produktion.Arbeiter3, tbl_Produktion.Von3, tbl_Produktion.Bis3,
tbl_Produktion.Pause3, tbl_Produktion.Arbeiter4,
tbl_Produktion.Von4, tbl_Produktion.Bis4, tbl_Produktion.Pause4,
tbl_Produktion.Leiharbeiter5, tbl_Produktion.Von5,
tbl_Produktion.Bis5, tbl_Produktion.Pause5,
tbl_Produktion.Leiharbeiter6, tbl_Produktion.Von6,
tbl_Produktion.Bis6, tbl_Produktion.Pause6, tbl_Produktion.Muster
FROM
tbl_Personal
INNER JOIN
tbl_Produktion ON tbl_Personal.PersID = tbl_Produktion.Schichtleiter
GROUP BY
tbl_Produktion.Datum, tbl_Produktion.Schichtleiter;
It works when I group it by all the columns, but not like this.
The error message say that the rest of the columns aren't part of the aggregation-function (translated from german to english as best as I could).
PS.: I also need the sum of "tbl_Produktion.Stueckzahl_Prod" therefore I tried using the SUM function (couldn't try it yet).
Have you tried something along these lines?
SELECT
tbl_Produktion.Datum, tbl_Produktion.Schichtleiter,
MAX(tbl_Produktion.ProduktionsID), MAX(tbl_Produktion.Linie),
MAX(tbl_Produktion.Schicht), MAX(tbl_Produktion.Anzahl_Schichten_P),
MAX(tbl_Produktion.Schichtteam), MAX(tbl_Produktion.Von), MAX(tbl_Produktion.Bis),
SUM(tbl_Produktion.Stueckzahl_Prod)
FROM
tbl_Personal
INNER JOIN
tbl_Produktion ON tbl_Personal.PersID = tbl_Produktion.Schichtleiter
GROUP BY
tbl_Produktion.Datum, tbl_Produktion.Schichtleiter;
I have used the MAX function for all the data except the two items you specify in the GROUP BY and the one where you desire the SUM. I took the liberty of leaving out mush of your data just to get started.
Using the MAX function turns out to be a convenient workaround when the data item is known to be unique within each group. We cannot know your data or your itent, so we cannot tell you whether MAX will yield the results you need.
If you use an aggregation function in the select clause, you must group by every column that you're selecting that's not an aggregation. If you don't want to do that for some reason (perhaps it changes the output of the aggregation in way that you don't intend) you either must think of an aggregate to use (pick a value. Average? Max? Min?) or just do two selects, one for the aggregate, and one for the non-aggregates. But, then, you have to decide how to get the non-aggregated fields that make sense for the aggregate (or show them all in a table, I suppose?)

SQL Specific LIKE ANY String Search

So I'm in Teradata trying to pull any products that have more than 1 color-related name, as seen in the code snippet here:
SELECT
pt.product_number,
COUNT (CASE WHEN ot.option_name like any ('%green%', '%red%', '%blue%') THEN 1 ELSE NULL END) as differentColorCount
FROM product_table pt
JOIN option_table ot on ot.product_num = pt.product_num
HAVING differentColorCount > 1
GROUP BY 1
This is running fine, but the problem that I'm realizing is that a product might have a hundred different "Red" options for instance. (Red-1, Red-2, Red-3, etc). But I only want a count of when two of the different color strings are present for a single product.
So instead of LIKE ANY what I really need is LIKE ANY TWO. If both Red AND Green are present, count 1. If both Blue AND Purple are present, count 1.
I realize I could do a really long list where I do dozens of LIKE ALLs in every possible combination, but that doesn't seem like it will scale well if I need to check for, say 100 different colors instead of 6?
If anyone has any insight on this I would be incredibly grateful. Thanks in advance for any help you can offer! :)
You can utilize a regular expression to extract the color and then apply a distinct count:
Count (DISTINCT RegExp_Substr(option_name, '(green|red|blue)')) AS differentColorCount
This is similar to your like any ('%green%', '%red%', '%blue%'), but returns the actual matching color instead of TRUE/FALSE.
The'(green|red|blue)' search pattern seperates defines three alternative search strings and returns the first match.

QlikView:Using dimensions value in expression

I am trying to figure out how can I use dimension values as one of the set modifiers in Expressions in qlikview. Consider the following:
Raw Data:
PName, count
AB,2
BC,3
CD,4
Dimension:
Name
Expression:
SUM(<{PName=Name}>count)
i-e using the dimension value as one of the set modifiers.
Thanks
As #bdiamante said. It is not clear what you exactly want to do.
But I assume that you only want to use the current value of the dimension to calculate the count of names.
If that is true, then you can simply say:
Expression:
=sum(count)
HTH
I believe I understand. Try sum({<Pname=p(Name)>}count). This says that pname will be the possible values of name. Also look into e() which is the excluded values.
If Name is a literal value, try this:
sum({<PName={'AB'}>}count)
It would always give you the count as if someone had selected PName = 'AB'.
If you only want it to show the count for AB, if AB has not been excluded based on the current selections (e.g. someone has selected PName of 'BC'), then use:
sum({<PName*={'AB'}>}count)
This will give you the count for AB, but only if AB is included in scope for (i.e. intersects with) the current selections.

SQL Management Studio filter Where Value "Does Not Exist"?

I joined two tables (let's call them Hours and Target) and want to pull a target from the second table if the there is a target associated within a time period that surrounds the date in Hours. (Target may have something like this: User:Joe, Target:70, From:1/1/2012, To:5/31/2012"
So far this was easy:
I joined 'All of' Hours with Target based on "user", I output Target and use 'From' and 'To' with a filter: "<=Hours.Date" and ">=Hours.Date", respectively.
The problem is that not all users may have targets in any time frame. In that case I would like to have a target of 0 returned. Based on the conditions, however, Lines that do not match my criteria above are not returned at all.
How can I set up a condition that returns something like this:
Target.Target where (Target.From <= Hours.Date and Target.To >= Hours.Date)
or
0 in all other cases
Thank You!
Marco
Are you after something like this?
http://sqlfiddle.com/#!3/18b5c/1/0
Ideally you would have a users table and store ID's but my understanding of what you have asked this should cover what your trying to do.

No Exact match when using LIKE in SQL statement

SELECT bp.*,r.rating,COUNT(r.review_for),bp.business_name,bp.profile_member
FROM ibf_business_reviews r
LEFT JOIN ibf_business_profiles bp ON ( r.review_for=bp.profile_member )
WHERE bp.sub_category LIKE '%{$id},%'{$location_sql}
GROUP BY r.review_for HAVING COUNT(r.review_for) >=1
ORDER BY r.date_posted DESC LIMIT 0,2");
This query is used to show results for business_name in a certain sub_category id '%{$id} in a certain location. My problem is that extra results are showing in categories that share a second or third digit aka ...viewcat&id=54 will show in ..viewcat&id=154 etc
I using the LIKE may be my issue? WHERE bp.sub_category LIKE '%{$id},%'
You are storing a comma-separated list in a varchar, when you should store one number per row in a child table. Then you wouldn't have to use LIKE at all.
Read up on First Normal Form.
Here was my comment
+! for the need to reformat the SQL. You do realize that the "percent"
signs (%) are the wildcards. So you're
essentially telling it that you can
return ANYTHING that includes id... so
if you search "23" you could get
"123", you could get "234" or
"1234"... etc.
and you replied
Thanks #Rock removing the wildcards worked!
Now my answer to this is... If you removed BOTH wildcards from your string, then you're essentially doing an "equals".
IE:
WHERE bp.sub_category LIKE '{$id},'
should be the same as
WHERE bp.sub_category = '{$id},'
Because you don't have any wildcards to "match" in the "LIKE" statement.
Please forgive me if I screwed up the "$" or the ","... I'm not a MySQL guy