【已解決】PHP項目需求:用戶購買商品時,給上級發送一條通知(無限級下級會員)

無限級的過程mysql

上下級會員關係經過id和pid肯定。sql

例如:a>b>c>d>e>f>g...數組

就是a的下級是b,b的下級是c,c的下級是d....(有點相似傳*銷模式?無視掉)函數

需求,經過用戶g查出全部的上級,則要查到f.e.d.c.b.a這些用戶idthis

方可給這些上級發送通知。設計

咱們最重要的是取出上級id而後就好辦多了。code

首先說明幾個值,user_id 爲用戶表中的用戶id,parent_id爲表中用戶的上級id。字符串

示例一條基本的查詢父級idSQL。get

SELECT parent_id FROM cx_user WHERE user_id = 10;##查詢user_id爲10的上級idstring

不說廢話了,直接進入中心。

打開MySQL開始寫存儲過程。

DROP PROCEDURE IF EXISTS `getpid`;

CREATE DEFINER = `root`@`localhost` PROCEDURE `getpid`(IN `id` int)
BEGIN
SET @pid:=id;#id爲查詢的參數 即當前用戶id
SET @pidarr:=','; #查詢到的上級數組字符串
recursion:WHILE @pid!=0 DO
  SELECT parent_id INTO @pid from cx_users WHERE user_id = @pid;#這裏是你查詢的SQL語句 @pid是動態id
      IF @pid=0 THEN #到0即結束
         LEAVE recursion;
      END IF;
      set @substr = concat(",",@pid);
      set @substr = concat(@substr,',');
      IF LOCATE(@substr ,@pidarr)>0 THEN #防止出現上下級關係混亂
         LEAVE recursion;
      END IF;
  set @pidarr = concat(@pidarr,@pid);
  set @pidarr = concat(@pidarr,',');	
END WHILE recursion;
SELECT @pidarr AS pidarr;
END;

存儲過程執行結果,拿圖嚇唬嚇唬你。

PHP端demo

$sql = "CALL getpid(104);";
$pidstr = mysql_query($sql);//換成你項目中執行MySQL的函數便可 而後取出 pidarr的值到$pidstr
$pidstr = rtrim($pidstr,',');//剔除最右側多餘英文逗號
$pidstr = ltrim($pidstr,',');//剔除最左側多餘英文逗號
$pidarr = explode(',',$pidstr);//到數組
//如下隨意 
#ncSJI$@CO3N#@329090*(@@()$u)@j(@(h(@jn9NCD9823N892

#################### 增長指定層級查詢

首先增長一個字符串查找函數

DROP FUNCTION IF EXISTS `substr_count`;
CREATE DEFINER = `root`@`%` FUNCTION `substr_count`(`pstring` varchar(255),`substring` varchar(255))
 RETURNS int(11)
BEGIN
 SELECT  (LENGTH(pstring) - LENGTH(REPLACE(pstring,substring, ""))) / LENGTH(substring) AS "count" into @ret ;
	RETURN @ret;
END;

修改以前的getpid存儲過程

BEGIN
SET @pid:=id;
SET @pidarr:=',';/* this return pid */
recursion:WHILE @pid!=0 DO
  SELECT parent_id INTO @pid from cx_users WHERE user_id = @pid;
			IF @pid=0 THEN #到0即結束
				LEAVE recursion;
			END IF;
				set @substr = concat(",",@pid);
				set @substr = concat(@substr,',');
			IF LOCATE(@substr,@pidarr)>0 THEN #防止出現上下級關係混亂
         LEAVE recursion;
      END IF;
  set @pidarr = concat(@pidarr,@pid);
  set @pidarr = concat(@pidarr,',');
	#LEVEL 增長的層級判斷
	IF substr_count(@pidarr,',')>=level+1 THEN
            set @pid=0;
            LEAVE recursion;
	END IF;
END WHILE recursion;
SELECT @pidarr AS pidarr;
END

調用SQL

CALL getpid(104,2);//獲取用戶id爲104的上級 層級2級  即獲取兩層上級

 

補充:

在某些MySQL版本中,在某些表的設計中,使用如上過程,出現相似如下報錯。

Result consisted of more than one row

面對這個能夠增長一個臨時交換ID或者是將SQL語句更改下,防止出現返回多個結果行。

SELECT parent_id INTO @pid from cx_users WHERE user_id = @pid LIMIT 1;

今天羣遇到一個網友,使用以上過程,就是查詢不出來數據,結果是NULL,研究好久才發現他的表項設計中出現容許爲NULL的字段,在過程執行中,直接跳過pid=0的判斷,進入concat(",",@pid);的語句,而此時的@pid 是null ,導致合併後的字符串也出現了NULL,更影響告終果@pidarr的數據。

在此,通常只須要將這種關係表設計的更標準些,如NOT NULL DEFAULT '0',或者在過程當中增長額外的判斷NULL、''(EmptyString)的條件讓他跳出WHILE也能夠獲得解決。

相關文章
相關標籤/搜索