[英]Complicated sql query with variables
這是我的查詢,以獲取每個城市/子類別組合的第一個$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");
我正在使用$contacts->fetchAll(PDO::FETCH_GROUP);
按標題對行進行分組
[
['City 1'] = > [
[ contact 1 ],
[ contact 2 ],
...
],
['City 2'] = > [
[ contact 3 ],
[ contact 4 ],
...
]
...
]
現在我需要升級該查詢,但對我來說太復雜了:(選定的行必須具有唯一的contact.catalog_id值。
怎么做?
“ 我們需要全局唯一的catalog_id ”
為了識別contacts
中catalog_id
唯一值,我們可以使用如下查詢:
SELECT r.catalog_id
FROM contacts r
GROUP BY r.catalog_id
HAVING COUNT(1) = 1
這表示,在給定的行contacts
,如果價值catalog_id
匹配catalog_id
在任何其他行contacts
,這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
編輯
如果規范有不同的解釋,而不是意catalog_id
必須是唯一的接觸,我們的意思是一個catalog_id
不應該在結果重復......我們可以用同樣的方法,但得到的單值id
從contacts
的每個catalog_id
。 我們可以這樣寫一個查詢:
SELECT MAX(r.id) AS max_id
, r.catalog_id
FROM contacts r
GROUP BY r.catalog_id
我們可以使用MIN()聚合代替MAX()。 我們的目標是返回一個contacts.id
的每個離散值catalog_id
。
我們可以將其作為內聯視圖合並到查詢中,使內聯視圖中的max_id
與contacts
中的id
匹配。
像這樣:
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
我們可能希望將外部查詢的WHERE
子句中的條件移動到該內聯視圖中。 如果不這樣做,那么內聯視圖返回的max_id
可能會引用不滿足WHERE
子句條件的contacts
中的行( id
)。
重新定位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.