如何运行有条件地使用连接的连接查询

时间:2017-09-28 12:22:15

标签: sql postgresql

我有以下架构:

Freelancers
===========
Id
Availabilities
===========
Date
available (bool)
freelancer_id
GeneralAvailabilities
===========
Date
available (bool)
freelancer_id

我希望得到在指定日期可用的所有自由职业者。如果满足以下任何条件,则可以使用自由职业者

  1. 他们在该日期没有AvailabilityGeneralAvailability
  2. 他们在该日期有一个GeneralAvailabilityavailable设为真
  3. 他们在该日期有一个Availabilityavailable设置为true。
  4. 如果他们将Availability设置为false但GeneralAvailability设置为true,则availabile的{​​{1}}值设置为true时,自由职业者可用真。

    换句话说,要查看自由职业者在给定日期是否可用,请检查该日期的Availability的布尔值,如果该日期没有Availability,请检查布尔值该日期Availability。如果该日期没有GeneralAvailabilityAvailability,则默认情况下可用。

    我到目前为止的SQL WHERE语句如下:

    GeneralAvailability

    这适用于大多数情况,除非WHERE ( ( availabilities.id IS NULL ) OR NOT ( availabilities.date = ? AND availabilities.available = false ) ) OR ( ( general_availabilities.id IS NULL ) OR NOT ( general_availabilities.weekday = ? AND general_availabilities.available = false ) ) 为假且Availability为真。在这种情况下,不应该返回自由职业者,因为GeneralAvailability应该取代Availability,并且如果该日期没有GeneralAvailability,则只返回GeneralAvailability。< / p>

    希望这是有道理的!非常感谢您花时间看看我的问题。

    乔什

3 个答案:

答案 0 :(得分:2)

使用日期左连接到可用性表,然后根据&#34;没有成功加入&#34;之前&#34;有一个真正的&#34;

select
    freelancers.id
from
    freelancers
    left join availabilities on(
        availabilities.freelancer_id = freelancers.id
        and availabilities.date = '2017.09.28'::date
    )
    left join general_availabilities on(
        general_availabilities.freelancer_id = freelancers.id
        and general_availabilities.date = '2017.09.28'::date
    )
where
    (
        availabilities is null
        and general_availabilities is null
    )
    or availabilities.available = true
    or (
        availabilities is null
        and general_availabilities.available = true
    )

答案 1 :(得分:0)

也许您应该提供一些数据集样本。但我从你的逻辑中感觉到OR是错误的。 也许这样的事情会更好?

WHERE (
  ( availabilities.id IS NULL )
  AND NOT (
    availabilities.date = ?
    AND
    availabilities.available = false
  )
) OR (
  ( general_availabilities.id IS NULL )
  AND NOT (
    general_availabilities.weekday = ?
    AND
    general_availabilities.available = false
  )
)

否则我认为您应该提供一些示例数据来演示您的示例。

答案 2 :(得分:0)

要分析多个条件,可以使用&#34; table&#34;像这样,称为&#34;真值表&#34;。

据我了解你的问题,可以是:

+---+-----------------+----------------+-----------------------------+----------------+-----------------------+
|   | TAB.            |                | TAB. GENERAL                |                |        OUTPUT         |
|   | AVAILABILITIES  |                |   AVAILABILITIES            |                |                       |
+---+-----------------+----------------+-----------------------------+----------------+-----------------------+
|   | DATE            | flag AVAILABLE | DATE                        | flag AVAILABLE | Free lancer Available |
| 1 | present         | F              | present                     | F              | F                     |
| 2 | present         | F              | not present                 | --             | T                     |
| 3 | present         | F              | present                     | T              | F                     |
| 4 | present         | T              | present                     | F              | T                     |
| 5 | present         | T              | not present                 | --             | T                     |
| 6 | present         | T              | present                     | T              | T                     |
| 7 | not present     | --             | present                     | F              | T                     |
| 8 | not present     | --             | not present                 | --             | T                     |
| 9 | not present     | --             | present                     | T              | T                     |
+---+-----------------+----------------+-----------------------------+----------------+-----------------------+

使用它,为您的查询编写条件(如果您修改上面的真值表,我们可以更改WHERE条件)可以非常简单地为给定日期选择可用的自由职业者(xxx是您的日期;我缩短了简单性一些字段和表名称,但我认为你可以看到它):

SELECT A.ID
FROM FREELANCER A
LEFT JOIN AVAILAB B ON A.ID = B.FREEL_ID AND B.DATE = xxx
LEFT JON GENERAL_AVAILAB C ON A.ID = C.FREEL_ID AND C.DATE = xxx
WHERE  B.AVAILABLE IS NULL OR B.AVAILABLE = TRUE  OR C.AVAILABLE IS NULL

如果您发布样本数据或告诉我条件,我可以测试/更改查询。

相关问题