sql-server – 选择所有记录,如果存在连接,则连接表A,否则连接表
副问题[/!--empirenews.page--]
以是这是我的景象: 我正在为我的项目举办当地化,凡是我会在C#代码中执行此操纵,可是我想在SQL中执行此操纵,由于我试图轻微增进SQL. 情形:SQL Server 2014 Standard,C#(.NET 4.5.1) 留意:编程说话自己应该是无关紧急的,我只是为了完备性而包括它. 以是我完成了我想要的对象,但没有到达我想要的水平.这已经有一段时刻了(至少一年),由于除了根基的SQL JOIN之外我已经完成了任何SQL JOIN,这是一个很是伟大的JOIN. 以下是数据库相干表格的图表. (这部门尚有许多,但不是必须的.) 图像中描写的全部相关在数据库中都是完备的 – PK和FK束缚都是配置和操纵的.所描写的列都不举动空.全部表都具有模式dbo. 此刻,我有一个险些完成我想要的查询:也就是说,给定任何支持种别ID和任何说话ID,它将返回: 假如该字符串的说话存在正确的正确翻译(即,StringKeyId – > StringKeys.Id存在,而且存在LanguageStringTranslations StringKeyId,LanguageId和StringTranslationId组合,则它将为该StringTranslationId加载StringTranslations.Text. 假如LanguageStringTranslations StringKeyId,LanguageId和StringTranslationId组合不存在,则它将加载StringKeys.Name值. Languages.Id是给定的整数. 我的查询,一团糟,如下: SELECT CASE WHEN T.x IS NOT NULL THEN T.x ELSE (SELECT CASE WHEN dbo.StringTranslations.Text IS NULL THEN dbo.StringKeys.Name ELSE dbo.StringTranslations.Text END AS Result FROM dbo.SupportCategories INNER JOIN dbo.StringKeys ON dbo.SupportCategories.StringKeyId = dbo.StringKeys.Id INNER JOIN dbo.LanguageStringTranslations ON dbo.StringKeys.Id = dbo.LanguageStringTranslations.StringKeyId INNER JOIN dbo.StringTranslations ON dbo.StringTranslations.Id = dbo.LanguageStringTranslations.StringTranslationId WHERE dbo.LanguageStringTranslations.LanguageId = 38 AND dbo.SupportCategories.Id = 0) END AS Result FROM (SELECT (SELECT CASE WHEN dbo.StringTranslations.Text IS NULL THEN dbo.StringKeys.Name ELSE dbo.StringTranslations.Text END AS Result FROM dbo.SupportCategories INNER JOIN dbo.StringKeys ON dbo.SupportCategories.StringKeyId = dbo.StringKeys.Id INNER JOIN dbo.LanguageStringTranslations ON dbo.StringKeys.Id = dbo.LanguageStringTranslations.StringKeyId INNER JOIN dbo.StringTranslations ON dbo.StringTranslations.Id = dbo.LanguageStringTranslations.StringTranslationId WHERE dbo.LanguageStringTranslations.LanguageId = 5 AND dbo.SupportCategories.Id = 0) AS x) AS T 题目是它无法为我提供全部SupportCategories及其各自的StringTranslations.Text(假如存在),可能它们的StringKeys.Name(假如它不存在).提供任何一个都是美满的,但基础不提供.根基上,逼迫执行假如某种说话没有特定键的翻译,则默认行使StringKeys.Name,它是StringKeys.DefaultLanguageId的翻译. (抱负环境下,它乃至不会这样做,而是加载StringKeys.DefaultLanguageId的翻译,假如指向其他查询的正确偏向,我可以本身做.) 我花了许多时刻在这上面,我知道假如我只是用C#写它(就像我凡是那样)它此刻就完成了.我想在SQL中执行此操纵,而且我无法得到我喜好的输出. 独一必要留意的是,我想限定应用的现实查询数目.全部列都已编入索引,譬喻我此刻喜好它们,假如没有真正的压力测试,我无法进一步索引它们. 编辑:另一个留意事项,我正在实行尽也许地保持数据库的类型化,以是假如我可以停止它,我不想复制内容. 示例数据 资源 dbo.SupportCategories(整个): Id StringKeyId 0 0 1 1 2 2 dbo.Languages(185笔记录,仅表现两个例子): Id Abbreviation Family Name Native 38 en Indo-European English English 48 fr Indo-European French fran?ais,langue fran?aise dbo.LanguagesStringTranslations(整数): StringKeyId LanguageId StringTranslationId 0 38 0 1 38 1 2 38 2 3 38 3 4 38 4 5 38 5 6 38 6 7 38 7 1 48 8 -- added as example dbo.StringKeys(整数): Id Name DefaultLanguageId 0 Billing 38 1 API 38 2 Sales 38 3 Open 38 4 Waiting for Customer 38 5 Waiting for Support 38 6 Work in Progress 38 7 Completed 38 dbo.StringTranslations(整数): Id Text 0 Billing 1 API 2 Sales 3 Open 4 Waiting for Customer 5 Waiting for Support 6 Work in Progress 7 Completed 8 Les APIs -- added as example 电流输出 鉴于下面简直切查询,它输出: Result Billing 祈望的输出 抱负环境下,我但愿可以或许省略特定的SupportCategories.Id,并获取全部这些内容(无论是行使说话38英语,照旧48法语,或今朝任何其他说话): Id Result 0 Billing 1 API 2 Sales 附加示例 鉴于我要为法语添加当地化(即添加1 48 8到LanguageStringTranslations),输出将变动为(留意:这仅是示例,显然我将向StringTranslations添加当地化字符串)(行使法语示例更新): Result Les APIs 特另外祈望输出 鉴于上面的示例,必要以下输出(行使法语示例更新): Id Result 0 Billing 1 Les APIs 2 Sales (是的,从技能上讲,从同等性的角度来看,我知道这是错误的,但这是在这种环境下所但愿的.) 编辑: 小更新,我确实变动了dbo.Languages表的布局,并从中删除了Id(int)列,并将其替代为缩写(此刻将其重定名为Id,并更新全部相对的外键和相关) .从技能角度来看,我以为这是一个更吻合的配置,由于该表仅限于ISO 639-1代码,这些代码一开始就是唯一无二的. 文艺青年最爱的 以是:题目是,怎样修改此查询以从SupportCategories返回全部内容,然后返回StringKeys.Id的StringTranslations.Text,Languages.Id组合,可能假如它不存在则返回StringKeys.Name? 我最初的设法是,我可以以某种方法将当前查询转换为另一个姑且范例作为另一个子查询,并将此查询包装在另一个SELECT语句中并选择我想要的两个字段(SupportCategories.Id和Result). 假如我没有找到任何对象,我将只行使我凡是行使的尺度要领,即将全部SupportCategories加载到我的C#项目中,然后行使它在上面针对每个SupportCategories.Id手动运行查询. 感激任何和全部提议/评述/品评. (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |