Yii關聯表的查詢和排序

2021-10-11 18:32:41 字數 4754 閱讀 5430

通過中間表,關聯多對多關係(via),實現一對一關聯

關聯一對多(hasmony)

操作步驟

要能排序

step3: 解決joinwith一對多關係之後分頁錯誤

end參考

環境:yii2.0

在做使用者列表展示的時候,需要展示子表的一些字段,並可以根據子表的字段進行排序,進行查詢。並且,關聯的多個表,其中乙個表(使用者標籤)是一對多的關係。

下面摘出具有代表性的關係表做一下說明,實際使用過程中多個一對一關係不做多次說明。

表模型:memberinfo

主鍵是memberinfo_id, 外來鍵有memberinfo_account(別問我為什麼不用id做主鍵,以前系統的設計就是如此)

目的:獲取使用者消費統計資料

使用者消費統計表:stat_member_consume

表模型:memberinfoconsume

關係是一對一stat_member_consume表的stat_member_consume_memberinfo_id=memberinfo表的memberinfo_id

關聯**:

memberinfo.php:

//使用者消費資訊

public

function

getmemberinfoconsume()

目的:獲取使用者會員卡的等級

會員卡資訊存在card表,使用者和會員卡的關係存在了memberinfo_card表。想要直接獲取card_level需要通過中間表關聯一下

會員卡表:card表

表字段是:

card_id 主鍵id

tag_name 會員卡名稱

card_level 會員卡等級

使用者會員卡表:memberinfo_card

三者之間的關係是

memberinfo表

memberinfo_card表

card表

memberinfo_account

memberinfo_card_memberinfo_account

memberinfo_card_card_id

card_id

關聯**:

memberinfo.php:

//關聯中間表使用者會員卡

public

function

getmemberinfocard()

//使用via

public

function

getcard()

已經了解via()viatable()的讀者可以跳過下面這一小節。

via和viatable

官方說明:

△ 官方截圖

via() 和 viatable() 之間的區別是前者是根據現有的關聯名稱來指定連線表,而後者直接使用 連線表

目的:獲取使用者所有的標籤

標籤表tag,模型:tag

中間關係表:memeber_tag,模型:membertag,用於存放使用者和標籤的關係

三者之間的關係是

memberinfo表

memeber_tag表

tag表

memberinfo_account

member_tag_member_account

member_tag_tag_id

tag_id

關聯**:

memberinfo.php:

//使用者標籤

public

function

getmemberinfotags()

關聯**已經在上一章說明了。

關鍵是後面步驟

為什麼要有這一步?是因為子表的排序暫時沒有發現用memberconsume.stat_member_consume_order_sum傳值進行排序的方式。前端呼叫介面的時候,通過傳sort引數來實現介面排序,用太長的名字也不太好。

於是,要使排序的**可用,需要把這些需要排序和搜尋的子表字段新增到主表的物件裡

你可以直接在searchmodel裡新增

public

$stat_member_consume_order_sum

不過更建議使用內建的函式去新增。

由於memberinfosearch 繼承了 memberinfo ,所以可以通過繼承attributes()方法新增字段

memberinfosearch.php:

public

function

attributes()

在memberinfosearch中新增關聯查詢

memberinfosearch.php

public

function

search

($params

,$isverify

=null

)

在membersearch中新增過濾搜尋

仍然是search()方法中

memberinfosearch.php:

1

//在**裡面照著隊形新增這一句即可

3$query

->

andfilterwhere([

'like'

,'tag_name'

,$this

->

tag_name])

;

這裡發現和 yii關聯欄位並帶搜尋排序功能 這篇教程中不一樣的地方是,搜尋的欄位名不需要加關聯表的名字,直接用已經加過的關聯欄位名就可以成功。

上面**只是乙個例子,使用中根據你需要搜尋的子表字段進行新增即可,多乙個搜尋,就多加一條andfilterwhere

我在使用中發現如果要搜陣列,比如stat_member_consume_order_sum的搜尋傳到後台是以$stat_member_consume_order_sum[0]$stat_member_consume_order_sum[1]的方式,這時不傳 andfilterwhere 會報錯,所以在外面多加了個判斷字段是否為陣列。

p.s. andfilterwhere() 可以在有值的時候進行搜尋過濾,沒有值的時候忽略這個where條件

繼續在search()方法中修改,activedataprovider類的sort屬性

memberinfosearch.php:

$dataprovider

=new

activedataprovider([

'query'

=>

$query

,//排序**在這裡

'sort'

=>

['attributes'

=>

['stat_member_consume_order_sum'

,'stat_member_consume_order_money_amount'

,'stat_member_consume_last_order_datetime'

,'finance_award'

,'card_level']]]);

也可以在例項化activedataprovider之後,用setsort()新增。

至此,前端傳sort引數(對應』sort』裡的名字)就可以進行排序啦

原本到上面2步就可以解決了,但是在列表顯示的時候發現分頁不對,明明指定了一頁顯示10條資料,可是第一頁只出來了4條,甚至有時候是3條、5條不等。

原因是yii 的joinwith,當出現一對多的時候,會出現這個問題。

在網上搜尋過後,有網友推薦 用with()代替joinwith(),不是不可以,我發現把一對多關係單獨用with之後,分頁錯亂確實解決了。

例子中的一對多關係是memberinfotags

$query

->

with([

'memberinfotags'])

;

但是引發另乙個問題,因為介面需求中,需要用標籤搜尋,用with()之後,搜尋memberinfotags裡的字段就失效了。

嘗試解決:仍然使用joinwith(),然後->distinct(memberinfo_id)

然後yii報了乙個錯,大意是要把orderby的字段加到select裡,於是,加->addselect([把sort欄位都加進來])。需要注意的是,addselect()之前一定要有select()才行

如有疑問或者更好的解決方案,歡迎和我溝通

yii2中gridview多表關聯顯示並可查詢

yii關聯欄位並帶搜尋排序功能

Yii關聯表字段查詢

yii的activerecord model裡有乙個search方法,可以用來搜尋 資料,但是今天在搜尋時,發現會用關聯表的字段來搜尋資料,查詢資料,找到了解決方法 比如article表與user表有關聯,需要在本表中用user.nickname欄位來搜尋資料 在model裡先定義乙個搜尋字段 pu...

關聯表查詢

1 imemoryrelationshipclassfactory fac mapcontext.createobject esrigeodatabase.memoryrelationshipclassfactory as imemoryrelationshipclassfactory irelat...

yii資料表關聯操作

首先在model中進行表關聯 public function relations 在增加和修改的頁面用下面的 來表示 textfield model s addon telephone array name hactiveform name model,addon telephone pattern...