如何转换查询而不多次调用子查询?

问题描述 投票:0回答:1

我有这样的疑问:

SELECT
       t.[DataTran]
      ,t.[Dok]
      ,t.[Product]
      ,p.idxbox
      ,po.[Mark]
      ,po.[Model]
      ,(SELECT 
            TOP(1) [poz_La]
        FROM [RaportyAutko].[dbo].[G_API_Data]
        WHERE
            idxbox= p.idxbox 
            AND DATEDIFF(second,{d '1970-01-01'}, [dataandtime])  <  DATEDIFF(second,{d '1970-01-01'},t.[DataTran]) 
            AND  [distance]<>0
        ORDER BY dataandtime DESC) AS [poz_La]
      ,(SELECT 
            TOP(1) [poz_Lo]
        FROM [RaportyAutko].[dbo].[G_API_Data]
        WHERE
            idxbox= p.idxbox 
            AND DATEDIFF(second,{d '1970-01-01'}, [dataandtime])  <  DATEDIFF(second,{d '1970-01-01'},t.[DataTran]) 
            AND  [distance]<>0
        ORDER BY dataandtime DESC) AS [poz_Lo]
      ,(SELECT 
            TOP(1) [adress]
        FROM [RaportyAutko].[dbo].[G_API_Data]
        WHERE
            idxbox= p.idxbox 
            AND DATEDIFF(second,{d '1970-01-01'}, [dataandtime])  <  DATEDIFF(second,{d '1970-01-01'},t.[DataTran]) 
            AND  [distance]<>0
        ORDER BY dataandtime DESC) AS [adress]
      ,
        (SELECT 
            TOP(1) [dyst]
        FROM [RaportyAutko].[dbo].[G_API_Data]
        WHERE
            idxbox= p.idxbox 
            AND DATEDIFF(second,{d '1970-01-01'}, [dataandtime])  <  DATEDIFF(second,{d '1970-01-01'},t.[DataTran]) 
            AND  [distance]<>0
        ORDER BY dataandtime DESC) AS [dyst]
          ,
        (SELECT 
            TOP(1) Total
        FROM [RaportyAutko].[dbo].[G_API_Data]
        WHERE
            idxbox= p.idxbox 
            AND DATEDIFF(second,{d '1970-01-01'}, [dataandtime])  <  DATEDIFF(second,{d '1970-01-01'},t.[DataTran]) 
            AND  [distance]<>0
        ORDER BY dataandtime DESC) AS Total
  FROM [ReportsA].[dbo].[Tank] t
      LEFT JOIN [ReportsA].[dbo].[G_API_CARS] p ON t.[NumberRej] = p.[nrRej]
      LEFT JOIN [ReportsA].[dbo].[POJ] po ON t.[NumberRej] = po.[Nr rej]
  WHERE t.[NumberRej] IS NOT NULL

我不想多次调用子查询。转换查询的最佳方式是什么?我正在考虑创建一个临时表并插入列:poz_La、poz_Lo、adress、dist、子查询中的 Total:

CREATE TABLE [dbo].[GBOX_API_PRZEBIEG]
(
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [poz_La] [float] NULL,
    [poz_Lo] [float] NULL,
    [adress] [varchar](255) NULL
    [dist] [int] NULL,
    [Total] [bigint] NULL   
) ON [PRIMARY]
GO

INSERT INTO #tmpData
           ([poz_La]
           ,[poz_Lo]
           ,[adress] 
           ,[dist]
           ,[Total])
    (SELECT 
        TOP(1) 
        poz_La, poz_Lo, adress, dist, Total
    FROM [RaportyAutko].[dbo].[G_API_Data]
            WHERE
                idxbox= p.idxbox 
                AND DATEDIFF(second,{d '1970-01-01'}, [dataandtime])  <  DATEDIFF(second,{d '1970-01-01'},t.[DataTran]) 
                AND  [distance]<>0
            ORDER BY dataandtime DESC)

这是正确的方法吗?如何调用引用主过程的函数或其他过程?

sql sql-server t-sql stored-procedures
1个回答
3
投票

将查询移至

FROM
,然后您可以在那里使用“每组的前 1 个”。此方法使用
APPLY
能够使用相关子查询并返回表中的所有列
G_API_DATA
:

SELECT t.[DataTran],
       t.[Dok],
       t.[Product],
       p.idxbox,
       po.[Mark],
       po.[Model],
       D.[poz_La],
       D.[poz_Lo],
       D.[adress],
       D.[dyst],
       D.Total
FROM [ReportsA].[dbo].[Tank] t
    LEFT JOIN [ReportsA].[dbo].[G_API_CARS] p ON t.[NumberRej] = p.[nrRej] --"p" is for "cars"?
    LEFT JOIN [ReportsA].[dbo].[POJ] po ON t.[NumberRej] = po.[Nr rej]
    --OUTER APPLY as unsure if this should be a LEFT JOIN or not
    OUTER APPLY (SELECT TOP (1)
                        GAD.[poz_La],
                        GAD.[poz_Lo],
                        GAD.[adress],
                        GAD.[dyst],
                        GAD.Total
                 FROM [RaportyAutko].[dbo].[G_API_Data] GAD
                 WHERE GADidxbox = p.idxbox
                   AND DATEDIFF(SECOND, { D '1970-01-01' }, GAD.[dataandtime]) < DATEDIFF(SECOND, { D '1970-01-01' }, t.[DataTran]) --This isn't SARgable, so may perform poorly
                   AND GAD.[distance] <> 0
                 ORDER BY GAD.dataandtime DESC) D
WHERE t.[NumberRej] IS NOT NULL;

© www.soinside.com 2019 - 2024. All rights reserved.