1

我有一张叫做 的桌子USERS和一张叫做 的桌子ADDRESSES,还有一张ADDRESS_TYPE桌子。每个用户可以有多个地址。

SELECT *
FROM USER
INNER JOIN address ON address.userId = user.userId
INNER JOIN address_type ON address_type.id = address.addressType
WHERE addressType = 4 
    OR primaryAddress = 1

如果地址类型为 4,我想将地址表加入用户表,但如果他们的地址类型不是 4,则它应该拉入标记为主要的地址。基本上问题是我需要对查询进行分组,以便每个用户只获得 1 行,同时具有逻辑 =“如果 addressType = 4,加入这个地址,否则如果 primaryAddress = 1,加入这个另一个地址”。

希望这是有道理的,非常感谢您的帮助。

编辑:这些是我正在处理的表格:

用户表

+--------+-----------------+-----------------+
| 用户名 | 名字 | 姓氏 |
+--------+-----------------+-----------------+
| 10001 | 黛比 | 巴松 |
| 10002 | 巴马瓦马 | 九冬 |
| 10003 | 杰西卡M | 史蒂夫 |
| 10004 | 金农 | 白色 |
+--------+-----------------+------------------+



地址类型
+----+------+-------------+------------+-------- ----+
| 编号 | 代码 | 描述 | 可修改 | 数据状态 |
+----+------+-------------+------------+--------- --+
| 1 | 主页 | 主页 | 1 | 1 |
| 2 | 布斯 | 商业 | 1 | 1 |
| 3 | SCH | 学校 | 1 | 1 |
| 4 | 唐 | 捐赠者地址 | 1 | 1 |
+----+------+-------------+------------+--------- --+

地址表

+----------------+--------+---------- ----+--------------+-------------+
| 主地址 | 用户名 | 街道1 | 城市| 地址类型 |
+----------------+--------+----------- --+-------------+--------------+
| 0 | 10001 | 12660 皮卡特广场 | 圣地亚哥 | 1 |
| 0 | 10001 | 威尔希尔大街 446 号 | 富乐顿 | 2 |
| 0 | 10001 | 4224 E. 114 路 | 桑顿 | 3 |
| 1 | 10001 | 科罗拉多大道 828 号 | 洛杉矶 | 4 |
| 0 | 10002 | 40A 林登大道,#2 | 萨默维尔 | 1 |
| 0 | 10002 | 446 37 街,#2 | 奥克兰 | 空 |
| 1 | 10002 | 邮政信箱 06562 | 芝加哥 | 空 |
| 0 | 10002 | 1281 W. 2nd St. | 圣佩德罗 | 空 |
| 1 | 10003 | 10557 S.奥克利大道。芝加哥 | 空 |
| 0 | 10003 | 1425 哈里森街,#324 | 奥克兰 | 空 |
+----------------+--------+----------- --+-------------+--------------+

4

5 回答 5

1

就像另一个答案说的那样,MySQL 确实支持 IF,但我觉得在这种情况下这是错误的方法。我的感觉是左连接可能更合适。

我认为这应该让你走到一半,但我需要知道“这个其他地址”来自哪里才能完成查询:

SELECT
  *
FROM
  user
LEFT JOIN
  address ON (address.userId = user.userId AND address.addressType = 4)

(ps.address_type 表似乎有点多余,所以我在连接中跳过它,但也许它很重要?)

于 2012-10-29T22:05:45.063 回答
1

MySQL 具有IF以下功能(以及更多):

SELECT *,
       IF(addressType = 4, chosen_table.address_field_name, alternative_table.address_field_name) AS field_name

用地址字段的名称替换address_field_name两次。chosen_table是“真”块,IFalternative_table“假”块。

于 2012-10-29T22:06:21.860 回答
1

您是否尝试过类似 UNION select 的方法?

也许是这样的:

SELECT *
FROM user, address, address_type 
WHERE address.userId = user.userId
AND address_type.id = address.addressType
AND addressType = 4 
UNION
SELECT *
FROM user, address, address_type 
WHERE address.userId = user.userId
AND address_type.id = address.addressType
AND primaryAddress = 1

不确定我的表结构是否正确..但基本点是尝试使用 UNION 语句:-)

于 2012-10-29T22:12:32.343 回答
1

我会删除 ADDRESS_TYPE 表并使您的 ADDRESS 表成为用户地址表,其中您有足够的列来支持 2 或 3 个地址。这样你就不会弄乱你的主用户表。

没有人会需要超过 2 个地址(下面提到的例外情况)。你失去了连接和复杂性,那么你只需要有应用程序逻辑来做你想做的事。按照您的设计方式,您使这些表上的每个操作都比只有一张表时更加复杂。

我可以看到您上面描述的方式的唯一方法是,如果这是针对商业用户的某种应用程序,他们可以有多个位置可以运送到。

于 2012-10-29T22:17:46.460 回答
1

这是你想要的?

SELECT *
FROM USER
INNER JOIN address ON address.userId = user.userId
INNER JOIN address_type ON address_type.id = address.addressType
WHERE addressType = 4 
OR NOT EXISTS
(SELECT addressType FROM USER
 INNER JOIN address ON address.userID = user.userID
 INNER JOIN address_type ON address_type.id = address.addressType
 WHERE addressType = 4)
AND primaryAddress = 1
于 2012-10-29T22:32:31.743 回答