为什么有两个LEFT JOINS会产生附加值?

时间:2020-04-23 03:53:25

标签: mysql

我试图合并三个表,一个与另一个表相关,另一个与另一个表相关,同时显示其中一个表USERS的所有行。然后,我计算每个用户有来自TICKET的TCKID和来自SEQUENCE的TCKID。这些表的相关性如下:用户<-票证<-序列

由于某种原因,当我运行查询时,前三行的“发出的机票”是2而不是1,这是在我添加第二个LEFT JOIN之后发生的。这是为什么?

USERS
+-------+-----------------------+
| USRID |         Name          |
+-------+-----------------------+
|     1 | Lula Wiley            |
|     2 | Isabell Horn          |
|     3 | Usman Hook            |
|     4 | Abdullah Singleton    |
+-------+-----------------------+

TICKET
+-------+-------+
| TCKID | USRID |
+-------+-------+
|     1 |     1 |
|     2 |     2 |
|     3 |     7 |
|     4 |    14 |
|     5 |    14 |
|     6 |     6 |
|     7 |     3 |
|     8 |     9 |
+-------+-------+

SEQUENCE
+-------+
| TCKID |
+-------+
|     1 |
|     1 |
|     2 |
|     2 |
|     3 |
|     4 |
|     5 |
|     6 |
|     6 |
|     7 |
|     7 |
|     8 |
+-------+

这是我的表格在运行时显示的内容:

+-----------------------+----------------+---------------+
|         Name          | Tickets Issued | Total Flights |
+-----------------------+----------------+---------------+
| Lula Wiley            |              2 |             2 |
| Isabell Horn          |              2 |             2 |
| Usman Hook            |              2 |             2 |
| Abdullah Singleton    |              0 |             0 |
+-----------------------+----------------+---------------+

这是我的代码

SELECT
    U.Name,
    COUNT(T.USRID) AS 'Tickets Issued',
    COUNT(S.TCKID) AS 'Total Flights'
FROM
    Users U
LEFT JOIN ticket T
    ON U.USRID = T.USRID
LEFT JOIN sequence S        -- Changes Tickets issued 
    ON T.TCKID = S.TCKID
GROUP BY U.Name, U.Phone, T.USRID, U.USRID

2 个答案:

答案 0 :(得分:2)

您的问题是,当您JOIN sequenceticket时,您会在结果集中为sequence中的每一行创建一行。这会导致USRID中的ticket值重复(尝试仅使用SELECT *,您将看到此情况),这导致对Tickets Issued值的计数加倍(或更多)。您可以通过计算TCKID中不同的ticket来解决此问题:

SELECT
    U.Name,
    COUNT(DISTINCT T.TCKID) AS 'Tickets Issued',
    COUNT(S.TCKID) AS 'Total Flights'
FROM
    Users U
LEFT JOIN ticket T
    ON U.USRID = T.USRID
LEFT JOIN sequence S        -- Changes Tickets issued 
    ON T.TCKID = S.TCKID
GROUP BY U.Name, U.USRID
ORDER BY U.USRID

输出:

Name                Tickets Issued  Total Flights
Lula Wiley          1               2
Isabell Horn        1               2
Usman Hook          1               2
Abdullah Singleton  0               0

Demo on dbfiddle

答案 1 :(得分:0)

尝试一下

SELECT
    U.Name,
    COUNT(T.USRID) AS 'Tickets Issued',
    (
        SELECT COUNT(*)
        FROM sequence S
        WHERE S.TCKID = T.TCKID
    ) AS 'Total Flights'
FROM
    Users U
LEFT JOIN ticket T
    ON U.USRID = T.USRID
GROUP BY U.Name, U.Phone, T.USRID

SELECT
    U.Name,
    COUNT(T.USRID) AS 'Tickets Issued',
    T_TOTAL_FLIGHT.total_flights AS 'Total Flights'
FROM
    Users U
LEFT JOIN ticket T
    ON U.USRID = T.USRID
LEFT JOIN (
    SELECT TCKID, COUNT(*) AS total_flights
    FROM sequence
    GROUP BY TCKID
) T_TOTAL_FLIGHT ON T.TCKID = T_TOTAL_FLIGHT.TCKID
GROUP BY U.Name, U.Phone, T.USRID