在MySQL中有条件地加入

时间:2012-10-29 21:59:16

标签: mysql sql if-statement group-by conditional

我有一个名为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

如果地址表的addressType为4,我想将地址表加入到用户表中,但如果它们的addressType不是4,则应该引入标记为主要的地址。基本上问题是我需要对查询进行分组,以便每个用户只获得1行,而具有logic =“如果addressType = 4,则加入此地址,否则如果primaryAddress = 1,则加入此其他地址”。

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

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

USER TABLE

+ -------- + ----------------- + ----------------- + <登记/> | userId | firstName | lastName |
+ -------- + ----------------- + ----------------- +
| 10001 |黛比|巴森|
| 10002 | Bamawama | Kudon |
| 10003 |杰西卡姆| Stevies |
| 10004 |金农|白色|
+ -------- + ----------------- + ----------------- +



地址类型
+ ---- + ------ + ------------- + ------------ + ---------- - +
| id |代码|描述|可修改的dataStatus |
+ ---- + ------ + ------------- + ------------ + ---------- - +
| 1 | HOME |主页| 1 | 1 |
| 2 |布斯|业务| 1 | 1 |
| 3 | SCH |学校| 1 | 1 |
| 4 | DON |捐助者地址| 1 | 1 |
+ ---- + ------ + ------------- + ------------ + ---------- - +

地址表

+ ---------------- + -------- + ----------------------- - + ------------- ------------- + +
| primaryAddress | userId | street1 |城市| addressType |
+ ---------------- + -------- + ----------------------- - + ------------- ------------- + +
| 0 | 10001 | 12660 Picarte Pl。 |圣地亚哥| 1 |
| 0 | 10001 | 446 W Wilshire Ave |富勒顿| 2 |
| 0 | 10001 | 4224 E. 114th Way |桑顿| 3 |
| 1 | 10001 | 828 Colorado Blvd. |洛杉矶| 4 |
| 0 | 10002 | 40A Linden Ave.,#2 |萨默维尔| 1 |
| 0 | 10002 | 446 37th St.,#2 |奥克兰| null |
| 1 | 10002 |邮政信箱06562 |芝加哥| null |
| 0 | 10002 | 1281 W. 2nd St. |圣佩德罗| null |
| 1 | 10003 | 10557 S. Oakley Ave. |芝加哥| null |
| 0 | 10003 | 1425 Harrison St.,#324 |奥克兰| null |
+ ---------------- + -------- + ----------------------- - + ------------- + ------------- +

5 个答案:

答案 0 :(得分:1)

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

我认为这应该会让你在中途,但我需要知道“这个其他地址”来自哪里来完成查询:

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

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

答案 1 :(得分:1)

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

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

address_field_name替换为地址字段的名称两次。 chosen_tableIF的“真实”区块,alternative_table是“假”区块。

答案 2 :(得分:1)

您是否尝试过UNION选择?

也许是这样的:

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语句: - )

答案 3 :(得分:1)

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

没有人需要超过2个地址(下面注明例外)。你失去了联接和复杂性,那么你只需要让app逻辑来做你想做的事情。你设计的方式,如果它只是一个表,你就可以使这些表上的每个动作都更复杂。

我能够看到你上面描述的方式的唯一方法是,如果这是商业用户的某种应用程序,他们可以将多个位置发送到。

答案 4 :(得分: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