有没有一种方法可以 return 来自子查询的多列,而不是为每一列重复子查询?它有效但需要太长时间

Is there a way that I can return multiple columns from a subquery rather than repeating the subquery for each column? It works but takes too long

As you can see I'm trying to add 4 columns by repeating the subquery, this works but takes too long to be useful. I tried to put all the joins at the end but then I only get the records that have values in [dbo.permit_terms] whereas I want all the records from [dbo.prd]. I hope this makes sense and will be very grateful for an answer.

   SELECT WLC.name AS WELLCOMPL
    , WLC.id_subsidiary AS SUB
    , PD.Date
    , PD.days
    , PD.oil
    , PD.water
    , PD.gas
    , PD.interest
    , PD.operator
    , PD.comments
    , (
    SELECT PT.net_working_int_oil
        FROM dbo.prd AS P (NOLOCK)
            left JOIN dbo.wellbore_compl AS W WITH (NOLOCK) ON (P.id_subsidiary = W.id_subsidiary) AND (P.id_wellborecompl = W.id) 
            left JOIN dbo.wellstring WITH (NOLOCK) ON W.id_wellstring = dbo.wellstring.id 
            left JOIN dbo.wellbore wb WITH (NOLOCK) ON dbo.wellstring.id_wellbore = wb.id 
            left JOIN dbo.wellbore_permit WP WITH (NOLOCK) ON wb.id = WP.id_wellbore
            left JOIN dbo.permit  WITH (NOLOCK) ON dbo.permit.id = WP.id_permit
            left JOIN dbo.permit_terms PT WITH (NOLOCK) ON dbo.permit.id = PT.id_permit 
        where (p.[date] >= pt.start_date and p.[date] <=pt.end_date)
    --      AND W.[name] = WLC.[name] 
            AND p.id = pd.id
            AND pd.id_subsidiary = w.id_subsidiary
            AND P.deletedAt Is Null 
            AND W.deletedAt Is Null
            AND dbo.wellstring.deletedAt Is Null
            AND dbo.permit.deletedAt Is Null
            AND wb.deletedAt Is Null
            AND PT.deletedAt Is Null
    )
     as permit_interest 
    , (
    SELECT PT.operator
        FROM dbo.prd AS P (NOLOCK)
            left JOIN dbo.wellbore_compl AS W WITH (NOLOCK) ON (P.id_subsidiary = W.id_subsidiary) AND (P.id_wellborecompl = W.id) 
            left JOIN dbo.wellstring WITH (NOLOCK) ON W.id_wellstring = dbo.wellstring.id 
            left JOIN dbo.wellbore wb WITH (NOLOCK) ON dbo.wellstring.id_wellbore = wb.id 
            left JOIN dbo.wellbore_permit WP WITH (NOLOCK) ON wb.id = WP.id_wellbore
            left JOIN dbo.permit  WITH (NOLOCK) ON dbo.permit.id = WP.id_permit
            left JOIN dbo.permit_terms PT WITH (NOLOCK) ON dbo.permit.id = PT.id_permit 
        where (p.[date] >= pt.start_date and p.[date] <=pt.end_date)
    --      AND W.[name] = WLC.[name] 
            AND p.id = pd.id
            AND pd.id_subsidiary = w.id_subsidiary
            AND P.deletedAt Is Null 
            AND W.deletedAt Is Null
            AND dbo.wellstring.deletedAt Is Null
            AND dbo.permit.deletedAt Is Null
            AND wb.deletedAt Is Null
            AND PT.deletedAt Is Null
    )
     as permit_operator
    , (
    SELECT pd.oil*PT.net_working_int_oil/100
        FROM dbo.prd AS P (NOLOCK)
            left JOIN dbo.wellbore_compl AS W WITH (NOLOCK) ON (P.id_subsidiary = W.id_subsidiary) AND (P.id_wellborecompl = W.id) 
            left JOIN dbo.wellstring WITH (NOLOCK) ON W.id_wellstring = dbo.wellstring.id 
            left JOIN dbo.wellbore wb WITH (NOLOCK) ON dbo.wellstring.id_wellbore = wb.id 
            left JOIN dbo.wellbore_permit WP WITH (NOLOCK) ON wb.id = WP.id_wellbore
            left JOIN dbo.permit  WITH (NOLOCK) ON dbo.permit.id = WP.id_permit
            left JOIN dbo.permit_terms PT WITH (NOLOCK) ON dbo.permit.id = PT.id_permit 
        where (p.[date] >= pt.start_date and p.[date] <=pt.end_date)
    --      AND W.[name] = WLC.[name] 
            AND p.id = pd.id
            AND pd.id_subsidiary = w.id_subsidiary
            AND P.deletedAt Is Null 
            AND W.deletedAt Is Null
            AND dbo.wellstring.deletedAt Is Null
            AND dbo.permit.deletedAt Is Null
            AND wb.deletedAt Is Null
            AND PT.deletedAt Is Null
    )
     as Oil_net
    , (
    SELECT pd.gas*PT.net_working_int_gas/100 
        FROM dbo.prd AS P (NOLOCK)
            left JOIN dbo.wellbore_compl AS W WITH (NOLOCK) ON (P.id_subsidiary = W.id_subsidiary) AND (P.id_wellborecompl = W.id) 
            left JOIN dbo.wellstring WITH (NOLOCK) ON W.id_wellstring = dbo.wellstring.id 
            left JOIN dbo.wellbore wb WITH (NOLOCK) ON dbo.wellstring.id_wellbore = wb.id 
            left JOIN dbo.wellbore_permit WP WITH (NOLOCK) ON wb.id = WP.id_wellbore
            left JOIN dbo.permit  WITH (NOLOCK) ON dbo.permit.id = WP.id_permit
            left JOIN dbo.permit_terms PT WITH (NOLOCK) ON dbo.permit.id = PT.id_permit 
        where (p.[date] >= pt.start_date and p.[date] <=pt.end_date)
    --      AND W.[name] = WLC.[name] 
            AND p.id = pd.id
            AND pd.id_subsidiary = w.id_subsidiary
            AND P.deletedAt Is Null 
            AND W.deletedAt Is Null
            AND dbo.wellstring.deletedAt Is Null
            AND dbo.permit.deletedAt Is Null
            AND wb.deletedAt Is Null
            AND PT.deletedAt Is Null
    )
    as Gas_net
    FROM (dbo.prd AS PD 
    INNER JOIN dbo.wellbore_compl AS WLC ON (PD.id_subsidiary = WLC.id_subsidiary) AND (PD.id_wellborecompl = WLC.id)) 
    WHERE 
     PD.deletedAt Is Null 
    AND WLC.deletedAt Is Null

这应该会让你接近

Select WELLCOMPL       = WLC.name
     , SUB             = WLC.id_subsidiary
     , PD.Date
     , PD.days
     , PD.oil
     , PD.water
     , PD.gas
     , PD.interest
     , PD.operator
     , PD.comments
     , permit_interest = tt.net_working_int_oil
     , permit_operator = tt.operator
     , Oil_net         = PD.oil * tt.net_working_int_oil / 100
     , Gas_net         = PD.gas * tt.net_working_int_gas / 100
  From dbo.prd                                  PD With (NoLock)
 Inner Join dbo.wellbore_compl                 WLC With (NoLock) On PD.id_subsidiary = WLC.id_subsidiary
                                                                And pd.id_wellborecompl = WLC.id

 Cross Apply (Select PT.operator
                   , PT.net_working_int_oil
                   , PT.net_working_int_gas
                From dbo.wellstring             ws With (NoLock)
               Inner Join dbo.wellbore          wb With (NoLock) On wb.id = ws.id_wellbore
               Inner Join dbo.wellbore_permit   WP With (NoLock) On WP.id_wellbore = wb.id
               Inner Join dbo.permit             p With (NoLock) On p.id = WP.id_permit
               Inner Join dbo.permit_terms      PT With (NoLock) On PT.id_permit = p.id
         Where ws.id = WLC.id_wellstring        -- this ties us back to the outer query
           And PD.[date] >= pt.Start_Date       -- this ties back to date on outer PD table
           And pd.[date] <= pt.end_date         -- this ties back to date on outer PD table
           And ws.deletedAt Is Null
           And wb.deletedAt Is Null
           And p.deletedAt Is Null
           And PT.deletedAt Is Null
             )                                  tt

 Where PD.deletedAt Is Null
   And WLC.deletedAt Is Null;

如前所述 - 删除 NOLOCK 提示,除非您确定您了解使用它的相关风险。

现在您可以添加许可证 (PT) table 所需的任何其他列,并根据这些值定义您的计算。这假设您将始终具有相关值并且只对显示那些实际具有值感兴趣。

如果您需要显示全部,即使没有井柱、井眼、许可证等...然后将交叉应用更改为外部应用,您将获得所有计算的 NULL 值。