Справка по SQL-запросу — объединение нескольких столбцов на основе условия

Возможный дубликат:
Справка по SQL-запросу — два условия where в условии соединения

У меня есть следующие таблицы со столбцами, как показано ниже. Я упомянул, что мне нужно от этого. Я уже разместил здесь ссылку справка по SQL-запросу - есть два условия соединения в условии соединения с тем, что я пытался, но не могу получить это через. Еще раз полагая это прямо с тем, что мне нужно:

Book
BookId, BookName

Desk
DeskId, BookId ,DeskName

CounterParty
CPId, CpName

Trade
TradeId, Buyer, Seller

Вот как будут выглядеть данные о покупателе и продавце:

Buyer Seller
B3232  B323
C32    B222
B323   C323

Основываясь на начальном символе B или C в этих двух столбцах, мне нужно присоединиться к таблице Book или CP, чтобы проверить идентификаторы.

I need **t.TradingDeskName, b.BookName, c.CpName, t.Buyer, t.Seller.**

Любая помощь очень ценится.

Спасибо, мани

p.s: я пытаюсь сделать это через SQL или Linq to Sql.


Недавний запрос, но есть еще что исправить:

SELECT DISTINCT desk.Name as TradingDeskName, b.Name as Book, t.Seller, t.Buyer, c.PartyName, FROM TradingDesk AS desk 

 RIGHT JOIN Book as b
    ON  b.TradingDeskId = d.Id
 RIGHT JOIN Trade as t  
    ON LEFT(t.Buyer, 1) = 'B' AND SUBSTRING(t.Buyer, 2, len(t.Buyer)) = b.Id
 LEFT JOIN Book as b1 
    ON LEFT(t.Seller, 1) = 'B' AND SUBSTRING(t.Seller, 2, len(t.Seller)) = b1.Id 
 LEFT JOIN CounterParty as c 
    ON LEFT(t.Buyer, 1) = 'C' AND SUBSTRING(t.Buyer, 2, len(t.Buyer)) = c.PartyId 
 LEFT JOIN CounterParty as c1 
    ON LEFT(t.Seller, 1) = 'C' AND SUBSTRING(t.Seller, 2, len(t.Seller)) = c1.PartyId

Как я уже упоминал, мне нужно: Desk.Name - B.Name - T.Seller - T.Buyer- C.PartyName

C.PartyName будет иметь значение, если значение T.Seller или T.Buyer начинается с «C» (из таблицы CounterParty), в противном случае оно будет нулевым.

С приведенным выше запросом у меня есть нулевые значения, поступающие в Desk.Name, B.Name, и логика gettig C.PartyName также не работает.



person Everything Matters    schedule 18.07.2011    source источник
comment
Я дал ссылку здесь для другого вопроса. Как только я смогу найти ответ, я опубликую его там и свяжу два.   -  person Everything Matters    schedule 18.07.2011
comment
но теперь вы создали дубликат сообщения с тем же вопросом. Как я уже сказал, вы должны отредактировать исходный пост с исправленным вопросом.   -  person Taryn    schedule 18.07.2011
comment
Согласно вашему образцу данных, и Buyer, и Seller могут быть книгами. На каком из них будет основываться b.Name в вашем запросе?   -  person Andriy M    schedule 19.07.2011
comment
Книга должна быть объединена с t.desks, а затем объединена с торговлей. B.Name будет союзом, основанным на покупателе и продавце, а затем будут взяты отдельные из них.   -  person Everything Matters    schedule 19.07.2011
comment
@Mani: Вы имеете в виду, что один и тот же Trade будет представлен в выводе дважды, один раз с именем книги Buyer и один раз с именем книги Seller, и оба раза с пустым (NULL) именем CounterParty?   -  person Andriy M    schedule 19.07.2011


Ответы (2)


Вы можете сделать это примерно так (не проверено):

select 
  t.Buyer, 
  t.Seller, 
  case when t.Buyer like 'B%' THEN (select BookName from Book where BookId = t.Buyer)
                              ELSE (select CpName from Counterparty where CPId = t.Buyer)
  end BuyerName,
  case when t.Buyer like 'B%' THEN (select DeskName from Desk where BookId = t.Buyer)
                              ELSE NULL
  end BuyerDeskName,
  case when t.Seller like 'B%' THEN (select BookName from Book where BookId = t.Seller)
                               ELSE (select CpName from Counterparty where CPId = t.Seller)
  end SellerName,
  case when t.Seller like 'B%' THEN (select DeskName from Desk where BookId = t.Seller)
                               ELSE NULL
  end SellerDeskName,
from 
  Trade t

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

person StevieG    schedule 18.07.2011
comment
Я получаю сообщение об ошибке: в списке выбора может быть указано только одно выражение, если подзапрос не введен с помощью EXISTS. - person Everything Matters; 18.07.2011
comment
являются первичными ключами BookId и CPId? Кроме того, попробуйте удалить подзапросы BuyerDeskName/SellerDeskName, даст ли это тот же результат? - person StevieG; 18.07.2011
comment
Да Стив они. Я пробовал и другой, кажется, он нуждается в дополнительной настройке. Я просто застрял, будучи новичком в SQL. - person Everything Matters; 19.07.2011
comment
Что вы имеете в виду, что он нуждается в дополнительной настройке ?? Сообщение об ошибке такое же? Вы должны быть более описательными или это очень трудно вам помочь! - person StevieG; 19.07.2011
comment
Спасибо. Отредактировал сообщение с запросом на обновление. Но все же проблема сохраняется для некоторых значений. - person Everything Matters; 19.07.2011

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

Итак, вот 2 запроса, которые я мог бы решить:

Запрос 1

SELECT `t`.*,
(CASE 
    WHEN LEFT(`t`.`Buyer`, 1) = 'B' THEN
        (SELECT `b`.`BookName`
         FROM `Book` `b`
         WHERE `b`.`BookId` = SUBSTRING(`t`.`Buyer`, 2))
    ELSE (SELECT `c`.`CPName`
          FROM `CounterParty` `c`
          WHERE `c`.`CPId` = SUBSTRING(`t`.`Buyer`, 2))
END) AS `buyer_name`,
(CASE
    WHEN LEFT(`t`.`Seller`, 1) = 'B' THEN
        (SELECT `b`.`BookName`
         FROM `Book` `b`
         WHERE `b`.`BookId` = SUBSTRING(`t`.`Seller`, 2))
    ELSE (SELECT `c`.`CPName`
          FROM `CounterParty` `c`
          WHERE `c`.`CPId` = SUBSTRING(`t`.`Seller`, 2))
END) AS `seller_name`
FROM `Trade` `t`

Запрос 2

SELECT *
FROM `Trade` `t`
LEFT JOIN `Book` `b` ON LEFT(`t`.`Buyer`, 1) = 'B' AND SUBSTRING(`t`.`Buyer`, 2) = `b`.`BookId`
LEFT JOIN `Book` `b1` ON LEFT(`t`.`Seller`, 1) = 'B' AND SUBSTRING(`t`.`Seller`, 2) = `b1`.`BookId`
LEFT JOIN `CounterParty` `c` ON LEFT(`t`.`Buyer`, 1) = 'C' AND SUBSTRING(`t`.`Buyer`, 2) = `c`.`CPId`
LEFT JOIN `CounterParty` `c1` ON LEFT(`t`.`Seller`, 1) = 'C' AND SUBSTRING(`t`.`Seller`, 2) = `c1`.`CPId`;

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

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

Обратите внимание, что предлагаемые запросы находятся в MySQL. Не очень понятно, какую систему вы используете - вы упомянули в своем посте, что пытаетесь использовать SQL или Linq SQL, а в тегах вы упомянули все + MySQL.

person Abhay    schedule 18.07.2011
comment
Спасибо за попытку. Я пытаюсь это сделать в SQL. Книга сначала соединяется с торговой площадкой, а затем полученные Книги используются только для дальнейших соединений. Попробую преобразовать в SQL и посмотреть, работает ли он. - person Everything Matters; 18.07.2011
comment
Не могли бы вы, пожалуйста, узнать, что здесь делает ЛЕВЫЙ оператор .. - person Everything Matters; 18.07.2011
comment
@Mani, LEFT JOIN возвращает все строки из левой таблицы (Trade в этом примере) и только совпадающие строки из правой таблицы (Book или CounterParty); для несовпадающих строк в правой таблице возвращается NULL. Это отличается от INNER JOIN, когда из левой и правой таблиц возвращаются только совпадающие строки. Вы можете прочитать больше здесь - dev.mysql.com/doc/ refman/5.0/en/join.html В этом конкретном примере ЛЕВОЕ СОЕДИНЕНИЕ имеет больше смысла, потому что неизвестно, всегда ли будет соответствующий набор строк. - person Abhay; 18.07.2011
comment
Спасибо. Я имел в виду ЛЕВОЕ ключевое слово в первом примере. Только что узнал, это снова синтаксис MYSQL для подстроки. - person Everything Matters; 19.07.2011
comment
Ага! Я не знал, что вы имеете в виду функцию LEFT(). Да, это похоже на подстроку, но немного проще и прямее. - person Abhay; 19.07.2011
comment
Пока спасибо Абхай. Я отредактировал, чтобы поставить обновленный запрос, который я взял у вас. Но все же это не дает ценности в пути, мне бы это понравилось. Любая помощь с обновленным форматом будет очень полезна. - person Everything Matters; 19.07.2011