SQL查询返回一些等于0的行,而它不应该

时间:2018-05-16 16:07:09

标签: sql

我有这三张桌子:

___卡迪斯

|--------|---------|-------------|
| KDX_Id | KDX_VIP | KDX_Regular |
|--------|---------|-------------|
| 1      |      No |          No |
| 2      |      No |          No |
|--------|---------|-------------|

___ BillableDatas

|--------|---------------|
| BIL_Id | BIL_BookingId |
|--------|---------------|
| 1      |            99 |
| 2      |            99 | 
| 3      |           100 | 
|--------|---------------|

___预订

|--------|--------------|
| BOO_Id | BOO_ClientId |
|--------|--------------|
|     99 |            1 |
|    100 |            2 | 
|--------|--------------|

我想循环到___Kardex并计算每个客户端:

  • 客户预订的预订次数(包含在___预订中)。

  • 客户花费的夜数(包含在___ BillableDatas中)。

所以我试过了:

SELECT 
    KDX_Id, 
    (
        SELECT COUNT(BOO_Id) 
        FROM ___Bookings
        WHERE KDX_Id = ___Bookings.BOO_ClientId
    ) AS nb_bookings,
    (
        SELECT COUNT(BIL_Id) 
        FROM ___Bookings, ___BillableDatas
        WHERE ___Bookings.BOO_Id = ___BillableDatas.BIL_BookingId
        AND KDX_Id = ___Bookings.BOO_ClientId
    ) AS nb_nights 
FROM  ___Kardex

我的问题是:查询会返回___Kardex中的所有行,而我只想查看nb_bookingsnb_nights> = 1的行。

你能帮忙吗?

这里是SQLFiddle:http://sqlfiddle.com/#!9/b1b497/1

预期结果是:

|--------|-------------|-----------|
| KDX_Id | nb_bookings | nb_nights |
|--------|-------------|-----------|
| 1      |           1 |         2 |
| 2      |           1 |         1 |
|--------|-------------|-----------|

感谢。

4 个答案:

答案 0 :(得分:0)

快速而肮脏,在WHERE中复制子查询并检查它们是否> = 1。

SELECT 
    KDX_Id, 
    (
        SELECT COUNT(BOO_Id) 
        FROM ___Bookings
        WHERE KDX_Id = ___Bookings.BOO_ClientId
    ) AS nb_bookings,
    (
        SELECT COUNT(BIL_Id) 
        FROM ___Bookings, ___BillableDatas
        WHERE ___Bookings.BOO_Id = ___BillableDatas.BIL_BookingId
        AND KDX_Id = ___Bookings.BOO_ClientId
    ) AS nb_nights 
FROM  ___Kardex
WHERE
    (
        SELECT COUNT(BOO_Id) 
        FROM ___Bookings
        WHERE KDX_Id = ___Bookings.BOO_ClientId
    ) >= 1
    OR
    (
        SELECT COUNT(BIL_Id) 
        FROM ___Bookings, ___BillableDatas
        WHERE ___Bookings.BOO_Id = ___BillableDatas.BIL_BookingId
        AND KDX_Id = ___Bookings.BOO_ClientId
    ) >= 1

答案 1 :(得分:0)

最简单的方法是子查询:

SELECT *
FROM (SELECT k.KDX_Id, 
            (SELECT COUNT(BOO_Id) 
             FROM ___Bookings b
             WHERE k.KDX_Id = b.BOO_ClientId
            ) AS nb_bookings,
            (SELECT COUNT(BIL_Id) 
             FROM ___Bookings b JOIN
                  ___BillableDatas bd
                  ON b.BOO_Id = bd.BIL_BookingId AND
                     k.KDX_Id = b.BOO_ClientId
           ) AS nb_nights 
     FROM  ___Kardex k
    ) k
WHERE nb_bookings > 0 OR nb_nights > 0;

请注意查询的其他更改:

  • 从不FROM子句中使用逗号。 始终使用正确,明确,标准的JOIN语法。
  • 表别名使查询更容易编写和阅读。
  • 如果查询中有多个表,则限定所有列引用。

如果您使用的是MySQL,则甚至不需要子查询。你可以放:

HAVING nb_bookings > 0 OR nb_nights > 0

在您的查询结束时。

答案 2 :(得分:0)

您也可以使用JOINS(即INNER JOIN),但使用正确的 JOIN 语法:

select k.KDX_Id,t.nb_bookings, t1.nb_nights  
from ___Kardex k
inner join (
    select  BOO_ClientId, count(*) nb_bookings
    from ___Bookings
    group by BOO_ClientId
           ) t on t.BOO_ClientId = k.KDX_Id 
inner join (
     select b.BOO_ClientId, COUNT(bl.BIL_Id) nb_nights
     from ___Bookings b
     inner join  ___BillableDatas bl on bl.BIL_BookingId = b.BOO_Id
     group by b.BOO_ClientId
           ) t1 on t1.BOO_ClientId = k.KDX_Id;

请参阅Demo

答案 3 :(得分:0)

select k.KDX_Id, COUNT(BOO_Id) as nb_bookings, COUNT(bd.BIL_Id) as nb_nights
from ___Kardex k
inner join ___Bookings b on k.KDX_Id = b.BOO_ClientId
inner join ___BillableDatas bd on bd.BIL_BookingId = b.BOO_Id
group by k.KDX_Id