簡體   English   中英

MySQL查詢獲取一個表的行作為另一個表的列,列名來自第三張表

[英]Mysql query to get rows of a table as columns of another, with column names from third table

我要解決的真正問題是如何從WHMCS數據庫中獲取所有具有其自定義字段的客戶端。 我以為我可以在phpmyadmin中使用查詢,以便最終在csv中獲得結果。

數據庫方案結構的簡短說明: WHMCS,有兩個額外的表(tblCustomFields和tblCustomFieldsValues),以方便應用程序用戶創建的自定義字段。 對於創建的每個新的自定義字段,名稱及其ID都存儲在tblCustomFields中。 填寫客戶配置文件中的自定義字段時,該值與客戶的ID和字段名稱的ID存儲在tblCustomFieldsValues行中。

問題的簡化/通用版本

我將嘗試描述該問題的簡化通用版本,該版本可能適用於許多類似情況。

假設

我有三個表:

+----------------------------------------------------+
|                     tblClients                     |
+----------------------------------------------------+
| id | company   | standard_field1 | standard_field2 |
+----+-----------+-----------------+-----------------+
| 1  | A company | abc             | yz              |
+----+-----------+-----------------+-----------------+
| 2  | B company | xyz             | foo             |
+----+-----------+-----------------+-----------------+
| 3  | C company | zyx             | bar             |
+----+-----------+-----------------+-----------------+


+--------------------------+
|      tblCustomFields     |
+--------------------------+
| id | fieldname           |
+----+---------------------+
| 1  | Custom Field Name 1 |
+----+---------------------+
| 2  | Custom Field Name 2 |
+----+---------------------+
| 3  | Custom Field Name 3 |
+----+---------------------+

+----------------------------------------------------+
|                tblCustomFieldsValues               |
+----------------------------------------------------+
|      relid      |      fieldid       |    value    |
| (corresponds to |   (corresponds to  |             |
|   a client id)  | a custom field id) |             |
+-----------------+--------------------+-------------+
| 1               | 1                  | any value   |
+-----------------+--------------------+-------------+
| 1               | 2                  | some value  |
+-----------------+--------------------+-------------+
| 1               | 3                  | field value |
+-----------------+--------------------+-------------+
| 2               | 1                  | data        |
+-----------------+--------------------+-------------+
| 2               | 2                  | whatever    |
+-----------------+--------------------+-------------+
| 2               | 3                  | anything    |
+-----------------+--------------------+-------------+
| 3               | 1                  | and so on   |
+-----------------+--------------------+-------------+
| 3               | 2                  | and on      |
+-----------------+--------------------+-------------+

目的

我需要從數據庫導出到csv的所有客戶端的數據。 重要提示:每個客戶只能出現在一行中 預期結果應類似於以下內容:

+-----------------------------------------------------------------------------+
|       query result, clients with their custom fields as extra columns       |
+-----------------------------------------------------------------------------+
| id |  company  | standard | standard |  Custom   |   Custom   |   Custom    |
|    |           |  field1  |  field2  |   Field   |    Field   |    Field    |
|    |           |          |          |   Name 1  |   Name 2   |    Name 3   |
+----+-----------+----------+----------+-----------+------------+-------------+
| 1  | A company | abc      | yz       | any value | some value | field value |
+----+-----------+----------+----------+-----------+------------+-------------+
| 2  | B company | xyz      | foo      | data      | whatever   | anything    |
+----+-----------+----------+----------+-----------+------------+-------------+
| 3  | C company | zyx      | bar      | and so on | and on     |             |
+----+-----------+----------+----------+-----------+------------+-------------+

這個主意

我認為一種解決方案是在phpmyadmin中輸入查詢,然后輕松在csv中獲取結果。

最后一個問題

將所有客戶及其自定義字段放在單獨的列中的mysql查詢是什么? 有沒有更好的方法可以達到上述目標?

如果您對如何改寫標題或問題的任何部分有任何想法以使其更清晰,請發表評論!

select distinct *
from tblClients tc
join tblCustomFieldsValues tcfv on tcfv.client_id = tc.id
join tblCustomFields tcf on tcfv.custom_field_id = tcf.id

您可以使用Pivot獲得預期的輸出,但是由於Mysql不支持Pivot,因此必須使用case when子句。 SQL查詢如下:靜態SQL查詢:

Select TB.*, TC.`standard_field1`, TC.`standard_field2`
from tblClients TC
Inner Join(
SELECT TBD.Id, TBD.company,
  Max(CASE WHEN (TBD.fieldname ='Custom Field Name 1') THEN TBD.value ELSE NULL END) AS 'Custom Field Name 1',
  Max(CASE WHEN (TBD.fieldname ='Custom Field Name 2') THEN TBD.value ELSE NULL END) AS 'Custom Field Name 2',
  Max(CASE WHEN (TBD.fieldname ='Custom Field Name 3') THEN TBD.value ELSE NULL END) AS 'Custom Field Name 3'
FROM(
Select TC.Id, TC.Company,
  TCF.fieldname, TCFV.Value
  from tblCustomFieldsValues TCFV
  Inner Join tblClients TC
  ON TCFV.relid = TC.ID
  Inner Join tblCustomFields TCF
  ON TCFV.fieldid = TCF.Id) TBD

 Group BY TBD.Id, TBD.company) TB
 On TB.Id = TC.Id

我還提供了SQL小提琴鏈接,它將幫助您獲取完整的數據以及輸出。

動態SQl查詢:

SET @sql = NULL;
SELECT 
  GROUP_CONCAT(DISTINCT
               CONCAT('Max(CASE WHEN (TBD.fieldname =''', UN.fieldname,
                      ''') THEN TBD.value ELSE NULL END) AS ''',UN.fieldname,''''))
    INTO @sql
    FROM (
      Select * from tblCustomFields) UN;

SET @sql =  CONCAT('Select TB.*, TC.`standard_field1`, TC.`standard_field2`
                    from tblClients TC
                    Inner Join(SELECT TBD.Id, TBD.company, ', @sql, ' 
                      FROM(
                        Select TC.Id, TC.Company,
                          TCF.fieldname, TCFV.Value
                          from tblCustomFieldsValues TCFV
                          Inner Join tblClients TC
                          ON TCFV.relid = TC.ID
                          Inner Join tblCustomFields TCF
                          ON TCFV.fieldid = TCF.Id) TBD

                         Group BY TBD.Id, TBD.company) TB On TB.Id = TC.Id');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SQL小提琴鏈接

我希望這能幫到您。

暫無
暫無

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

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