-1

私は次の一連の配列とmysqlテーブル、table1を持っています

$arr1 = ("A0","A1","A2","A3","A4")
$arr2 = ("B0","B1","B2","B3","B4")

+----+-----------------+------+------+
| id | Col1            | Col2 | Col3 |
+----+-----------------+------+------+
|  0 | A0;B1;B2;       | x    | 9    |
|  1 | A0;B1;B2;A1;A2; | x    | 15   |
|  2 | A0;             | x    | 7    |
|  3 | B0;             | x    | 5    |
|  4 | C0;             | j    | 5    |
+----+-----------------+------+------+

最終的な出力がこのようなものになるように、テーブルの値をクエリすることは可能ですか?

    +----+-------+------+
    | id |  C31T | C32T |
    +----+-------+------+
    |  0 |  19   |  17  |
    +----+-------+------+

C31TとC32Tはこの表から

    +----+------+------ +-------+------+------+
    | id | Arr1 | Arr2  |  C31  | C32  | tot  |
    +----+------+-------+-------+------+------+
    |  0 | 1    | 2     |  3    |  6   | 3    |
    |  1 | 3    | 2     |  9    |  6   | 5    |
    |  2 | 1    | 0     |  7    |  0   | 1    |
    |  3 | 0    | 1     |  0    |  5   | 1    |
    +----+------+-------+-------+------+------+

卵液に続いて、私はこの時点まで立ち往生しています

    SELECT   table1.id,
         COUNT(DISTINCT arr1.element) AS Arr1,
         COUNT(DISTINCT arr2.element) AS Arr2,
         COUNT(DISTINCT arr1.element) +
         COUNT(DISTINCT arr2.element) AS tot,
(COUNT(DISTINCT arr1.element)/(COUNT(DISTINCT arr1.element)+COUNT(DISTINCT arr2.element)))*col3 AS c31,
(COUNT(DISTINCT arr2.element)/(COUNT(DISTINCT arr1.element)+COUNT(DISTINCT arr2.element)))*col3 AS c32
FROM     table1
  LEFT JOIN (
    SELECT 'A0' AS element
    UNION ALL SELECT 'A1'
    UNION ALL SELECT 'A2'
    UNION ALL SELECT 'A3'
    UNION ALL SELECT 'A4'
  ) arr1 ON FIND_IN_SET(
    arr1.element,
    REPLACE(table1.Col1, ';', ',')
  )
  LEFT JOIN (
    SELECT 'B0' AS element
    UNION ALL SELECT 'B1'
    UNION ALL SELECT 'B2'
    UNION ALL SELECT 'B3'
    UNION ALL SELECT 'B4'
  ) arr2 ON FIND_IN_SET(
    arr2.element,
    REPLACE(table1.Col1, ';', ',')
  )
WHERE    table1.Col2 = 'x'
GROUP BY table1.id
4

2 に答える 2

1

ちょっとした遊び。

テーブルを次のように変更します

Table1
+----+------+------+
| id | Col2 | Col3 |
+----+------+------+
|  0 | x    | x    |
|  1 | x    | f    |
|  2 | x    | g    |
|  3 | x    | k    |
|  4 | j    | k    |
+----+------+------+

Table2
+----+----------+------+
| id | Table1id | Col1 |
+----+----------+------+
|  0 | 0        | A0   |
|  1 | 0        | B1   |
|  2 | 0        | B2   |
|  3 | 1        | A0   |
|  4 | 1        | B1   |
|  5 | 1        | B2   |
|  6 | 1        | A1   |
|  7 | 1        | A2   |
|  8 | 2        | A0   |
|  9 | 3        | B0   |
| 10 | 4        | C0   |
+----+-----------------+

次に、次のようなものを含むクエリの一時テーブルを作成します。-

TempTable
+-------+----------+
| arrno | arrvalue | 
+-------+----------+
| arr1  | A0       |
| arr1  | A1       |
| arr1  | A2       |
| arr1  | A3       |
| arr1  | A4       |
| arr2  | B0       |
| arr2  | B1       |
| arr2  | B2       |
| arr2  | B3       |
| arr2  | B4       |
+-------+----------+

その後、次のようにSQLを使用できます。-

SELECT table1.id, COUNT(TempTable1.arrvalue), COUNT(TempTable2.arrvalue), COUNT(*)
FROM table1
INNER JOIN table2
ON table1.id = table2.table1id
LEFT OUTER JOIN temptable TempTable1 ON table2.Col1 = TempTable1.arrvalue AND TempTable1.arrno = 'arr1'
LEFT OUTER JOIN temptable TempTable2 ON table2.Col1 = TempTable2.arrvalue AND TempTable2.arrno = 'arr2'
GROUP BY table1.id

少し遅れましたが、何か他のことをしていて、それもあなたに役立つかもしれないと思いました。

iと呼ばれる単一の列を持つ整数と呼ばれるテーブルを設定します。値が0〜9の10行。これを使用して、次のSQLを使用して単一のフィールドを分割できます。

SELECT DISTINCT id, SUBSTRING_INDEX(SUBSTRING_INDEX(Col1, ';', anInteger), ';', -1) AS Col1_split, Col2, Col3
FROM table1, 
(SELECT a.i*100+b.i*10+c.i AS anInteger FROM integers a, integers b, integers c) Sub1
HAVING Col1_split <> ''

これは、区切られたフィールドを別のテーブルにコピーするのに役立つ場合があります(または、必死になっている場合は、テーブルを直接使用するのではなく、独自のSQLで副選択として使用できます)。

于 2012-12-03T14:15:53.987 に答える
1

@Kickstartのコメントに完全に同意します。スキーマを正規化する必要があります。

CREATE TABLE associations (
  id      INT,
  element VARCHAR(2),
  FOREIGN KEY (id) REFERENCES table1 (id)
);

INSERT INTO associations
  (id, element)
VALUES
  (0, 'A0'), (0, 'B1'), (0, 'B2'),
  (1, 'A0'), (1, 'B1'), (1, 'B2'), (1, 'A1'), (1, 'A2'),
  (2, 'A0'),
  (3, 'B0'),
  (4, 'C0')
;

ALTER TABLE table1 DROP Col1;

次に、クエリは次のようになります。

SELECT   table1.id,
         COUNT(DISTINCT arr1.element) AS Arr1,
         COUNT(DISTINCT arr2.element) AS Arr2,
         COUNT(DISTINCT arr1.element) +
         COUNT(DISTINCT arr2.element) AS tot
FROM     table1 JOIN associations USING (id)
  LEFT JOIN (
    SELECT 'A0' AS element
    UNION ALL SELECT 'A1'
    UNION ALL SELECT 'A2'
    UNION ALL SELECT 'A3'
    UNION ALL SELECT 'A4'
  ) arr1 USING (element)
  LEFT JOIN (
    SELECT 'B0' AS element
    UNION ALL SELECT 'B1'
    UNION ALL SELECT 'B2'
    UNION ALL SELECT 'B3'
    UNION ALL SELECT 'B4'
  ) arr2 USING (element)
WHERE    table1.Col2 = 'x'
GROUP BY table1.id

結果

| | ID | ARR1 | ARR2 | トット |
--------------------------
| | 0 | 1 | 2 | 3 |
| | 1 | 3 | 2 | 5 |
| | 2 | 1 | 0 | 1 |
| | 3 | 0 | 1 | 1 |

そのような正規化されたスキーマがなければ、彼が言及した「非常に恐ろしいコーディング」は次のようになります。

SELECT   table1.id,
         COUNT(DISTINCT arr1.element) AS Arr1,
         COUNT(DISTINCT arr2.element) AS Arr2,
         COUNT(DISTINCT arr1.element) +
         COUNT(DISTINCT arr2.element) AS tot
FROM     table1
  LEFT JOIN (
    SELECT 'A0' AS element
    UNION ALL SELECT 'A1'
    UNION ALL SELECT 'A2'
    UNION ALL SELECT 'A3'
    UNION ALL SELECT 'A4'
  ) arr1 ON FIND_IN_SET(
    arr1.element,
    REPLACE(table1.Col1, ';', ',')
  )
  LEFT JOIN (
    SELECT 'B0' AS element
    UNION ALL SELECT 'B1'
    UNION ALL SELECT 'B2'
    UNION ALL SELECT 'B3'
    UNION ALL SELECT 'B4'
  ) arr2 ON FIND_IN_SET(
    arr2.element,
    REPLACE(table1.Col1, ';', ',')
  )
WHERE    table1.Col2 = 'x'
GROUP BY table1.id

結果

| | ID | ARR1 | ARR2 | トット |
--------------------------
| | 0 | 1 | 2 | 3 |
| | 1 | 3 | 2 | 5 |
| | 2 | 1 | 0 | 1 |
| | 3 | 0 | 1 | 1 |

アップデート

編集に続いて、この既存のクエリに対して外部クエリを実行するだけです。

SELECT SUM(Arr1/tot) AS C31T, SUM(Arr2/tot) AS C32T
FROM (

  SELECT   COUNT(DISTINCT arr1.element) * table1.Col3 AS Arr1,
           COUNT(DISTINCT arr2.element) * table1.Col3 AS Arr2,
           COUNT(DISTINCT arr1.element) +
           COUNT(DISTINCT arr2.element) AS tot
  FROM     table1
    LEFT JOIN (
      SELECT 'A0' AS element
      UNION ALL SELECT 'A1'
      UNION ALL SELECT 'A2'
      UNION ALL SELECT 'A3'
      UNION ALL SELECT 'A4'
    ) arr1 ON FIND_IN_SET(
      arr1.element,
      REPLACE(table1.Col1, ';', ',')
    )
    LEFT JOIN (
      SELECT 'B0' AS element
      UNION ALL SELECT 'B1'
      UNION ALL SELECT 'B2'
      UNION ALL SELECT 'B3'
      UNION ALL SELECT 'B4'
    ) arr2 ON FIND_IN_SET(
      arr2.element,
      REPLACE(table1.Col1, ';', ',')
    )
  WHERE    table1.Col2 = 'x'
  GROUP BY table1.id

) t

結果

| C31T | C32T |
---------------
|   19 |   17 |
于 2012-12-03T14:11:53.960 に答える