I have an MDX query that needs to display result based on a CASE statement. I have written the below query, the query is not throwing any error neither is it giving out any result.
How can I get the query correct?
Query:
SELECT NULL ON 0,
CASE
WHEN [MARKET BASE].[Market Base].[Market Base].&[1] = "Vitamin C (04D1+04D2)"
THEN "Vitamin C (04D1 + 04D2)" END ON 1
FROM [PharmaTrend Monthly Ext]
WHERE [PRODUCT].[Company - Product - Pack].[Company].&[2991]
Try this -
WITH MEMBER Measures.SomeValue AS
CASE
WHEN [MARKET BASE].[Market Base].[Market Base].&[1] IS
[MARKET BASE].[Market Base].[Market Base].[Vitamin C (04D1+04D2)]
THEN "Vitamin C (04D1 + 04D2)"
END
SELECT
Measures.SomeValue ON 0
FROM [SomeCube]
WHERE [PRODUCT].[Company - Product - Pack].[Company].&[2991]
Related
I am trying to run the below query, but I am encountering this error:
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
SELECT
IVCSUM1.ivcnum "Invoice Number"
,IVCSUM1.ivcgrsamt_amt "Gross Amount"
,IVCSUM1.ivcgrsamt_cur "Gross Amount Currency"
,SUM(ISNULL(IVCLINE1.ivclinextamt_amt, 0)
+ ISNULL((SELECT SUM(TaxAmount_amt) FROM MC_INVTAX WHERE ivclinref_oi = IVCLINE1.ivlnoi), 0)
+ ISNULL((SELECT SUM(amtchg_amt) FROM MC_INVCHG INVCHG1 WHERE IVCLINE1.ivlnoi = ivclinref_oi), 0)) "Invoice Line Amount"
FROM
MC_IVCSUM IVCSUM1 LEFT JOIN
MC_IVCLINE IVCLINE1 on IVCSUM1.ivsmoi = IVCLINE1.invsumm_oi
GROUP BY ivsmoi, ivcnum,IVCSUM1.ivcgrsamt_amt, IVCSUM1.ivcgrsamt_cur
I cannot join the tables MC_INVCHG and MC_INVTAX to the main query because it's causing duplicates in the IVCLINE1.ivclinextamt_amt field and the sum ends up being wrong.
Below is sample data I have pulled from the tables by joining them.
Invoice Number
Line
Gross Amount
Tax amount
Change
00 0001180 7 DEC03
1
80
-5.04
NULL
00 0001180 7 DEC03
1
80
5.04
NULL
00 0001180 7 DEC03
2
40
2
NULL
What I am trying to accomplish with the query is, Invoice Line Amount = (80 + (5.04 + (-5.04)) + 0) + (40 + 2 + 0)
Since change is NULL for this, it is being considered as 0.
Is there a way to accomplish this in a different way?
This is a good place to use CROSS APPLY as it allows you to calculate a value and then use it, without the constraints you've run into.
SELECT
IVCSUM1.ivcnum [Invoice Number]
, IVCSUM1.ivcgrsamt_amt [Gross Amount]
, IVCSUM1.ivcgrsamt_cur [Gross Amount Currency]
, SUM(ISNULL(IVCLINE1.ivclinextamt_amt, 0)
+ ISNULL(S1.TaxAmount_amt_Total, 0)
+ ISNULL(S2.amtchg_amt_Total, 0)) [Invoice Line Amount]
FROM MC_IVCSUM IVCSUM1
LEFT JOIN MC_IVCLINE IVCLINE1 on IVCSUM1.ivsmoi = IVCLINE1.invsumm_oi
CROSS APPLY (
SELECT SUM(TaxAmount_amt) TaxAmount_amt_Total
FROM MC_INVTAX
WHERE ivclinref_oi = IVCLINE1.ivlnoi
) S1
CROSS APPLY (
SELECT SUM(amtchg_amt) amtchg_amt_Total
FROM MC_INVCHG INVCHG1
WHERE IVCLINE1.ivlnoi = ivclinref_oi
) S2
GROUP BY ivsmoi, ivcnum, IVCSUM1.ivcgrsamt_amt, IVCSUM1.ivcgrsamt_cur;
Note square brackets, [], are the best practice way to escape object names.
Here is my code:
SELECT
ISNULL (CONVERT(VARCHAR, MONTH(PurchaseDate)), NULL) [Month],
ISNULL (Brand, CASE
WHEN MONTH(PurchaseDate) IS NOT NULL THEN 'Monthly SubTotal'
WHEN Brand IS NULL THEN 'Grand Total'
ELSE 'N/A'
END) [Brand], SUM(Price) [Total Amount]
FROM
[dbo].[Purchase_Items]
GROUP BY
MONTH(PurchaseDate), Brand WITH CUBE
I want to change it to Grand Total on selected box. How to code it or change the string on it.
If you first get your data (a simpler version of what you have above) you can then use that as a data source to do conversions/updates as needed.
I'm using a CTE here, but you can do it with subqueries just as well.
WITH MonthTotals AS
(SELECT
MONTH(PurchaseDate) [Month],
[Brand],
SUM(Price) [Total Amount]
FROM [dbo].[Purchase_Items]
GROUP BY MONTH(PurchaseDate), Brand WITH CUBE
)
SELECT CONVERT(VARCHAR(2), mt.[Month]) AS [Month],
CASE WHEN mt.[Month] IS NULL AND mt.[Brand] IS NULL THEN 'Grand Total'
WHEN mt.[Month] IS NULL THEN 'Grand total for ' + mt.[Brand]
WHEN mt.[Brand] IS NULL THEN 'Monthly total'
ELSE mt.[Brand] END AS [Brand]
[Total Amount]
FROM MonthTotals mt;
Note though that CUBE is usually done in SQL Server like the following - it means you can select which columns you CUBE by (or rollup, etc)
GROUP BY CUBE(MONTH(PurchaseDate), Brand)
IMPORTANT UPDATE following #MartinSmith's comment below
Martin Smith gave the advice that I should use the GROUPING function. In reviewing that function, he is 100% correct (and thankyou Martin - this is my learning for today).
For reference, the GROUPING function indicates (with a 1 or 0) whether the row is an aggregate row or not (e.g., one of the rows added by ROLLUP/CUBE/GROUPING SETs).
I also made a mistake with subtotals for months - put it in the wrong column.
Therefore, the update should be the following (note also that I have included the 'original' vales from the CUBE for month and brand as well)
WITH MonthTotals AS
(SELECT
MONTH(PurchaseDate) [Month],
[Brand],
SUM(Price) [Total Amount],
GROUPING(MONTH(PurchaseDate)) AS Agg_flag_Month,
GROUPING([Brand]) AS Agg_flag_Brand
FROM [dbo].[Purchase_Items]
GROUP BY CUBE(MONTH(PurchaseDate), Brand)
)
SELECT [Month] AS Orig_Month,
[Brand] AS Orig_Brand,
CASE WHEN Agg_flag_Month = 1 THEN 'Grand total for ' + mt.[Brand]
ELSE CONVERT(VARCHAR(2), mt.[Month])
END AS [Month],
CASE WHEN Agg_flag_Month * Agg_flag_Brand = 1 THEN 'Grand Total'
WHEN Agg_flag_Brand = 1 THEN 'Monthly total'
ELSE mt.[Brand]
END AS [Brand],
[Total Amount]
FROM MonthTotals mt;
I have my query:
SELECT [Shipment Date], [Amount] as [Running Costs], Sum([Amount]) OVER
(ORDER BY [Shipment Date]) as [Total Running Costs]
FROM...
This gets me 3 columns:
Shipment Date | Running Costs | Total Running Costs
I would like to add a fourth column to this query which has the same value for all rows, and the same number of rows as my original query results.
I know you could add for example '999'as Something to the search results, but how can I do the same for a sum of another column (example: Imagine the total sum of the a column in another table is 1500, and I want to have 1500 for all rows in the fourth column. Something like select sum(column_name)?
The database engine is MSSQL.
You can use a nested query
SELECT [Shipment Date], [Amount] as [Running Costs], [Total Running Costs], SUM([Total Running Costs] OVER ())
FROM
(
SELECT [Shipment Date], [Amount] as [Running Costs], Sum([Amount]) OVER
(ORDER BY [Shipment Date]) as [Total Running Costs]
FROM...
)
Nested window function should also work
SUM(SUM([Running costs]) OVER (ORDER BY [Shipment Date])) OVER ()
I have the following SQL query which I am trying to convert into MDX:
select avg(skucount)
from
(
SELECT count(distinct [SKUCode]) as skucount
--,[SHOPCODE_WITHOUT_DIST]
FROM [HFPL_DW].[dbo].[FactSecondarySales]
where DISTCODE in
(
SELECT [DISTRIBUTORCODE]
FROM [HFPL_DW].[dbo].[DimDistHierarchy]
where REGION = 'KARACHI'
)
and month(saledate) = 7 and year(saledate) = 2018
group by [SHOPCODE_WITHOUT_DIST]
) as inner_query
The inner query returns the count of SKU saled on each shop(which is fulfilled by using "Group by ShopCode")
First I am trying to convert the inner query to MDX, I have tried the following:
WITH MEMBER [Measures].[SKU Count] AS
COUNT( NonEmpty( { [Product Hierarchy].[SKU].[SKU].Members }, ( [Shop Hierarchy].[SHOPCODE WITHOUT DIST] ) ) )
SELECT
{
[Measures].[SKU Count]
} ON COLUMNS,
NonEmpty(
{ [Product Hierarchy].[SKU].[SKU].Members },
([Shop Hierarchy].[SHOPCODE WITHOUT DIST] )
) ON ROWS
FROM
[Consolidated Sales]
where(
[Time Analysis].[Month].&[2018-07-01T00:00:00],
[Distribution Hierarchy].[DISTRIBUTORCODE].&[1002]
)
Reference: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/51988607-78cc-4520-88db-c6d3e99dd1fc/mdx-to-count-the-number-of-members-in-a-dimension-based-on-another-dimension?forum=sqlanalysisservices
It is not returning anything.
Kindly help me acheive the desired output of the Average SKUs saled(The outer query), the number of SKUs saled per shop (inner query)
I can't seem to find a solution that fits.
Here is the situation. I have a two SQL queries from the same table each with a different where clause.
Table A uses this SQL statement:
Select jo.AssemblySeq As Assm,
jo.OprSeq As [OP Center #],
jo.WCCode As WC,
Convert(Varchar, jo.DueDate, 101) As [Due Date],
ja.RequiredQty As Qty,
jo.QtyCompleted As [Qty Comp],
jo.OpComplete As OpComplete
From JobOper jo
Join JobAsmbl ja
On jo.JobNum = ja.JobNum
And jo.AssemblySeq = ja.AssemblySeq
Where jo.JobNum Like '236087.%'
And ja.AssemblySeq <> 0
Order By jo.AssemblySeq;
And returns this data:
Table B uses this SQL query:
Select jo.AssemblySeq As Assm,
jo.OprSeq As [OP Center #],
jo.WCCode As WC,
Convert(Varchar, jo.DueDate, 101) As [Due Date],
jo.QtyPer As QTY,
jo.QtyCompleted As [Qty Comp],
jo.OpComplete As OpComplete
From JobOper jo
Join JobAsmbl ja
On jo.JobNum = ja.JobNum
And jo.AssemblySeq = ja.AssemblySeq
Where jo.JobNum Like '236087.%'
And ja.AssemblySeq = 0
Order By jo.AssemblySeq;
And returns this data:
What I need to do is merge these two tables so that I have columns called Assm, OP Center #, WC, Due Date, Qty, Qty Completed, OpComplete. My problem is that the where clause for the query for table A has ja.AssemblySeq <> 0 and the where clause for the query for table B has ja.AssemblySeq = 0.
I need all the lines from both queries. I am not sure if I need some type of Join or if it would involve sub queries?
A simple UNION ALL will help as below:
Select * from Query1
Union All
Select * from Query2
You don't need to do a UNION ALL at all. You can do this with one single query, without the need to hit the table twice.
Your queries are identical with the exception of the column selected based on the value of ja.AssemblySeq. You can just remove the WHERE clause altogether and make the Qty column a CASE expression.
Select jo.AssemblySeq As Assm,
jo.OprSeq As [OP Center #],
jo.WCCode As WC,
Convert(Varchar, jo.DueDate, 101) As [Due Date],
Case When ja.AssemblySeq = 0
Then jo.QtyPer
Else ja.RequiredQty
End As Qty,
jo.QtyCompleted As [Qty Comp],
jo.OpComplete As OpComplete
From JobOper jo
Join JobAsmbl ja
On jo.JobNum = ja.JobNum
And jo.AssemblySeq = ja.AssemblySeq
Where jo.JobNum Like '236087.%'
Order By jo.AssemblySeq;