2009-10-01 5 views
1

Я пытаюсь понять, как объединить запросы, когда один из них возвращает более одной записи.Консолидация запросов

Это отчет о выставлении счета, в котором я хочу вывести серийные номера выставленных счетов. Я сокращу сценарий как можно больше, чтобы уточнить. Вот мой сценарий перед добавлением серий:

SELECT ARM.fcustno AS [Cust No] 
,  ARM.fbcompany AS [Cust Name] 
,  ARM.fcinvoice AS [Invoice No] 
,  ARM.fdgldate AS [Post Date] 
,  ARI.fitem AS [Item No] 
,  ARI.fprodcl AS [Prod Class] 
,  ARI.fshipkey AS [Qty Invoiced] 
,  ARI.fpartno AS [Part No] 
,  ARI.frev AS [Part Rev] 
,  ARI.FTOTPRICE AS [Net Invoiced] 
,  ARM.fsono AS [Sales No] 
,  SOM.fcusrchr2 
FROM dbo.armast ARM 
INNER JOIN dbo.aritem ARI ON ARM.FCINVOICE = ARI.FCINVOICE 
INNER JOIN slcdpm SLC ON SLC.fcustno = ARM.fcustno 
LEFT OUTER JOIN slcdpm_ext SLCE ON SLC.identity_column = SLCE.fkey_id 
LEFT OUTER JOIN somast SOM ON SOM.fsono = ARM.fsono 

Это возвращает счета-фактуры, их цены и т. Д. Когда я втягиваю в следующее:

SELECT ARM.fcustno AS [Cust No] 
,  ARM.fbcompany AS [Cust Name] 
,  ARM.fcinvoice AS [Invoice No] 
,  ARM.fdgldate AS [Post Date] 
,  ARI.fitem AS [Item No] 
,  ARI.fprodcl AS [Prod Class] 
,  ARI.fshipkey AS [Qty Invoiced] 
,  ARI.fpartno AS [Part No] 
,  ARI.frev AS [Part Rev] 
,  ARI.FTOTPRICE AS [Net Invoiced] 
,  ARM.fsono AS [Sales No] 
,  SOM.fcusrchr2 
,  LOTC.fcuseinlot 
FROM dbo.armast ARM 
INNER JOIN dbo.aritem ARI ON ARM.FCINVOICE = ARI.FCINVOICE 
INNER JOIN slcdpm SLC ON SLC.fcustno = ARM.fcustno 
LEFT OUTER JOIN slcdpm_ext SLCE ON SLC.identity_column = SLCE.fkey_id 
LEFT OUTER JOIN somast SOM ON SOM.fsono = ARM.fsono 

--** New stuff below: ****** 
LEFT OUTER JOIN ShItem SHI ON SHI.fShipNo + SHI.fItemNo = ARI.fShipKey 
LEFT OUTER JOIN ShSrce ON ShSrce.fcShipNo = SHI.fShipNo 
         AND ShSrce.fcItemNo = SHI.fItemNo 
LEFT OUTER JOIN QaLotC LOTC ON LOTC.fcUseInDoc = ShSrce.fcShipNo + ShSrce.fcItemNo + ShSrce.fcSrcItmNo 

Проблема в том, что на счет-фактуру может быть несколько записей SHSRCE. Каков наилучший способ справиться с этим? Возможно, используйте подзапрос, чтобы объединить поле LOTC.fcuseinlot, чтобы вернуть одно соответствующее значение на запись.

Чтобы уточнить, дополнительный запрос возвращает более одной записи на каждую позицию, поскольку несколько частей серийного номера могут быть выставлены на счет одной позиции. В идеале я бы хотел, чтобы они были объединены как (NCC1701, R2D2, C3PO) и т. Д. Вот почему я подумал об использовании подзапроса для их конкатенации.

+1

Личное мнение: не будучи свободно с контекстом (ваша компания/проект), этот код трудно читать.Вы можете выиграть, изменив имена объектов на «MyTable» и «Col1, Col2» и удалив те части запроса (дополнительные столбцы, псевдонимы столбцов, дополнительные объединения), которые не являются основополагающими для вашей проблемы. –

+0

Я также предлагаю макет, как вы хотите получить результирующие данные - хотите ли вы повторять данные? –

+0

плюс вы не вернули никаких дополнительных полей в свой второй запрос, я полагаю, вы хотели? –

ответ

1

Все еще ждет ОП прояснить этот вопрос, но если несколько записей SHSRCE все еще относятся только к одному SerialNumber (который я предполагая находится в LOTC.fcuseinlot)

SELECT 
    ARM.fcustno AS [Cust No] , 
    ARM.fbcompany AS [Cust Name] , 
    ARM.fcinvoice AS [Invoice No] , 
    ARM.fdgldate AS [Post Date] , 
    ARI.fitem AS [Item No] , 
    ARI.fprodcl AS [Prod Class] , 
    ARI.fshipkey AS [Qty Invoiced] , 
    ARI.fpartno AS [Part No] , 
    ARI.frev AS [Part Rev] , 
    ARI.FTOTPRICE AS [Net Invoiced] , 
    ARM.fsono AS [Sales No] , 
    SOM.fcusrchr2, 
     MAX(LOTC.fcuseinlot) 
FROM 
    dbo.ARMAST ARM 
JOIN dbo.aritem ARI ON ARI.FCINVOICE = ARM.FCINVOICE 
JOIN slcdpm SLC ON SLC.fcustno = ARM.fcustno 
LEFT JOIN slcdpm_ext SLCE ON SLCE.fkey_id = SLC.identity_column 
LEFT JOIN somast SOM ON SOM.fsono = ARM.fsono 
LEFT JOIN ShItem SHI ON SHI.fShipNo + SHI.fItemNo = ARI.fShipKey 
LEFT JOIN ShSrce ON ShSrce.fcShipNo = SHI.fShipNo AND ShSrce.fcItemNo = SHI.fItemNo 
LEFT JOIN QaLotC LOTC ON LOTC.fcUseInDoc = ShSrce.fcShipNo + ShSrce.fcItemNo + ShSrce.fcSrcItmNo 
GROUP BY 
    ARM.fcustno , 
    ARM.fbcompany , 
    ARM.fcinvoice , 
    ARM.fdgldate , 
    ARI.fitem , 
    ARI.fprodcl , 
    ARI.fshipkey , 
    ARI.fpartno , 
    ARI.frev , 
    ARI.FTOTPRICE , 
    ARM.fsono , 
    SOM.fcusrchr2 

вы можете оставить некоторые примеры данных.

Если я получаю вас прямо, посмотрите на этот вид SQL

create table tableA (id int, ref varchar(50)) 

insert into tableA 
select 1, 3536757616 
union select 1, 3536757617 
union select 1, 3536757618 
union select 2, 3536757628 
union select 2, 3536757629 
union select 2, 3536757630 

Я знаю, что могу просто конкатенации рефов с помощью

SELECT distinct 
    id, 
    stuff ((SELECT 
        '/ ' + ref 
       FROM 
        tableA tableA_1 
       where tableA_1.id = tableA_2.id 
    FOR XML PATH ('')) , 1 , 2 , '') 
from TableA tableA_2 

дать

1 3536757616/ 3536757617/ 3536757618 
2 3536757628/ 3536757629/ 3536757630 
+0

Да, я уже говорил об этом, но это дает мне самый большой серийный номер, а не список из них. – DavidStein

+0

@David: Я отредактировал свой ответ, чтобы включить пример конкатенации данных, но если вы можете дать некоторые примеры данных ... –

0

Объединить запросы? Как и в случае UNION?

+0

Нет, объединение создаст дополнительные строки, которые я не хочу. Мне просто нужна конкатенация серийных номеров, возвращаемых на запись исходного запроса. – DavidStein

0

Что нам действительно нужно знать, какую основу вы собираетесь использовать, чтобы выбрать, какая из возможных записей имеет значения, которые вы используете? муравей вернулся? Это определит наилучшие возможности для вас.

И поскольку вы не добавляете никаких столбцов, и используете левые соединения (поэтому из объединений не будет исключено никаких записей), чего вы ожидаете достичь, добавив эти объединения, за исключением увеличения времени обработки?

0

У вас есть тэг SQL Server 2000 по вашему вопросу, поэтому я не уверен, что это будет возможно для вас. В SQL Server 2005 и выше вы можете создавать настраиваемые агрегированные функции. Я использую агрегатную функцию FormDelimitedString, которая делает именно то, что вы ищете.

Существует страница here, в которой описывается, как реализовать эту функцию - она ​​записывается как сборка .NET, а затем выполняется из ваших запросов. С этим на месте, ваш запрос будет ...

SELECT ARM.fcustno AS [Cust No] 
,  ARM.fbcompany AS [Cust Name] 
-- (a few fields skipped for brevity) 
,  SOM.fcusrchr2 
-- Aggregate function will combine multiple values into a single string - 'value1, value2, value3' etc 
, dbo.FormDelimitedString(LOTC.fcuseinlot) AS ConcatenatedValues 
FROM dbo.armast ARM 
INNER JOIN dbo.aritem ARI ON ARM.FCINVOICE = ARI.FCINVOICE 
INNER JOIN slcdpm SLC ON SLC.fcustno = ARM.fcustno 
LEFT OUTER JOIN slcdpm_ext SLCE ON SLC.identity_column = SLCE.fkey_id 
LEFT OUTER JOIN somast SOM ON SOM.fsono = ARM.fsono 
LEFT OUTER JOIN ShItem SHI ON SHI.fShipNo + SHI.fItemNo = ARI.fShipKey 
LEFT OUTER JOIN ShSrce ON ShSrce.fcShipNo = SHI.fShipNo 
         AND ShSrce.fcItemNo = SHI.fItemNo 
LEFT OUTER JOIN QaLotC LOTC ON LOTC.fcUseInDoc = ShSrce.fcShipNo + ShSrce.fcItemNo + ShSrce.fcSrcItmNo 

-- Group by clause needed as its an aggregate function 
GROUP BY ARM.fcustno, ARM.fbcompany, SOM.fcusrchr2 
Смежные вопросы