2010-08-07 32 views
2

問題定義。如何在DBIx :: Class :: ResultSet上執行此搜索和order_by

我有多個用戶的多個客戶端。每個客戶端都需要能夠將自定義數據與用戶相關聯,搜索和排序。


數據庫解決方案:

甲表Customfields限定customfields表。它有一個id和名字。 它與Userfields表(又名「屬性」)具有has_many關係。

Userfields表具有用戶標識,customfieldid,內容和標識。 它belongs_to的一個Useraccounts表(又名 「useraccount」)和Customfields(又名 「的CustomField」)


提出,我想選擇語句:

這是實現和生產什麼select語句我需要。

SELECT ua.*, (
    SELECT content FROM Userfields uf 
    INNER JOIN Customfields cf 
     ON cf.id = uf.customfieldid 
    WHERE cf.name = 'Mothers birthdate' 
    AND uf.uid=ua.uid 
) AS 'Mothers birthdate', 
    (
    SELECT content FROM Userfields uf 
    INNER JOIN Customfields cf 
     ON cf.id = uf.customfieldid 
    WHERE cf.name = 'Join Date' AND 
    uf.uid=ua.uid 
) AS 'Join Date' 
FROM UserAccounts ua 
ORDER BY 'Mothers birthdate'; 

在這種情況下,它們可能是從0什麼...在SELECT語句×副SELECT語句和它們中的任何一個,或者都不可以希望被訂購。


問題

如何實現這一目標用 - >我dbix類的ResultSet或者我如何實現與我dbix類的ResultSet搜索結果相同的搜索?

下面是我通常如何從我的Useraccounts表中選擇,但我不確定如何從這裏執行復雜的語句。

my @users = $db->resultset('Useraccounts')->search(
    undef, 
    { 
     page  => $page, 
     join  => 'attributes', 
     ... 
    }); 

謝謝你的時間。

-pdh

+0

我太累了,不想回答這個問題,但是男人,我必須給你一些道具來編寫這樣一個寫得很好的問題! – 2010-08-07 09:13:04

+0

乾杯JGB;希望它會鼓勵一個很好的答案:) – 2010-08-07 09:22:32

回答

2

這是真的很漂亮毛茸茸的,任何解決方案不會是漂亮,但它確實如果你通融一點一下就可以了。原諒我犯的任何錯誤,因爲我沒有去創建一個模式來測試它,但它基於我擁有的最好的信息(以及來自ribasushi的很多幫助)。

首先,(假設你的userfields表具有與customfields表belongs_to的關係,稱爲customfield

my $mbd = $userfields_rs->search(
    { 
     'customfield.name' => 'Mothers birthdate', 
     'uf.uid' => \'me.uid' # reference to outer query 
    }, 
    { 
     join => 'customfield', 
     alias => 'uf', # don't shadow the 'me' alias here. 
    } 
)->get_column('content')->as_query; 

# Subqueries and -as don't currently mix, so hack the SQL ourselves 
$mbd->[0] .= q{ AS 'Mothers Birthdate'}; 

是uf.uid正在對匹配的文字me.uid是一個未綁定變量 - 這是uid字段來自我們最終要將此查詢作爲子查詢的查詢。默認情況下,DBIC將查詢所針對的表別名爲me;如果你給它一個不同的別名,那麼你會在這裏使用不同的東西。 無論如何,只要改變字段名稱(如果你聰明的話,你會寫一個方法來生成它們),並將它們放在一個數組中,就可以重複這個業務。現在讓我們假設@field_queries是一個數組,包含上面的$mbd以及另一個基於Join Date的數組,以及任何您喜歡的數據。

一旦你的,它是「簡單」爲...

my $users = $useraccounts_rs->search(
    { }, # any search criteria can go in here, 
    { 
     '+select' => [ @field_queries ], 
     '+as' => [qw/mothers_birthdate join_date/], # this is not SQL AS 
     order_by => {asc => 'Mothers birthdate'}, 
    } 
); 

,其中將包括每個子查詢到選擇的。

現在的傷心部分:截至目前,這整個事情實際上將不會工作,因爲帶佔位符的子查詢不能正常工作。所以現在你需要一個額外的解決方法:在子選擇搜索中,而不是'customfield.name' => 'Mothers birthdate',做'customfield.name' => \q{'Mothers birthdate'} - 這是使用字面名稱字段SQL(BE注意SQL注入這裏!!),這將回避佔位符錯誤。但在不久的將來,該錯誤將得到解決,上面的代碼將正常工作,我們將更新答案,讓您知道是這種情況。

+0

非常感謝Hobbs(和Ribasushi):)。 在這麼短的時間裏,這比我所希望的要多:D。很榮幸給你:) – 2010-08-07 11:46:05

+0

兩點。 1) - > get_column('content') - > as_query;返回一個對數組引用的引用,而不是對數組的引用,這可能是我當前dbix :: class中的一個錯誤,但是我看不到更改日誌中提到的任何修復,文檔似乎表明這是預期的行爲!我解決了這個問題 $ {userfields_rs-> search(...)} 2)我解決了佔位符問題,在我的搜索中加入了 'bind'=> $ mbd - > [1] 。 在今天早上玩了很多遊戲後,它的所有功能:) – 2010-08-09 13:19:23

+0

輕微的問題,如果我調用 - >對結果集進行分頁,我無法獲取 - > total_entries,它看起來像抓住它不需要的佔位符,將它們追加到最後,這會導致錯誤。現在用eval來解決這個問題,但這很醜陋。 – 2010-08-12 14:58:53

相關問題