Отображение результатов запроса по горизонтали - PullRequest
0 голосов
/ 02 июня 2010

Мне интересно, можно ли взять результаты запроса и вернуть их в виде строки CSV, а не в виде столбца ячеек.

По сути, у нас есть таблица с именем Customers, и у нас есть таблица с именем CustomerTypeLines, и у каждого Customer может быть несколько CustomerTypeLines. Когда я запускаю запрос к нему, я сталкиваюсь с проблемами, когда хочу проверить несколько типов, например:

    Select * 
      from Customers a 
Inner Join CustomerTypeLines b on a.CustomerID = b.CustomerID 
     where b.CustomerTypeID = 14 and b.CustomerTypeID = 66

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

Чтобы заставить его работать, мне пришлось добавить в Customer поле с именем CustomerTypes, которое выглядит как ,14,66,67,, чтобы я мог сделать Where a.CustomerTypes like '%,14,%' and a.CustomerTypes like '%,66,%', который возвращает 85 строк.

Конечно, это проблема, потому что мне приходится заставлять мою программу перестраивать это поле для этого клиента каждый раз, когда изменяется таблица CustomerTypeLines.

Было бы неплохо, если бы я мог выполнить подзапрос в моем месте, который бы работал для меня, поэтому вместо того, чтобы возвращать результаты вроде:

14
66
67

он вернул бы их как ,14,66,67,

Возможно ли это?

Ответы [ 5 ]

2 голосов
/ 02 июня 2010

Чтобы сделать это без денормализации, вы можете использовать что-то вроде следующего, чтобы получить таблицу всех клиентов, соответствующих всем значениям в предложении IN, к которым вы затем можете присоединиться.

SELECT CustomerId 
FROM CustomerTypes
WHERE CustomerTypeID in (14, 66)
GROUP BY CustomerId
HAVING COUNT(DISTINCT CustomerTypeID) = 2

На самом деле вы говорите в своем вопросе, что у вас уже есть запрос, который возвращает результаты, такие как:

14
66
67

Это правильный формат уже для следующей техники реляционного деления .

SELECT * 
FROM Customers c
    WHERE NOT EXISTS
    (
        SELECT * FROM @YourQuery y
        WHERE NOT EXISTS
            (
            SELECT * FROM CustomerTypeLines ctl
            WHERE ctl.CustomerTypeID = y.CustomerTypeID
            AND c.CustomerID = ctl.CustomerID
            )
        )
1 голос
/ 02 июня 2010

Вы столкнетесь с различными проблемами, выполнив запрос LIKE в списке, разделенном запятыми. Я знаю, я был там.

Например, если вы ищете '%,14,%', что произойдет, если 14 является первым или последним элементом в списке? (Я понимаю, что вы задаете дополнительные начальные и конечные запятые, но метод COALESCE не предоставляет их.)

Как насчет этого:

Select * from Customers a 
Inner Join CustomerTypeLines b 
on a.CustomerID = b.CustomerID 
WHERE a.CustomerID in 
    (SELECT customerID from CustomerTypeLines
     WHERE CustomerTypeID = 14)
AND a.CustomerID in
    (SELECT customerID from CustomerTypeLines
     WHERE CustomerTypeID in 66)

Отредактировано для исправления чрезмерного чтения вопроса!

1 голос
/ 02 июня 2010

Если вы хотите получить всех клиентов, у которых есть и 14, и 66, то вы можете использовать:

SELECT
    C.CustomerID,
    C.SomeColumn
FROM
    Customers C
WHERE
    EXISTS (SELECT * FROM CustomerTypes CT1 WHERE CT1.CustomerID = C.CustomerID AND CT1.CustomerTypeID = 14) AND
    EXISTS (SELECT * FROM CustomerTypes CT2 WHERE CT2.CustomerID = C.CustomerID AND CT2.CustomerTypeID = 66)

Более общее решение (получение клиентов на основе любого количества идентификаторов типов клиентов будет зависеть от того, как вы передаете эти идентификаторы в SQL (например, как параметр таблицы в хранимую процедуру).

1 голос
/ 02 июня 2010

Я полагаю, что техника, которую вы ищете, будет использовать функцию COALESCE. Смотри http://www.4guysfromrolla.com/webtech/092105-1.shtml.

0 голосов
/ 02 июня 2010

Это боль, потому что вы сделали это неправильно.

Поскольку у клиентов есть отношение один-ко-многим с CustomerType, вам следует создать другую таблицу для хранения этих значений вместо того, чтобы заклинивать все эти значения в одном поле. Таким образом, вы можете делать запросы к этим значениям намного проще и быстрее.

Затем вы можете использовать предложение FOR XML PATH для разделения записей запятыми http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=createacommadelimitedlist

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...