简体   繁体   English

MySQL-在所有符合结果的列中选择多个值

[英]MySQL - Select multiple values across multiple columns where all matches have a result

I am trying to construct a query that will allow me to "filter" on pairs of columns for particular criteria. 我正在尝试构造一个查询,该查询将允许我对特定条件的成对列进行“过滤”。 I need to be able to construct multiple filters for the same given pair. 我需要能够为同一给定对构造多个过滤器。 The end result should only return instances that have data for the case where all filters are applied. 最终结果应仅返回具有适用所有过滤器情况下的数据的实例。

I constructed a trivial example demonstrating what I would like to be able to do. 我构造了一个简单的示例,演示了我想做的事。

Using the follow table definition: 使用下表定义:

DROP TABLE IF EXISTS foo;

CREATE TEMPORARY TABLE `foo` (
  `ID` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `Index` INT UNSIGNED NOT NULL,
  `Header` VARCHAR(50) NOT NULL,
  `Value` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE INDEX `ID_UNIQUE` (`ID` ASC));

INSERT INTO `foo` (`Index`, `Header`, `Value`)
VALUES
    (0, 'Header_1', 'a'),
    (0, 'Header_2', 'b'),
    (1, 'Header_1', 'a'),
    (1, 'Header_2', 'c');

I would like a query that would return the following, given that you are looking for the case where 'Header_1' == 'a' and 'header_2' == 'b': 假设您正在寻找'Header_1'=='a'和'header_2'=='b'的情况,我希望查询返回以下内容:

Index | Header   | Value
------------------------
0     | Header_1 | a
0     | Header_2 | b

My current attempt is as follows: 我目前的尝试如下:

SELECT `Index`, `Header`, `Value` FROM `foo`
    WHERE (
            (`Header` = 'Header_1') AND (`Value` = 'a')
        OR (
            (`Header` = 'Header_2') AND (`Value` = 'b')
        )
    )
GROUP BY `Header`, `Value`
HAVING COUNT(DISTINCT `Index`) = 2
ORDER BY `Index`, `Header`;

That code returns the following: 该代码返回以下内容:

Index | Header   | Value
------------------------
0     | Header_1 | a

I am missing one of my return rows. 我缺少我的返回行之一。 How can I restructure the query to return all of the matching rows? 如何重组查询以返回所有匹配的行?

Note that I declared the table as a temporary table. 请注意,我已将该表声明为临时表。 This is important, as I am working with temporary tables, and they have special restrictions to keep in mind (namely not being able to open it more than once in the same statement). 这很重要,因为我正在使用临时表,并且要牢记一些特殊限制(即在同一条语句中不能多次打开它)。

Your query returns only header_1 because the clause: 您的查询仅返回header_1,因为该子句:

HAVING COUNT(DISTINCT `Index`) = 2

is only correct for Header_1. 仅对Header_1正确。

Header_2 has count=1, therefore removed from the end result. 标头_2的计数为= 1,因此已从最终结果中删除。

To get a clearer picture of what i say use: 为了更清楚地了解我所说的内容,请使用:

SELECT `Index`, `Header`, `Value`, COUNT(DISTINCT `Index`) FROM `foo`
    WHERE (
            (`Header` = 'Header_1') AND (`Value` = 'a')
        OR (
            (`Header` = 'Header_2') AND (`Value` = 'b')
        )
    )
GROUP BY `Header`, `Value`
ORDER BY `Index`, `Header`;

and take a look at the last column. 并查看最后一列。

I couldn't figure out how to do this with only the one temporary table. 我不知道如何仅使用一个临时表来执行此操作。 I'm not happy with this result, but at least it works. 我对这个结果不满意,但至少能奏效。

DROP TABLE IF EXISTS `foo2`;

CREATE TEMPORARY TABLE `foo2` (
    SELECT `Index` FROM `foo`
        WHERE (
            (`Header` = 'Header_1') AND (`Value` = 'a')
        OR (
            (`Header` = 'Header_2') AND (`Value` = 'b')
        )
    )
    GROUP BY `Index`
    HAVING COUNT(DISTINCT `Header`) = 2
);

SELECT DISTINCT t1.`Index`, t1.`Header`, t1.`Value` FROM `foo` t1
INNER JOIN `foo2` t2 ON t2.`Index` = t1.`Index`
ORDER BY t1.`Index`, t1.`Header`;

How about... 怎么样...

SELECT `index` 
  FROM foo 
 WHERE (header,value) IN (('header_1','a')) 
    OR (header,value) IN (('header_2','b')) 
 GROUP 
    BY `index` 
HAVING COUNT(*) = 2;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM