在查询中转换/删除交叉连接

时间:2016-12-01 16:36:27

标签: sql sql-server sql-server-2008 sequelize.js cross-join

我有这个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的情况下这样做,因为我的情况不允许。我的意思是我不能使用Command CROSS JOIN只有左/内连接 我怎么能用左/内连接为同一个结果转换它?
我找到了一个提到交叉连接的地方是一个没有条件的内部连接,所以我尝试过像这样的内部。

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];

第一个Query正在使用MsSql。第二个是由Sequelize生成的,它不能生成交叉连接,仅提到左/内连接。

EDIT1:
也许完全另一个查询可以在这里提供帮助 所以我想要实现的是导出一些Keys。对于每个Key应该是一个翻译,在没有翻译的情况下,将发生后备。对于这种情况,coalesce..首先写入英文翻译,如果没有,它只写入KeyName,所以永远不会出现Null值。 此密钥与产品相关。 所以我需要一个查询:

// 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_idLangs Table ResultTable为 - > DEHello 即可。如果被value Value table的{​​{1}}中没有pp_id,那么请将Fallback->coalesce结果表作为 - >你好即可。我希望这能为我的需求提供更多帮助 由于Hogan的答案给了我所有 values而不尊重pp_id IN(7,9)或仅给我 values {{1}存在而不是pp_id in (7,9)

1 个答案:

答案 0 :(得分:0)

根据您在下面的评论,您不想要交叉加入,您需要内部联接。通过将标准添加到where语句,您将结果限制为与内部联接相同。运行以下代码,看看我是否正确。

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._idAND prod._id IN (2)
INNER JOIN [Values] v1 ON k._id = v1.key_id 
INNER JOIN [Langs] l1 ON l1._id = v1.lang_id and l1.pp_id IN (7, 9)
LEFT JOIN [Values] v2 ON k._id = v2.key_id AND v2.lang_id = 75

回到我们对评论的错误理解 - 我的查询将[Langs]表限制为7和9 - 但它并没有将其他表限制为7和9 - 这是一个定义内部联接 - 将其他表限制为仅包括连接到表的行是内部联接。交叉连接与此完全相反。显然(正如我一直在说的那样)你不想要交叉加入的功能,所以你不应该试图让交叉加入工作"。 / p>

原始回答

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._idAND prod._id IN (2)
LEFT JOIN [Values] v1 ON k._id = v1.key_id 
LEFT JOIN [Langs] l1 ON l1._id = v1.lang_id and l1.pp_id IN (7, 9)
LEFT JOIN [Values] v2 ON k._id = v2.key_id AND v2.lang_id = 75