使用非重复计数时SQL SQLERE语句语法错误

时间:2014-12-19 11:09:55

标签: sql sql-server-2008

我有一个WHERE条款,从逻辑上讲,我希望它能够在短名称的第一个数字不匹配的情况下恢复结果。

短名称可以是:

1.1
1.2
2.1
2.2

没有where子句的示例数据:

+-----------+--------+------+
| Shortname | number |  ID  |
+-----------+--------+------+
| 2.1       |      1 | 3333 |
| 1.1       |     60 | 3333 |
| 1.2       |     90 | 3333 |
| 2.1       |     50 | 4444 |
| 2.2       |     30 | 4444 |
| 1.1       |     80 | 5555 |
| 1.2       |     10 | 5555 |
+-----------+--------+------+

带有where子句的预期数据:

+-----------+--------+------+
| Shortname | number |  ID  |
+-----------+--------+------+
| 2.1       |      1 | 3333 |
| 1.1       |     60 | 3333 |
| 1.2       |     90 | 3333 |
+-----------+--------+------+

我尝试了代码:

SELECT shortname, number, id
FROM table
WHERE ((left(shortname,1) like '%1%') != ((left(shortname,1) like '%2%')

但它会产生错误:

  

Msg 102,Level 15,State 1,Line 21
  '!'附近的语法不正确。

澄清更新

我需要每个ID的结果,所以在上面的示例中有ID 3333,4444和5555.我想只返回ID 3333,因为它没有唯一的第一个字符值每个shortname。它包含值12

我不希望看到其他ID,因为短名称在第一个数字1 = 1和2 = 2等匹配。

4 个答案:

答案 0 :(得分:10)

如果您想要返回IDshortname多个第一个字符的select id from yourtable group by id having count(distinct left(shortname, 1)) > 1; ,那么请先查看获得明确的行数:

;with cte as
(
  select id
  from yourtable
  group by id
  having count(distinct left(shortname, 1)) > 1
)
select 
  t.shortname,
  t.number, 
  t.id
from yourtable t
inner join cte c
  on t.id = c.id;

当与ID关联时,这应该返回具有2和1作为第一个字符的行。然后,您可以使用它来返回其余数据:

| SHORTNAME | NUMBER |   ID |
|-----------|--------|------|
|       2.1 |      1 | 3333 |
|       1.1 |     60 | 3333 |
|       1.2 |     90 | 3333 |

SQL Fiddle with Demo。这将返回:

LEFT

更灵活的选项是获取小数点前的字符,并验证您是否具有所有数字的明确计数。为此,您将使用CHARINDEX等函数以及;with cte as ( select id from yourtable group by id having count(distinct left(shortname, charindex('.', shortname)-1)) > 1 ) select t.shortname, t.number, t.id from yourtable t inner join cte c on t.id = c.id;

| SHORTNAME | NUMBER |   ID |
|-----------|--------|------|
|       2.1 |      1 | 3333 |
|       1.1 |     60 | 3333 |
|       1.2 |     90 | 3333 |
|      14.1 |      5 | 6666 |
|      14.2 |     78 | 6666 |
|      24.1 |     89 | 6666 |

SQL Fiddle with Demo。这将返回:

{{1}}

答案 1 :(得分:2)

你正在比较两个条件!你可能想做这样的事情:

SELECT shortname, number, id
FROM table
WHERE ((left(shortname,1) like '%1%') OR ((left(shortname,1) like '%2%')))

无论如何你的问题:

SELECT shortname, number, id
FROM (
SELECT shortname, number, id, (SELECT COUNT(*)
                               FROM table AS TI
                               WHERE LEFT(ShortName, 1) = RIGHT(ShortName, 1)
                                 AND TI.ID = T.ID) AS C
FROM table AS T) AS TT

在哪里C = 0

但这也遗漏了ID 3333,因为它有一个短名称= 1.1。

答案 2 :(得分:2)

怎么样:

SQL Fiddle

MS SQL Server 2008架构设置

CREATE TABLE Sample
(
  Shortname VARCHAR(10),
  number tinyint,
  Id int)

INSERT INTO Sample
VALUES
   ('2.1', 1, 3333),
   ('1.1', 60, 3333),
   ('1.2', 90, 3333),
   ('2.1', 50, 4444),
   ('2.2', 30, 4444),
   ('1.1', 80, 5555),
   ('1.2', 10, 5555)

查询1

SELECT shortname, number, id
FROM [Sample] t1
WHERE EXISTS (
   SELECT * 
   FROM [Sample] t2 
   WHERE t1.id = t2.id and LEFT(t1.shortname,1) <> LEFT(t2.shortname,1))

<强> Results

| SHORTNAME | NUMBER |   ID |
|-----------|--------|------|
|       2.1 |      1 | 3333 |
|       1.1 |     60 | 3333 |
|       1.2 |     90 | 3333 |

答案 3 :(得分:-2)

请检查select查询

应该是这样的

SELECT shortname, number, id
FROM table
WHERE ((left(shortname,1) like '%1%') <> ((left(shortname,1) like '%2%')))

您错过了关闭 ))括号。