1

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

表项

+----+-------+-----+
| ID | sdesc | ... |
+----+-------+-----+
|  1 | item1 | ... |
+----+-------+-----+

表 itemaffectTable (调用这些 qProps 以获得具有数量的属性)

+--------+---------+----------+
| itemID | affectID| quantity |
+--------+---------+----------+
|      1 |       2 |       10 | // item 1 has affect 2 for a value of 10
|      1 |       3 |        2 | // item 1 has affect 3 for a value of 2
|      2 |       1 |        5 | // item 2 gets aff 1 for 5
|      2 |       1 |        6 | // item 2 gets aff 1 for 6 which means 11 total
|      3 |       5 |        5 | 
+--------+---------+----------+

表 itemaffectbyTable (称这些 bProps 存在时它们是相关的)

+--------+---------+
| itemID | affbyID |
+--------+---------+
|      1 |       6 |
|      3 |       2 |
|      3 |       3 |
+--------+---------+

样本输出:

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 次……这是可以容忍的。在第二种情况下,我们将影响 ID 19 和影响值 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

主要问题是 qpropID 和值的重复,因为它们是相加的。如果解决方案重复 bpropID,那没什么大不了的。

** 更新 **

我试图使用 FULL JOIN 的想法来获得我的结果,但似乎无法归零。

我最接近我想要的结果来自使用 sqlFiddle 来获得

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

所以最重要的想法是我想检索符合过滤器标准的项目列表,然后将这些项目与其关联的 effectID 和 effectbyID 匹配。

原文如下。

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
4

3 回答 3

1

看看这里。我相信这就是您正在寻找的。在 SSMS 中,我会使用完全连接来解决这个问题,但显然你不能在 mysql 中这样做,所以你需要一个联合来组合右外连接和左外连接。

http://www.tutorialspoint.com/sql/sql-full-joins.htm

于 2013-07-24T02:31:54.653 回答
1

这真的是你所追求的一个奇怪的结果——它是一种旋转联合之类的东西。

尽管如此,但它就在这里,拥有您所要求的所有花里胡哨!

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值重置逻辑,如果列(或列对)与前一行具有相同的值,则其他列为空。

在 SQLFiddle 上查看现场演示

于 2013-07-24T14:32:35.613 回答
0

我没有完全得到你的预期结果......这对我来说似乎很不合理。

您是否想为每个项目做一些事情,假设您分别获得 item-affect 和 item-affectedBy,并且您想以基于行的方式组合结果?即第一个结果中项目 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

正确的?

如果是这样,您能想到的最直接的方法是,首先使 item-affect 的结果看起来像:

Item     Affect   seq
 1         a        1
 1         b        2
 2         c        1 
 3         d        1
 5         e        1
 5         f        2

Seq 列是项目组中的“排名”。在 item-affectedBy 中做类似的事情

然后对 item 和 seq 列进行完全外连接。

我不确定如何在 MySQL 中实现这些,在 Oracle 中,生成 seq 的方式类似于:

select item_id, affect_id, rank() over (partition by item_id order by rownum) rank
from item_affect
order by item_id, rank;

试着想想你是否可以在 MySQL 中做类似的事情。

对于完全外连接,如果不支持,您始终可以使用左连接和右连接执行联合。

于 2013-07-24T03:42:40.110 回答