[英]How to make a nested query for a specific condition in MySQL
我進行了此查詢,在其中可以獲取按狀態顯示的項目列表,並獲取每個狀態的數量。 這是查詢:
SELECT DISTINCT (status) AS Status, COUNT(status) AS Quantity
FROM projects
GROUP BY status
ORDER BY Quantity DESC
結果如下:
Status Quantity
'PRO', 238
'TER', 75
'SUS', 14
'REI', 3
現在,對於那些具有“ TER”狀態的產品,我想獲得今年已更新或修改的那些“ TER”狀態,並將它們添加到結果中(不包括往年的那些“ TER”產品)。 為此,我需要將此列updated_at
(可以這么說)。
如何過濾這些值?
例如,我嘗試過:
SELECT DISTINCT (status) AS Status, COUNT(status) AS Quantity,
IF(status='TER',SELECT * FROM projects WHERE year(updated_at)=YEAR(CURDATE()))
FROM projects
GROUP BY status
ORDER BY Quantity DESC
但這沒有用。
有任何想法嗎?
感謝您的想法。
可能的解決方案 :
我已經通過使用UNION找到了另一種解決方案:
(SELECT DISTINCT (status) AS Status, COUNT(status) AS Quantity,
IF(status='TER',SELECT * FROM projects WHERE year(updated_at)=YEAR(CURDATE()))
FROM projects
GROUP BY status
ORDER BY Quantity DESC)
UNION
(
SELECT DISTINCT (status) AS Status, COUNT(status) AS Quantity,
IF(status='TER',SELECT * FROM projects WHERE year(updated_at)=YEAR(CURDATE()))
FROM projects
WHERE year(updated_at) = YEAR(curdate())
AND status IN ('TER')
GROUP BY status
ORDER BY Quantity DESC
)
因此,現在我將那些項目設為“ TER”狀態,並且只將其當年。
因此,“ TER”的過濾器結果現在為(應該是更少的結果):
Status Quantity
'PRO', 238
'SUS', 14
'REI', 3
'TER', 45
現在的問題是我需要重新排列結果,我的意思是,'TER'應該排在第二位...好吧,我剛剛在這里找到了。
所以我的最終查詢是:
SELECT * FROM (
(SELECT DISTINCT (status) AS Status, COUNT(status) AS Quantity,
IF(status='TER',SELECT * FROM projects WHERE year(updated_at)=YEAR(CURDATE()))
FROM projects
GROUP BY status
ORDER BY Quantity DESC)
UNION
(
SELECT DISTINCT (status) AS Status, COUNT(status) AS Quantity,
IF(status='TER',SELECT * FROM projects WHERE year(updated_at)=YEAR(CURDATE()))
FROM projects
WHERE year(updated_at) = YEAR(curdate())
AND status IN ('TER')
GROUP BY status
ORDER BY Quantity DESC
)
) a
GROUP BY status
ORDER BY Quantity DESC
現在,我得到了想要的結果並訂購了desc:
Status Quantity
'PRO', 238
'TER', 45
'SUS', 14
'REI', 3
還是有更好的出路?
根據對問題的編輯(現在可以更好地解釋預期的結果),我用其他查詢更新了此答案。 我仍然建議條件聚合 。
SELECT p.status AS Status
, COUNT( IF( p.status = 'TER'
, IF( YEAR(p.updated_at) = YEAR(CURDATE())
, 1
, NULL
)
, 1
)
) AS Quantity
FROM projects p
GROUP BY p.status
ORDER BY Quantity DESC
不需要換行和間隔...我只是這樣做,以使其更易於解密。
對於status = 'TER'
的行,僅當滿足updated_at
的條件時,該行才包含在“計數”中。 對於status
所有其他值,該行包含在該狀態的“ count”中。
MySQL特定的表達式:
IF( p.status = 'TER'
, IF( YEAR(p.updated_at) = YEAR(CURDATE())
, 1
, NULL
)
, 1
)
可以用更符合ANSI標准的表達式代替,例如:
CASE WHEN p.status = 'TER'
CASE WHEN YEAR(p.updated_at) = YEAR(CURDATE()
THEN 1
END
ELSE 1
END
原始答案
還不清楚您想要返回什么結果。
看起來您希望返回一個附加列,並且看起來您可能希望該列成為“數量”列中所包含行的子集的“計數”。 我們能做到這一點。
但是首先,讓我們解決原始查詢的一些問題。
關鍵字DISTINCT
是不必要的,它與GROUP BY
無關。 並且無需在引用status
旁注。 這樣做不是違法的,但是它什么也沒做,所以很混亂。 它看起來好像有人認為DISTINCT
是一個函數。 不是。 這是一個關鍵字,適用於整個SELECT
列表。
SELECT p.status AS Status
, COUNT(p.status) AS Quantity
FROM projects p
GROUP BY p.status
ORDER BY Quantity DESC
似乎您要進行條件匯總...如果updated_at
是當前年份中的日期或日期時間,則將其包括在計數中,否則不包括在內。
SELECT p.status AS Status
, COUNT(p.status) AS Quantity
, SUM(IF(p.status = 'TER' AND YEAR(p.updated_at)=YEAR(CURDATE()),1,NULL)) AS curcnt
FROM projects p
GROUP BY p.status
ORDER BY Quantity DESC
表達方式:
IF(p.status = 'TER' AND YEAR(p.updated_at)=YEAR(CURDATE()),1,NULL)
是MySQL的簡寫。 使用更符合ANSI標准的表達式可以獲得等效的結果:
CASE WHEN p.status = 'TER' AND YEAR(p.updated_at)=YEAR(CURDATE()) THEN 1 END
根據您希望在該行和其他行上顯示“零”計數的方式,您可能希望使用0
代替NULL
和/或使用包含其他IF
, IFNULL
或NULLIF
函數的表達式。
跟進
這個問題尚不清楚所需的結果集。
上面的答案基於這樣的假設:期望的結果是另外一列,其中包含當年內具有status='TER'
和updated_at
的行的“計數”。
上面的答案演示了條件聚合 ,並且沒有使用“嵌套查詢”。
“嵌套查詢”可用於獲取等效結果。
作為使用“嵌套查詢”作為內聯視圖的示例:
SELECT p.status AS Status
, COUNT(p.status) AS Quantity
, NULLIF(MAX(q.curcnt),0) AS curcnt
FROM projects p
LEFT
JOIN ( SELECT r.status
, COUNT(1) AS curcnt
FROM projects r
WHERE r.status = 'TER'
AND YEAR(r.updated_at) = YEAR(NOW())
GROUP BY r.status
) q
ON q.status = p.status
GROUP BY p.status
ORDER BY Quantity DESC
並以“嵌套查詢”作為SELECT列表中的子查詢的示例:
SELECT p.status AS Status
, COUNT(p.status) AS Quantity
, NULLIF( SELECT COUNT(1)
FROM projects r
WHERE r.status = p.status
AND r.status = 'TER'
AND YEAR(r.updated_at) = YEAR(NOW())
,0) AS curcnt
FROM projects p
GROUP BY p.status
ORDER BY Quantity DESC
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.