在sql查询中运行检查(可能是子查询?)

kupeojn6  于 2021-06-19  发布在  Mysql
关注(0)|答案(2)|浏览(311)

我有一个简单的笔记本电脑测试预订系统,有6台笔记本电脑,命名为laptop01到06,每台都有三个分配的时间段。
如果未预订时隙或预订已取消/拒绝,用户可以选择这些时隙。
当我有工作代码时,我意识到一个致命的错误,它会导致取消/拒绝的插槽重复。
让我解释一下。。。
event_information -保存预订事件信息(本例只需要id) event_machine_time -这可以容纳所有的笔记本电脑,每台笔记本电脑有三行,可以选择独特的计时方式 event_booking -它保存实际的预订,然后链接到另一个候选数据库,这里不包括
然后我运行一个简单的查询,将所有内容连接在一起,并(我认为)标识预订的事件:

SELECT machine_laptop, machine_name, B.id AS m_id, C.id AS c_id, C.confirmed AS c_confirmed, C.live AS c_live, 
(C.id IS NOT NULL AND C.confirmed !=2 AND C.live !=0) AS booked
FROM event_information A
INNER JOIN event_machine_time B ON ( 1 =1 ) 
LEFT JOIN event_booking C on (B.id = C.machine_time_id and A.id = C.information_id )
WHERE A.id = :id
ORDER BY `B`.`id` DESC
``` `booked` 正在检查 `confirmed` 不是2-这意味着预订已被取消/拒绝(0-未确认,1-已确认),并且 `live` 正在检查是否删除(0-已删除,1-未删除)。
但是如果一个人( `live` -0)或取消/拒绝( `confirmed` -2)然后在我的前端插槽选择器下拉列表中,它将添加一个额外的插槽作为 `booked` 列仍为0,如下所示:
![](https://i.stack.imgur.com/REa1R.png)
这允许用户同时从两个插槽中进行选择,这意味着会发生双重预订。
我现在知道使用连接是错误的,我假设我需要运行子查询,但我不是sqlMaven,我希望能得到一些帮助,找到类似的“第二次查询”的例子,我可以从中学习。
如果我的术语有误,也要道歉。
编辑:
根据要求,我已将输出包括在内:
![](https://i.stack.imgur.com/80g8p.png)
第二次编辑和结论:
最后,我使用子查询在输出之前删除取消/拒绝的预订,然后使用groupby只显示每个时间点中的一个。这很可能不是最好的方法,但对我很有效。

SELECT machine_laptop, machine_name, B.id AS m_id, C.id AS c_id, C.confirmed AS c_confirmed, C.live AS c_live, B.start_time AS b_start_time, (
C.id IS NOT NULL
AND C.confirmed !=2
AND C.live !=0
) AS booked
FROM event_information A
INNER JOIN event_machine_time B ON (1=1)
LEFT JOIN (SELECT * FROM event_booking WHERE confirmed <> '2' AND live <> '0') AS C ON ( B.id = C.machine_time_id AND A.id = C.information_id )
WHERE A.id = :id
GROUP BY m_id
ORDER BY machine_name ASC, b_start_time ASC

谢谢你的意见。
y1aodyip

y1aodyip1#

如果您将event(b)作为查询的起点,您可以看到不需要使用pull a和c中的所有行和列。intead您可以直接连接匹配的行。但由于我甚至无法正确理解您的查询想要实现的目标,我首先有几个问题:
虽然这可能会奏效,但它实际上并不在你的控制之下,也不由你来定义。一些更严格的模式会礼貌地告诉您指定在select中引用哪个别名表,如下所示

SELECT machine_laptop, machine_name  -- combined with
FROM event_information A

实际上是没有意义的,它工作的唯一原因是你在利用mysql的优化。除此之外,您还尝试以混合模式进行表联接(这意味着您同时使用join和where ta.colx=tb.coly方法)。这就很难理解了。

INNER JOIN event_machine_time B ON ( 1 =1 )

嗯?这到底是为了什么?据我所知,这只会导致它连接两个完整的表,只会在以后使用where过滤结果。
此外,您是否使用主键?条件包括c.id不为null,而主键甚至不能包含null(因为null是sqlland中的第三个布尔状态)。有true、false和null(这意味着未定义,这显然不能用在主键中,因为主键必须是唯一的,未定义的值可以是任何值,也可以是零,因此它违反了唯一性要求)。所以我假设您实际上在使用这个空检查,因为join期间的temp表似乎包含它们?
编辑:试着把它分成两部分,首先连接两个表,然后连接第三个表和结果。
我建议你简单地看一下“内部连接”和“外部连接”之间的区别因为这是一个非常好的帖子,澄清了很多方面。
对于startest,我会选择这样的:

SELECT
    <i.cols>,
    <b.cols>,
    <mt.cols>, 
    IF(b.confirmed !=2 AND b.live !=0, True, False) sa booked
FROM 
   event_booking b 
LEFT JOIN 
   event_information i ON b.information_id = i.id
LEFT JOIN 
   event_machine_time mt ON b.machine_time_id = mt.id
WHERE <conditions>

后来我把左连接改成更合适的。但是请记住,只有100%确定从联接表列返回的行是唯一的,内部联接才有用。
在i和b表之间是否存在1:n,n:1的关系?我假设不能对同一事件信息(n:1)进行多个预订,也不能对多个事件进行相同的事件信息预订(1:n(不适用)

i34xakig

i34xakig2#

请尝试以下操作:

SELECT machine_laptop, machine_name, B.id AS m_id, C.id AS c_id, C.confirmed 
AS c_confirmed, C.live AS c_live, 
(C.id IS NOT NULL AND C.confirmed !=2 AND C.live !=0) AS booked
FROM event_information A
LEFT JOIN event_booking C ON A.id = C.information_id
RIGHT JOIN event_machine_time B ON B.id = C.machine_time_id
WHERE A.id = :id
ORDER BY `B`.`id` DESC

相关问题