簡體   English   中英

僅在滿足兩個條件的情況下,才在單個sql語句中選擇兩行

[英]Selecting two rows in a single sql statement only if both conditions are met

我有一張包含以下數據的表。

表名稱: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語句來決定要顯示的內容,但這不適用於我為顯示結果而設計的分頁,因為我的限制會扭曲每頁結果數。 我知道我可以使用“具有計數的行數= 2”,但是我不確定該如何措辭。

如果僅當在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

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

使用以下SQL查詢。

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

希望這對您有幫助

試試這個將起作用:

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

條件應為(prodID = 2且catNo = 10)或(prodID = 2且catNo = 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;

這個工作了。 這個問題真的很棘手。

發布的大多數解決方案都缺少關於什么都不返回的部分,除非兩者都滿足條件。 因此,大多數解決方案將僅在滿足一個條件的情況下失敗,因為它們仍將返回一行而不是無行。

假設您希望能夠檢查任意數量的WHERE條件,而不僅僅是兩個,那么您可以使用基於子查詢的解決方案。

使用這種方法,您可以在輸出之前檢查結果集中合格行的數量。 有幾種方法可以做到這一點,但其目的是將符合條件的行數與預期的行數進行比較。 如果它們匹配,則輸出行。 如果它們不匹配,則返回一個空結果集。

M Khalid Junaid發布了一個使用group by的解決方案,該解決方案在子查詢中具有條件,以檢查結果集大小是否為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)與您期望的后行大小匹配,則僅從前者輸出行。

您可以嘗試編寫一個函數。 很長,但很容易理解

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

謝謝M. Khalid Junaid的回答 我設法提出了一種不需要連接的解決方案,因為它的連接速度非常慢:

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;  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM