假设我有一个带有以下字段的mySQL表(用户):
userid
gender
region
age
ethnicity
income
我希望能够根据用户输入的数目返回总记录数。此外,他们还将提供其他标准。
在最简单的示例中,他们可能要求提供1000条记录,其中600条记录的性别应为“男”,而400条记录的性别应为“女”。这很简单。
现在,再往前走一步。假设他们现在要指定Region:
GENDER
Male: 600 records
Female: 400 records
REGION
North: 100 records
South: 200 records
East: 300 records
West: 400 records
同样,只应返回1000条记录,但最后必须有600位男性,400位女性,100位北方人,200位南方人,300位东方人和400位西方人。
我知道这不是有效的语法,但是使用伪mySQL代码,它有望说明我正在尝试执行的操作:
(SELECT * FROM users WHERE gender = 'Male' LIMIT 600
UNION
SELECT * FROM users WHERE gender = 'Female' LIMIT 400)
INTERSECT
(SELECT * FROM users WHERE region = 'North' LIMIT 100
UNION
SELECT * FROM users WHERE region = 'South' LIMIT 200
UNION
SELECT * FROM users WHERE region = 'East' LIMIT 300
UNION
SELECT * FROM users WHERE region = 'West' LIMIT 400)
请注意,我不是在寻找一次性查询。记录的总数和每个条件内的记录数将根据用户的输入不断变化。因此,我正在尝试提出一种可以反复使用的通用解决方案,而不是硬编码的解决方案。
为了使事情变得更复杂,现在添加更多条件。每个组也可能有年龄,种族和收入,并有各自固定的记录数量,上面附加了其他代码:
INTERSECT
(SELECT * FROM users WHERE age >= 18 and age <= 24 LIMIT 300
UNION
SELECT * FROM users WHERE age >= 25 and age <= 36 LIMIT 200
UNION
SELECT * FROM users WHERE age >= 37 and age <= 54 LIMIT 200
UNION
SELECT * FROM users WHERE age >= 55 LIMIT 300)
INTERSECT
etc.
我不确定这是否可以在一个查询中编写,或者是否需要多个语句和迭代。
最佳答案
展平您的标准
您可以将多维标准简化为单级标准
现在,可以通过以下一个查询来实现此标准
(SELECT * FROM users WHERE gender = 'Male' AND region = 'North' LIMIT 40) UNION ALL
(SELECT * FROM users WHERE gender = 'Male' AND region = 'South' LIMIT 80) UNION ALL
(SELECT * FROM users WHERE gender = 'Male' AND region = 'East' LIMIT 120) UNION ALL
(SELECT * FROM users WHERE gender = 'Male' AND region = 'West' LIMIT 160) UNION ALL
(SELECT * FROM users WHERE gender = 'Female' AND region = 'North' LIMIT 60) UNION ALL
(SELECT * FROM users WHERE gender = 'Female' AND region = 'South' LIMIT 120) UNION ALL
(SELECT * FROM users WHERE gender = 'Female' AND region = 'East' LIMIT 180) UNION ALL
(SELECT * FROM users WHERE gender = 'Female' AND region = 'West' LIMIT 240)
问题
调整条件
假设来自北方的男性用户少于40个。然后,您需要调整其他标准数量,以弥补“男性”和“北部”缺少的数量。我相信使用裸露的SQL不可能做到这一点。我想到的是伪代码。为了简化起见,我认为我们只会查询男性,女性,北方和南方
conditions.add({ gender: 'Male', region: 'North', limit: 40 })
conditions.add({ gender: 'Male', region: 'South', limit: 80 })
conditions.add({ gender: 'Female', region: 'North', limit: 60 })
conditions.add({ gender: 'Female', region: 'South', limit: 120 })
foreach(conditions as condition) {
temp = getResultFromDatabaseByCondition(condition)
conditions.remove(condition)
// there is not enough result for this condition,
// increase other condition quantity
if (temp.length < condition.limit) {
adjust(...);
}
}
假设只有30个北风公。因此,我们需要调整+10男性,和+10北方人。
To Adjust
---------------------------------------------------
Male +10
North +10
Remain Conditions
----------------------------------------------------
{ gender: 'Male', region: 'South', limit: 80 }
{ gender: 'Female', region: 'North', limit: 60 }
{ gender: 'Female', region: 'South', limit: 120 }
“男性” +“南部”是与“男性”调整条件匹配的第一个条件。将其增加+10,并将其从“剩余条件”列表中删除。由于我们增加了南方,因此我们需要在其他情况下将其减少。因此,将“南方”条件添加到“调整”列表中
To Adjust
---------------------------------------------------
South -10
North +10
Remain Conditions
----------------------------------------------------
{ gender: 'Female', region: 'North', limit: 60 }
{ gender: 'Female', region: 'South', limit: 120 }
Final Conditions
----------------------------------------------------
{ gender: 'Male', region: 'South', limit: 90 }
查找与“南部”匹配的条件,然后重复相同的过程。
To Adjust
---------------------------------------------------
Female +10
North +10
Remain Conditions
----------------------------------------------------
{ gender: 'Female', region: 'North', limit: 60 }
Final Conditions
----------------------------------------------------
{ gender: 'Female', region: 'South', limit: 110 }
{ gender: 'Male', region: 'South', limit: 90 }
最后
{ gender: 'Female', region: 'North', limit: 70 }
{ gender: 'Female', region: 'South', limit: 110 }
{ gender: 'Male', region: 'South', limit: 90 }
我还没有想出调整的确切实现方式。这比我预期的要难。一旦我弄清楚如何实现它,我将进行更新。
关于mysql - MySQL查询可获取众多带有限制的查询的 “intersection”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27160122/