3

下面是我正在工作的 2 个非常大的表的粗略简化。

campaign桌子

| 编号 | uid | 姓名 | 联系方式 | 销 | 图标 |
| 1 | 7 | 鲍勃 | 泰德 | y6w | 哟 |
| 2 | 7 | 内德 | 乔 | y6e | ygy |
| 3 | 6 | 山姆 | 乔恩 | y6t | 哎哟|

records桌子

| 编号 | uid | 西德 | 名称 | 姓名 | 地址 | 城市| 电话 |
| 1 | 7 | 1 | 拉尔斯 | 杰克| 13 主要 | 乐嘉 | 55555 |
| 2 | 7 | 1 | rar | 乔克 | 10 马翁 | oyjh | 55595 |
| 2 | 7 | 1 | ssrs | 弗瑞克 | 10 欧 | 欧尔| 88595 |

该页面循环通过记录表并将结果打印到 HTML 表中。出于某种原因,现有代码对每条记录进行单独的查询,"select name from campaign where id = $res['cid']"我想摆脱第二个查询并进行某种连接,但最有效的方法是什么?

我需要

SELECT * FROM records

并且

SELECT name FROM campaigns WHERE campaigns.id = records.cid

在单个查询中。

我怎样才能有效地做到这一点?

4

4 回答 4

2

只需连接两个表。您已经具备所需的WHERE条件。从一列中选择所有列,但从另一列中选择一列。像这样:

SELECT records.*, campaigns.name
FROM records, campaigns
WHERE campaigns.id = records.cid

请注意,没有匹配活动的记录行将丢失。为避免这种情况,请改写您的查询,如下所示:

SELECT records.*, campaigns.name
FROM records LEFT JOIN campaigns
ON campaigns.id = records.cid

现在您将获得NULL名称而不是丢失的行。

于 2013-10-02T01:25:52.997 回答
2

“最有效”的部分是答案变得非常棘手的地方。一般来说,一个很好的方法是简单地在两个表上编写一个带有连接的查询,然后愉快地跳过唱关于小猫的歌曲。但是,这实际上取决于更多的因素。表有多大,它们是否在查询的正确列上很好地索引?查询运行时,会生成多少条记录?结果是否在查询中排序?

这就是开始成为一种艺术而不是科学的地方。查看解释计划,了解正在发生的事情,寻找使其更有效或更简单的方法。有时在from子句中运行两个仅生成数据子集的子查询比尝试连接整个表并从中选择所需数据要高效得多。

要更详细地回答这个问题,同时希望对您的特定情况准确,需要更多信息。

如果我要猜测您的数据库中的其中一些内容,如果您的表少于几百万行并且您的数据库性能不错,我会建议使用简单的连接进行以下操作。如果您多次重新运行 EXACT 查询,即使是慢速查询也可以很好地被 MySQL 缓存,所以也要看看。我有一个应用程序在一个非常规范的机器上运行,在那里我编写了一个 cron 作业,它只运行一些查询,这些查询是在一夜之间加载的新数据,我的所有用户都认为查询是即时的,因为我确保它们被缓存。有时,真正奏效的是小技巧。

最后,如果您实际上是刚开始使用 SQL 或者并不像您认为最终会得到的那样熟悉 - 您可能想阅读我写的这个问答,它涵盖了很多关于查询的基本到中级主题,例如连接、子查询、聚合查询以及基本上更多值得了解的东西。

于 2013-10-02T01:27:12.067 回答
1

您可以使用此查询

SELECT records.*, campaigns.name
FROM records, campaigns
WHERE campaigns.id = records.cid

但是,使用 INNER JOIN(新的 ANSI 标准,ANSI-92)要好得多,因为它更具可读性,并且您可以轻松地将 INNER 替换为 LEFT 或其他类型的连接。

SELECT records.*, campaigns.name
FROM records INNER JOIN campaigns
ON campaigns.id = records.cid

更多解释在这里:

  1. SQL 内连接。ON 条件 vs WHERE 子句
  2. INNER JOIN ON vs WHERE 子句
于 2013-10-02T01:48:45.767 回答
0
SELECT *
FROM records
LEFT JOIN campaigns
on records.cid = campaigns.id;

使用左连接而不是内连接可以保证您仍然会列出每个记录条目。

于 2013-10-02T01:21:14.923 回答