仅当满足两个条件时,才在单个sql语句中选择两行

时间:2015-01-13 10:07:16

标签: php mysql sql database multiple-conditions

我有一张包含以下数据的表格。

  

表名:myTable

prodID   catNo   variable1  variable2
1        20      Cat        Blue
2        10      Cat        Red
2        15      Cat        Green
2        20      Cat        Black
3        20      Cat        Yellow
4        10      Cat        Orange
4        15      Cat        Brown
4        20      Cat        Black
5        30      Cat        Pink

我希望能够从myTable中选择以下内容的所有列:"( prodID = 2 catNo = 10 ) AND( prodID = 2 catNo = 15 )"。因此,只有在满足两个条件时才获得两行的结果,并且如果两行都不存在则不返回任何结果。 所以我的结果表将如下所示。

  

表名:结果

prodID   catNo   variable1  variable2
2        10      Cat        Red
2        15      Cat        Green

我尝试使用条件if语句,但似乎无法让它们在sql中运行。我目前的解决方案是使用prodID = 2返回所有行,然后使用php执行if语句来决定要显示的内容,但这不会影响我设计用于显示结果的分页作为我的limit会扭曲每页的结果数。 我知道我可以使用'计数行= 2'但我不确定如何说出来。

9 个答案:

答案 0 :(得分:3)

如果你想在catNo(10,15)中找到记录时得到结果,但如果你在(10,12)中寻找catNo,那么也要返回0结果

SELECT * FROM `myTable` 
WHERE (`prodID` = 2 AND `catNo` IN (10,15)) 
AND (SELECT COUNT(`catNo`) FROM `myTable` WHERE `prodID` = 2 AND `catNo` IN (10,15))>1;

对于三个CatNo&#39>

SELECT * FROM `myTable` 
WHERE (`prodID` = 4 AND `catNo` IN (10,15,20)) 
AND (SELECT COUNT(`catNo`) FROM `myTable` WHERE `prodID` = 4 AND `catNo` IN (10,15,20))>2;

SQL Fiddle

答案 1 :(得分:2)

要匹配同一产品的两个类别,您可以这样做

select t.*
from table1 t
join (
select prodID
from table1
where catNo in (10,15)
and prodID = 2
group by prodID
having count(distinct catNo ) = 2
  ) t2
using(prodID)
where t.catNo in (10,15)

DEMO

答案 2 :(得分:1)

使用以下SQL查询。

SELECT * FROM myTable where prodID = 2 and (catNo = 10 OR catNo = 15)

希望这有助于你

答案 3 :(得分:1)

试试这个会起作用:

SELECT * FROM `myTable` WHERE `prodID` = '2' AND `catNo` IN ('10','15')

答案 4 :(得分:0)

条件应为(prodID = 2且catNo = 10)或(prodID = 2且catNo = 15)

答案 5 :(得分:0)

 SELECT DISTINCT a.*,b.catNo,c.catNo FROM myTable AS a
 JOIN mytable AS b ON b.prodID=a.prodID
 JOIN mytable AS c ON c.prodID=a.prodID
 WHERE a.prodID=2 AND b.catNo=10
 AND c.catNo=15;
这个有用了。这个问题非常棘手。

答案 6 :(得分:0)

发布的大多数解决方案都缺少关于什么都不返回的部分,除非满足条件。因此,如果满足一个且只有一个条件,大多数解决方案将失败,因为它们仍将返回一行而不是一行。

假设您希望能够检查任何数量的WHERE条件,而不仅仅是两个,您可以使用基于子查询的解决方案。

使用此方法,您可以在输出之前检查结果集中的合格行数。有几种方法可以做到这一点,但想法是将符合条件的行数与预期的行数进行比较。如果匹配,则输出行。如果它们不匹配,则返回空结果集。

M Khalid Junaid已经发布了一个使用组的解决方案,其中包含子查询中的条件,以检查结果集大小是否为2.此解决方案适用于您的特定示例以及其他类似示例。如果您的WHERE条件变得更复杂或变化,可能不会因为它依赖于每个WHERE条件中的ProdID相同,但是主体是声音。此外,这种特殊方法要求对源表处理WHERE条件两次,而下面的一次仅执行一次。对于非常大的表和/或许多WHERE条件,此方法应该更有效。

您可以像在其他示例中一样直接在FROM条件中构建子查询,也可以通过WITH语句构造子查询。我在这里使用了后者,因为它更清楚地显示了正在发生的事情:

With ResultSet as (select * from myTable
        where (prodID = 2 AND catNo = 10) OR (prodID = 2 AND catNo = 15)), -- your WHERE condition
    TotalRows as (select COUNT(*) as TRows from ResultSet) -- count of result set
select ResultSet.*
from ResultSet
    inner join TotalRows on 1=1 -- force the join to work no matter what the tables contain
where TRows = 2 -- this is where you check against how many result rows you expect

" ResultSet"子查询是WHERE原因所在的位置,它可以根据需要简单或复杂。 " TotalRows"计算结果集,因此只包含一行。然后,您可以将子查询连接在一起,但如果结果集计数(TRows)与之后的预期行大小匹配,则只输出前者的行。

答案 7 :(得分:0)

您可以尝试编写一个函数。它很长但很容易理解

DROP FUNCTION getIt();
CREATE OR REPLACE FUNCTION getIt()
RETURNS TABLE (prodID INTEGER, catNo INTEGER, variable1 TEXT, variable2 TEXT) AS
$BODY$
BEGIN
  IF (CAST ((SELECT "prodID" 
     FROM "myTable" 
     where "prodID"=2 and "catNo" = 10) AS INTEGER)>0 AND CAST ((SELECT "prodID" 
     FROM "myTable" 
     where "prodID"=2 and "catNo" = 15) AS INTEGER)>0)
  THEN RETURN QUERY SELECT * 
     FROM "myTable" 
     where "prodID"=2 and ("catNo" = 10 or "catNo" = 15 );
  END IF;
END;
$BODY$ 
LANGUAGE 'plpgsql';
SELECT * FROM getIt();

可以参数化

DROP FUNCTION getIt(pid integer, cid1 integer, cid2 integer);
CREATE OR REPLACE FUNCTION getIt(pid integer, cid1 integer, cid2 integer)
RETURNS TABLE (prodID INTEGER, catNo INTEGER, variable1 TEXT, variable2 TEXT) AS
$BODY$
BEGIN
  IF (CAST ((SELECT "prodID" 
     FROM "myTable" 
     where "prodID"=$1 and "catNo" = $2) AS INTEGER)>0 AND CAST ((SELECT "prodID" 
     FROM "myTable" 
     where "prodID"=$1 and "catNo" = $3) AS INTEGER)>0)
  THEN RETURN QUERY SELECT * 
     FROM "myTable" 
     where "prodID"=$1 and ("catNo" = $2 or "catNo" = $3 );
  END IF;
END;
$BODY$ 
LANGUAGE 'plpgsql';
SELECT * FROM getIt(2, 10, 15);

答案 8 :(得分:-1)

谢谢你M Khalid Junaid's answer的作品。我设法提出了一个不需要加入的解决方案,像我这样的非常大的桌子将会很慢:

select * 
from myTable 
where ((prodID = 2 and catNo = 10) or (prodID = 2 and catNo = 15)) 
group by catNo
having (
        select count(distinct(catNo))
        from myTable 
        where ((prodID = 2 and catNo = 10) or (prodID = 2 and catNo = 15))
)=2;