-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    |
    +----+------+-------+-------+------+------+

遵循eggyal解决方案,我坚持到了这一点

    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

我完全同意@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

结果

| 身份证 | 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

结果

| 身份证 | 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 回答
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

有点晚了,但正在做其他事情,并认为它也可能对您有所帮助。

设置一个名为 integers 的表,其中包含一个名为 i 的列。10 行,值为 0 到 9。然后,您可以使用以下 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 回答