我能在这个问题上得到一些帮助吗。我会详细解释的。为了更简单,我将举一个HTML标记和属性的例子。
我有三张桌子:
tbl1-包含所有HTML标记(tagId
,tagName
)
tbl2-包含可能出现在
标签(attId
,attName
)
tbl3是tbl1和tbl2的映射表(tagId
,attId
)
我要选择属于所选标记(在下面的示例中为标记id 4)和标记id的所有属性(以及有关属性的相关信息)。
下面是我希望从查询中获得的信息的示例:
attId tagId attName
50 4 The name of the attribute with id 50
89 4 The name of the attribute with id 89
114 4 The name of the attribute with id 114
下面是我的问题,但我相信有更好的方法。
SELECT tbl2.*, tbl3.tagId
FROM tbl2 JOIN tbl3
WHERE tbl3.attId IN (
SELECT tbl3.attId FROM tbl3 where tbl3.tagId=4
)
AND tbl3.attIdd = tbl2.attId
GROUP BY tbl3.attId
提前谢谢。
最佳答案
第1期
您正在进行交叉连接,稍后通过在where
子句中放置筛选器将其减少为内部连接。
这是使用隐式连接语法时的旧skool方法。
在大多数SQL方言(而不是MySQL)上,这会导致错误。
不要在没有ON子句的情况下进行连接。
如果要进行交叉联接,请使用以下语法:select * from a cross join b
第2期
实际上不需要子select,只需在where子句中进行测试。
SELECT tbl2.*, tbl3.tagId
FROM tbl2
INNER JOIN tbl3 ON (tbl3.attIdd = tbl2.attId)
WHERE tbl3.tagId = 4
GROUP BY tbl3.attId
第3a期
您正在执行group by on
tbl3.ATTid
,这在本文中与执行group by ontbl2.attid
相同(因为ON (tbl3.attIdd = tbl2.attId)
子句)后者更有意义,因为你在做
select tbl2.*
,而不是select tbl3.*
第3b期
如果attId不是tbl2的主键或唯一键,则查询结果将是不确定的。
这意味着查询将从具有相同
attID
的可能行列表中随机选择一行。如果您不希望这样做,您将不得不包含一个having
子句,该子句将根据某些条件选择一行。例子
/*selects the most recent row per attID, instead of a random one*/
SELECT tbl2.*, tbl3.tagId
FROM tbl2
INNER JOIN tbl3 ON (tbl3.attIdd = tbl2.attId)
WHERE tbl3.tagId = 4
GROUP BY tbl2.attId
HAVING tbl2.dateadded = MAX(tabl2.dateadded)