Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 重构多个左连接_Mysql - Fatal编程技术网

Mysql 重构多个左连接

Mysql 重构多个左连接,mysql,Mysql,我的表格布局的简化版本如下: 表项 +----+-------+-----+ | ID | sdesc | ... | +----+-------+-----+ | 1 | item1 | ... | +----+-------+-----+ 表itemaffectTable(为具有数量的属性调用这些QPROP) TableItemAffectByTable(将这些BProp称为它们在出现时是相关的) 样本输出: itemID sdesc qpropID value

我的表格布局的简化版本如下:

表项

+----+-------+-----+
| ID | sdesc | ... |
+----+-------+-----+
|  1 | item1 | ... |
+----+-------+-----+
表itemaffectTable(为具有数量的属性调用这些QPROP)

TableItemAffectByTable(将这些BProp称为它们在出现时是相关的)

样本输出:

itemID  sdesc           qpropID value   bpropID
1221    a copper lantern      4     2   5
1221    a copper lantern     18     2   5
1221    a copper lantern     17    -5   5
 477    a shade              19     3   4
 477    a shade              19     3   6
这在两方面是不正确的。对于第一项,affectbyID 5重复3次。。。这是可以容忍的。在第二种情况下,我们将affectID 19和affect值3重复两次,这是不允许的

理想情况下我想看看

itemID  sdesc           qpropID value   bpropID
1221    a copper lantern      4     2   5
1221    a copper lantern     18     2   NULL
1221    a copper lantern     17    -5   NULL
 477    a shade              19     3   4
 477    a shade            NULL  NULL   6
主要问题是qpropIDs和值的重复,因为它们是相加的。如果解决方案重复bpropIDs,那没什么大不了的

**更新**

我试图使用完全连接的想法来获得结果,但似乎无法实现

最接近我想要的结果是使用SQLFIDLE获得

select i.id, i.sdesc, iaft.affectID, iaft.amount, NULL FROM item i
    LEFT JOIN itemaffectTable iaft ON i.id=iaft.itemID
UNION
select i.id, i.sdesc, NULL, NULL, iafbt.affectbyID FROM item i
    LEFT JOIN itemaffectedbyTable iafbt ON i.id=iafbt.itemID
ORDER BY id
所以最基本的想法是我想检索一个符合过滤器标准的项目列表,然后将这些项目与其关联的affectID和AffectById进行匹配

原文如下

SELECT DISTINCT i.id, i.sdesc, iaft.affectID, iaft.amount, iafbt.affectbyID FROM item i
INNER JOIN itemwearTable iwt ON i.id=iwt.itemID 
    LEFT JOIN itemaffectTable iaft ON i.id=iaft.itemID
    LEFT JOIN itemaffectedbyTable iafbt ON i.id=iafbt.itemID
LEFT JOIN itemalignTable iat ON i.id = iat.itemID
LEFT JOIN itemgenderTable igt ON i.id = igt.itemID
LEFT JOIN itemgenreTable igrt ON i.id = igrt.itemID
LEFT JOIN itemclassTable ict ON i.id = ict.itemID
LEFT JOIN itemraceTable irt ON i.id = irt.itemID
WHERE (iat.itemID IS NULL OR iat.alignID = 1)
AND (igt.itemID IS NULL OR igt.genderID = 1)
AND (igrt.itemID IS NULL OR igrt.genreID = 1)
AND (ict.itemID IS NULL OR ict.classID = 1)
AND (irt.itemID IS NULL OR irt.raceID = 1)
AND i.minlvl <= 50
AND iwt.wearlocID=1
ORDER BY sdesc
从项目i中选择不同的i.id、i.sdesc、iaft.affectID、iaft.amount、iafbt.affectbyID
i.id上的内部联接项WearTable iwt=iwt.itemID
i.id上的左联接itemaffectTable iaft=iaft.itemID
i.id=iafbt.itemID上的LEFT JOIN itemaffectedbyTable iafbt
i.id上的左连接itemalignTable iat=iat.itemID
i.id=igt.itemID上的左连接项可转换igt
i.id=igrt.itemID上的左连接itemgeneretable igrt
i.id上的左联接itemclassTable ict=ict.itemID
i.id=irt.itemID上的左连接项RaceTable irt
其中(iat.itemID为NULL或iat.alignID=1)
和(igt.itemID为NULL或igt.genderID=1)
和(igrt.itemID为NULL或igrt.genreID=1)
和(ict.itemID为NULL或ict.classID=1)
和(irt.itemID为NULL或irt.raceID=1)

还有i.minlvl看看这里。我相信这就是你要找的。在SSMS中,我会用完全联接来解决这个问题,但显然在mysql中无法做到这一点,因此需要一个联合来组合左右外部联接


我不太明白你的预期结果。。。我觉得这很不合理

是否要对每个项目执行类似操作,假设分别获得item affect和item affectedBy,并希望以基于行的方式组合结果?i、 e.第一个结果中项目A的第1行将与第二个结果中项目A的第1行放在一起:例如

Item     Affect               Item     AffectedBy
 1         a                    1         r
 1         b                    
 2         c                    2         s
                                2         t
 3         d
                                4         u
 5         e                    5         v
 5         f                    5         w
您希望看到以下内容:

Item    Affect    AffectedBy
1         a          r
1         b          NULL
2         c          s
2         NULL       t
3         d          NULL
4         NULL       u
5         e          v
5         f          w
select item_id, affect_id, rank() over (partition by item_id order by rownum) rank
from item_affect
order by item_id, rank;
对吧?

如果是这样的话,您可以想到的最直接的方法是,首先使项目影响的结果如下所示:

Item     Affect   seq
 1         a        1
 1         b        2
 2         c        1 
 3         d        1
 5         e        1
 5         f        2
Seq列是项目组中的“等级”。 在受影响的项目中做类似的事情

然后对item和seq列进行完全外部联接

我不知道如何在MySQL中实现这些,在Oracle中,生成seq的方法如下:

Item    Affect    AffectedBy
1         a          r
1         b          NULL
2         c          s
2         NULL       t
3         d          NULL
4         NULL       u
5         e          v
5         f          w
select item_id, affect_id, rank() over (partition by item_id order by rownum) rank
from item_affect
order by item_id, rank;
试着想想你是否可以在MySQL中做类似的事情


对于完全外部联接,如果不支持,则始终可以使用左联接和右联接执行并集。

这确实是一个奇怪的结果—它是一种旋转并集之类的

尽管如此,但它在这里,有你要求的所有钟声和口哨

select id, sdesc, affectID, amount, affectbyID
from (select 
    id, sdesc, 
    if(sameid and @affectID = affectID and @amount = amount, null, affectID) as affectID,
    if(sameid and @affectID = affectID and @amount = amount, null, amount) as amount,
    @affectID := affectID,
    @amount := amount,
    if(sameid and @affectbyID = affectbyID, null, affectbyID) as affectbyID,
    @affectbyID := affectbyID
from (select
    if(@id is null, false, @id = id) as sameId,
    @id := id as id,
    sdesc, affectID, amount, affectbyID
from (select distinct
  i.id,
  i.sdesc,
  iaft.affectID,
  iaft.amount,
  iafbt.affectbyID
FROM item i
LEFT JOIN itemaffectTable iaft ON i.id=iaft.itemID
LEFT JOIN itemaffectedbyTable iafbt ON i.id=iafbt.itemID
ORDER BY 1,3,4,5
) x) y) z
这将使用来记住以前列的值

对于每个新的
id
值,逻辑都会重置,如果列(或列对)的值与前一行的值相同,则其他列将变为null


请看a

我正在努力理解你在说什么。也许一些示例数据和期望的输出会有所帮助。安会更好。@Bohemian我希望上面的编辑能澄清我的问题。谢谢!:)这个问题有一个赤裸裸的版本好吧,好吧,你把我累坏了!看到我的答案了吗?它做了你想要的一切(我希望!):)当我在我的完整数据集上使用它时,我看到弹出了几个错误的行,我添加了这些行。这似乎非常接近我想要的,比我提到的联合想法快了大约3倍。我添加了一个以前应该存在的
orderby
,但是输出有什么问题?只是给我看小提琴没告诉我什么。我现在就开始gtg——我会寻找你的额外反馈,看看我能在大约12小时内做些什么。我看到了我的实时数据和sqfiddle之间的差异。我在一个新的sqfiddle中添加了一个“问题”项,您的查询处理得非常好。当我在live server上运行查询时,会得到旧的、不正确的结果,就好像IF语句没有执行一样。这可能是GoDaddy的配置问题或版本问题。此外,将DISTINCT添加到第一个select处理了最初引起我注意的重复项。