仅当满足两个条件时才在单个 sql 语句中选择两行
Selecting two rows in a single sql statement only if both conditions are met
我有一个 table,其中包含以下数据。
table name: 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
我希望能够 select myTable 中满足以下条件的所有列
"(prodID = 2 and catNo = 10) AND (prodID = 2 and catNo = 15)”。因此,只有在满足两个条件的情况下才会得到两行的结果,如果两行都不存在,它将 return 什么都没有。
所以我的结果 table 将如下所示。
table name: results
prodID catNo variable1 variable2
2 10 Cat Red
2 15 Cat Green
我试过使用条件 if 语句,但似乎无法让它们在 sql 中工作。我目前的解决方案是取回 prodID = 2 的所有行,然后使用 php 执行 if 语句来决定显示什么,但这不适用于我为显示结果而设计的分页limit 会扭曲每页的结果数。
我知道我可以使用 'having count rows=2' 但我不确定如何表达它。
条件应该是 (prodID = 2 and catNo = 10) OR (prodID = 2 and catNo = 15)
如果您只想在 catNo (10,15) 中找到记录时获得结果,但如果您在 (10,12)
中查找 catNo 也想获得 return 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;
三个目录号
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 查询。
SELECT * FROM myTable where prodID = 2 and (catNo = 10 OR catNo = 15)
希望对您有所帮助
试试这个它会起作用:
SELECT * FROM `myTable` WHERE `prodID` = '2' AND `catNo` IN ('10','15')
要匹配同一产品的两个类别,您可以这样做
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)
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;
这个有效。这个问题真的很棘手。
谢谢作品。我设法想出了一个不需要连接的解决方案,它有一个非常大的 table 像我的那样会很慢:
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;
发布的大多数解决方案都缺少关于 return 什么都没有的部分,除非两个条件都满足。因此,如果满足一个且仅一个条件,大多数解决方案都会失败,因为它们仍然 return 一行而不是 none.
假设您希望能够检查任意数量的 WHERE 条件,而不仅仅是两个,您可以使用基于子查询的解决方案。
使用这种方法,您可以在输出之前检查结果集中符合条件的行数。有几种方法可以做到这一点,但我们的想法是将符合条件的行数与您预期的行数进行比较。如果它们匹配,则输出行。如果它们不匹配,return 一个空结果集。
M Khalid Junaid 发布了一个解决方案,该解决方案使用 group by 和子查询中的 having 条件来检查结果集大小是否为 2。此解决方案适用于您的特定示例和其他类似示例。如果您的 WHERE 条件变得更加复杂或变化,则可能不会,因为它依赖于 ProdID 在每个 WHERE 条件下都相同,但原则是合理的。此外,此特定方法要求针对源 table 处理 WHERE 条件两次,而下面的方法只处理一次。对于非常大的 tables and/or 许多 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) 与后面的预期行大小匹配,则只输出前者的行。
你可以尝试写一个函数。很长但很容易理解
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"= and "catNo" = ) AS INTEGER)>0 AND CAST ((SELECT "prodID"
FROM "myTable"
where "prodID"= and "catNo" = ) AS INTEGER)>0)
THEN RETURN QUERY SELECT *
FROM "myTable"
where "prodID"= and ("catNo" = or "catNo" = );
END IF;
END;
$BODY$
LANGUAGE 'plpgsql';
SELECT * FROM getIt(2, 10, 15);
我有一个 table,其中包含以下数据。
table name: 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
我希望能够 select myTable 中满足以下条件的所有列
"(prodID = 2 and catNo = 10) AND (prodID = 2 and catNo = 15)”。因此,只有在满足两个条件的情况下才会得到两行的结果,如果两行都不存在,它将 return 什么都没有。
所以我的结果 table 将如下所示。
table name: results
prodID catNo variable1 variable2
2 10 Cat Red
2 15 Cat Green
我试过使用条件 if 语句,但似乎无法让它们在 sql 中工作。我目前的解决方案是取回 prodID = 2 的所有行,然后使用 php 执行 if 语句来决定显示什么,但这不适用于我为显示结果而设计的分页limit 会扭曲每页的结果数。 我知道我可以使用 'having count rows=2' 但我不确定如何表达它。
条件应该是 (prodID = 2 and catNo = 10) OR (prodID = 2 and catNo = 15)
如果您只想在 catNo (10,15) 中找到记录时获得结果,但如果您在 (10,12)
中查找 catNo 也想获得 return 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;
三个目录号
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 查询。
SELECT * FROM myTable where prodID = 2 and (catNo = 10 OR catNo = 15)
希望对您有所帮助
试试这个它会起作用:
SELECT * FROM `myTable` WHERE `prodID` = '2' AND `catNo` IN ('10','15')
要匹配同一产品的两个类别,您可以这样做
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)
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;
这个有效。这个问题真的很棘手。
谢谢
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;
发布的大多数解决方案都缺少关于 return 什么都没有的部分,除非两个条件都满足。因此,如果满足一个且仅一个条件,大多数解决方案都会失败,因为它们仍然 return 一行而不是 none.
假设您希望能够检查任意数量的 WHERE 条件,而不仅仅是两个,您可以使用基于子查询的解决方案。
使用这种方法,您可以在输出之前检查结果集中符合条件的行数。有几种方法可以做到这一点,但我们的想法是将符合条件的行数与您预期的行数进行比较。如果它们匹配,则输出行。如果它们不匹配,return 一个空结果集。
M Khalid Junaid 发布了一个解决方案,该解决方案使用 group by 和子查询中的 having 条件来检查结果集大小是否为 2。此解决方案适用于您的特定示例和其他类似示例。如果您的 WHERE 条件变得更加复杂或变化,则可能不会,因为它依赖于 ProdID 在每个 WHERE 条件下都相同,但原则是合理的。此外,此特定方法要求针对源 table 处理 WHERE 条件两次,而下面的方法只处理一次。对于非常大的 tables and/or 许多 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) 与后面的预期行大小匹配,则只输出前者的行。
你可以尝试写一个函数。很长但很容易理解
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"= and "catNo" = ) AS INTEGER)>0 AND CAST ((SELECT "prodID"
FROM "myTable"
where "prodID"= and "catNo" = ) AS INTEGER)>0)
THEN RETURN QUERY SELECT *
FROM "myTable"
where "prodID"= and ("catNo" = or "catNo" = );
END IF;
END;
$BODY$
LANGUAGE 'plpgsql';
SELECT * FROM getIt(2, 10, 15);