Не уверен, как идти о соединении этих двух таблиц - PullRequest
2 голосов
/ 26 июля 2010

Мне было трудно придумать заголовок для этого вопроса, потому что я не совсем уверен, как делать то, что я хочу, поэтому я не уверен, является ли «объединение» лучшей терминологией в этом случае.

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

Таблица планов

Plankey  ass1 ass2 ass3 ass4
aplan    0    6    5    7
bplan    2    0    7    4

Таблица допущений

assType refKey assName
"ass1"  0      "gender factors a"
"ass1"  2      "gender factors b"
"ass2"  0      "age factors a"
"ass2"  6      "age factors b"
"ass3"  5      "inflation factors a"
"ass3"  7      "inflation factors b"
"ass4"  4      "tax factors a"
"ass4"  7      "tax factors b"

Мне нужно сделать запрос (или набор запросов и подзапросов), который дает мне названия предположений, используемых для каждого плана:

Plankey  assName1           assName2         assName3               assName4
aplan    "gender factors a" "age factors b"  "inflation factors a"  "tax factors b"
bplan    "gender factors b" "age factors a"  "inflation factors b"  "tax factors a"

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

Я должен также упомянуть, что существует более 500 типов предположений (ass1, ass2, ..., ass500 и т. Д.), И каждый тип может иметь более 100 предположений refKey / Names на тип предположения.

Я пытаюсь обернуть голову вокруг этого, и это кажется легким, но я просто не могу понять, как это сделать. Есть идеи? Может быть, я пропускаю концепцию, потому что просто еще не сталкивался с ней. Я в порядке с жестким кодированием имен столбцов assName1, assName2 и т. Д. В моем запросе, но даже тогда я не уверен, как «искать» assNames из таблицы предположений, когда мне кажется, что я смотрю из одной и той же таблицы для нескольких столбцы в моем результате.

РЕДАКТИРОВАТЬ: я пропустил что-то действительно важное. refkey повторно используется в таблице предположений. Таким образом, assName однозначно определяется комбинацией assType и refKey. Я прошу прощения за то, что не разъяснил это в моем примере! Я забыл об этом, пока не посмотрел на ответы. Я изменил свой пример, чтобы отразить это также.

EDIT2: я использую MS SQL Server.

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

Ответы [ 5 ]

6 голосов
/ 26 июля 2010

Вы должны присоединиться к таблице ASSUMPTIONS для каждого столбца ass# в таблице PLANS:

   SELECT p.plankey,
          a1.assname,
          a2.assname,
          a3.assname,
          a4.assname
     FROM PLANS p
LEFT JOIN ASSUMPTIONS a1 ON a1.refkey = p.ass1
                        AND a1.asstype = 'ass1'
LEFT JOIN ASSUMPTIONS a2 ON a2.refkey = p.ass2
                        AND a2.asstype = 'ass2'
LEFT JOIN ASSUMPTIONS a3 ON a3.refkey = p.ass3
                        AND a3.asstype = 'ass3'
LEFT JOIN ASSUMPTIONS a4 ON a4.refkey = p.ass4
                        AND a4.asstype = 'ass4'

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

1 голос
/ 26 июля 2010

Вы можете попробовать нормализовать таблицу планов как встроенный запрос, а затем присоединиться к нему. Я не знаю, что будет хуже - 500 союзов или 500 объединений.

SELECT
    SQ.Plankey,
    A.assName
FROM
(

    SELECT Plankey, ass1 AS assRefKey, 'ass1' AS assType FROM Plans WHERE ass1 IS NOT NULL UNION ALL
    SELECT Plankey, ass2, 'ass2' AS assType FROM Plans WHERE ass2 IS NOT NULL UNION ALL
    ...
    SELECT Plankey, ass500, 'ass500' AS assType FROM Plans WHERE ass500 IS NOT NULL
) SQ
INNER JOIN Assumptions A ON
    A.refKey = SQ.assRefKey AND
    A.assType = SQ.assType

Набор результатов будет не в том формате, который вы запрашивали, но он может быть лучше для некоторых видов использования данных. В любом случае, это один уродливый дизайн базы данных. Можно подумать, что к тому времени, когда они дойдут до ass100, они поймут, что могут что-то делать не так.

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

1 голос
/ 26 июля 2010

Лучший способ справиться с этим - превратить столбцы assName * в строки в подзапросе или в представление второй таблицы.

Если вы используете SQL Server, вы можете использовать UNPIVOT для этого. Я не уверен, какие другие СУБД поддерживают UNPIVOT, поэтому дайте нам знать, какую вы используете. Если вы используете SQL Server, я приведу пример.

http://msdn.microsoft.com/en-us/library/ms177410.aspx

UPDATE:

Вот запрос, который преобразует таблицу «Планы» в форму, к которой легко присоединиться. Тем не менее, Я упустил из виду тот факт, что желаемый результат по-прежнему «разворачивается», поэтому он будет бесполезен, если вы не сможете принять результаты запроса в более «нормализованной» форме. поворотный результат, другие предложения намного лучше.

Вот запрос в любом случае, для всех, кто заинтересован:

SELECT [PVT].[PlanKey], [PVT].[RefKey], [PVT].[Ass]
FROM   [Plans] [P]
       UNPIVOT
       ([RefKey] FOR [Ass] IN ([ass1], [ass2], [ass3], [ass4])) [PVT]

Извиняюсь, если это бесполезно - моя ошибка.

1 голос
/ 26 июля 2010

Это было бы довольно просто в языке программирования.Вы прочитали бы всю таблицу Предположений, а затем прочитали таблицу Планов, подставив assName для четырех refKeys в каждой строке Планов.

У OMG Ponies самый популярный ответ SQL в то время, когда я редактировал этот ответ.

1 голос
/ 26 июля 2010
SELECT p.PlanKey, a1.name, a2.name, a3.name, a4.name
FROM Plans AS p
LEFT JOIN Assumptions AS a1 ON p.ass1 = a1.refKey
LEFT JOIN Assumptions AS a2 ON p.ass2 = a2.refKey
LEFT JOIN Assumptions AS a3 ON p.ass3 = a3.refKey
LEFT JOIN Assumptions AS a4 ON p.ass4 = a4.refKey
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...