0

我正在尝试编写一个查询,例如

if (select count(*) from Users where fkId=5000 and status='r') =
   (select count(*) from Users where fkId=5000) then ..

一个查询中。

这意味着,如果所有具有 fkId=5000 的行status=r,那么做一些事情。

可以有任意数量的行fkId=5000,并且这些行的任何部分都可以有status=r, status=k,status=lstatus=a。我对所有行fkId=5000 status=r(而不是任何其他状态)的情况感兴趣。

我现在的做法是

how many rows with id=5000 and status = 'r'?
how many rows with id=5000?
are those numbers equal? then ..

我试图弄清楚如何仅使用 1 个查询而不是 2 个来重写此查询。关键字ALL似乎无法编写这样的查询(<> ALL相当于NOT IN)。我尝试了几种GROUP BY配方,但无法获得正确的结果。

4

5 回答 5

3

最有效的方法是:

if not exists (select 1
               from users
               where fkid = 5000 and (status <> 'r' or status is null)
              )

这将在第一个不匹配的行停止查询。

于 2013-06-08T16:09:50.373 回答
2

我建议您检查任何状态不等于“r”的行

     SELECT count(*)>0 FROM Users WHERE fkId = 5000 AND status != 'r'
于 2013-06-08T15:59:44.377 回答
0

除了NOT EXISTS版本 - 这应该是最有效的,因为它根本不计算并且一旦找到与条件不匹配的值就退出,还有另一种方法,如果status不可为空并且将是如果有索引,则有效(fkId, status)

IF EXISTS 
   ( SELECT 1 
     FROM Users 
     WHERE fkId = 5000 
     HAVING MIN(status) = 'r' 
        AND MAX(status) = 'r'
   ) 

不过有一个区别。如果根本没有行,上面将显示 false fkId=5000,而NOT EXISTS版本将显示 true - 无论如何这可能是您想要的。

于 2013-06-08T21:08:47.997 回答
0

在以下情况下,如果数字1是“真”(它是),那么你会Yes回来,如果不是,你会No回来:

SELECT IF(1, 'Yes', 'No') AS yesorno

(来吧——试试吧!)

但是,在您的情况下,以下内容会更合适:

SELECT IF (
   (SELECT COUNT(*) FROM Users WHERE fkId=5000 AND status IN('r') AND status NOT IN('1', 'a', 'k')) = (SELECT COUNT(*) FROM Users WHERE fkId=5000),
   'They are equal.',
   'They are not equal.'
)
AS are_they_equal

通过添加AS,您可以操纵返回给您的“列”的名称。

希望对您有所帮助...此外,如果您想了解更多信息,请参阅此页面。

:)

于 2013-06-08T19:03:38.920 回答
0

简单的!

只需加入同一张桌子。下面是完整的测试代码:

CREATE TABLE Users(id int NOT NULL AUTO_INCREMENT, fkID int NOT NULL,  status char(1), PRIMARY KEY (id));

INSERT Users (fkID, status) VALUES (5000, 'r');
INSERT Users (fkID, status) VALUES (5000, 'r');
INSERT Users (fkID, status) VALUES (5000, 'r');

-- The next query produces "0" to indicate no miss-matches
SELECT COUNT(*) FROM Users u1 LEFT JOIN Users u2 ON u1.id=u2.id AND u2.status='r' WHERE u1.fkID=5000 AND u2.id IS NULL;

-- now change one record to create a miss-match
UPDATE Users SET status='l' WHERE id=3 ;

-- The next query produces "1" to indicate 1 miss-match
SELECT COUNT(*) FROM Users u1 LEFT JOIN Users u2 ON u1.id=u2.id AND u2.status='r' WHERE u1.fkID=5000 AND u2.id IS NULL;

DROP TABLE Users;

因此,您需要在结果中测试它是否为 0(零),这意味着所有内容都有 fkID=5000 也有 status='r'

如果您正确索引您的表,那么连接回同一个表不是问题,并且肯定比必须进行第二次查询要好。

于 2013-06-08T20:24:41.970 回答