Dice query only returning with a specific fields condition - sql

We're doing a dice olap query that gets a certain production company's total revenue of a specific year on the schema below:
Using this query:
SELECT PC.name, RC.year, SUM(revenue) as total_revenue
FROM movies_reception_facts MR
JOIN ref_calendar RC ON MR.release_date_key = RC.date_key
JOIN pc_groups PG ON MR.pc_group_key = PG.pc_group_key
JOIN movies_pc MP ON PG.pc_group_key = MP.pc_group_key
JOIN production_companies PC ON MP.pc_id = PC.pc_id
WHERE PC.pc_id IN(
SELECT pc_id
FROM production_companies
WHERE name = 'Disney') AND
RC.date_key IN(
SELECT RC.date_key
FROM ref_calendar
WHERE RC.year = 2014
)
GROUP BY (PC.name, RC.year)
The problem is that, it's only returning results when the year is set to 2014: WHERE RC.year = 2014. Any other value would return an empty row.

I'm not sure if this fixes your problem, but that subquery is problematic. First, if you did use a subquery, it would be:
RC.date_key IN(
SELECT RC2.date_key
FROM ref_calendar RC2
WHERE RC2.year = 2014
)
But a subquery is not necessary. You can just replace the logic with:
RC.year = 2014
Then putting this condition in the IN clause is silly. It should be a filter in the outer where. And since the tables are already joined in, I think you just want:
WHERE pc.name = 'Disney' AND
RC.year = 2014
That said, I'm not sure if this fixes your problem of no data being returned for other years.

Related

Summing using a case expression

I am looking to roll up my numbers.
SELECT
SORDERQ.SOHNUM_0,
YQTYORD_0,
ORDINVNOT_0
FROM LIVE.SORDER
LEFT JOIN LIVE. SORDERQ ON SORDER.SOHNUM_0 = SORDERQ.SOHNUM_0
WHERE SORDER.SOHNUM_0 = 'SC111-162420_19'
AND ZBPSELECTION_0 <> ''
AND YCROPYR_0 = '2019'
AND SORDER.SALFCY_0 = '111'
I want to return 1 record per SOHNUM_0,the sum of YQTYORD_0 by SOHNUM_0 and ORDINVNOT_0.
I want to return 1 record per SOHNUM_0,the sum of YQTYORD_0 by SOHNUM_0 and ORDINVNOT_0.
Are you just looking for simple aggregation?
SELECT
q.SOHNUM_0,
SUM(YQTYORD_0) SUM_YQTYORD_0,
ORDINVNOT_0
FROM LIVE.SORDER o
LEFT JOIN LIVE.SORDERQ q ON o.SOHNUM_0 = q.SOHNUM_0
WHERE
o.SOHNUM_0 = 'SC111-162420_19'
AND o.SALFCY_0 = '111'
AND ZBPSELECTION_0 <> ''
AND YCROPYR_0 = '2019'
GROUP BY
q.SOHNUM_0,
ORDINVNOT_0
Note:
I modified your query so it uses table aliases - this makes it shorter
you should prefix all columns in the query with the table they belong to, to make your query unmabiguous and easier to understand

MSSQL 2012 - Why is AVG & TRY_CONVERT not returning the correct value?

I am using MSSQL 2012 and I am trying to use AVG together with TRY_CONVERT on a table column with the following datatype: nvarchar(255), NOT NULL
First before I try to query using AVG & TRY_CONVERT, this is the data that I want to get the AVG value out of using this query:
And this is the results after using AVG and TRY_CONVERT, 0 rows returned.
I also tried to use a subquery then i got 18 row returned, but with value NULL, i skipped out on AVG just to see if i was getting the correct values.. but it seems not, i also included the p.serialnumber column to show that its the correct rows that was returned, its just the value NULL that somehow appears after TRY_CONVERT.
UPDATE!:
When I execute the query below which target data that has a "." separator (qtv2.qtv_qteid = 58 (instead of 63)) , it works! So the issue is the "," separator. Anyone know solution to this??
declare #ProjectSelection nvarchar(10)
set #ProjectSelection = 'C82007588'
SELECT AVG(TRY_CONVERT(numeric(10,5), avgcap))
FROM
(
select qtv2.qtv_result as avgcap
from ProductionOrder PO
left join CustomerOrder co on co.CustomerOrderId=po.customerorderid
left join ProductionOrderProperty pop on pop.ProductionOrderId=po.productionorderid
left join product p on p.ProductionOrderId=po.productionorderid
left join QualityTestValues qtv on qtv.qtv_productid=p.ProductId
left join QualityTestValues qtv2 on qtv2.qtv_productId=p.ProductId
where pop.Value=#ProjectSelection and pop.name = 'project' and po.ProductTypeId = 1
and qtv2.qtv_qteid = 58 and qtv2.qtv_valid = 1 and qtv.qtv_ProductSegmentId = 144 and qtv.qtv_valid = 1
and qtv.qtv_qteid = 51 and qtv.qtv_result = 'J'
group by co.CustomerName, pop.Value, qtv2.qtv_result, p.SerialNumber
) A
Result:
(No column name)
22.200000
How about your compatibility level? A similar question can be found here:
TRY_CONVERT fails on SQL Server 2012
Although your server version is 2012, a lower compatibility level can cause the try_convert to be unavailable for use in your database. You can check this by running the following code in your specific database and afterwards on for instance the master database.
DECLARE #b VARCHAR(10) = '12312'
SELECT TRY_CONVERT(INT,#b)
You can take your first query and do something like this:
SELECT AVG(TRY_CONVERT(numeric(10,5), avgcap))
FROM
(
-- Insert your first query here.
) A
This should give you the average of the numbers.
EDIT
Here is a workable example that should return 24.000000.
SELECT AVG(TRY_CONVERT(numeric(10,5), A))
FROM
(
SELECT '22.5' AS A
UNION
SELECT '23.5' AS A
UNION
SELECT '26.0' AS A
) B
I found out the solution, using TRY_PARSE instead of TRY_CONVERT.
DECLARE #ProjectSelection nvarchar(10)
SET #ProjectSelection = 'C82007588'
SELECT AVG(avgcap) as avgcap
FROM
(
SELECT qtv2.qtv_result, TRY_PARSE( qtv2.qtv_result AS NUMERIC(10,3)) avgcap
FROM ProductionOrder PO
LEFT JOIN CustomerOrder co on co.CustomerOrderId=po.customerorderid
LEFT JOIN ProductionOrderProperty pop on pop.ProductionOrderId=po.productionorderid
LEFT JOIN product p on p.ProductionOrderId=po.productionorderid
LEFT JOIN QualityTestValues qtv on qtv.qtv_productid=p.ProductId
LEFT JOIN QualityTestValues qtv2 on qtv2.qtv_productId=p.ProductId
WHERE pop.Value=#ProjectSelection
AND pop.name = 'project'
AND po.ProductTypeId = 1
AND qtv2.qtv_qteid = 63
AND qtv2.qtv_valid = 1
AND qtv.qtv_ProductSegmentId = 144
AND qtv.qtv_valid = 1
AND qtv.qtv_qteid = 51
AND qtv.qtv_result = 'J'
GROUP BY co.CustomerName, pop.Value, qtv2.qtv_result, p.SerialNumber
) A`
Results:
avgcap
21264.850000

Left Join on subquery

Can someone help me with this query? In the subquery P, a fiscal year exists where the same year does not exist in BudgetActivityDetailCurrentBiennium. I need this query to show a null value for Amount in that year. Currently that year does not show up at all.
SELECT
P.FiscalYear
,P.BudgetNbr
,SUM(sec.BudgetActivityDetailCurrentBiennium.TranAmount) AS Amount
FROM
(SELECT
sec.BudgetIndexCurrentBiennium.BudgetNbr
,AVG(CAST(sec.BudgetIndexCurrentBiennium.BienniumYear AS INT)+1) AS FiscalYear
FROM
sec.BudgetIndexCurrentBiennium
GROUP BY
sec.BudgetIndexCurrentBiennium.BudgetNbr
UNION ALL
SELECT
sec.BudgetIndexCurrentBiennium.BudgetNbr
,AVG(CAST(sec.BudgetIndexCurrentBiennium.BienniumYear AS INT)+2) AS FiscalYear
FROM
sec.BudgetIndexCurrentBiennium
GROUP BY
sec.BudgetIndexCurrentBiennium.BudgetNbr) AS P
LEFT JOIN sec.BudgetActivityDetailCurrentBiennium
ON
P.BudgetNbr = sec.BudgetActivityDetailCurrentBiennium.BudgetNbr
AND P.FiscalYear = sec.BudgetActivityDetailCurrentBiennium.FiscalYear
WHERE sec.BudgetActivityDetailCurrentBiennium.BudgetNbr = '076036'
GROUP BY
P.FiscalYear
,P.BudgetNbr
I think the problem is your WHERE clause,
WHERE sec.BudgetActivityDetailCurrentBiennium.BudgetNbr = '076036'
which applies to the SELECT as a whole, not just (as I guess you intend) to the left join.
Change the WHERE to an AND. That should do the trick.

SQL - Joining a list of dates with observations within a date range

I have a sample query below that uses GETDATE to pull the most recent estimates. The table has TWO date columns, effectiveDate and toDate. The problem? I want to pull a weekly value so I can have a time series of estimates. If I run the query now, I will end up with all the estimates as of today, but I also want to know what they were last week, the week before, etc.
Should I create a new table containing the dates that I want and then join them against the results of the query. This is where I am stuck. Thank you.
select GETDATE() as observeDate
, (select C.companyName from ciqCompany C where C.companyId = EP.companyId) as companyName
, (select EPT.periodTypeName from ciqEstimatePeriodType EPT where EPT.periodTypeId = EP.periodTypeId) as periodTypeName
, EP.fiscalYear
, EB.brokerName as brokerName
, EA.firstName+' '+EA.lastName as AnalystName
, EDND.tradingitemid
, (select DI.dataItemName from ciqdataitem DI where DI.dataitemid = EDND.dataitemid) as dataItemName
, (select EAS.accountingStandardDescription from dbo.ciqEstimateAccountingStd EAS where EAS.accountingStandardId = EDND.accountingStandardId) as AccountingStandard
, (select Cu.ISOCode from ciqCurrency Cu where Cu.currencyid = EDND.currencyid) as ISOCode
, (select EST.estimateScaleName from ciqEstimateScaleType EST where EST.estimateScaleId = EDND.estimateScaleId) as estimateScaleName
,EDND.dataItemValue,EDND.effectiveDate,EDND.isExcluded
from ciqEstimatePeriod EP
--- link estimate period table to detailed numeric data table
----------------------------------------------------------
join ciqEstimateDetailNumericData EDND
on EDND.estimatePeriodId = EP.estimatePeriodId
and GETDATE() between EDND.effectiveDate and EDND.toDate
----------------------------------------------------------
left outer join ciqEstimateBroker EB
on EB.estimateBrokerId = EDND.estimateBrokerId --- left outer join must be used if you receive any of the anonymous estimates packages
left outer join ciqEstimateAnalyst EA
on EA.estimateAnalystId = EDND.estimateAnalystId --- left outer join must be used if you receive any of the anonymous estimates packages
where EP.companyId = 112350 -- IBM
and EP.periodTypeId = 1 -- annual
and EDND.dataItemId = 21634 --- EPS Normalized (Detailed)
and EP.fiscalYear = 2010
order by 4,5,6,10
This query is complicated enough as it is - I would hate to add to it. I would probably turn it into a view or a stored proc and query from it as needed. Then you could also have, instead of just GETDATE(), a date range as input.

Confused in join query in SQL

The following works:
SELECT IBAD.TRM_CODE, IBAD.IPABD_CUR_QTY, BM.BOQ_ITEM_NO,
IBAD.BCI_CODE, BCI.BOQ_CODE
FROM IPA_BOQ_ABSTRCT_DTL IBAD,
BOQ_CONFIG_INF BCI,BOQ_MST BM
WHERE BM.BOQ_CODE = BCI.BOQ_CODE
AND BCI.BCI_CODE = IBAD.BCI_CODE
AND BCI.STATUS = 'Y'
AND BM.STATUS = 'Y'
order by boq_item_no;
Results:
But after joining many tables with that query, the result is confusing:
SELECT (SELECT CMN_NAME
FROM CMN_MST
WHERE CMN_CODE= BRI.CMN_RLTY_MTRL) MTRL,
RRI.RRI_RLTY_RATE AS RATE,
I.BOQ_ITEM_NO,
(TRIM(TO_CHAR(IBAD.IPABD_CUR_QTY,
'9999999999999999999999999999990.999'))) AS IPABD_CUR_QTY,
TRIM(TO_CHAR(BRI.BRI_WT_FACTOR,
'9999999999999999999999999999990.999')) AS WT,
TRIM(TO_CHAR((IBAD.IPABD_CUR_QTY*BRI.BRI_WT_FACTOR),
'9999999999999999999999990.999')) AS RLTY_QTY,
(TRIM(TO_CHAR((IBAD.IPABD_CUR_QTY*BRI.BRI_WT_FACTOR*RRI.RRI_RLTY_RATE),
'9999999999999999999999990.99'))) AS TOT_AMT,
I.TRM_CODE AS TRM
FROM
(SELECT * FROM ipa_boq_abstrct_dtl) IBAD
INNER JOIN
(SELECT * FROM BOQ_RLTY_INF) BRI
ON IBAD.BCI_CODE = BRI.BCI_CODE
INNER JOIN
(SELECT * FROM RLTY_RATE_INF) RRI
ON BRI.CMN_RLTY_MTRL = RRI.CMN_RLTY_MTRL
INNER JOIN
( SELECT IBAD.TRM_CODE, IBAD.IPABD_CUR_QTY,
BM.BOQ_ITEM_NO, IBAD.BCI_CODE, BCI.BOQ_CODE
FROM IPA_BOQ_ABSTRCT_DTL IBAD,
BOQ_CONFIG_INF BCI,BOQ_MST BM
WHERE
BM.BOQ_CODE = BCI.BOQ_CODE
AND BCI.BCI_CODE = IBAD.BCI_CODE
and BCI.status = 'Y'
and bm.status = 'Y') I
ON BRI.BCI_CODE = I.BCI_CODE
AND I.TRM_CODE = BRI.TRM_CODE
AND BRI.TRM_CODE =4
group by BRI.CMN_RLTY_MTRL, RRI.RRI_RLTY_RATE, I.BOQ_ITEM_NO,
IBAD.IPABD_CUR_QTY, BRI.BRI_WT_FACTOR, I.TRM_CODE, I.bci_code
order by BRI.CMN_RLTY_MTRL
Results:
TRM should be 11 instead of 4 in the first row.
you getting 4 because you use
AND BRI.TRM_CODE =4
if you remove this criter you can get true result
In your first query, both of the rows you've highlighted have BCI_CODE=1866.
In the second query, you are joining that result set with a number of others (which come from the same tables, which seems odd). In particular, you are joining from the subquery to another table using BCI_CODE, and from there to (SELECT * FROM ipa_boq_abstrct_dtl) IBAD. Since both of the rows from the subquery have the same BCI_CODE, they will join to the same rows in the other tables.
The quantity that you are actually displaying in the second query is from (SELECT * FROM ipa_boq_abstrct_dtl) IBAD, not from the other subquery.
Is the problem simply that you mean to select I.IPABD_CUR_QTY instead of IBAD.IPABD_CUR_QTY?
You might find this clearer if you did not reuse the same aliases for tables at multiple points in the query.