[英]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.