簡體   English   中英

(Doctrine ORM)如何通過多對一關系訂購SELECT

[英](Doctrine ORM) How to order SELECT by many-to-one relationship

我有一個包含類型類別的數據庫(以及其他不相關的東西)。 類型類別具有多對一關系。 我想要的是選擇所有類型的行,首先按類別名稱排序,然后按類型權重排序,最后按類型名稱排序(全部升序)。 關鍵部分是我希望所有具有相同類別的類型在結果中組合在一起。 作為我的SQL新手,我認為一個簡單的連接語句后跟適當的語句順序就足夠了。 我錯了。 我得到的結果對我來說毫無意義。

實際結果(類型名稱 - 類別名稱):

  1. 飛機着陸支柱 - 飛機
  2. Aicraft轉子葉片 - 飛機
  3. 飛機機翼 - 飛機
  4. 自行車車架 - 騎行周期
  5. 船弓 - 船只
  6. 船貨船甲板 - 船只
  7. 博爾德底部 - 岩石
  8. 博爾德頂部 - 岩石
  9. 鞠躬元素 - 其他
  10. 磚1x1瓦特/果汁紙盒打印 - 磚打印
  11. 磚1x1瓦特/牛奶紙箱打印 - 磚打印
  12. 洗車刷架 - 其他
  13. [等等。]

預期結果(類型名稱 - 類別名稱):

  1. 飛機着陸支柱 - 飛機
  2. Aicraft轉子葉片 - 飛機
  3. 飛機機翼 - 飛機
  4. 磚1x1瓦特/果汁紙盒打印 - 磚打印
  5. 磚1x1瓦特/牛奶紙箱打印 - 磚打印
  6. 鞠躬元素 - 其他
  7. 洗車刷架 - 其他
  8. 自行車車架 - 騎行周期
  9. 博爾德底部 - 岩石
  10. 博爾德頂部 - 岩石
  11. 船弓 - 船只
  12. 船貨船甲板 - 船只
  13. [等等。]

有超過2,000種類型的行,因此上面的列表顯然是非常截斷的。 沒有錯誤。 對結果進行分頁(一直運行良好)可能也很重要。

我正在使用Doctrine 2.5.x和我自己的內容管理系統。 在類型實體的存儲庫中,我使用QueryBuilder構建查詢,如下所示(最大結果是全局設置,第一個結果是根據當前頁碼在存儲庫外部計算的):

$qb = $this->createQueryBuilder('t');

$qb->select('t, c'); // omitting this does not change the result
$qb->join('t.category', 'c');
$qb->addOrderBy('c.name', 'ASC'); // this does not work as expected
$qb->addOrderBy('t.weight', 'ASC');
$qb->addOrderBy('t.name', 'ASC');
$qb->setMaxResults(20);
$qb->setFirstResult(0);

return $qb->getQuery()->getResult();

生成的SQL語句如下:

SELECT b0_.ID AS ID_0, b0_.weight AS weight_1, b0_.name AS name_2, b0_.number AS number_3, b0_.name_alt AS name_alt_4, b0_.note AS note_5, b1_.ID AS ID_12, b1_.slug AS slug_13, b1_.name AS name_14, b1_.`desc` AS desc_15, b0_.cat_id AS cat_id_16 FROM types b0_ INNER JOIN categories b1_ ON b0_.cat_id = b1_.ID ORDER BY b1_.name ASC, b0_.weight ASC, b0_.name ASC LIMIT 20 OFFSET 0

類型實體設置如下(省略了不相關的字段):

/**
 * @Entity(repositoryClass="Nevermind\Repository\TypeRepository")
 * @Table(name="types", options={"collate"="utf8mb4_unicode_ci", "charset"="utf8mb4"})
 */
class Type {

    /**
     * @Id
     * @Column(type="integer", name="ID")
     * @GeneratedValue
     */
    protected $id;

    /**
     * @ManyToOne(targetEntity="Category", inversedBy="types", fetch="EAGER")
     * @JoinColumn(name="cat_id", referencedColumnName="ID")
     */
    protected $category;

    /**
     * @Column(type="integer")
     */
    protected $weight = 0;

    /**
     * @Column(type="string", unique=true)
     */
    protected $name = '';

    /**
     * @Column(type="string", unique=true, length=12)
     */
    protected $number = '';

    /**
     * @Column(type="string", nullable=true)
     */
    protected $name_alt;

    /**
     * @Column(type="text", nullable=true)
     */
    protected $note;

}

類別實體設置如下:

/**
 * @Entity(repositoryClass="Nevermind\Repository\DefaultRepository")
 * @Table(name="categories", options={"collate"="utf8mb4_unicode_ci", "charset"="utf8mb4"})
 */
class Category {

    /**
     * @Id
     * @Column(type="integer", name="ID")
     * @GeneratedValue
     */
    protected $id;

    /**
     * @Column(type="string", unique=true)
     */
    protected $slug = '';

    /**
     * @Column(type="string", nullable=true)
     */
    protected $name;

    /**
     * @Column(type="text", name="`desc`", nullable=true)
     */
    protected $desc;

    /**
     * @OneToMany(targetEntity="Type", mappedBy="category", fetch="EXTRA_LAZY", cascade={"persist", "remove"})
     * @OrderBy({"weight"="ASC", "name"="ASC"})
     */
    protected $types;

}

TypeRepository擴展了DefaultRepository ,它擴展了Doctrine的EntityRepository

結果的奇怪排序是由於類別name列有時為null (當顯示時名稱會回落到slug列的轉換內容,這是我完全忘記的更改)。 因此,只需將第一個order-by語句更改為c.slug解決問題。 D'哦!

所以請記住,按列排序可能為空將導致奇怪的結果!

你有沒有嘗試過

$qb->select('t, c');
...
$qb->orderBy('c.name', 'ASC'); // orderBy not addOrderBy for the first clause
$qb->addOrderBy('t.weight', 'ASC');
$qb->addOrderBy('t.name', 'ASC');
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM