Php 从具有多个联接的SQL查询中提取和计算唯一列
我正在尝试解决如何从具有多个联接的SQL查询的结果中的一个给定列中选择X个唯一值,这会产生一些重复,一旦找到X个唯一值,就需要向下过滤(后查询) 一个简单的例子可能是一个结果,其中包含用户id和他们访问过的国家名称的一对多关系 因此,可能需要40、60或6000行结果才能得到10个人,但10是查询中所需的参数,而要返回的实际行数是实现唯一人数所需的任何结果 如果没有太多的信息,我想我会参考真实的PHP/MYSQL示例 在这个例子中,我从一个查询中一次选择10个用户ID,以找到与给定点的距离最匹配的用户,然后是他们演奏的任何乐器的权重,然后是他们演奏的任何风格的权重。(风格和乐器的权重表示每个成员的兴趣或技能水平,其中1是他们最喜欢或最好的) 因为样式和工具权重是结果顺序的一部分,所以我认为我需要运行一个包含多个连接的biq查询,以使所有内容都符合结果的正确优先顺序。)而不是仅仅通过距离搜索,然后在另一个查询中循环搜索这些结果,查看组合的工具和样式信息 一些相关的表及其列 成员:Php 从具有多个联接的SQL查询中提取和计算唯一列,php,mysql,sql,loops,join,Php,Mysql,Sql,Loops,Join,我正在尝试解决如何从具有多个联接的SQL查询的结果中的一个给定列中选择X个唯一值,这会产生一些重复,一旦找到X个唯一值,就需要向下过滤(后查询) 一个简单的例子可能是一个结果,其中包含用户id和他们访问过的国家名称的一对多关系 因此,可能需要40、60或6000行结果才能得到10个人,但10是查询中所需的参数,而要返回的实际行数是实现唯一人数所需的任何结果 如果没有太多的信息,我想我会参考真实的PHP/MYSQL示例 在这个例子中,我从一个查询中一次选择10个用户ID,以找到与给定点的距离最匹配
USER_ID
PASSWORD
FIRST_NAME
LAST_NAME
BIO
BIO_IMAGE
WILL_CONNECT_STATUS
PROFILE_COMPLETE
EMAIL
SIGNUP_DATE
LAST_LOGIN
ACCOUNT_TYPE
EMAIL_ACTIVATED
NOTIFY_MSG int(11)
NOTIFY_CONN_REQ
NOTIFY_PROF_CHANGE
LATITUDE
LONGTITUDE
ID
USER_ID
INSTRUMENT_ID
ACTIVE
WEIGHT
id
name
active
ID
USER_ID
STYLE_ID
ACTIVE
WEIGHT
id
style
active
成员说明:
USER_ID
PASSWORD
FIRST_NAME
LAST_NAME
BIO
BIO_IMAGE
WILL_CONNECT_STATUS
PROFILE_COMPLETE
EMAIL
SIGNUP_DATE
LAST_LOGIN
ACCOUNT_TYPE
EMAIL_ACTIVATED
NOTIFY_MSG int(11)
NOTIFY_CONN_REQ
NOTIFY_PROF_CHANGE
LATITUDE
LONGTITUDE
ID
USER_ID
INSTRUMENT_ID
ACTIVE
WEIGHT
id
name
active
ID
USER_ID
STYLE_ID
ACTIVE
WEIGHT
id
style
active
仪器:
USER_ID
PASSWORD
FIRST_NAME
LAST_NAME
BIO
BIO_IMAGE
WILL_CONNECT_STATUS
PROFILE_COMPLETE
EMAIL
SIGNUP_DATE
LAST_LOGIN
ACCOUNT_TYPE
EMAIL_ACTIVATED
NOTIFY_MSG int(11)
NOTIFY_CONN_REQ
NOTIFY_PROF_CHANGE
LATITUDE
LONGTITUDE
ID
USER_ID
INSTRUMENT_ID
ACTIVE
WEIGHT
id
name
active
ID
USER_ID
STYLE_ID
ACTIVE
WEIGHT
id
style
active
成员\u风格:
USER_ID
PASSWORD
FIRST_NAME
LAST_NAME
BIO
BIO_IMAGE
WILL_CONNECT_STATUS
PROFILE_COMPLETE
EMAIL
SIGNUP_DATE
LAST_LOGIN
ACCOUNT_TYPE
EMAIL_ACTIVATED
NOTIFY_MSG int(11)
NOTIFY_CONN_REQ
NOTIFY_PROF_CHANGE
LATITUDE
LONGTITUDE
ID
USER_ID
INSTRUMENT_ID
ACTIVE
WEIGHT
id
name
active
ID
USER_ID
STYLE_ID
ACTIVE
WEIGHT
id
style
active
样式:
USER_ID
PASSWORD
FIRST_NAME
LAST_NAME
BIO
BIO_IMAGE
WILL_CONNECT_STATUS
PROFILE_COMPLETE
EMAIL
SIGNUP_DATE
LAST_LOGIN
ACCOUNT_TYPE
EMAIL_ACTIVATED
NOTIFY_MSG int(11)
NOTIFY_CONN_REQ
NOTIFY_PROF_CHANGE
LATITUDE
LONGTITUDE
ID
USER_ID
INSTRUMENT_ID
ACTIVE
WEIGHT
id
name
active
ID
USER_ID
STYLE_ID
ACTIVE
WEIGHT
id
style
active
这里有一个测试查询,我到目前为止已经有了。它似乎给了我一个一对多的级联结果集,所有东西都按正确的顺序排列。我知道我的LIMIT参数不能满足我的需要,但我希望将结果范围从返回的原始行数转移到m.USER_ID列中的唯一值数。我只需要能够在“一对多”中选择一系列的“一”——例如1-10、11-20等等。我想我所追求的是某种循环,它检测m.USER_ID的新值,作为检测所需范围的开始和结束的手段
SELECT
m.USER_ID,
m.FIRST_NAME,
m.LAST_NAME,
m.LATITUDE,
m.LONGTITUDE,
mi.INSTRUMENT_ID,
i.name,
mi.WEIGHT AS MI_WEIGHT,
ms.STYLE_ID,
s.style, ms.WEIGHT AS MS_WEIGHT,( 6371 * acos( cos( radians(-38.14854370) ) * cos( radians( LATITUDE ) ) * cos( radians( LONGTITUDE ) - radians(144.36134790) ) + sin( radians(-38.14854370) ) * sin( radians( LATITUDE ) ) ) )
AS distance
FROM members m
INNER JOIN members_inst mi
ON m.USER_ID = mi.USER_ID
INNER JOIN instruments i
ON mi.INSTRUMENT_ID = i.id
INNER JOIN members_styles ms
ON m.USER_ID = ms.USER_ID
INNER JOIN styles s
ON ms.STYLE_ID = s.id
WHERE mi.ACTIVE=1 AND i.active=1 AND mi.WEIGHT != -1 AND ms.WEIGHT!=-1
HAVING distance < 1000 AND USER_ID!= 1 ORDER BY distance, MI_WEIGHT, MS_WEIGHT LIMIT 0 , 10
选择
m、 用户ID,
m、 名字,
m、 姓,
m、 纬度,
m、 长相,
mi.仪器仪表ID,
i、 名字,
mi.重量作为mi_重量,
史迪丽女士,
s、 样式,ms.WEIGHT作为ms_WEIGHT,(6371*acos(弧度(-38.14854370))*cos(弧度(纬度))*cos(弧度(经度)-弧度(144.36134790))+sin(弧度(-38.14854370))*sin(弧度(纬度)))
作为距离
m成员
内部连接成员\u inst mi
在m.USER\u ID=mi.USER\u ID上
内连接仪表i
在mi.INSTRUMENT_ID=i.ID上
内部联接成员
在m.USER\u ID=ms.USER\u ID上
内部连接样式
在ms.STYLE_ID=s.ID上
其中mi.ACTIVE=1,i.ACTIVE=1,mi.WEIGHT!=-1和ms.WEIGHT=-1.
距离<1000且用户ID!=1按距离订购,最小重量,最小重量限制0,10
首先,您需要子查询,以找到适合每个用户的具有最佳重量的乐器和样式。关于文书:
SELECT mi.USER_id,max(i.weight) as max_i_weight
FROM members_inst mi INNER JOIN instruments i ON mi.INSTRUMENT_ID = i.id
WHERE i.weight!=-1 and mi.ACTIVE=1 and i.active=1
GROUP BY mi.USER_ID
至于风格:
SELECT ms.USER_id,max(s.weight) as max_s_weight
FROM members_style ms INNER JOIN styles s ON ms.STYLE_ID = s.id
WHERE s.weight!=-1
GROUP BY ms.USER_ID
这些查询对于以后根据仪器和样式的最大重量对用户进行排序很有用
然后,连接不同的表以构建信息,并按距离、最大仪器重量和最大样式重量(从上述查询中得知)对用户进行排序
选择
m、 用户ID,
m、 名字,
m、 姓,
m、 纬度,
m、 长相,
mi.仪器仪表ID,
i、 名字,
最大重量,
史迪丽女士,
s、 风格,
最大重量,
6371*acos(cos(弧度(-38.14854370))*cos(弧度(纬度))*cos(弧度(经度)-弧度(144.36134790))+sin(弧度(-38.14854370))*sin(弧度(纬度))作为距离
从成员m内部加入成员\u inst mi ON m.USER\u ID=mi.USER\u ID
内部联接(选择mi.USER\u ID,max(i.weight)作为max\u i\u weight
从成员安装mi内部连接mi上的仪表i。仪表ID=i.ID
其中i.weight!=-1,mi.ACTIVE=1,i.ACTIVE=1
按mi.USER\U ID)m.USER\U ID上的最佳仪器分组=最佳仪器.USER\U ID
在mi.INSTRUMENT\u ID=i.ID和best\u INSTRUMENT上的内部连接仪器i。最大\u i\u重量=i.weight
内部联接成员\u样式m.USER\u ID=ms.USER\u ID上的ms
内部联接(选择ms.USER\u id,max(s.weight)作为max\u s\u weight
来自成员\u style ms内部连接样式s ON ms.style\u ID=s.ID
其中s.weight!=-1
按ms.USER\u ID)m.USER\u ID上的最佳样式分组=最佳样式.USER\u ID
ms.STYLE\u ID=s.ID和best\u STYLE.max\u s\u weight=s.weight上的内部连接样式s
其中用户_ID!=1.
按m.USER\u ID分组
距离小于1000的
按距离订购,最大重量,最大重量
限值0,10;
通过增加距离,然后增加仪器重量,然后增加样式重量,结果应该是前十个用户的列表(没有任何重复)。
我不尝试,但它应该工作,除了一些打字错误 所以“更轻”的重量更重要。真遗憾-(我可以在没有太多问题的情况下切换它们。因此,您需要10个不同的用户,仅此而已?(即,同一用户不会在结果中以不同的样式或工具出现两次)是的。我希望一次呈现10个名称,以及它们的工具和样式(无论这两个列表中有多少个)以及按距离顺序列出的名称,然后是仪器权重,然后是样式权重,这些顺序是从完整结果集派生的(在折叠为唯一名称之前)。