尝试在表中使用列之间选择数据 - 子查询返回多于1行

时间:2017-10-26 15:51:32

标签: mysql

我遇到问题,我尝试在特定IP范围之间选择数据,所有内容都使用INET_ATOM& INET_NTOA

我一直收到错误'#1242 - 子查询返回超过1行'

导致错误的子查询是:

WHERE
    dst_address NOT BETWEEN(
    SELECT
        INET_NTOA(iprangestart) AS iprangestart
    FROM
        accountingipranges
) AND(
    SELECT
        INET_NTOA(iprangestart) AS iprangestart
    FROM
        accountingipranges

WHERE
     src_address NOT BETWEEN(
     SELECT
           INET_NTOA(iprangestart) AS iprangestart
     FROM
           accountingipranges
    ) AND(
     SELECT
           INET_NTOA(iprangestart) AS iprangestart
     FROM
         accountingipranges

我的整个查询是:

SELECT
    ip_address,
    SUM(upload_bytes) AS upload_bytes,
    SUM(download_bytes) AS download_bytes,
    SUM(upload_bytes + download_bytes) AS totalbytes,
    package_id,
    username,
    networkaccess,
    packagename,
    speedlimit,
    threshold,
    throttlelimit,
    extendeddata,
    datalimitamount,
    accountingdays
FROM
    (
        (
        SELECT
            ipaccounting.src_address AS ip_address,
            SUM(ipaccounting.bytes) AS upload_bytes,
            0 AS download_bytes,
            users.username,
            users.networkaccess,
            users.extendeddata,
            datapackages.package_id,
            datapackages.packagename,
            datapackages.speedlimit,
            datapackages.threshold,
            datapackages.throttlelimit,
            datapackages.datalimitamount,
            datapackages.accountingdays
        FROM
            ipaccounting
        JOIN
            users
        ON
            users.ipaddress = ipaccounting.src_address
        JOIN
            datapackages
        ON
            datapackages.package_id = users.datapackage
        WHERE
            dst_address NOT BETWEEN(
            SELECT
                INET_NTOA(iprangestart) AS iprangestart
            FROM
                accountingipranges
        ) AND(
        SELECT
            INET_NTOA(iprangestart) AS iprangestart
        FROM
            accountingipranges
    ) AND timeanddate BETWEEN SUBDATE(
        CURRENT_TIMESTAMP(), INTERVAL datapackages.accountingdays DAY) 
AND CURRENT_TIMESTAMP()
    GROUP BY
        src_address)
    UNION ALL
        (
        SELECT
            ipaccounting.dst_address AS ip_address,
            0 AS upload_bytes,
            SUM(ipaccounting.bytes) AS download_bytes,
            users.username,
            users.networkaccess,
            users.extendeddata,
            datapackages.package_id,
            datapackages.packagename,
            datapackages.speedlimit,
            datapackages.threshold,
            datapackages.throttlelimit,
            datapackages.datalimitamount,
            datapackages.accountingdays
        FROM
            ipaccounting
        JOIN
            users
        ON
            users.ipaddress = ipaccounting.dst_address
        JOIN
            datapackages
        ON
            datapackages.package_id = users.datapackage
        WHERE
            src_address NOT BETWEEN(
            SELECT
                INET_NTOA(iprangestart) AS iprangestart
            FROM
                accountingipranges
        ) AND(
        SELECT
            INET_NTOA(iprangestart) AS iprangestart
        FROM
            accountingipranges
    ) AND timeanddate BETWEEN SUBDATE(
        CURRENT_TIMESTAMP(), INTERVAL datapackages.accountingdays DAY) 
AND CURRENT_TIMESTAMP()
    GROUP BY
        dst_address)
    ) a
GROUP BY
    ip_address
ORDER BY
    INET_ATON(ip_address)

我的研究表明我失踪了' IN'在某个地方,我已经尝试将它放在不同的地方,但无法做到正确:(

1 个答案:

答案 0 :(得分:2)

Between期待单个结果,下面的子查询返回多行。 您需要添加WHERE子句来限制结果,或者更改此查询以使用连接而不是子查询。

SELECT
    INET_NTOA(iprangestart) AS iprangestart
FROM
    accountingipranges

SELECT
    INET_NTOA(iprangestart) AS iprangestart
FROM
    accountingipranges
WHERE %some condition to ensure only 1 row is returned%

SELECT
    INET_NTOA(iprangestart) AS iprangestart
FROM
    accountingipranges
LIMIT 1

我不认为你的表是这样设置的,但这是一个连接示例。

select *
from sometable A
INNER JOIN accountingipranges B on (%some condition%)
WHERE A.dst_address NOT BETWEEN B.iprange_start AND B.iprange_end

https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_between