SQL-如果其他联接为空,则从联接获取数据

SQL-如果其他联接为空,则从联接获取数据,sql,join,group-by,union,distinct,Sql,Join,Group By,Union,Distinct,我已经尝试了很多解决方案,但还没有找到一个合适的。感谢您的帮助。我正在使用SQL Server 我有一些这样的表格: 汽车 +-------+-----------------+-----------------+ | CarId | CarImage | CarVideo | +-------+-----------------+-----------------+ | 1 | http://imageurl | http://videourl | |

我已经尝试了很多解决方案,但还没有找到一个合适的。感谢您的帮助。我正在使用SQL Server

我有一些这样的表格:

汽车

+-------+-----------------+-----------------+
| CarId |    CarImage     |    CarVideo     |
+-------+-----------------+-----------------+
|     1 | http://imageurl | http://videourl |
|     2 | http://imageurl | http://videourl |
|     3 | http://imageurl | http://videourl |
|     4 | http://imageurl | http://videourl |
+-------+-----------------+-----------------+
+----+-------+---------+------------+
| Id | CarId | CarName | LanguageId |
+----+-------+---------+------------+
|  1 |     1 | Car 1   |          1 |
|  2 |     1 | Bil 1   |          2 |
|  3 |     2 | Car 2   |          1 |
|  4 |     2 | Bil 2   |          2 |
|  5 |     3 | Car 3   |          1 |
|  6 |     3 | Bil 3   |          2 |
|  7 |     4 | Car 4   |          1 |
|  8 |     4 | Bil 4   |          2 |
+----+-------+---------+------------+
+--------+--------+-------+---------------------+---------------------+
| NickId | UserId | CarId |      CarImage       |      CarVideo       |
+--------+--------+-------+---------------------+---------------------+
|      1 |      1 |     1 |                     |                     |
|      2 |      1 |     2 | http://NEW-imageurl |                     |
|      3 |      1 |     3 |                     | http://NEW-videourl |
|      4 |      2 |     1 |                     | http://NEW-videourl |
+--------+--------+-------+---------------------+---------------------+
+----+--------+--------------+------------+
| Id | NickId |   CarName    | LanguageId |
+----+--------+--------------+------------+
|  1 |      1 | Nickname 1   |          1 |
|  2 |      1 | Nicknavn 1   |          2 |
|  3 |      4 | Nickname 1-2 |          1 |
|  4 |      4 | Nicknavn 1-2 |          2 |
|  5 |      2 | Nickname 2   |          1 |
|  6 |      2 | Nicknavn 2   |          2 |
+----+--------+--------------+------------+
汽车名称

+-------+-----------------+-----------------+
| CarId |    CarImage     |    CarVideo     |
+-------+-----------------+-----------------+
|     1 | http://imageurl | http://videourl |
|     2 | http://imageurl | http://videourl |
|     3 | http://imageurl | http://videourl |
|     4 | http://imageurl | http://videourl |
+-------+-----------------+-----------------+
+----+-------+---------+------------+
| Id | CarId | CarName | LanguageId |
+----+-------+---------+------------+
|  1 |     1 | Car 1   |          1 |
|  2 |     1 | Bil 1   |          2 |
|  3 |     2 | Car 2   |          1 |
|  4 |     2 | Bil 2   |          2 |
|  5 |     3 | Car 3   |          1 |
|  6 |     3 | Bil 3   |          2 |
|  7 |     4 | Car 4   |          1 |
|  8 |     4 | Bil 4   |          2 |
+----+-------+---------+------------+
+--------+--------+-------+---------------------+---------------------+
| NickId | UserId | CarId |      CarImage       |      CarVideo       |
+--------+--------+-------+---------------------+---------------------+
|      1 |      1 |     1 |                     |                     |
|      2 |      1 |     2 | http://NEW-imageurl |                     |
|      3 |      1 |     3 |                     | http://NEW-videourl |
|      4 |      2 |     1 |                     | http://NEW-videourl |
+--------+--------+-------+---------------------+---------------------+
+----+--------+--------------+------------+
| Id | NickId |   CarName    | LanguageId |
+----+--------+--------------+------------+
|  1 |      1 | Nickname 1   |          1 |
|  2 |      1 | Nicknavn 1   |          2 |
|  3 |      4 | Nickname 1-2 |          1 |
|  4 |      4 | Nicknavn 1-2 |          2 |
|  5 |      2 | Nickname 2   |          1 |
|  6 |      2 | Nicknavn 2   |          2 |
+----+--------+--------------+------------+
汽车缺口

+-------+-----------------+-----------------+
| CarId |    CarImage     |    CarVideo     |
+-------+-----------------+-----------------+
|     1 | http://imageurl | http://videourl |
|     2 | http://imageurl | http://videourl |
|     3 | http://imageurl | http://videourl |
|     4 | http://imageurl | http://videourl |
+-------+-----------------+-----------------+
+----+-------+---------+------------+
| Id | CarId | CarName | LanguageId |
+----+-------+---------+------------+
|  1 |     1 | Car 1   |          1 |
|  2 |     1 | Bil 1   |          2 |
|  3 |     2 | Car 2   |          1 |
|  4 |     2 | Bil 2   |          2 |
|  5 |     3 | Car 3   |          1 |
|  6 |     3 | Bil 3   |          2 |
|  7 |     4 | Car 4   |          1 |
|  8 |     4 | Bil 4   |          2 |
+----+-------+---------+------------+
+--------+--------+-------+---------------------+---------------------+
| NickId | UserId | CarId |      CarImage       |      CarVideo       |
+--------+--------+-------+---------------------+---------------------+
|      1 |      1 |     1 |                     |                     |
|      2 |      1 |     2 | http://NEW-imageurl |                     |
|      3 |      1 |     3 |                     | http://NEW-videourl |
|      4 |      2 |     1 |                     | http://NEW-videourl |
+--------+--------+-------+---------------------+---------------------+
+----+--------+--------------+------------+
| Id | NickId |   CarName    | LanguageId |
+----+--------+--------------+------------+
|  1 |      1 | Nickname 1   |          1 |
|  2 |      1 | Nicknavn 1   |          2 |
|  3 |      4 | Nickname 1-2 |          1 |
|  4 |      4 | Nicknavn 1-2 |          2 |
|  5 |      2 | Nickname 2   |          1 |
|  6 |      2 | Nicknavn 2   |          2 |
+----+--------+--------------+------------+
车名

+-------+-----------------+-----------------+
| CarId |    CarImage     |    CarVideo     |
+-------+-----------------+-----------------+
|     1 | http://imageurl | http://videourl |
|     2 | http://imageurl | http://videourl |
|     3 | http://imageurl | http://videourl |
|     4 | http://imageurl | http://videourl |
+-------+-----------------+-----------------+
+----+-------+---------+------------+
| Id | CarId | CarName | LanguageId |
+----+-------+---------+------------+
|  1 |     1 | Car 1   |          1 |
|  2 |     1 | Bil 1   |          2 |
|  3 |     2 | Car 2   |          1 |
|  4 |     2 | Bil 2   |          2 |
|  5 |     3 | Car 3   |          1 |
|  6 |     3 | Bil 3   |          2 |
|  7 |     4 | Car 4   |          1 |
|  8 |     4 | Bil 4   |          2 |
+----+-------+---------+------------+
+--------+--------+-------+---------------------+---------------------+
| NickId | UserId | CarId |      CarImage       |      CarVideo       |
+--------+--------+-------+---------------------+---------------------+
|      1 |      1 |     1 |                     |                     |
|      2 |      1 |     2 | http://NEW-imageurl |                     |
|      3 |      1 |     3 |                     | http://NEW-videourl |
|      4 |      2 |     1 |                     | http://NEW-videourl |
+--------+--------+-------+---------------------+---------------------+
+----+--------+--------------+------------+
| Id | NickId |   CarName    | LanguageId |
+----+--------+--------------+------------+
|  1 |      1 | Nickname 1   |          1 |
|  2 |      1 | Nicknavn 1   |          2 |
|  3 |      4 | Nickname 1-2 |          1 |
|  4 |      4 | Nicknavn 1-2 |          2 |
|  5 |      2 | Nickname 2   |          1 |
|  6 |      2 | Nicknavn 2   |          2 |
+----+--------+--------------+------------+
我想做的是显示一个汽车列表,如下所示:

汽车(用于用户标识1)

汽车(用于用户识别码2)

这主要是从Cars和CarNames表中获取每辆车的所有默认信息。但是,我希望这些数据被Cars\u Nicks和Cars\u Nicks\u Names表覆盖(如果存在)

在我们的应用程序中,每个用户基本上都有一个“老师”。每个教师的设置也将是每个学生的默认设置,除非学生自己也设置了刻痕。所以在本例中,userid1是userid2的“老师”。这就是为什么在userid2的表中,他们有一些userid1的数据,但也有他们自己的nick,如果nick中不存在某个数据点,除了默认的Cars信息之外

我尝试了不同的解决方案来实现这一点,包括
JOIN
UNION
groupby
DISTINCT
,以及我能想到的所有组合。但我总是得到多个结果,如下表所示:

汽车(用户识别码2)(我的尝试)

有人知道我怎么才能得到这个吗

这是我多次尝试中的一次:

SELECT
    CarId,
    ISNULL(CarNicks.CarName, CarNames.CarNames) CarNames,
    ISNULL(CarNicks.CarImage, Cars.CarImage) CarImage,
    ISNULL(CarNicks.CarVideo, Cars.CarVideo) CarVideo
FROM 
    Cars
LEFT JOIN 
    (SELECT CarId, CarName, CarImage, CarVideo
     FROM Cars_Nicks Nicks
     JOIN Cars_Nicks_Names NickNames ON NickNames.NickId = Nicks.NickId 
                                     AND NickNames.LanguageId = 1 AND UserId = 1
     UNION
     SELECT CarId, CarName, CarImage, CarVideo
     FROM Cars_Nicks Nicks
     JOIN Cars_Nicks_Names NickNames ON NickNames.NickId = Nicks.NickId  
                                     AND NickNames.LanguageId = 1 AND UserId = 2) CarNicks ON CarNicks.CarId = Cars.CarId
JOIN 
    CarNames ON CarNames.CarId = Cars.CarId;

使用
LEFT JOIN
将各种表组合在一起,而不复制连接键。使用
CarId
NickId
作为各自的连接键,您应该(在外部)连接所有三个表
Cars
Cars\u nick
Cars\u nick\u name
。这自然会为每个
CarId
生成多个记录,但是(如果我正确理解了您的数据模型),每个
CarId
用户
,最多只能生成一个昵称。您需要将教师的昵称作为
Cars\u Nicks
Cars\u Nicks\u Names
表的另一个副本加入,并适当重命名,以便您可以确定昵称是来自学生还是教师

使用
合并
使一件事优先于另一件事。在
SELECT
子句中,您将执行类似于最初发布的字段尝试的操作,您希望其中一个表中的值覆盖另一个表中某个字段中的值,并且每个列表中的最后一项应为最终回退值

在这种情况下,不要使用
UNION

以下只是一个未经测试的名称示例。扩展要连接的内容以包含输出中所需的其他字段是相当容易的

select Cars.CarId, Cars.LanguageId, coalesce( StudentNN.CarName, TeacherNN.CarName, Cars.CarName ) as CarName
  from
      Car_Names left join (
           select NickId from Cars_Nicks where UserId = :student
      ) StudentN using (CarId)
      left join (
          select NickId from Cars_Nicks where UserId = :teacher
      ) TeacherN using (CarId)
      left join (
          select CarName from Cars_Nicks_Names
      ) StudentNN on StudentN.NickId = StudentNN.NickId and Car_Names.LanguageId = StudentNN.LanguageId
      left join (
          select CarName from Cars_Nicks_Names
      ) TeacherNN on TeacherN.NickId = TeacherNN.NickId and Car_Names.LanguageId = TeacherNN.LanguageId


我认为您需要
内部联接
车名
车名
,然后通过
左联接
引入
车名
。然后可以使用
coalesce()
实现替换逻辑:


您没有解释如何管理
languageid
列,该列位于
*\u names
表中,因此我将其强制为固定值。在现实世界中,您将拥有一个存储用户语言的
users
表,并使用该值进行筛选。

感谢您提供的格式化链接,我已经更新了。你对我可以使用的查询有什么想法吗?请在代码问题中给出一个--cut&paste&runnable代码;示例输入(作为初始化代码)以及所需和实际输出(包括逐字错误消息);标签和版本;清晰的说明和解释。对于包含最少代码的错误,您可以给出“显示为OK”的代码,并通过“显示为not OK”的代码进行扩展。(调试基础。)对于包含DBMS和DDL的SQL,其中包括约束和索引以及表格初始化。当您得到一个您不期望/不理解的结果时,停止寻找你的总体目标,找出你的误解是什么。--分离出第一个意外/误解的子表达式及其输入和输出,了解是什么误解、打字错误、错误推理等导致了它。(基本原理)问一下。PS是一个“基本上”或“基本上”或“换句话说”,它没有介绍或总结您给出的清晰、准确和完整的描述,只是表示“不明确”。谢谢philipxy,我补充说我正在使用MSSQL。否则,我相信我已经给出了一个最小的可复制的例子来说明我的问题,而我所拥有的数据我们无法剪切、粘贴和运行——所以没有。也没有一个明确的规范,只是一些“基本上”的模糊短语——没有。也请看我的最后一条评论,与你的评论相左。PS在给出业务关系(ship)/关联或表(基或查询结果)时,请说明其中的一行根据其列值对业务状况的说明。似乎联合是相关的——学生自己的尼克取代了教师尼克,然后我们根据这些尼克将Cars行与行联合。但是规格不清楚。我试着将Car_Nick_名字加入Cars_Nick表两次(一次用于学生id,一次用于教师id)。。。但即使这样,也会返回多行,尽管对carname使用了COALESCE,这是因为某些数据确实有多行,因为它同时包含教师和学生数据。是的,现在应该可以了。不幸的是,我不得不为此额外做一组2个左连接,但我认为这可能是最好的解决方案。谢谢,只要你能为没有老师的用户使用sentinel ID,你就很好。这是真的,对于LanguageId。我有一个用户表来获得它,但是将它设置为1,就像你所做的那样,对于基本的想法来说是很好的。很抱歉。至于