【发布时间】:2017-04-16 09:34:28
【问题描述】:
我有这个 MsSql
SELECT k._id,
coalesce(NULLIF(v1.value,''), NULLIF(v2.value,''), k.name) valueWithFallback,
FROM [Keys] k
INNER JOIN [ProductKeys] pk ON pk.key_id = k._id
INNER JOIN [Products] prod ON pk.product_id = prod._id
AND prod._id IN (2)
CROSS JOIN [Langs] l1
LEFT JOIN [Values] v1 ON k._id = v1.key_id
AND l1._id = v1.lang_id
LEFT JOIN [Values] v2 ON k._id = v2.key_id
AND v2.lang_id = 75
WHERE l1.pp_id IN (7,
9)
但我必须在没有Cross Join 的情况下这样做,因为我的情况不允许这样做。我的意思是我不能只使用命令CROSS JOIN 左/内连接。
如何使用左/内连接将其转换为相同的结果?
我发现某处提到 Cross Join 是 Inner Join without Condition 所以我尝试过这样的 Inner。
SELECT [dict_Keys].[_id],
coalesce(NULLIF([value1].[value], ''), NULLIF([value2].[value], ''), [dict_Keys].[name]) AS [fallBack],
FROM [Keys]AS [dict_Keys]
INNER JOIN ([ProductKeys] AS [Products.ProductKeys]
INNER JOIN [Products] AS [Products] ON [Products].[_id] = [Products.ProductKeys].[product_id]
AND [Products.ProductKeys].[product_id] IN (2)) ON [dict_Keys].[_id] = [Products.ProductKeys].[key_id]
LEFT JOIN [Values] AS [value1] ON [dict_Keys].[_id] = [value1].[key_id]
INNER JOIN [Langs] AS [value1.dict_Lang] ON [value1].[lang_id] = [value1.dict_Lang].[_id]
LEFT JOIN [Values] AS [value2] ON [dict_Keys].[_id] = [value2].[key_id]
AND [value2].lang_id = 75
WHERE [value1.dict_Lang].pp_id IN (7,
9)
ORDER BY [value1.dict_Lang].[pp_id],
[name];
第一个查询是使用 MsSql 的。第二个是由无法产生交叉连接的 Sequelize 生成的,仅提到了左/内连接。
编辑1:
也许一个完全另一个查询可以在这里提供帮助。
所以我想要实现的是导出一些Keys。对于每个 Key 都应该是 Translation,在没有 Translation 的情况下,将发生 Fallback。对于这种情况,coalesce.. 先写英文翻译,如果没有,它只写 KeyName,所以永远不会发生空值。
此密钥与产品相关。
所以我需要一个查询:
// get me the Key Id
SELECT k._id,
// Get me the Value to this Key. If there is none for the Selected Lang get the Default = 75, if this is not as well there wirte just the KeyName
coalesce(NULLIF(v1.value,''), NULLIF(v2.value,''), k.name) valueWithFallback,
// Get me all Keys
FROM [Keys] k
// Which belongs to this selected Product
INNER JOIN [ProductKeys] pk ON pk.key_id = k._id
// through n:m Table ProductKey
INNER JOIN [Products] prod ON pk.product_id = prod._id
// Selected Product
AND prod._id IN (2)
// for Fallback
CROSS JOIN [Langs] l1
// get me the Value to the selected Lang
LEFT JOIN [Values] v1 ON k._id = v1.key_id
AND l1._id = v1.lang_id
// If null for this selected Language get the Default
LEFT JOIN [Values] v2 ON k._id = v2.key_id
AND v2.lang_id = 75
// The selected Languages in which I want to export
WHERE l1.pp_id IN (7,
9)
这实际上适用于带有交叉连接的第一个 MsSql 查询。没有交叉连接的另一个查询可以做同样的结果吗?
编辑2:
表: Key
x---------------------x
| _Id | Name |
x----------|----------|
| 1 | Hello|
| 2 | Test |
x---------------------x
表: Value
x----------------------------------------x
| _id | key_id | lang_id| value |
x---------|-----------|------------------x
| 1 | 1 | 73 | Dehello |
| 2 | 2 | 73 | DeTest |
x-----------------------------------------x
表: Lang
x---------------------------x
| _id | pp_id | code|
x---------|-----------|-----|
| 73 | 7 | de |
| 75 | 9 | en |
x---------------------------x
使用 cross join 我的结果是:
结果
x-----------------------x
| key_Id | value |
x----------|------------|
| 1 | Hello |
| 2 | Test |
| 1 | DEHello|
| 2 | DETest |
x-----------------------x
我得到了属于所选产品的所有密钥(缺少产品表示例,因为我认为问题不在于那里)。按照要求,将所有Values 和pp_id 到Langs Table,ResultTable as -> DEHello 都给我。如果Value table 中没有value 用于询问pp_id,那么请给我Fallback->coalesce,ResultTable as -> Hello。我希望这对我的需求有所帮助。
正如霍根的回答要么给了我 all values 而不尊重 pp_id IN(7,9) 要么给我 only values 其中pp_id in (7,9) 存在而不做@ 987654347@.
【问题讨论】:
-
你可以试试
INNER JOIN [Langs] AS [value1.dict_Lang] ON 1=1 -
不知道什么情况下不允许使用
CROSS JOIN,但是如果您需要没有此代码的相同效果,您可以使用SELECT * FROM tblA,tblB.在这两种情况下,您都会得到 笛卡尔积 (each-with-each)。实际上有理由更喜欢CROSS JOIN... -
这听起来像是一个非常奇怪的人为要求。 CROSS JOIN 在这里是正确的。
-
@SeanLange -- 不是真的,因为 where 语句 (
WHERE l1.pp_id IN...) 它并不是真正的“交叉连接” -
我知道是的。但如前所述,Sequelize 不支持它或具有命令交叉连接。问题不是我应该改变还是交叉加入这里更好。它即将在没有命令交叉连接的情况下获得相同的结果。但同样的逻辑。
标签: sql sql-server sql-server-2008 sequelize.js cross-join