我有三个表...
表1 消息类型
表2 businesschannel ,其列为:idBusinessChannel,idsystem,idMessageType,方向
表3 合作伙伴系统消息,其中包括: idSystem, idMessageType
我需要编写一个查询,该查询返回消息类型列表,该列表散发partnersystemmessages(idSystem列)表和businesschannel(方向列)已使用的消息。
到目前为止,我有以下查询,该查询返回消息类型列表,但忽略方向
SELECT DISTINCT messagetype.*
FROM messagetype
LEFT OUTER JOIN BUSINESSCHANNEL bc ON
bc.idMessageType = messagetype.idMessageType
AND bc.direction = 'out'
LEFT JOIN partnersystemmessages ON
messagetype.idMessageType = partnersystemmessages.idMessageType
AND partnersystemmessages.idSystem = 522
WHERE partnersystemmessages.idMessageType IS NULL
更新-添加示例数据
messagetype
+--------------+----------+
| idMessageType| Name |
+--------------+----------+
| 1 | SMTP |
| 2 | EDI |
| 3 | AS2 |
| 4 | WED |
| 5 | IDOC |
| 6 | general |
+--------------+----------+
businesschannel
+------------------------+----------+---------------+------------+
| idpartnersystemmessages| idsystem | idMessageType | direction| |
+------------------------+----------+---------------+------------+
| 1859 | 522 | 2 | in |
| 5131 | 522 | 1 | out |
| 1773 | 522 | 2 | out |
| 1775 | 522 | 3 | in |
| 1777 | 522 | 4 | out |
| 4555 | 522 | 5 | in |
+------------------------+----------+---------------+------------+
partnersystemmessages
+-------------------------+----------------+---------------+
| idpartnersystemmessages |MessageidSystem | |idMessageType|
+-------------------------+----------------+---------------+
| 1859 | 522 | 2 |
| 5131 | 522 | 1 |
| 1773 | 522 | 2 |
| 1775 | 522 | 3 |
| 1777 | 522 | 4 |
| 4555 | 522 | 5 |
--------------------------+----------------+--------------+
对于idSystem = 522和direction ='out' 我期望:
messagetype
+--------------+----------+
| idMessageType| Name |
+--------------+----------+
| 1 | SMTP |
| 3 | AS2 |
| 5 | idoc |
| 6 | general |
+--------------+----------+
不包括已经用于外向的EDI和WEB
答案 0 :(得分:0)
尝试通过更改连接如下所示
SELECT DISTINCT m.*
FROM messagetype m
LEFT OUTER JOIN BUSINESSCHANNEL bc ON
bc.idMessageType = m.idMessageType
JOIN partnersystemmessages ON
bc.idsystem= partnersystemmessages.idsystem
AND partnersystemmessages.idSystem = 522
WHERE bc.idMessageType IS NULL
答案 1 :(得分:0)
由于要将两个表重新连接到需要排除的主表,因此请将两个条件都添加到WHERE
中。 LEFT JOIN.... IS NULL
模式通常表现出色,尽管NOT EXISTS()
通常也可以很好地工作,并且可能是更好的选择。您必须对数据进行测试。
完整查询:
SELECT *
FROM messagetype mt
LEFT OUTER JOIN businesschannel bc ON bc.idMessageType = mt.idMessageType
AND bc.direction = 'out'
LEFT OUTER JOIN partnersystemmessages psm ON mt.idMessageType = psm.idMessageType
AND psm.idSystem = 522
Results :
| idMessageType | Name | idBusinessChannel | idsystem | idMessageType | direction | idSystem | idMessageType |
|---------------|---------|-------------------|----------|---------------|-----------|----------|---------------|
| 1 | SMTP | 2 | 522 | 1 | out | 522 | 1 |
| 2 | EDI | 3 | 522 | 2 | out | 522 | 2 |
| 2 | EDI | 3 | 522 | 2 | out | 522 | 2 |
| 3 | AS2 | (null) | (null) | (null) | (null) | 522 | 3 |
| 4 | WED | 5 | 522 | 4 | out | 522 | 4 |
| 5 | IDOC | (null) | (null) | (null) | (null) | 522 | 5 |
| 6 | general | (null) | (null) | (null) | (null) | (null) | (null) |
首先,您的原始问题似乎表明您想从messagetype
中排除与businesschannel
或partnersystemmessages
匹配的行。但是,您的示例结果显示的行仅限于同时显示。
使用左连接...为空:
SELECT DISTINCT mt.*
FROM messagetype mt
LEFT OUTER JOIN businesschannel bc ON bc.idMessageType = mt.idMessageType
AND bc.direction = 'out'
LEFT OUTER JOIN partnersystemmessages psm ON mt.idMessageType = psm.idMessageType
AND psm.idSystem = 522
WHERE bc.idBusinessChannel IS NULL
OR psm.idSystem IS NULL
Results :
| idMessageType | Name |
|---------------|---------|
| 3 | AS2 |
| 5 | IDOC |
| 6 | general |
使用“不存在” :
SELECT DISTINCT mt.*
FROM messagetype mt
WHERE NOT EXISTS (
SELECT 1 FROM businesschannel bc
WHERE bc.direction = 'out'
AND bc.idMessageType = mt.idMessageType
)
OR NOT EXISTS (
SELECT 1 FROM partnersystemmessages psm
WHERE psm.idSystem = 522
AND psm.idMessageType = mt.idMessageType
)
Results :
| idMessageType | Name |
|---------------|---------|
| 3 | AS2 |
| 5 | IDOC |
| 6 | general |
将OR
更改为AND
会将结果进一步限制为仅general
。我仍不清楚您的原始结果为何包含SMTP
。我原来的查询显示它包含在两个表中。那是错字吗?