Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL中非规范化表的查询_Mysql_Arrays - Fatal编程技术网

MySQL中非规范化表的查询

MySQL中非规范化表的查询,mysql,arrays,Mysql,Arrays,我有一组数组和一个mysql表,表1 $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 | 1

我有一组数组和一个mysql表,表1

$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
我完全同意-你真的应该考虑你的模式:

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

:

:

有点好玩

把你的桌子换成这样

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       |
+-------+----------+
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
然后可以像这样使用SQL:-

TempTable
+-------+----------+
| arrno | arrvalue | 
+-------+----------+
| arr1  | A0       |
| arr1  | A1       |
| arr1  | A2       |
| arr1  | A3       |
| arr1  | A4       |
| arr2  | B0       |
| arr2  | B1       |
| arr2  | B2       |
| arr2  | B3       |
| arr2  | B4       |
+-------+----------+
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的列。值为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中的子选择,而不是直接使用该表。

不太可能,可能需要一些非常糟糕的编码。我建议将这两个数组的内容放入一个临时表中,每个数组元素一行,这样这两个数组就意味着10行,然后使用like将临时表与现有表连接起来。不过,它的表现将非常糟糕。正确的解决方案需要重新设计您的表以摆脱分号分隔的列表,将它们放在各自的表中,每个元素一行,以便您可以轻松地在表之间联接。@Kickstart,谢谢,将尝试重新设计我的表修改我的答案,可能有助于您将数据提取到重新设计的表中。不确定这是否违反SO中的规则,但我更新了原始帖子中的所需输出。。。我研究了我们现有的表,但由于一些页面已经依赖于当前的模式,因此无法很容易地正常化。。更改它需要我们另一次时间来检查现有页面。我遵循了eggyal的解决方案,但是我仍然停留在如何从Col3中获取与令牌发现数量相关的值上。谢谢,我尝试在1个查询中提取我需要的所有内容时失败了
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
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 <> ''