2016-12-01 49 views
0

Ive得到了这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只有左/内部加入。
我怎样才能转换这与相同的结果左/内部联接?
我发现某处提到一个交叉连接是一个没有条件的内部连接,所以我试着用这样的内部连接。

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生成的,它不能生成交叉连接,只提到了Left/Inner Join。

编辑1:
也许一个完全另一个查询可以帮助这里。
所以我想实现的是导出一些Keys。对于每个密钥应该是翻译,在没有翻译的情况下应该发生回退。对于这种情况,首先编写英文翻译的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查询与交叉连接工作​​。没有交叉连接的另一个查询可以做同样的结果吗?

EDIT2:

表: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 

我得到了属于选定产品的所有密钥(产品表例子里缺了,因为我觉得问题不在于那里)。如问我所有Valuespp_idLangs Table,ResultTable as - > DEHello。如果对于pp_id询问Value table没有value,则请将Fallback->coalesce,ResultTable设为 - >您好。我希望这能帮助我进一步满足我的需求。
正如霍根的答案要么给我所有values如果不尊重pp_id IN(7,9)或给我只有其中pp_id in (7,9)存在,而不是做Fallbackvalues

+2

你可以试试'INNER JOIN [LANGS] AS [value1.dict_Lang] ON 1 = 1' – HoneyBadger

+0

不知道是什么情况*不允许使用'CROSS JOIN' *,但是如果你没有这个代码就需要相同的效果,你可以用'SELECT * FROM tblA,tblB'来达到这个效果。在这两种情况下,你都会得到*笛卡尔产品*(* each-with-each *)。有理由更喜欢'CROSS JOIN'实际上... – Shnugo

+0

这听起来像一个非常奇怪的人为要求。 CROSS JOIN在这里是正确的。 –

回答

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 - 这是内部连接的定义 - 限制其他表只包含连接到表的行是内部连接。交叉连接是与此完全相反。显然(正如我一直在说的),你不希望交叉连接的功能,所以你不应该试图“交叉连接工作​​”。


原来的答案

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 
+0

这似乎不是尊重'l1.pp_id IN(7,9)',因为它加入了所有的Langs,而不仅仅是那些用'pp_id' 7/9 – AkAk47

+0

@ AkAk47你是说你的平台没有正确处理这个? – Hogan

+0

结果是错误的。通过我的交叉查询,我只获得具有选定语言的值的Keys。随着你的代码,它给了我每个语言的选择键每个值,而不仅仅是选定的键。所以我认为它不正确检查'l1.pp_id IN(7,9)'?也许我的编辑给你一个提示,我实际上想要达到什么。 – AkAk47