MySQL 来自 3 个表的多个联接
MySQL Multiple Joins from 3 Tables
我需要 select 来自 assets_tbl (A) 的所有记录。在这些记录中,我需要有任何灯箱 (lightbox_name
) 链接到
asset_id
来自 assets_tbl
,其中 author = "scott@co.com"
或 authorized_viewers
包括 "scott@co.com"
我认为这接近我的需要,但它 returns 同一记录的多行:
SELECT
A.*,
C.lightbox_name,
C.author,
C.authorized_viewers
FROM
media_tbl A
LEFT JOIN lightbox_assets_tbl B ON A.asset_id = B.asset_id
LEFT JOIN lightboxes_tbl C
ON B.lightbox_id = C.id
AND C.author = "scott@co.com"
LEFT JOIN lightboxes_tbl D ON D.authorized_viewers LIKE "scott@co.com"
ORDER BY A.id DESC
这是表格:
lightboxes_tbl
+-----+----------------+---------------+---------------------+
|id |lightbox_name |author |authoried_viewers |
+-----+----------------+---------------+---------------------+
|100 | aircraft-types |scott@co.com |jon@co.com,aj@co.com |
|101 | maintenance |nicole@co.com |jon@co.com |
|102 | ramp |nicole@co.com |scott@co.com |
+-----+----------------+---------------+---------------------+
lightbox_assets_tbl
+-----+-------------+-------------+---------------+----------+
|id |lightbox_id |asset_name |asset_path | asset_id |
+-----+-------------+-------------+---------------+----------+
|1 |100 |a321.jpg |project1/imgs/ | 3700 |
|2 |100 |b757.jpg |project1/imgs/ | 3444 |
|3 |101 |FlyBy.swf |project4/imgs/ | 1444 |
|4 |102 |Door_757.swf |project5/imgs/ | 3701 |
+-----+-------------+-------------+---------------+----------+
assets_tbl
+-----+---------------------+-------------------------------------+
|asset_id |asset_name | asset_location |
+-----------+---------------------+-------------------------------+
|3700 |a321.jpg |Libraries\Library_Media\Images |
|200 |757_Taxi.swf |Libraries\Library_Media\Images |
|3444 |b757.jpg |Libraries\Library_Media\Images |
|1444 |FlyBy.swf |Libraries\Library_Media\Images |
|3701 |Door_757.swf |Libraries\Library_Media\Images |
+----------+---------------------+--------------------------------+
以下是查询的预期结果:
+-----------+---------------------+-------------------------------+------------------+-------------+------------------------+
|asset_id |asset_name | asset_location |lightbox_name | author | authorized_viewers |
+-----------+---------------------+-------------------------------+------------------+-------------+------------------------+
|3700 |a321.jpg |Libraries\Library_Media\Images |aircraft-types |scott@co.com |jon@co.com,aj@co.com |
+-----------+---------------------+-------------------------------+------------------+-------------+------------------------+
|200 |757_Taxi.swf |Libraries\Library_Media\Images |NULL |NULL |NULL |
+-----------+---------------------+-------------------------------+------------------+-------------+------------------------+
|3444 |b757.jpg |Libraries\Library_Media\Images |aircraft-types |scott@co.com |jon@co.com,aj@co.com |
+-----------+---------------------+-------------------------------+------------------+-------------+------------------------+
|1444 |FlyBy.swf |Libraries\Library_Media\Images |NULL |NULL |NULL |
+-----------+---------------------+-------------------------------+------------------+-------------+------------------------+
|3701 |Door_757.swf |Libraries\Library_Media\Images |ramp |nicole@co.com|scott@co.com |
+----------+---------------------+--------------------------------+------------------+-------------+------------------------+
谢谢!
我想知道为什么您需要 两个 连接到 lightboxes_tbl
table。似乎对 table(别名 D
)的第二次引用是不必要的。好像你可以使用 OR
.
作为演示,在您的查询中复制谓词:
LEFT JOIN lightboxes_tbl C
ON B.lightbox_id = C.id
AND ( C.author = 'scott@co.com'
OR C.authorized_viewers = 'scott@co.com'
)
但是考虑到 authorized_user
包含一个逗号分隔列表 (ACCKKK!!!),我怀疑您真的想在逗号分隔列表中查找与某项完全匹配的内容。当前的 LIKE
比较等同于等于比较(对 authorized_viewers
列的全部内容)。您可以添加 '%'
通配符来搜索作为字符串一部分的值...
但这种方法也将匹配包含例如ebscott@co.com
,这可能不是你真正想要的。
您可以使用 FIND_IN_SET
函数在逗号分隔列表中找到完全匹配...
LEFT JOIN lightboxes_tbl C
ON B.lightbox_id = C.id
AND ( C.author = 'scott@co.com'
OR FIND_IN_SET('scott@co.com',C.authorized_viewers)
)
存储逗号分隔列表是一种 SQL 反模式。我推荐 Bill Karwin 的书:SQL Anti-Patterns: Avoiding the Pitfalls of Database Programming
http://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers/dp/1934356557
我需要 select 来自 assets_tbl (A) 的所有记录。在这些记录中,我需要有任何灯箱 (lightbox_name
) 链接到
asset_id
来自 assets_tbl
,其中 author = "scott@co.com"
或 authorized_viewers
包括 "scott@co.com"
我认为这接近我的需要,但它 returns 同一记录的多行:
SELECT
A.*,
C.lightbox_name,
C.author,
C.authorized_viewers
FROM
media_tbl A
LEFT JOIN lightbox_assets_tbl B ON A.asset_id = B.asset_id
LEFT JOIN lightboxes_tbl C
ON B.lightbox_id = C.id
AND C.author = "scott@co.com"
LEFT JOIN lightboxes_tbl D ON D.authorized_viewers LIKE "scott@co.com"
ORDER BY A.id DESC
这是表格:
lightboxes_tbl
+-----+----------------+---------------+---------------------+
|id |lightbox_name |author |authoried_viewers |
+-----+----------------+---------------+---------------------+
|100 | aircraft-types |scott@co.com |jon@co.com,aj@co.com |
|101 | maintenance |nicole@co.com |jon@co.com |
|102 | ramp |nicole@co.com |scott@co.com |
+-----+----------------+---------------+---------------------+
lightbox_assets_tbl
+-----+-------------+-------------+---------------+----------+
|id |lightbox_id |asset_name |asset_path | asset_id |
+-----+-------------+-------------+---------------+----------+
|1 |100 |a321.jpg |project1/imgs/ | 3700 |
|2 |100 |b757.jpg |project1/imgs/ | 3444 |
|3 |101 |FlyBy.swf |project4/imgs/ | 1444 |
|4 |102 |Door_757.swf |project5/imgs/ | 3701 |
+-----+-------------+-------------+---------------+----------+
assets_tbl
+-----+---------------------+-------------------------------------+
|asset_id |asset_name | asset_location |
+-----------+---------------------+-------------------------------+
|3700 |a321.jpg |Libraries\Library_Media\Images |
|200 |757_Taxi.swf |Libraries\Library_Media\Images |
|3444 |b757.jpg |Libraries\Library_Media\Images |
|1444 |FlyBy.swf |Libraries\Library_Media\Images |
|3701 |Door_757.swf |Libraries\Library_Media\Images |
+----------+---------------------+--------------------------------+
以下是查询的预期结果:
+-----------+---------------------+-------------------------------+------------------+-------------+------------------------+
|asset_id |asset_name | asset_location |lightbox_name | author | authorized_viewers |
+-----------+---------------------+-------------------------------+------------------+-------------+------------------------+
|3700 |a321.jpg |Libraries\Library_Media\Images |aircraft-types |scott@co.com |jon@co.com,aj@co.com |
+-----------+---------------------+-------------------------------+------------------+-------------+------------------------+
|200 |757_Taxi.swf |Libraries\Library_Media\Images |NULL |NULL |NULL |
+-----------+---------------------+-------------------------------+------------------+-------------+------------------------+
|3444 |b757.jpg |Libraries\Library_Media\Images |aircraft-types |scott@co.com |jon@co.com,aj@co.com |
+-----------+---------------------+-------------------------------+------------------+-------------+------------------------+
|1444 |FlyBy.swf |Libraries\Library_Media\Images |NULL |NULL |NULL |
+-----------+---------------------+-------------------------------+------------------+-------------+------------------------+
|3701 |Door_757.swf |Libraries\Library_Media\Images |ramp |nicole@co.com|scott@co.com |
+----------+---------------------+--------------------------------+------------------+-------------+------------------------+
谢谢!
我想知道为什么您需要 两个 连接到 lightboxes_tbl
table。似乎对 table(别名 D
)的第二次引用是不必要的。好像你可以使用 OR
.
作为演示,在您的查询中复制谓词:
LEFT JOIN lightboxes_tbl C
ON B.lightbox_id = C.id
AND ( C.author = 'scott@co.com'
OR C.authorized_viewers = 'scott@co.com'
)
但是考虑到 authorized_user
包含一个逗号分隔列表 (ACCKKK!!!),我怀疑您真的想在逗号分隔列表中查找与某项完全匹配的内容。当前的 LIKE
比较等同于等于比较(对 authorized_viewers
列的全部内容)。您可以添加 '%'
通配符来搜索作为字符串一部分的值...
但这种方法也将匹配包含例如ebscott@co.com
,这可能不是你真正想要的。
您可以使用 FIND_IN_SET
函数在逗号分隔列表中找到完全匹配...
LEFT JOIN lightboxes_tbl C
ON B.lightbox_id = C.id
AND ( C.author = 'scott@co.com'
OR FIND_IN_SET('scott@co.com',C.authorized_viewers)
)
存储逗号分隔列表是一种 SQL 反模式。我推荐 Bill Karwin 的书:SQL Anti-Patterns: Avoiding the Pitfalls of Database Programming
http://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers/dp/1934356557