嗨,我对SQL很新 - 所以对我很温柔!
我基本上有两个表,我试图加入第一个表中的主键在第二个表中多次使用(并在第二个表中形成主键以及另一个列)
如果我提供一个例子,那可能是最好的:
表1:TravelRecords
TravelEventID EventType RecordLocator OfficeID
0001 F ABC123 LDN
0002 F ABC234 LDN
0003 T BDF232 SOU
0004 F DFD890 GLA
表2:TravelRecordRmks
TravelEventID RemarkNo Keyword Text
0001 1 TVL LOWCOST BOOKING
0001 2 TVL CREDIT CARD USED
0001 3 PSG COST CENTRE REQUIRED
0001 4 PSG EMPLOYEE NUM REQUIRED
0002 1 TVL CREDIT CARD USED
0002 2 AGT BOOKED BY AGENT
0002 3 AGT CONFIRM WITH AIRLINE
0002 4 TVL LOWEST FARE CONFIRMED
0002 5 TVL NO CANCELLATION CHARGE
0003 1 TVL LOWCOST BOOKING
0003 2 TVL CARRIER : EASYJET
0003 3 TVL LOWEST FARE CONFIRMED
0004 1 TVL LOWCOST BOOKING
0004 2 TVL CREDIT CARD USED
对于第二个表,密钥是TravelEventID和RemarkNo的组合,它们组合在一起给出了唯一的ID。
基本上我所要做的就是将表连在一起并返回记录定位器,以便使用注释文本行使用LOWCOST BOOKING和CREDIT CARD(因此在上面的示例中,只应返回ABC123和DFD890。 / p>
我尝试过以下方面:
SELECT TravelRecords.RecordLocator
FROM TravelRecords INNER JOIN
TravelRecordRmks ON TravelRecords.TravelEventID = TravelRecordRmks.TravelEventID db
WHERE (TravelRecordRmks.RemarkText = 'LOWCOST BOOKING')
and (TravelRecordRmks.RemarkText = 'CREDIT CARD USED')
ORDER BY dbo.vw_gTravelOrderEvent.RecordLocator
然而 - 什么都不返回。这可能非常简单 - 但是当我在寻找包含备注文本字段的单个TravelEventID时,我无法让它返回所需的响应。
任何帮助非常感谢 干杯
答案 0 :(得分:5)
检查这个问题最可读的方法可能是双where exists
,例如:
SELECT tr.*
FROM TravelRecords tr
WHERE EXISTS (
SELECT * FROM TravelRecordRmks trr
WHERE trr.TravelEventID = tr.TravelEventID
AND trr.RemarkText = 'LOWCOST BOOKING'
)
AND EXISTS (
SELECT * FROM TravelRecordRmks trr
WHERE trr.TravelEventID = tr.TravelEventID
AND trr.RemarkText = 'CREDIT CARD USED'
)
使用inner join
子查询作为过滤器的替代方案可能表现更好:
SELECT tr.*
FROM TravelRecords tr
INNER JOIN (
SELECT TravelEventID
FROM TravelRecordRmks trr
WHERE RemarkText IN ('CREDIT CARD USED','LOWCOST BOOKING')
GROUP BY TravelEventID
HAVING COUNT(DISTINCT RemarkText) = 2
) filter
ON filter.TravelEventID = tr.TravelEventID
HAVING COUNT(DISTINCT RemarkText) = 2
确保找到两种类型的评论。
答案 1 :(得分:2)
WHERE (TravelRecordRmks.RemarkText = 'LOWCOST BOOKING')
and (TravelRecordRmks.RemarkText = 'CREDIT CARD USED')
您似乎需要OR
而不是AND
。
SQL布尔逻辑(OR和AND)的解释方式与日常英语不同。
答案 2 :(得分:2)
除了Andomar的IF EXISTS逻辑之外,你可以做的另一种方式是备注表的两个连接:
SELECT
TR.record_locator,
FROM
Travel_Records TR
INNER JOIN Travel_Record_Remarks TRR1 ON
TRR1.travel_event_id = TR.travel_event_id AND
TRR1.remark_text = 'LOWCOST BOOKING'
INNER JOIN Travel_Record_Remarks TRR2 ON
TRR2.travel_event_id = TR.travel_event_id AND
TRR2.remark_text = 'CREDIT CARD USED'
但是这个陈述存在一个缺陷,即如果旅行事件有两个具有相同文本的备注,那么最终可能会使用相同的记录定位器返回多行。
答案 3 :(得分:1)
您不能使用and
之类的内容来检查多行上发生的值。您可以做的最好的事情是使用or
和count
来确保符合您想要的条件数量。类似的东西:
select
tr.RecordLocator
from
TravelRecords tr
join (
select
r.TravelEventID,
count(*)
from
TravelRecords r
join TravelRecordRmks rr on r.TravelEventID = rr.TravelEventID
where
rr.Text = 'LOWCOST BOOKING' or rr.Text = 'CREDIT CARD USED'
group by
r.TravelEventID
having
count(*) = 2 -- must match both (or have one of them twice) for a single TravelEventID
) x on x.TravelEventID = tr.TravelEventID
order by
tr.RecordLocator
答案 4 :(得分:0)
尝试这样的事情:
SELECT DISTINCT
tr.RecordLocator
FROM
TravelRecords tr
INNER JOIN TravelRecordRmks rmk
ON tr.TravelEventID = rmk.TravelEventID
WHERE
rmk.RemarkText = 'LOWCOST BOOKING'
OR rmk.RemarkText = 'CREDIT CARD USED'
ORDER BY
tr.RecordLocator
答案 5 :(得分:0)
问题在于你的状况。您要求TravelRecordRmks提供记录,其中RemarkText字段为'LOWCOST BOOKING'且同时是'CREDIT CARD USED'。
你想要的是:
WHERE RemarkText IN ('LOWCOST BOOKING', 'CREDIT CARD USED')
将找到包含 值的行。