【问题标题】:SQL Select multiple rows into one displayed rowSQL 选择多行到一个显示的行
【发布时间】:2012-06-27 03:14:59
【问题描述】:

我的情况是我有两张桌子。我想将它们连接在一起并让重复的记录出现在同一行。下面给出的模拟表结构

主表 列:MKey1,MKey2,MData1,MData2,MData3

补充表 列:SPrimaryKey,SKey1,SKey2,SData1,SData2

我想将 MainTbl 左连接到 SuppTbl。但是,SuppTbl 包含重复的 SKey1 和 SKey2 组合键。

我想要的结果如下,其中“-#”表示重复数。

MKey1,MKey2,MData1,MData2,MData3,SData1-1,SData2-1,SData1-2,SData2-2

本质上,连接中的所有字段都应包含在基于 Key1 和 Key2 的一行中。

肖恩·W 的尝试回答

SELECT
    MainTbl.MKey1,
     MainTbl.MKey2,
    tcd.SData1 AS SData11,  
    tcd.SData2 AS SData22,
    tcr.SData1 AS SData12,  
    tcr.SData2 AS SData22
FROM MainTbl
LEFT JOIN SuppTbl tcd
ON MainTbl.MKey1=tcd.SKey1 AND MainTbl.MKey2=tcd.SKey2
LEFT JOIN SuppTbl tcr
ON MainTbl.MKey1=tcr.SKey1 AND MainTbl.MKey2=tcr.SKey2
WHERE tcd.SData1 < tcr.SData1

结果没有成功。没有提取任何记录。

【问题讨论】:

  • Table2 最多有两个匹配项吗?
  • @tony 不一定。它可能有一个或两个。如果它有更多,这是一种罕见的情况,但有可能。我确实有条件可以将其限制为两个。 “WHERE DataD1 = 4”和“WHERE DataD1=22”
  • 您使用的是什么风格的 SQL?
  • 充其量,您会得到一些未填充列的行,其中只有 1 个连接。没事?然后只需对第二个表执行 2 个左连接并返回结果。
  • 您的列和样本数据不匹配,并且您的 where 条件(在注释中)将返回样本数据的零记录。再加上 500 多个没有换行符的字符,阅读起来非常困难,并且会给想要帮助您的人带来障碍。

标签: sql sql-server tsql row


【解决方案1】:

修订(之后的cmets):

CREATE TABLE MainTbl (MKey1 int,MKey2 int,MData1 varchar(10),MData2 varchar(10),MData3 varchar(10))
CREATE TABLE SuppTbl (SPrimaryKey int,SKey1 int,SKey2 int,SData1 varchar(10),SData2 varchar(10))

INSERT INTO MainTbl VALUES (1, 1, '1MData1', '1MData2', '1MData3')
INSERT INTO SuppTbl VALUES (1, 1, 1, '1SData1-1', '1SData2-1')
INSERT INTO SuppTbl VALUES (2, 1, 1, '1SData1-2', '1SData2-2')

INSERT INTO MainTbl VALUES (1, 2, '2MData1', '2MData2', '2MData3')
INSERT INTO SuppTbl VALUES (3, 1, 2, '2SData1-1', '2SData2-1')

SELECT
    MainTbl.MKey1,
    MainTbl.MKey2,
    tcd.SData1 AS SData11,  
    tcd.SData2 AS SData22,
    tcr.SData1 AS SData12,  
    tcr.SData2 AS SData22
FROM MainTbl
INNER JOIN SuppTbl tcd
ON MainTbl.MKey1=tcd.SKey1 AND MainTbl.MKey2=tcd.SKey2
LEFT JOIN SuppTbl tcr
ON MainTbl.MKey1=tcr.SKey1 AND MainTbl.MKey2=tcr.SKey2
AND tcd.SPrimaryKey < tcr.SPrimaryKey

现在,对于那些在 SuppTbl 中有 2 行的实例,这不会 100% 起作用:它会给出两个结果行 - 一个很好,另一个你想排除。要排除它,您必须提供一些有关如何识别将具有 >1 SuppTbl 行的实例的更多信息。您在上面的 cmets“WHERE Data1 = 4”中提到过。所以这需要成为 WHERE 子句的一部分。它会是这样的:

 WHERE tcd.SData1 = 4

这可能会排除单个 SuppTbl 行。因此,您需要提供有关如何不过滤掉该行的信息。也许:

 WHERE tcd.SData1 IN (4, 22)

(这不适用于上面表格中的数据)。

【讨论】:

  • 我试过你的答案(上面发布的尝试),但没有记录被提取。也许是假设之一?哪些信息可以帮助您更好地了解我的结构?
  • 回顾您的答案,实际上这就是我从最终解决方案中获得很多方向的地方。抱歉,如果我没有在应得的地方给予信任。
【解决方案2】:

找到了答案。为简单起见,我将其稍微精简了一点,但只要有可以应用的 WHERE 条件,它就可以很好地工作,就像我的情况一样。

SELECT 
    MainTbl.MKey1,
    MainTbl.MKey2,
    tcd.stat AS SData11,
    tcr.stat AS SData12
FROM MainTbl
LEFT JOIN(
    SELECT * FROM SuppTbl WHERE SData1 <> 22
) tcd
ON MainTbl.MKey1=tcd.SKey1 AND MainTbl.MKey2=tcd.SKey2
LEFT JOIN(
    SELECT * FROM SuppTbl WHERE SData1 = 22
) tcr
ON MainTbl.MKey1=tcr.SKey1 AND MainTbl.MKey2=tcr.SKey2

【讨论】:

  • 您确实应该提供更多关于 SData1 存储什么以及这将如何影响行的选择的信息。
  • 22 是从哪里突然冒出来的?!
  • @whytheq 22 是对 Tony 在 OP 的 cmets 中提出的问题的回答。
  • @SeanW 我描述了我正在尝试的内容以便获得方向。给我的方向和被问到的问题使我得到了这个答案。在 OP 的 cmets 中询问并回答了有关 SData1 持有什么的信息。如果你问,我很乐意给你更多的信息。感谢您查看内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-30
  • 1970-01-01
  • 2019-12-06
相关资源
最近更新 更多