SQL OR NOT EXISTS 无效
SQL OR NOT EXISTS doesn't work
我有一个关于以下不起作用的查询的问题:
{thistable}.id IN (
SELECT id
FROM fab_booking_slots AS slots
WHERE id = '{fab_booking___book_starttime_raw}'
OR NOT EXISTS (
SELECT id +1 FROM (
SELECT taken.book_date, slots.*, count(taken.book_date) AS nbre
FROM fab_booking_taken AS taken
CROSS JOIN fab_booking_slots AS slots
WHERE NOT ((slots.heuredepart_resa < taken.book_end
AND slots.heurearrivee_resa > taken.book_start))
AND DATE(taken.book_date) = DATE('{fab_booking___book_bookingdate}')
GROUP BY slots.id) AS x
WHERE nbre = (
SELECT count(taken.book_date)
FROM fab_booking_taken AS taken
WHERE taken.book_date = x.book_date)
)
)
Order BY id ASC
此查询应 return 数据库中已存在的下拉列表中的值,如果它们是可用槽,则为可用槽。
当我 运行 2 SELECT 独立工作时,他们正在工作。
感谢这里的一些专业知识,因为我找不到原因而且我被困住了。
此主题跟在以下主题之后:
Whosebug
表格可以在那里下载。
提前感谢您的支持。
干杯,
马克
在这种情况下,我认为错误在于您使用 WHERE NOT EXISTS
的方式。如果您的子查询 return 没有行,这将 return true
。通常,您与 EXISTS
或 NOT EXISTS
一起使用的子查询将是一个 correlated subquery,它引用外部 select 中的列(在您的情况下为 fab_booking_slots
),以便子查询 return 对外部 select 的每一行都有不同的结果。
因此,您可能已经知道足够多的理论(假设它是为未来的读者准备的),您在这里所做的是没有将子查询与外部引用相关联。由于您在外部查询和子查询中都使用了相同的 table 别名 slots
,所以这很复杂。我会分配不同的别名以防止混淆。
我已经稍微简化了您的子查询中的逻辑,这应该仍然是 return 正确的结果。请注意,午夜后的时间有一个陷阱,因此我们需要通过在这些时间上增加一天来处理它们,然后比较才能正常进行:
{thistable}.id IN (
SELECT t.id
FROM fab_booking_slots AS t
WHERE t.id = null
OR NOT EXISTS (
Select 1
From (Select book_date,
Convert(book_start, datetime) As book_start,
Case When book_end < '02:00:00' Then Date_Add(Convert(book_end, datetime), INTERVAL 1 DAY) Else Convert(book_end, datetime) End As book_end
From fab_booking_taken) AS p1
Where Date(p1.book_date) = '2017-01-10'
And Convert(p1.book_end, datetime) > Convert(t.heuredepart_resa, datetime)
And Convert(p1.book_start, datetime) < Case When t.heurearrivee_resa < '02:00:00' Then Date_Add(Convert(t.heurearrivee_resa, datetime), INTERVAL 1 DAY) Else Convert(t.heurearrivee_resa, datetime) End
)
)
Order BY id ASC;
我有一个关于以下不起作用的查询的问题:
{thistable}.id IN (
SELECT id
FROM fab_booking_slots AS slots
WHERE id = '{fab_booking___book_starttime_raw}'
OR NOT EXISTS (
SELECT id +1 FROM (
SELECT taken.book_date, slots.*, count(taken.book_date) AS nbre
FROM fab_booking_taken AS taken
CROSS JOIN fab_booking_slots AS slots
WHERE NOT ((slots.heuredepart_resa < taken.book_end
AND slots.heurearrivee_resa > taken.book_start))
AND DATE(taken.book_date) = DATE('{fab_booking___book_bookingdate}')
GROUP BY slots.id) AS x
WHERE nbre = (
SELECT count(taken.book_date)
FROM fab_booking_taken AS taken
WHERE taken.book_date = x.book_date)
)
)
Order BY id ASC
此查询应 return 数据库中已存在的下拉列表中的值,如果它们是可用槽,则为可用槽。
当我 运行 2 SELECT 独立工作时,他们正在工作。
感谢这里的一些专业知识,因为我找不到原因而且我被困住了。
此主题跟在以下主题之后:
Whosebug
表格可以在那里下载。
提前感谢您的支持。
干杯,
马克
在这种情况下,我认为错误在于您使用 WHERE NOT EXISTS
的方式。如果您的子查询 return 没有行,这将 return true
。通常,您与 EXISTS
或 NOT EXISTS
一起使用的子查询将是一个 correlated subquery,它引用外部 select 中的列(在您的情况下为 fab_booking_slots
),以便子查询 return 对外部 select 的每一行都有不同的结果。
因此,您可能已经知道足够多的理论(假设它是为未来的读者准备的),您在这里所做的是没有将子查询与外部引用相关联。由于您在外部查询和子查询中都使用了相同的 table 别名 slots
,所以这很复杂。我会分配不同的别名以防止混淆。
我已经稍微简化了您的子查询中的逻辑,这应该仍然是 return 正确的结果。请注意,午夜后的时间有一个陷阱,因此我们需要通过在这些时间上增加一天来处理它们,然后比较才能正常进行:
{thistable}.id IN (
SELECT t.id
FROM fab_booking_slots AS t
WHERE t.id = null
OR NOT EXISTS (
Select 1
From (Select book_date,
Convert(book_start, datetime) As book_start,
Case When book_end < '02:00:00' Then Date_Add(Convert(book_end, datetime), INTERVAL 1 DAY) Else Convert(book_end, datetime) End As book_end
From fab_booking_taken) AS p1
Where Date(p1.book_date) = '2017-01-10'
And Convert(p1.book_end, datetime) > Convert(t.heuredepart_resa, datetime)
And Convert(p1.book_start, datetime) < Case When t.heurearrivee_resa < '02:00:00' Then Date_Add(Convert(t.heurearrivee_resa, datetime), INTERVAL 1 DAY) Else Convert(t.heurearrivee_resa, datetime) End
)
)
Order BY id ASC;