【问题标题】:SQL Query Help - Joining Multiple Columns Based On Condition [duplicate]SQL 查询帮助 - 基于条件连接多个列 [重复]
【发布时间】:2011-10-07 19:10:11
【问题描述】:

可能重复:
SQL query help - have two where conditons in join condition

我有下表,其列如下。我已经提到了我需要的东西。我已经在这里SQL query help - have two where conditons in join condition 发布了一个链接,其中包含我一直在尝试但无法通过的链接。再次明确提出我的需要:

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 表来检查 id。

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

如果 T.Seller 或 T.Buyer 值以“C”开头(来自 CounterParty 表),则 C.PartyName 将具有该值,否则将为空。

通过上述查询,我​​在 Desk.Name、B.Name 中有空值,gettig C.PartyName 的逻辑也不起作用。


【问题讨论】:

  • 我在这里给出了另一个问题的链接。一旦我能够找到答案,我将在那里发布相同的内容并将两者联系起来。
  • 但您现在创建了同一问题的重复帖子。正如我所说,您应该使用更正的问题编辑您的原始帖子。
  • 根据您的数据样本,BuyerSeller 都可以是书籍。那么您的查询中的b.Name 将基于哪一个?
  • Book 必须先加入 t.desks,然后再加入 trade。 B.Name 将是基于买方和卖方的联合,然后将采用不同的方式。
  • @Mani: 你的意思是说同一个Trade 会在输出中出现两次,一次是Buyer 书名,一次是Seller 书名,然后是空的 ( NULL) CounterParty 名称两次?

标签: mysql sql sql-server sql-server-2008 linq-to-sql


【解决方案1】:

你可以这样做(未经测试):

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 子句中指定它..

【讨论】:

  • 我得到一个错误:当没有用 EXISTS 引入子查询时,选择列表中只能指定一个表达式。
  • BookId 和 CPId 是主键吗?另外,尝试删除 BuyerDeskName/SellerDeskName 子查询,结果是否相同?
  • 是的,史蒂夫他们是。我也尝试了另一个,似乎需要更多调整。我只是被困在 SQL 新手..
  • 你是什么意思它需要更多的调整?错误信息是否相同?您需要更具描述性,否则很难为您提供帮助!
  • 谢谢你。已使用更新查询编辑了帖子。但是某些值仍然存在问题。
【解决方案2】:

我可以想出几种方法来实现预期的结果,但因为首先要做的事情应该放在第一位,所以如果可能的话,我建议修改数据库设计。

所以,我可以解决以下 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。

【讨论】:

  • 感谢您的尝试。我在 SQL 中尝试这个。 Book 首先与交易台连接,然后生成的 Books 仅用于进一步连接。将尝试转换为 SQL 并查看它是否有效。
  • 请您知道这里的 LEFT 运算符是做什么的..
  • @Mani,LEFT JOIN 返回左表中的所有行(在此示例中为 Trade),并且仅匹配右表中的行(Book 或 CounterParty);对于右表中不匹配的行,它返回 NULL。这与 INNER JOIN 不同,后者只从左右表返回匹配的行。您可能想在此处阅读更多信息 - dev.mysql.com/doc/refman/5.0/en/join.html 在这个特定示例中,LEFT JOIN 更有意义,因为不知道是否总会有匹配的行集。
  • 谢谢。我的意思是第一个示例中的 LEFT 关键字。刚学,又是MYSQL的substring语法..
  • 啊哈!我没有意识到您指的是 LEFT() 函数。是的,它就像子字符串,但更简单直接
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
  • 1970-01-01
  • 2014-08-04
  • 2012-11-13
  • 2018-10-29
  • 2017-08-31
相关资源
最近更新 更多