我認為對此的簡短回答是否定的,但是是否可以在不支持 CTE 的資料庫中使用類似于表函式的東西來模擬遞回 CTE?例如:
-- get weekday names -- 'Monday', 'Tuesday', ...
WITH cte_numbers(n, weekday) AS (
SELECT
0,
DATENAME(DW, 0)
UNION ALL
SELECT
n 1,
DATENAME(DW, n 1)
FROM
cte_numbers
WHERE n < 6
)
SELECT
weekday FROM cte_numbers;
例如上面的模式是否可以重寫以在 Mysql5.7 中運行,或者不能在那里模擬遞回?
uj5u.com熱心網友回復:
沒有一個解決方案是非常有效的,而且大多數都涉及撰寫比你應該撰寫的更多的代碼。升級到 MySQL 8.0 會更好。
SQL 在集合上效果最好,而不是在迭代上。因此,在單個查詢中生成系列的標準方法是在臨時表中已經有一組行,并對其應用一些基于集合的操作。
例如:
SELECT 0 AS num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5;
-----
| num |
-----
| 0 |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
-----
以此為基礎,您可以進行日期運算,然后使用 DATE_FORMAT() 提取作業日名稱:
SELECT DATE_FORMAT(CURDATE() INTERVAL num DAY, '%W') AS weekday
FROM (
SELECT 0 AS num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5
) AS t;
-----------
| weekday |
-----------
| Friday |
| Saturday |
| Sunday |
| Monday |
| Tuesday |
| Wednesday |
-----------
您還可以準備一個固定的整數基表,根據需要填充它,并將其用于不同目的。
SELECT DATE_FORMAT(CURDATE() INTERVAL num DAY, '%W') AS weekday
FROM MySetOfIntegers
WHERE num BETWEEN 0 AND 5;
使用迭代方法的建議將涉及撰寫更多代碼。這也意味著 N 個 SQL 查詢,每個查詢都會生成一個單獨的結果集,因此您必須在應用程式中撰寫更多代碼來獲取所有結果集并將它們附加在一起。
您可以撰寫遞回存盤程序,但如果您允許深度遞回,則存在超出執行緒堆疊空間的風險。存盤程序遞回的默認限制為 0。也就是說,除非您設定有限限制,否則根本不允許遞回。見https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_max_sp_recursion_depth
下面是一個遞回存盤程序的示例:
DROP PROCEDURE IF EXISTS Weekdays;
DELIMITER //
CREATE PROCEDURE Weekdays(IN date DATE, IN num INT)
BEGIN
IF num >= 1 THEN
CALL Weekdays(date, num-1);
END IF;
SELECT DATE_FORMAT(date INTERVAL num-1 DAY, '%W') AS weekday;
END//
DELIMITER ;
并呼叫它。請注意,它會產生多個結果集。
mysql> set max_sp_recursion_depth=6;
mysql> call Weekdays(CURDATE(), 6);
----------
| weekday |
----------
| Thursday |
----------
1 row in set (0.00 sec)
---------
| weekday |
---------
| Friday |
---------
1 row in set (0.00 sec)
----------
| weekday |
----------
| Saturday |
----------
1 row in set (0.00 sec)
---------
| weekday |
---------
| Sunday |
---------
1 row in set (0.00 sec)
---------
| weekday |
---------
| Monday |
---------
1 row in set (0.00 sec)
---------
| weekday |
---------
| Tuesday |
---------
1 row in set (0.00 sec)
-----------
| weekday |
-----------
| Wednesday |
-----------
1 row in set (0.00 sec)
我可能在某個地方得到了遞回。這實際上支持了實作遞回例程并不像聽起來那么容易的觀點。
哦,如果你超過遞回限制,你會得到一個錯誤——而且沒有結果。
mysql> call Weekdays(CURDATE(), 8);
ERROR 1456 (HY000): Recursive limit 6 (as set by the max_sp_recursion_depth variable) was exceeded for routine Weekdays
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/489056.html
上一篇:我如何對1253進行遞回求和,得到1 2 5 3,即11,然后加起來得到2,直到我剩下的最后一個數字是Elixir中的一個數字?
