MySQL - 在多个列中选择多个值,其中所有匹配都有结果

时间:2013-12-03 23:30:37

标签: mysql sql

我正在尝试构建一个查询,允许我对特定条件的列对进行“过滤”。我需要能够为同一对给定构建多个过滤器。最终结果应仅返回具有应用所有过滤器的情况的数据的实例。

我构建了一个简单的例子,展示了我希望能够做到的事情。

使用以下表格定义:

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');

我想要一个返回以下内容的查询,因为您正在寻找'Header_1'=='a'和'header_2'=='b'的情况:

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

我目前的尝试如下:

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`;

该代码返回以下内容:

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

我错过了一条回程行。如何重构查询以返回所有匹配的行?

请注意,我将该表声明为临时表。这很重要,因为我正在使用临时表,并且它们有特殊的限制要记住(即无法在同一语句中多次打开它)。

3 个答案:

答案 0 :(得分:1)

您的查询仅返回header_1,因为该子句:

HAVING COUNT(DISTINCT `Index`) = 2

仅适用于Header_1。

Header_2的count = 1,因此从最终结果中删除。

为了更清楚地了解我所说的内容:

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`;

并查看最后一栏。

答案 1 :(得分:0)

我无法弄清楚如何只使用一个临时表。我对这个结果不满意,但至少它有效。

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`;

答案 2 :(得分:0)

怎么样......

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