[英]Complicated sql query with variables
That's my query to get first $count
rows for each city/subcategory combination 这是我的查询,以获取每个城市/子类别组合的第一个
$count
行
$contacts = $dbh->prepare("
SELECT *
FROM (SELECT c.*,
(@rn := IF(@cc = CONCAT_WS(':', city_id, subcategory_id), @rn + 1,
IF(@cc := CONCAT_WS(':', city_id, subcategory_id), 1, 1)
)
) as rn
FROM (SELECT reg.title as region_title, cnt.title, cnt.city_id, cnt.id, cnt.catalog_id, cnt.address, cnt.phone, cnt.email, cnt.website, cnt.subcategory_title, cnt.subcategory_id, cnt.manufacturer
FROM contacts as cnt
LEFT JOIN regions as reg
ON cnt.city_id = reg.id
WHERE city_id IN (".implode(',', $regions).") AND
subcategory_id IN (".implode(',', $categories).")
ORDER BY subcategory_title, city_id, title
) c CROSS JOIN
(SELECT @cc := '', @rn := 0) params
) c
WHERE rn <= $count");
And i'm using $contacts->fetchAll(PDO::FETCH_GROUP);
我正在使用
$contacts->fetchAll(PDO::FETCH_GROUP);
to group rows by reg.title 按标题对行进行分组
[
['City 1'] = > [
[ contact 1 ],
[ contact 2 ],
...
],
['City 2'] = > [
[ contact 3 ],
[ contact 4 ],
...
]
...
]
Now I need to upgrade that query but it's too complicated for me :( Selected rows must have unique contacts.catalog_id value. 现在我需要升级该查询,但对我来说太复杂了:(选定的行必须具有唯一的contact.catalog_id值。
How it can be done? 怎么做?
UPD UPD
Here is a demo database - http://sqlfiddle.com/#!9/ac71d7/2 这是一个演示数据库-http ://sqlfiddle.com/#!9/ ac71d7/2
" We need unique catalog_id globally " “ 我们需要全局唯一的catalog_id ”
To identify unique values of catalog_id
in contacts
, we could use a query like this: 为了识别
contacts
中catalog_id
唯一值,我们可以使用如下查询:
SELECT r.catalog_id
FROM contacts r
GROUP BY r.catalog_id
HAVING COUNT(1) = 1
That says, for a given row in contacts
, if the value of catalog_id
matches catalog_id
on any other row in contacts
, that catalog_id
will be excluded from the result. 这表示,在给定的行
contacts
,如果价值catalog_id
匹配catalog_id
在任何其他行contacts
,这catalog_id
将被从结果中排除。
If we want to restrict the original query to returning only those values of catalog_id
, we could include this query as an inline view, and join that to rows in contacts with matching catalog_id. 如果我们希望将原始查询限制为仅返回那些
catalog_id
值,则可以将该查询作为内联视图包括在内,并将其连接到与catalog_id匹配的联系人中的行。
FROM contacts cnt
-- ------------
JOIN ( SELECT r.catalog_id
FROM contacts r
GROUP BY r.catalog_id
HAVING COUNT(1) = 1
) s
ON s.catalog_id = cnt.catalog_id
-- ------------
LEFT
JOIN regions reg
ON reg.id = cnt.city_id
EDIT 编辑
If the specification is interpreted differently, instead of meaning catalog_id
must be unique in contacts, we mean that a catalog_id
should not be repeated in the result... we can use the same approach, but get single value of id
from contacts
for each catalog_id
. 如果规范有不同的解释,而不是意
catalog_id
必须是唯一的接触,我们的意思是一个catalog_id
不应该在结果重复......我们可以用同样的方法,但得到的单值id
从contacts
的每个catalog_id
。 We could write a query like this: 我们可以这样写一个查询:
SELECT MAX(r.id) AS max_id
, r.catalog_id
FROM contacts r
GROUP BY r.catalog_id
We could use MIN() aggregate in place of MAX(). 我们可以使用MIN()聚合代替MAX()。 The goal is to return a single
contacts.id
for each discrete value of catalog_id
. 我们的目标是返回一个
contacts.id
的每个离散值catalog_id
。
We can incorporate that into the query as an inline view, matching max_id
from the inline view to the id
from contacts
table. 我们可以将其作为内联视图合并到查询中,使内联视图中的
max_id
与contacts
中的id
匹配。
Something like this: 像这样:
FROM contacts cnt
-- ------------
JOIN ( SELECT MAX(r.id) AS max_id
FROM contacts r
WHERE ...
GROUP BY r.catalog_id
) s
ON s.max_id = cnt.id
-- ------------
LEFT
JOIN regions reg
ON reg.id = cnt.city_id
We probably want to move the conditions in the WHERE
clause of the outer query into that inline view. 我们可能希望将外部查询的
WHERE
子句中的条件移动到该内联视图中。 If we don't, then the max_id
returned by the inline view might reference an row ( id
) in contacts
that doesn't satisfy the conditions in the WHERE
clause. 如果不这样做,那么内联视图返回的
max_id
可能会引用不满足WHERE
子句条件的contacts
中的行( id
)。
Relocating the WHERE
conditions on cnt
into the inline view ... 重新定位
WHERE
上条件cnt
入联视图...
SELECT d.*
FROM ( SELECT c.*
, ( @rn := IF( @cc = CONCAT_WS(':', city_id, subcategory_id)
, @rn + 1
, IF( @cc := CONCAT_WS(':', city_id, subcategory_id),1,1)
)
) AS rn
FROM ( SELECT reg.title AS region_title
, cnt.title
, cnt.city_id
, cnt.id
, cnt.catalog_id
, cnt.address
, cnt.phone
, cnt.email
, cnt.website
, cnt.category_title
, cnt.subcategory_title
, cnt.subcategory_id
, cnt.manufacturer
FROM contacts cnt
-- --------------
JOIN ( SELECT MAX(r.id) AS max_id
FROM contacts r
WHERE r.city_id IN ( ... )
AND r.subcategory_id IN ( ... )
AND r.email IS NOT NULL
AND r.manufacturer = 1
GROUP BY r.catalog_id
) s
ON s.max_id = cnt.id
-- --------------
LEFT
JOIN regions reg
ON reg.id = cnt.city_id
ORDER
BY cnt.category_title
, cnt.subcategory_title
, cnt.city_id
, cnt.title
) c
CROSS
JOIN ( SELECT @cc := '', @rn := 0) i
) d
WHERE d.rn <= 10
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.