I am facing a challenge with a SQL query.
Basically I would like to retrieve the registers which present a [Start] later than their respective [Outgoing tasks].
The table looks like this:
Main Project Main Link Name Start Outgoing tasks
A 1 A1 02.01.2012 A2
A 1 A2 01.01.2012 A3
...
The query I wrote is this one:
SELECT [Name], [Start], [Outgoing tasks]
FROM [Sheet1$]
WHERE [Main project] = 'A'
AND [Main link] = '1'
AND [Outgoing tasks] IS NOT NULL
AND [Start] > (SELECT [Start]
FROM [Sheet1$]
WHERE [Main project] = 'A'
AND [Main link] = '1'
AND [Name] = [Outgoing tasks])
It doesn't return any error, however it simply doesn't bring the expected results.
Do you guys know what might be wrong?
Any support is very appreciated!!!
Further info:
This table comes from a MS Project like application. So we have a milestone, its data, successor and predecessor. What I actually need is a list of milestones which have a start date later than its successor (Which is an error in the project management perspective). So if A1.Start > A2.Start, then i should appear in the results. Let me know if you need any further detail.
Try
select t1.* from [$Sheet1] t1
inner join [$Sheet1] t2
on t1.[main project] = t2.[main project]
and t1.[main link] = t2.[main link]
and t1.[outgoing tasks] = t2.name
and t1.start>t2.start
If this is meant to be a correlated sub-query, you need a way to refer to the outer statement's table inside the inner query. In MySQL you'd do it like this:
SELECT name, start, outgoing_tasks FROM sheet1 foo WHERE main_project = 'A' AND main_link = '1' AND outgoing_tasks IS NOT NULL AND start > (SELECT start FROM sheet1 bar WHERE main_project = 'A' AND main_link = '1' AND bar.name = foo.outgoing_tasks);
Notice that I give the outer query's table an alias of foo and the inner query's table the alias of bar. Then I can refer to the outer table in the WHERE predicate of the nested (inner) query: ... AND bar.name = foo.outgoing_tasks ...
Related
Elon Reeve Musk FRS is an entrepreneur and business magnate. He is the founder, CEO, and Chief Engineer at SpaceX; early-stage investor, CEO, and Product Architect of Tesla, Inc.; founder of The Boring Company; and co-founder of Neuralink and OpenAI.
Your inner select returns a table. That can't be used as parameter to match a WHERE IN condition. Instead try using an INNER JOIN
sum(decode(
select sum(dou.noukn)
from dou
join v_kzeiritsu on
dou.zeiritsu = v_kzeiritsu.zeiritsu
)) as noukn2;
Just move your sum logic inside select as follows:
(SELECT SUM(DOU$2.NOUKN)
FROM SDNISHI.V_KZEIRITSU V
WHERE DOU$2.ZEIRITSU = V.ZEIRITSU) AS NOUKN2
In case If it gives aggregation error then use sum(above query) AS NOUKN2
Your code is very strange. For instance, it seems to assume that V_KZEIRITSU has one row. But, you can move this to the FROM clause:
SELECT SUM(CASE WHEN DOU.ZEIRITSU = K.ZEIRITSU THEN DOU.NOUKN ELSE 0 END) AS NOUKN2
FROM DOU LEFT JOIN
V_KZEIRITSU K
ON 1=1 -- in case the table is really empty
A slightly more reasonable version would be:
SELECT SUM(DOU.NOUKN) AS NOUKN2
FROM DOU LEFT JOIN
V_KZEIRITSU K
ON DOU.ZEIRITSU = K.ZEIRITSU -- in case the table is really empty
It seems rather unlikely to me that this is what you really intend. If not, I would suggest that you ask a new question with appropriate same data, desired results, and explanation of the results. A non-working query should not be expected to provide the same level of information.
I'd say that it is, actually, as simple as
select sum(dou.noukn)
from dou
where dou.zeiritsu in (select zeiritsu from v_kzeiritsu)
(I'm not sure what dou is (table? alias?), but I hope you do.)
After you edited the question, I'm editing the answer. I marked with "--> this" two lines that - in my opinion - might help. As previously, the whole sum(case ...) as noukn2 is replaced by a simple sum(dou$2.noukn).
Note that - in Oracle - you can't use as keyword for table alias. For example:
no: from employees as e
yes: from employees e
Here's your query:
SELECT DOU$2.CUSTCD AS CUSTCD,
DOU$2.CHUNO AS CHUNO,
DOU$2.LINNO AS LINNO,
DOU$2.SHIPDAYYM AS SHIPDAYYM,
SUM (DOU$2.NOUKN) AS NOUKN,
SUM (DOU$2.ZEIKN) AS ZEIKN,
SUM (dou$2.noukn) AS noukn2 --> this
FROM SDNISHI.T_HCHUMON_DOUSOU DOU$2
INNER JOIN SDNISHI.SY_KANRI KNR ON KNR.SHIPDAYYM = DOU$2.SHIPDAYYM
INNER JOIN SDNISHI.T_HCHUMON_MEI MEI
ON MEI.CUSTCD = DOU$2.CUSTCD
AND MEI.CHUNO = DOU$2.CHUNO
AND MEI.LINNO = DOU$2.LINNO
AND MEI.SHIPDAYYM = DOU$2.SHIPDAYYM
AND MEI.USEDNGKBN = '0'
AND MEI.CANCELKBN = '0'
LEFT OUTER JOIN SDNISHI.T_HCHUMON_HD HD
ON HD.CUSTCD = MEI.CUSTCD
AND HD.CHUNO = MEI.CHUNO
AND HD.LINNO = MEI.LINNO
AND HD.USEDNGKBN = '0'
AND HD.CANCELKBN = '0'
AND isnull (HD.CANKBN, '00') = '00'
JOIN v_keziritsu vk ON vk.zeiritsu = dou$2.zeiritsu --> this
WHERE DOU$2.USEDNGKBN = '0'
AND DOU$2.CANCELKBN = '0'
AND ( ( MEI.CHGDELKBN = '1'
AND MEI.HDOUSOUKBN = '02'
AND ( MEI.CHUSU > 0
OR MEI.BCHUSU > 0))
OR ( MEI.CHGDELKBN != '1'
AND HD.HDOUSOUKBN = '02'
AND ( MEI.CHKBTNFGA = '1'
AND HD.CHUSU > 0)
OR ( MEI.CHKBTNFGB = '1'
AND HD.BCHUSU > 0)))
GROUP BY DOU$2.CUSTCD,
DOU$2.CHUNO,
DOU$2.LINNO,
DOU$2.SHIPDAYYM
Let me open with:
SHOWPLAN permission denied in database 'MyDatabase'.
With that out of the way, I'll layout my situation.
So, The database I work with has a view that executes fairly quickly.
SELECT * FROM MyView
returns 32 rows in 1 second and includes a non-indexed column of values (IDs) I need to filter on.
If I filter on these IDs directly in the view:
SELECT * FROM MyView WHERE MyView.SomeId = 18
Things slow immensely and it takes 21 seconds to return the 20 rows with that ID.
As an experiment I pushed the unfiltered results into a temporary table and executed the filtered query on the the temporary table:
IF OBJECT_ID('tempdb..#TEMP_TABLE') IS NOT NULL
BEGIN
DROP TABLE #TEMP_TABLE
END
SELECT * INTO #TEMP_TABLE
FROM MyView;
SELECT *
FROM #TEMP_TABLE
WHERE #TEMP_TABLE.SomeId = 18
DROP TABLE #TEMP_TABLE
And found that it returns the filtered results far faster (roughly 1 second)
Is there a cleaner syntax or pattern that can be implemented to achieve the same performance?
UPDATE: View Definition and Description
Manually obfuscated, but I was careful so hopefully there aren't many errors. Still waiting on SHOWPLAN permissions, so Execution Plan is still pending.
The view's purpose is to provide a count of all the records that belong to a specific component (CMP.COMPONENT_ID = '100') grouped by location.
"Belonging" is determined by the record's PROC_CODE (mapped through PROC_ID) being within the CMP's inclusion range (CMP_INCs) and not in the CMP's exclusion range (CMP_EXCs).
In practice, exclusion ranges are created for individual codes (the bounds are always equal) making it sufficient to check that the code is not equal a bound.
PROC_CODES can (and don't always) have an alphabetic prefix or suffix, which makes the ISNUMERIC() comparison necessary.
Records store PROC_IDs for their PROC_CODEs, so it's necessary to convert the CMP's PROC_CODE ranges into a set of PROC_IDs for identifying which records belong to that component
The performance issue occurs when trying to filter by DEPARTMENT_ID or LOCATION_ID
[CO_RECORDS] is also a view, but if it's that deep I'm going turf this to someone with less red tape to fight through.
CREATE VIEW [ViewsSchema].[MyView] AS
WITH
CMP_INCs AS (SELECT RNG.*, COALESCE(RNG.RANGE_END, RNG.RANGE_BEG) [SAFE_END] FROM DBEngine.DBO.DB_CMP_RANGE [RNG] WHERE [RNG].COMPONENT_ID = '100'),
CMP_EXCs AS (SELECT CER.* FROM DBEngine.DBO.DB_CMP_EXC_RANGE CER WHERE CER.COMPONENT_ID = '100'),
CMP_PROC_IDs AS (
SELECT
DBEngine_ProcTable.PROC_ID [CMP_PROC_ID],
DBEngine_ProcTable.PROC_CODE [CMP_PROC_CODE],
DB_CmpTable.COMPONENT_ID [CMP_ID],
MAX(DB_CmpTable.COMPONENT_NAME) [CMP_NAME]
FROM [DBEngine].DBO.DBEngine_ProcTable DBEngine_ProcTable
LEFT JOIN CMP_INCs ON ISNUMERIC(DBEngine_ProcTable.PROC_CODE) = ISNUMERIC(CMP_INCs.RANGE_BEG)
AND(DBEngine_ProcTable.PROC_CODE = CMP_INCs.RANGE_BEG
OR DBEngine_ProcTable.PROC_CODE BETWEEN CMP_INCs.RANGE_BEG AND CMP_INCs.SAFE_END)
INNER JOIN DBEngine.DBO.DB_CmpTable ON CMP_INCs.COMPONENT_ID = DB_CmpTable.COMPONENT_ID
LEFT JOIN CMP_EXCs EXCS ON EXCS.COMPONENT_ID = DB_CmpTable.COMPONENT_ID AND EXCS.EXCL_RANGE_END = DBEngine_ProcTable.PROC_CODE
WHERE EXCS.EXCL_RANGE_BEG IS NULL
GROUP BY
DBEngine_ProcTable.PROC_ID,
DBEngine_ProcTable.PROC_CODE,
DBEngine_ProcTable.BILL_DESC,
DBEngine_ProcTable.PROC_NAME,
DB_CmpTable.COMPONENT_ID
)
SELECT
RECORD.LOCATION_NAME [LOCATION_NAME]
, RECORD.LOCATION_ID [LOCATION_ID]
, MAX(RECORD.[Department]) [DEPARTMENT]
, RECORD.[Department ID] [DEPARTMENT_ID]
, SUM(RECORD.PROCEDURE_QUANTITY) [PROCEDURE_COUNT]
FROM DBEngineCUSTOMRPT.ViewsSchema.CO_RECORDS [RECORDS]
INNER JOIN CMP_PROC_IDs [CV] ON [CV].CMP_PROC_ID = [RECORDS].PROC_ID
CROSS JOIN (SELECT DATEADD(M, DATEDIFF(M, 0,GETDATE()), 0) [FIRSTOFTHEMONTH]) VARS
WHERE [RECORDS].TYPE = 1
AND ([RECORDS].VOID_DATE IS NULL OR [RECORDS].VOID_DATE >= VARS.[FIRSTOFTHEMONTH] )
AND [RECORDS].POST_DATE < VARS.[FIRSTOFTHEMONTH]
AND [RECORDS].DOS_MONTHS_BACK = 2
GROUP BY [RECORDS].LOCATION_NAME, [RECORDS].[Department ID]
GO
Based on the swift down votes, the answer to my question is
'No, there is not a clean syntax based solution for the improved
performance, and asking for one is ignorant of the declarative nature
of SQL you simple dirty plebeian'.
From the requests for the view's definition, it's clear that performance issues in simple queries should be addressed by fixing the structure of the objects being queried ('MyView' in this case) rather than syntactical gymnastics.
For interested parties the issue was resolved by adding a Row_Number() column to the final select in the view definition, wrapping it in a CTE, and using the new column in an always true filter while selecting the original columns.
I have no idea if this is the optimal solution. It doesn't feel good to me, but it appears to be working.
CREATE VIEW [ViewsSchema].[MyView] AS
WITH
CMP_INCs AS (SELECT RNG.*, COALESCE(RNG.RANGE_END, RNG.RANGE_BEG) [SAFE_END] FROM DBEngine.DBO.DB_CMP_RANGE [RNG] WHERE [RNG].COMPONENT_ID = '100'),
CMP_EXCs AS (SELECT CER.* FROM DBEngine.DBO.DB_CMP_EXC_RANGE CER WHERE CER.COMPONENT_ID = '100'),
CMP_PROC_IDs AS (
SELECT
DBEngine_ProcTable.PROC_ID [CMP_PROC_ID],
DBEngine_ProcTable.PROC_CODE [CMP_PROC_CODE],
DB_CmpTable.COMPONENT_ID [CMP_ID],
MAX(DB_CmpTable.COMPONENT_NAME) [CMP_NAME]
FROM [DBEngine].DBO.DBEngine_ProcTable DBEngine_ProcTable
LEFT JOIN CMP_INCs ON ISNUMERIC(DBEngine_ProcTable.PROC_CODE) = ISNUMERIC(CMP_INCs.RANGE_BEG)
AND(DBEngine_ProcTable.PROC_CODE = CMP_INCs.RANGE_BEG
OR DBEngine_ProcTable.PROC_CODE BETWEEN CMP_INCs.RANGE_BEG AND CMP_INCs.SAFE_END)
INNER JOIN DBEngine.DBO.DB_CmpTable ON CMP_INCs.COMPONENT_ID = DB_CmpTable.COMPONENT_ID
LEFT JOIN CMP_EXCs EXCS ON EXCS.COMPONENT_ID = DB_CmpTable.COMPONENT_ID AND EXCS.EXCL_RANGE_END = DBEngine_ProcTable.PROC_CODE
WHERE EXCS.EXCL_RANGE_BEG IS NULL
GROUP BY
DBEngine_ProcTable.PROC_ID,
DBEngine_ProcTable.PROC_CODE,
DBEngine_ProcTable.BILL_DESC,
DBEngine_ProcTable.PROC_NAME,
DB_CmpTable.COMPONENT_ID
),
RESULTS as (
SELECT
RECORD.LOCATION_NAME [LOCATION_NAME]
, RECORD.LOCATION_ID [LOCATION_ID]
, MAX(RECORD.[Department]) [DEPARTMENT]
, RECORD.[Department ID] [DEPARTMENT_ID]
, SUM(RECORD.PROCEDURE_QUANTITY) [PROCEDURE_COUNT]
, ROW_NUMBER() OVER (ORDER BY TDL.[Medical Department ID], TDL.[BILL_AREA_ID], TDL.JP_POS_NAME) [ROW]
FROM DBEngineCUSTOMRPT.ViewsSchema.CO_RECORDS [RECORDS]
INNER JOIN CMP_PROC_IDs [CV] ON [CV].CMP_PROC_ID = [RECORDS].PROC_ID
CROSS JOIN (SELECT DATEADD(M, DATEDIFF(M, 0,GETDATE()), 0) [FIRSTOFTHEMONTH]) VARS
WHERE [RECORDS].TYPE = 1
AND ([RECORDS].VOID_DATE IS NULL OR [RECORDS].VOID_DATE >= VARS.[FIRSTOFTHEMONTH] )
AND [RECORDS].POST_DATE < VARS.[FIRSTOFTHEMONTH]
AND [RECORDS].DOS_MONTHS_BACK = 2
GROUP BY [RECORDS].LOCATION_NAME, [RECORDS].[Department ID]
)
SELECT
[LOCATION_NAME]
, [LOCATION_ID]
, [DEPARTMENT]
, [DEPARTMENT_ID]
, [PROCEDURE_COUNT]
FROM RESULTS
WHERE [ROW] > 0
GO
I have a view vwDocumentLinks with data as shown below:
I have another table RiskTypes with data as below.
The link between the table & viewis : Idx25 = Risk Type and LinkDocNo = DocumentType. What I am trying to achieve is to get DocumentType in RiskTypes that's not in the view vwDocumentLinks foreach BaseValue and where Idx25 = RiskType. An example using a single BaseValue will be:
SELECT * FROM RiskTypeDocuments WHERE RiskType = 'BUSINESS LIMITED COMPANY' AND DocumentType NOT IN (SELECT LINKDOCNO FROM DBO.VWLINKS WHERE BaseValue = '00007573-1637-4B8E-9374-730AF58BCFB6')
I tried the below query and it's not working as expected. Any help will be greatly appreciated. I am a newbie in SQL
SELECT dbo.RiskTypeDocuments.DocumentType,
dbo.RiskTypeDocuments.RiskType,
dbo.vwLinks.BaseValue AS Document
FROM dbo.vwLinks LEFT OUTER JOIN
dbo.RiskTypeDocuments ON dbo.vwLinks.LinkDocNo =
dbo.RiskTypeDocuments.DocumentType AND dbo.vwLinks.Idx25 =
dbo.RiskTypeDocuments.RiskType
WHERE dbo.RiskTypeDocuments.DocumentType IS NOT NULL
ORDER BY Document
NB: I can't change the schema. I can only create views from the existing tables.
Sample Data from the two datasets: vwDocumentLinks & RiskTypeDocuments
SELECT a.DocumentType,
a.RiskType,
b.BaseValue AS Document
FROM dbo.RiskTypeDocuments as a
INNER JOIN (Select distinct Idx25, BaseValue from vwDocumentLinks) as b on b.Idx25 = a.RiskType
where a.DocumentType not in (Select LINKDOCNO from vwDocumentLinks as c where c.basevalue = b.BaseValue )
I think what you are looking for is NOT EXISTS. It takes a little to get your head around, but the idea is to have what is called a correlated subquery. The subquery is joined to the main query, hence the term correlated.
SELECT *
FROM RiskTypeDocuments
WHERE NOT EXISTS (
SELECT 1 FROM vwDocumentLinks
WHERE RiskTypeDocuments.RiskType = vwDocumentLinks.idx25
AND RiskTypeDocuments.DocumentType = vwDocumentLinks.LinkDocNo
)
If you want to retrieve the records which don't exist in the view then
Try like this
SELECT d.DocumentType,
d.RiskType,
v.BaseValue
FROM dbo.vwLinks AS v
OUTER JOIN dbo.RiskTypeDocuments d ON v.LinkDocNo = d.DocumentType AND v.vwLinks.Idx25 =d.RiskType
WHERE v.BaseValue IS NULL
ORDER BY DocumentType
I received the following error, which is based off of my code (attached below) in Netezza .
^ found "WHERE" (at char 543) expecting an identifier found a keyword
But how I find where in the code this is located at? Do I need to divide 543 by the amount of characters per line ?
the code is shown below :
DELETE FROM TDM_FEE_DISCOUNT_FACT;;
----------------------------------------------------------------------------
-- INSERT INTO TDM TABLE ---
----------------------------------------------------------------------------
INSERT INTO FEE_DISCOUNT_FACT
(
FEE_DISCNT_F_DK ,
HLTH_PLN_GRP_DK,
HLTH_PLN_SPSR_DK,
PLN_MBR_DK,
COV_PRD_STRT_DT,
COV_PRD_END_DT,
BIL_DUE_DT,
FEE_AMT,
DISCNT_AMT,
BIL_ID,
SS_CD,
TNT_CD,
INSRT_DT,
UPDT_DT,
CREAT_RUN_CYC_EXEC_SK,
LST_UPDT_RUN_CYC_EXEC_SK,
REC_PRCS_TYP_CD,
ROW_EFF_STRT_DT,
ROW_EFF_END_DT,
CUR_ROW_IND
)
WITH LAST_RUN_DATE(DT) AS
(
SELECT NVL(LAST_RUN, TO_DATE('01/01/1900', 'MM/DD/YYYY'))
FROM (
SELECT MAX(NVL(TCT.MANIFEST_COMPLETED_TS, TO_DATE('01/01/1900', 'MM/DD/YYYY'))) LAST_RUN
FROM :DB_XREF..TGT_CONTROL_TBL TCT
WHERE MANIFEST = 'F_FEE_DISCOUNT'
) T
)
,
--Need to modify the following section , on line 66 of FEE_DISCOUNT_FACT
DRIVER AS
(
select
PM.HLTH_PLN_GRP_NBR||'|'||SBFD.SS_CD AS HLTH_PLN_GRP_BK
,PM.HLTH_PLN_GRP_NBR AS SPSR_ID
,PM.PLN_MBR_SK
--COV_PRD_STRT_DT
--COV_PRD_END_DT
,SBFD.BIL_DUE_DT AS BIL_DUE_DT
,NVL(SBFD.FEE_AMT,0) AS FEE_AMT
,NVL(SBFD.DISCNT_AMT,0) AS DISCNT_AMT
,SBFD.BIL_ID
,SBFD.SS_CD
,SBFD.FEE_DISCNT_CREAT_DT_TM
from MBRBOR_TGT_D4..SUBSCRIBER_BILLING_FEE_DISCOUNT SBFD
LEFT OUTER JOIN MBRBOR_TGT_D4..PLAN_MEMBER PM
ON PM.SBSCR_SK = SBFD.SBSCR_SK
AND PM.CUR_ROW_IND = 'Y'
AND PM.REC_PRCS_TYP_CD <> 'D'
AND PM.SBSCR_DPND_RLNSP_TYP_CD_SK IN (SELECT CD_MAP_SK FROM REFBOR_TGT_D4..CODEMAP
WHERE CONFOR_CD = 'SUB')
)
/* IN the code, only need to join to the dimensions .. FACT DK's are the sequence */
SELECT NEXT VALUE FOR FEE_DISCOUNT_F_SEQ AS FEE_DISCNT_F_DK,
NVL(HPGD.HLTH_PLN_GRP_DK,-9) AS HLTH_PLN_GRP_DK,
NVL(HPGD.HLTH_PLN_SPSR_DK,-9) AS HLTH_PLN_SPSR_DK,
PM.PLN_MBR_SK AS PLN_MBR_DK,
NVL(??.COV_PRD_STRT_DT,-9) AS COV_PRD_STRT_DT,
NVL(??.COV_PRD_END_DT,-9) AS COV_PRD_END_DT,
NVL(BIL_DUE_DT,0) AS BIL_DUE_DT,
NVL(FEE_AMT, 0) AS FEE_AMT,
NVL(DISCNT_AMT, 0) AS DISCNT_AMT,
NVL(BIL_ID,-9) AS BIL_ID,
DR.SS_CD AS SS_CD,
'BSC' AS TNT_CD,
NOW() AS INSRT_DT,
NOW() AS UPDT_DT,
NVL(SBFD.CREAT_RUN_CYC_EXEC_SK,-9) AS CREAT_RUN_CYC_EXEC_SK,
NVL(SBFD.LST_UPDT_RUN_CYC_EXEC_SK,-9) AS LST_UPDT_RUN_CYC_EXEC_SK,
NVL(SBFD.REC_PRCS_TYP_CD,0) AS REC_PRCS_TYP_CD,
NVL(SBFD.ROW_EFF_STRT_DT,0) AS ROW_EFF_STRT_DT,
NVL(SBFD.ROW_EFF_END_DT,0) AS ROW_EFF_END_DT,
NVL(SBFD.CUR_ROW_IND,0) AS CUR_ROW_IND --FEE_DISCNT_CREAT_DT_TM
FROM DRIVER DR
LEFT OUTER JOIN :DB_TGT..HEALTH_PLAN_GROUP_DIMENSION HPGD ON DR.HLTH_PLN_GRP_BK = HPGD.HLTH_PLN_GRP_BK
AND FEE_DISCNT_CREAT_DT_TM BETWEEN HPGD.ROW_EFF_STRT_DT AND HPGD.ROW_EFF_END_DT
LEFT OUTER JOIN :DB_TGT..HEALTH_PLAN_SPONSOR_DIMENSION HPSD ON DR.SPSR_ID = HPSD.SPSR_ID
AND FEE_DISCNT_CREAT_DT_TM BETWEEN HPSD.ROW_EFF_STRT_DT AND HPSD.ROW_EFF_END_DT --DONE
--some of the joins will have different conditions . like for SS_CD it will be different
LEFT OUTER JOIN :DB_TGT..PLAN_MEMBER_DIMENSION PMD ON DR.PLN_MBR_SK = PMD.PLN_MBR_SK
AND FEE_DISCNT_CREAT_DT_TM BETWEEN PMD.ROW_EFF_STRT_DT AND PMD.ROW_EFF_END_DT
--LEFT OUTER JOIN
LEFT OUTER JOIN
(SELECT SBSCR.PLN_MBR_DK AS SBSCR_DK, PM.*
FROM :DB_TGT..PLAN_MEMBER_DIMENSION PM
LEFT OUTER JOIN
(SELECT PM.PLN_MBR_DK, PM.PLN_MBR_SK, PM.SBSCR_SK, PM.CUR_ROW_IND, PM.ROW_EFF_STRT_DT, PM.ROW_EFF_END_DT FROM
:DB_TGT..PLAN_MEMBER_DIMENSION PM WHERE PLN_MBR_SK = SBSCR_SK) SBSCR
ON PM.SBSCR_SK = SBSCR.SBSCR_SK AND (PM.ROW_EFF_END_DT -1) BETWEEN
SBSCR.ROW_EFF_STRT_DT AND SBSCR.ROW_EFF_END_DT) PMD
ON DR.PLN_MBR_SK = PMD.PLN_MBR_SK
AND DR.CAPITN_ERN_FROM_DT BETWEEN PMD.ROW_EFF_STRT_DT AND PMD.ROW_EFF_END_DT
Thanks
Since vi is the editor used for the queries (if you're in nzsql) - you can navigate 543 characters from the start by typing in 0543l in the editor - this will take you the start, then 543 steps to the "right". This should bring you to the area of the sql where the problem is.
I have a project in which I need to save request for file. I have to save the state of the request with the date of each step.
I have two tables in my database :
FileRequest :
FileRequestStatus :
I would like to create a request to get each FileName from the table FileRequest having only the Status == 'NEW'. The desired output would be in this case C12345, LIVE.
If you have a better idea in order to build my database, I'll take it
I tried something like that :
SELECT [FileName] FROM [FileRequest]
INNER JOIN [FileRequestStatus] ON [FileRequestStatus].[RequestId] = [FileRequest].[RequestId]
GROUP BY [FileRequestStatus].[RequestId]
HAVING COUNT([FileRequestStatus].[RequestStatus]) < 2
SELECT FR.FileName
FROM [FileRequest] FR
INNER JOIN [FileRequestStatus] FRS ON FRS.[RequestId] = FR.[RequestId]
GROUP BY FR.FileName
HAVING COUNT(CASE WHEN FRS.RequestStatus <> 'New' THEN 1 END) = 0 --No statuses other than `NEW`
AND COUNT(CASE WHEN FRS.RequestStatus = 'New' THEN 1 END) >= 1 --Atleast one status `NEW`
I think the simplest method is aggregation:
select fr.FileName
from nep.FileRequest fr join
nep.FileRequestStatus] frs
on frs.RequestId = fr.RequestId
group by fr.FileName
having min(frs.RequestStatus) = max(frs.RequestStatus) and
min(frs.RequestStatus) = 'New';
Note: This assumes that the request status is never NULL (although that is easy to take into account).
What this does is aggregate by file name and then check that the statuses for a given file are all equal (the first condition) and equal to 'New' (the second condition).
You need to include [FileName] to your GROUP BY, then you can select it in result
SELECT [nep].[FileRequest].[FileName] FROM [nep].[FileRequest]
INNER JOIN [nep].[FileRequestStatus] ON [nep].[FileRequestStatus].[RequestId] = [nep].[FileRequest].[RequestId]
GROUP BY [nep].[FileRequestStatus].[RequestId], [nep].[FileRequest].[FileName]
HAVING COUNT([nep].[FileRequestStatus].[RequestStatus]) < 2