2013-02-26 4 views
4

У меня есть запрос, как:Выберите несколько строк из SQL в одну строку в подзапроса

DECLARE @razem VARCHAR(MAX); 

SELECT Ordering.orderID , 
     Document.number, 
     (User_info.name +' '+ User_info.surname), 
     Ordering.dateStart, 
     Ordering.dateEnd , 
     (
      select COALESCE(' ',@razem)+sell_type.name as r 
      from Ordering_sell_type, Sell_type 
      where orderID = Ordering.orderID and 
        Ordering_sell_type.sell_typeID = sell_type.sell_typeID 
     ) podz 
FROM Ordering, User_info, Product_Document, Document, Document_type 
WHERE Ordering.orderID = Product_document.orderID 
     AND Document.documentID = Document_type.documentID 
     AND Document.documentID = Product_document.documentID 
     AND Ordering.userID = User_info.userID 
     AND Ordering.isClosed = 1 AND Document_type.typeID = 1 
GROUP BY Document.isitfiscal, Document.refDocID, 
      Document.number, Ordering.orderID, User_info.name, 
      User_info.surname, Ordering.dateStart, 
      Ordering.dateEnd , Ordering.isCLosed 
ORDER BY Ordering.dateEnd 

И в этой функции COALESCE Я хочу, чтобы получить все виды оплаты для выбранного заказа - например, идентификатор заказа 123 имеют payTypes = Card , Cash, orderID имеют payTypes = Cash.

Проблема заключается в том, что я хочу иметь его в одном просто грести в качестве последней строки основного запроса, как: OrderID, Document.number, UserInfo.name + фамилия, dateStart, dateEnd, -> карта, наличные деньги < - но после попытки запроса, как указано выше, я получил ошибку:

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. 

потому что он возвращает более одной строки. Возможно ли, получить типы оплаты в подзапросе и вернуть в виде одной строки?

+1

Какие СУБД вы используете? – sgeddes

+0

В оракуле: функции WM_CONCAT, LISTAGG или XMLAGG превратят несколько строк, которые поделились бы подобными данными в список. Coalese работает только по одной строке и не объединяет строки. [XMLpath] (http://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-microsoft-sql-server-2005) в SQL-сервере, я считаю, что подобные комбинации; Я думаю, что mySQL использует [Group_Concat] (http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html # function_group-concat) – xQbert

ответ

5

Основываясь на синтаксисе, который вы использовали, я предполагаю, что вы используете SQL-Server, и, таким образом, вы можете использовать расширение XML-серверов SQL для конкатенации строк.

SELECT Ordering.orderID, 
     Document.number, 
     [UserName] = User_info.name +' '+ User_info.surname, 
     Ordering.dateStart, 
     Ordering.dateEnd, 
     [podz] = STUFF(( SELECT DISTINCT ' ' + SellType.Name 
          FROM Ordering_Sell_Type 
            INNER JOIN Sell_Type 
             ON Sell_Type.sell_typeID = Ordering_Sell_Type.sell_typeID 
          WHERE Ordering.OrderID = Ordering_SellType.OrderId 
          FOR XML PATH(''), TYPE 
         ).value('.', 'NVARCHAR(MAX)'), 1, 1, '') 
FROM Ordering 
     INNER JOIN User_Info 
      ON Ordering.UserID = User_Info.UserID 
     INNER JOIN ProductDocument 
      ON Ordering.OrderID = Product_Document.OrderID 
     INNER JOIN Document 
      ON Document.DocumentID = Product_Document.DocumentID 
     INNER JOIN Document_Type 
      ON Document_Type.DocumentID = Document.DocumentID 
WHERE Ordering.IsClosed = 1 
AND  Document_Type.TypeID = 1 
ORDER BY Ordering.dateEnd; 

Примечание Я заменил все ваши ANSI 89 соединяется с ANSI 92, так как это более современный синтаксис, и generally accepted как более разборчивым вариант (я говорю в целом принято, как это, конечно, личных предпочтений и там также все еще есть случаи, когда Oracle оптимизирует соединения ANSI89 лучше).

EDIT

Просмотрев данные дубликаты из Product_Document таблицы, вы можете удалить их с помощью этого:

SELECT Ordering.orderID, 
     Document.number, 
     [UserName] = User_info.name +' '+ User_info.surname, 
     Ordering.dateStart, 
     Ordering.dateEnd, 
     [podz] = STUFF(( SELECT DISTINCT ' ' + SellType.Name 
          FROM Ordering_Sell_Type 
            INNER JOIN Sell_Type 
             ON Sell_Type.sell_typeID = Ordering_Sell_Type.sell_typeID 
          WHERE Ordering.OrderID = Ordering_SellType.OrderId 
          FOR XML PATH(''), TYPE 
         ).value('.', 'NVARCHAR(MAX)'), 1, 1, '') 
FROM Ordering 
     INNER JOIN User_Info 
      ON Ordering.UserID = User_Info.UserID 
     INNER JOIN 
     ( SELECT DISTINCT OrderID, DocumentID 
      FROM Product_Document 
     ) Product_Document 
      ON Ordering.OrderID = Product_Document.OrderID 
     INNER JOIN Document 
      ON Document.DocumentID = Product_Document.DocumentID 
     INNER JOIN Document_Type 
      ON Document_Type.DocumentID = Document.DocumentID 
WHERE Ordering.IsClosed = 1 
AND  Document_Type.TypeID = 1 
ORDER BY Ordering.dateEnd; 
+0

Если я не правильно догадался о СУБД, на это ответил еще один ряд методов [здесь] (http://stackoverflow.com/questions/10791247/ sql-server-possible-pivot-solution/10796492 # 10796492) – GarethD

+0

Где происходит дублирование, есть ли несколько документов на заказ, где тип документа равен 1? – GarethD

+0

Нет, для каждого заказа есть только один документ. Таким образом, заказы - это только порядок, когда он не закрыт. после того, как мы закрываем его (- порядок), он становится документом (и он появляется в таблице Document). – user13657

0

Этот SO товар/ответ делает хорошую работу по обсуждению разные подходы к свертыванию/объединению ряда рядов варчара в один столбец, например, вы говорите о https://stackoverflow.com/a/2410524/283895

0

Да. Но это зависит от используемой СУБД.

Чтобы создать список данных в одной строке, вы должны использовать аналитическую функцию, специфичную для РСУБД, используемую вами, или написать свою собственную конкретную функцию.

В oracle: функции WM_CONCAT, LISTAGG или XMLAGG превратят несколько строк, которые будут совместно использовать похожие данные в список.

Coalese работает только одна строка за раз и не объединяет ряды.

  • ORACLE: WM_CONCAT, LISTAGG, XMLAgg
  • SQL SERVER: XMLpath
  • My SQL: GROUP_CONCAT

Использование/Синтаксис изменяется. поэтому я предлагаю искать на этих условиях в зависимости от вашей РСУБД.

Смежные вопросы