繁体   English   中英

MySQL从另一个表中选择值数组

[英]mysql Select array of values from another tables values

我已经对此进行了几次搜索,但是不幸的是,由于查询类型的不同,它总是给我PHP答案。

我将恢复为代码来生成脚本,但是考虑得越多,我知道在单个查询中必须有一种更简单的方法来完成该脚本,这将更快。

我的代码:

SELECT DISTINCT
se.mailingID AS "mailingID",
(
    SELECT
        SUM(l.averageReadTime) 
    FROM
        eventlog AS l
    INNER JOIN sends as s ON l.mailingIDKey=s.id
    WHERE
        s.TFPIDSanitised=se.TFPIDSanitised
        AND
        l.averagerEadtIme!="-1"
        AND
        l.averageReadTime!="(none)"
) AS "Total",
(
    SELECT
        SUM(l.averageReadTime)
   FROM
        eventlog AS l
    INNER JOIN recipients AS r ON l.recipientKey=r.id
    INNER JOIN devices AS d ON r.commonDeviceKey=d.id
    INNER JOIN sends AS s ON l.mailingIDKey=s.id
    WHERE 
        d.name="AOL Mail"
        AND
        s.mailingID=se.mailingID
        AND
        l.averageReadTime!="-1"
        AND
        l.averageReadTime!="(none)"
) AS "AOL Mail",
...
[repeat for all email app types]
...
(
    SELECT
        SUM(l.averageReadTime)
    FROM
        eventlog AS l
    INNER JOIN recipients AS r ON l.recipientKey=r.id
    INNER JOIN devices AS d ON r.commonDeviceKey=d.id
    INNER JOIN sends AS s ON l.mailingIDKey=s.id
    WHERE
        d.name="AOL Desktop"
        AND
        s.mailingID=se.mailingID
        AND
        l.averageReadTime!="-1"
        AND
        l.averageReadTime!="(none)"
) AS "AOL Desktop"
FROM sends AS se
WHERE
    (
        se.sendDateTime BETWEEN '2018-01-01 00:00:00' AND '2018-01-15 23:59:59'
    );

如您所见,它是查询的庞然大物。

我已经在考虑删除内部联接之一(设备名称,然后仅在devices.id上搜索,而无需第三个JOIN)。

我要做的是在查询中执行某种循环:

所以就像(我知道不是真正的代码)

SELECT LOOP (devices)
    where device.id=recipients.commonDeviceKey
    AS device.name

mysql根本就没有这样的东西吗? 我正在循环(讽刺的是,这并没有让我失望),因为mysql和loop不会带来相关的答案。

我想像这样的事情会起作用。 我没有确切的架构,但这应该可以满足您的需求。

SELECT s.mailingID, SUM(l.averageReadTime), 'Total' as name
FROM eventlog AS l
  JOIN sends as s ON l.mailingIDKey=s.id
 WHERE
  l.averagerEadtIme!="-1"
  AND l.averageReadTime!="(none)"
  AND s.sendDateTime BETWEEN '2018-01-01 00:00:00' AND '2018-01-15 23:59:59'

UNION ALL

SELECT s.mailingID, SUM(l.averageReadTime), d.name 
FROM eventlog AS l
  JOIN recipients AS r ON l.recipientKey=r.id
  JOIN devices AS d ON r.commonDeviceKey=d.id
  JOIN sends AS s ON l.mailingIDKey=s.id
 WHERE 
  l.averageReadTime!="-1"
  AND l.averageReadTime!="(none)"
  AND s.sendDateTime BETWEEN '2018-01-01 00:00:00' AND '2018-01-15 23:59:59'
GROUP BY d.name
;

我希望找到一种更灵活的方法,最后我将在一个循环中使用脚本来使用数据库动态创建“ devicesList”,但以下方法可以工作。

感谢@Napoli的帮助,虽然您可能还没有提供给我答案,但是您却使我沿着不同的思路(每个设备使用线性表的2步过程)进行思考。

def reports_engagement_device_archive():
    selectList = []
    selectString = ""
    devicesList = [
        "aoldesktop|4|AOL Desktop",
        "aolmail|14|AOL Mail",
        "appleipad|24|Apple iPad",
        "appleiphone|34|Apple iPhone",
        "applemail|44|Apple Mail",
        "blackberry|54|BlackBerry",
        "gmail|64|Gmail",
        "googleandroid|74|Google Android",
        "icloud|84|iCloud",
        "officethreesixfive|394|Office 365",
        "other|94|Other",
        "outlook|104|Outlook",
        "outlookcom|114|Outlook.com",
        "samsungemailapp|124|Samsung Email App",
        "samsungemailapp|134|Samsung Mail",
        "thunderbird|364|Thunderbird",
        "webversion|144|Web version",
        "windowslivemail|154|Windows Live Mail",
        "windowsmail|164|Windows Mail",
        "windowsphone|174|Windows Phone",
        "yahoomail|184|Yahoo! Mail"
    ]
    for devString in devicesList:
        (tblName, devID, devName) = devString.split("|")
        dropMySQLTable("temp_" + tblName ,verbose)
        selectList.append("""(SELECT SUM(t.total) FROM temp_""" + tblName + """ AS t WHERE t.mailingID=s.mailingID) AS \"""" + devName +  """\"""")
        db.sql("""
                CREATE TABLE temp_""" + tblName + """ AS (
                    SELECT s.mailingID,SUM(l.averageReadTime) AS "total" FROM eventlog AS l
                    INNER JOIN recipients AS r ON l.recipientKey=r.id
                    INNER JOIN sends AS s ON l.mailingIDKey=s.id
                    WHERE r.commonDeviceKey=""" + devID + """ AND l.averageReadTime!="-1" AND l.averageReadTime!="(none)" AND (s.sendDateTime BETWEEN '""" + startDate + """' AND '""" + endDate + """')
                    GROUP BY s.mailingID
                );
        """, verbose)
    selectString = ",".join(selectList)
    dropMySQLTable("t1" ,verbose)
    db.sql("""
        CREATE TABLE t1 AS (
            SELECT DISTINCT
            s.mailingID AS "mailingID"
            s.TFPIDSanitised AS "TFPID Sanitised",
            (SELECT SUM(l2.averageReadTime) FROM eventlog AS l2 INNER JOIN sends as s2 ON l2.mailingIDKey=s2.id WHERE s2.TFPIDSanitised=s.TFPIDSanitised AND l2.averageReadTime!="-1" AND l2.averageReadTime!="(none)") AS "Total",
            """ + selectString + """
            FROM sends AS s
            WHERE s.TFPIDSanitised IS NOT NULL
            AND (s.sendDateTime BETWEEN '""" + startDate + """' AND '""" + endDate + """')
        );
    """, verbose)
    for devString in devicesList:
        (tblName, devID, devName) = devString.split("|")
        dropMySQLTable("temp_" + tblName ,verbose)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM