使用join检索匹配的行

时间:2013-10-15 07:10:42

标签: sql sql-server tsql sql-server-2005

这是我的问题的简化版本。

我有如下表格

Id   Name       SNumber
100  XYZ        123
100  XYZ        123
101  ABC        123
103  QAZ        123
100  XYZ        971
100  XYZ        872
100  XYZ        659
102  PQR        145
102  PQR        707
103  QAZ        421

我想计算具有Snumber为“123”的行,即列和具有Snumber的行不是'123',即 otherTotal

Id   Name       Total   OtherTotal
100  XYZ        2           3
101  ABC        1           0
102  PQR        0           2
103  QAZ        1           1

我正在做的是使用连接

Select xx.*,otherTotal
From
    ( Select Id,Name,count(*) as Total 
      From  table
      Where Snumber like '123'
      Group By id,name
     )xx

Inner join

     ( Select Id,Name,count(*) as otherTotal
      From  table
      Where Snumber not like '123'
      Group By id,name
     )yy

On xx.Id=yy.Id

但如果特定Id同时Snumber123而不是123

,则此广告只会返回行

返回的数据如下所示

Id   Name       Total   OtherTotal
100  XYZ        2           3
103  QAZ        1           1

现在没有保证特定身份证总是将Snumber设为123,所以我不能使用Left或Right join。如何解决这个泥潭? Giggity

3 个答案:

答案 0 :(得分:4)

试试这个:

SELECT id, name,
  COUNT(CASE WHEN SNumber = 123 THEN 1 END) Total,
  COUNT(CASE WHEN SNumber <> 123 THEN 1 END) OtherTotal
FROM t
GROUP BY id, name
ORDER BY id

小提琴here

答案 1 :(得分:3)

select
    Id, Name,
    sum(case when SNumber = 123 then 1 else 0 end) as Total,
    sum(case when SNumber <> 123 then 1 else 0 end) as OtherTotal
from Table1
group by Id, Name
order by Id

select
    Id, Name,
    count(*) - count(nullif(SNumber, 123)) as Total,
    count(nullif(SNumber, 123)) as OtherTotal
from Table1
group by Id, Name
order by Id

<强> sql fiddle demo

答案 2 :(得分:1)

尝试这个。

DECLARE @TABLE TABLE (ID INT,   NAME VARCHAR(40), SNUMBER INT)
INSERT INTO @TABLE
VALUES 
(100  ,'XYZ',        123),
(100  ,'XYZ',        123),
(101  ,'ABC',        123),
(103  ,'QAZ',        123),
(100  ,'XYZ',        971),
(100  ,'XYZ',        872),
(100  ,'XYZ',        659),
(102  ,'PQR',        145),
(102  ,'PQR',        707),
(103  ,'QAZ',        421)

SELECT 
    ID, 
    NAME, 
    (
        SELECT 
            COUNT(SNUMBER) FROM @TABLE B
        WHERE 
            SNUMBER = '123' AND A.ID = B.ID
    ) AS TOTAL,
    (
        SELECT 
            COUNT(SNUMBER) FROM @TABLE B
        WHERE 
            SNUMBER <> '123' AND A.ID = B.ID
    ) AS OTHERTOTAL
FROM 
    @TABLE A
GROUP BY ID, NAME