Первый матч только на одном поле - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть отчет activulsoft, в котором я хочу получить первую запись актива, которая прикреплена только к рабочему заданию. Мой источник данных состоит из трех разных объединений, поэтому я стараюсь избегать использования дополнительного выбора. Я попытался использовать TOP, MIN и DISTINCT в первоначальном операторе select, но ни один из них не работает. Есть ли другой способ добиться этого?

Ниже мой запрос. Поле, в котором мы хотим вернуть первое совпадение, - это woa.AssetID

select 
wo.[EndDate],
wo.[WorkOrderID],
wo.[ID],
woa.[AssetID],
trm.*
from 
[reports].[WorkOrders] wo
Left Join [reports].[InventoryTransactions] invt On wo.[ID]=invt.[WorkOrderID]  
Left Join [reports].[WorkOrderAssets] woa On woa.[ID]=wo.[ID]
Join [reports].[WorkOrderForm_TrafficLightingRepairMaintenance] trm On trm.ID = wo.ID 
where
wo.[DepartmentName]='TPW Traffic' 
and wo.[StatusName]='Closed' 
and ((invt.[Name] like '%LED%' OR invt.[Name] like '%led%') 
and (invt.[Name] like '%Head%' OR invt.[Name] like '%head%' 
OR invt.[Name] like '%LAMP%' OR invt.[Name] like '%lamp%'))
and (cast(wo.[EndDate] as date) between @from and @to)

1 Ответ

0 голосов
/ 16 апреля 2020

Если я правильно понимаю, вы получаете слишком много строк из-за объединения с WorkOrderAssets, и вы хотите, чтобы это объединение возвратило не более одной строки ресурса (только первую).

Одна из лучших Способы решения этой проблемы - использование оконной функции для таблицы, которая возвращает больше строк, чем вы хотите. Я не знаю, какую базу данных вы используете, но для SQL Server измененный запрос будет выглядеть так:

select
wo.[EndDate],
wo.[WorkOrderID],
wo.[ID],
woa.[AssetID],
trm.*
from 
[reports].[WorkOrders] wo
Left Join [reports].[InventoryTransactions] invt On wo.[ID]=invt.[WorkOrderID]  

Left Join 
    (select
        [ID],
        [AssetID],
        row_number() over (partition by ID order by AssetID) as RowNumber
    from [reports].[WorkOrderAssets] 
    ) woa On woa.[ID]=wo.[ID] and RowNumber = 1

Join [reports].[WorkOrderForm_TrafficLightingRepairMaintenance] trm On trm.ID = wo.ID 
where
wo.[DepartmentName]='TPW Traffic' 
and wo.[StatusName]='Closed' 
and ((invt.[Name] like '%LED%' OR invt.[Name] like '%led%') 
and (invt.[Name] like '%Head%' OR invt.[Name] like '%head%' 
OR invt.[Name] like '%LAMP%' OR invt.[Name] like '%lamp%'))
and (cast(wo.[EndDate] as date) between @from and @to)
...