选择不在子字符串中的唯一值

时间:2012-03-29 14:06:19

标签: sql sql-server tsql

由于某种原因,我无法绕过这个。我试图从多个列不同的表中获取ID ...基本上类似于 -

Select ID from table where ID in (Select distinct ID, Card, PunchTime, PunchDate)

虽然这显然不起作用。我想获得所有这些字段唯一的ID作为标准。我似乎无法提出有效的语法。我不确定我还能说些什么呢,看起来它看起来应该很简单...但是我从昨天起就一直在反弹,没有什么工作。谁知道我应该走哪条路?提前谢谢!

编辑:发布的内容有效,但结果不符合我的预期。这是一些saple数据:

ID  Card  PunchDate  PunchTime In/Out
================================
1  00123  3/17/2012  13:00  1
2  00123  3/17/2012  17:00  2
3  00123  3/17/2012  17:00  1
4  00123  3/17/2012  20:00  2
5  00456  3/17/2012  14:00  1
6  00456  3/17/2012  17:00  2

我试图这样做的原因是计时软件决定任何卡片,打卡和打卡时间与另一张相同的内容都是重复的,无论是打入还是打出并删除一个。我唯一的解决方案是消除重复,并基本上从第一次冲击到最后一次重复的冲击。所以我的目标是只选择基于卡片,打卡日期和打卡时间的唯一值。然而,我所拥有的并不是将ID排除在使其成为独特价值的事物中。我有一个解决方法,所以时间不是特别的问题,但我更愿意弄清楚如何获得正确的数据。

再次感谢大家的快速回复!

5 个答案:

答案 0 :(得分:2)

有新信息更新的答案:

SELECT *
FROM TABLE
WHERE NOT EXISTS
(
    SELECT 1 
    FROM TABLE AS Duplicates
    WHERE Duplicates.Card = TABLE.Card
        AND Duplicates.PunchDate = TABLE.PunchDate
        AND Duplicates.PunchTime = TABLE.PunchTime
        AND Duplicates.ID != TABLE.ID
)

基本上,这就是说,获取所有不具有相同card, punchdate, punchtime的记录(确保不对自己计算相同的行。)

答案 1 :(得分:2)

假设没有第二次转移,从一天开始,到下一次结束......

表格

DECLARE @table TABLE
    (
      [ID] INT IDENTITY,
      [Card] INT,
      [PunchDate] DATETIME,
      [PunchTime] DATETIME,
      [In/Out] TINYINT
    )
INSERT  INTO @table
        (
          [Card],
          [PunchDate],
          [PunchTime],
          [In/Out]
        )
        SELECT  00123,
                '3/17/2012',
                '3/17/2012 13:00',
                1
        UNION ALL
        SELECT  00123,
                '3/17/2012',
                '3/17/2012 17:00',
                2
        UNION ALL
        SELECT  00123,
                '3/17/2012',
                '3/17/2012 17:00',
                1
        UNION ALL
        SELECT  00123,
                '3/17/2012',
                '3/17/2012 20:00',
                2
        UNION ALL
        SELECT  00456,
                '3/17/2012',
                '3/17/2012 14:00',
                1
        UNION ALL
        SELECT  00456,
                '3/17/2012',
                '3/17/2012 17:00',
                2

查询:

SELECT  [Card],
        [PunchDate],
        MIN([PunchTime]) [PunchTime],
        [In/Out]
FROM    @table
WHERE   [In/Out] = 1
GROUP BY [Card],
        [PunchDate],
        [In/Out]
UNION
SELECT  [Card],
        [PunchDate],
        MAX([PunchTime]) [PunchTime],
        [In/Out]
FROM    @table
WHERE   [In/Out] = 2
GROUP BY [Card],
        [PunchDate],
        [In/Out]
ORDER BY [Card],
        [PunchDate]

<强>结果:

Card    PunchDate   PunchTime   In/Out
123 2012-03-17 00:00:00.000 2012-03-17 13:00:00.000 1
123 2012-03-17 00:00:00.000 2012-03-17 20:00:00.000 2
456 2012-03-17 00:00:00.000 2012-03-17 14:00:00.000 1
456 2012-03-17 00:00:00.000 2012-03-17 17:00:00.000 2

接下来他会想要这个:

SELECT  a.[Card],
        a.[PunchDate],
        a.[PunchTime],
        b.[PunchTime],
        DATEDIFF(hour, a.[PunchTime], b.[PunchTime]) TotalTime
FROM    (
          SELECT    [Card],
                    [PunchDate],
                    MIN([PunchTime]) [PunchTime]
          FROM      @table
          WHERE     [In/Out] = 1
          GROUP BY  [Card],
                    [PunchDate]
        ) a
        INNER JOIN (
                     SELECT [Card],
                            [PunchDate],
                            MAX([PunchTime]) [PunchTime]
                     FROM   @table
                     WHERE  [In/Out] = 2
                     GROUP BY [Card],
                            [PunchDate]
                   ) b
            ON a.[Card] = b.[Card]
               AND a.[PunchDate] = b.[PunchDate]
ORDER BY a.[Card],
        a.[PunchDate]

<强>结果

Card    PunchDate   PunchTime   PunchTime                   TotalTime
123 2012-03-17 00:00:00.000 2012-03-17 13:00:00.000 2012-03-17 20:00:00.000 7
456 2012-03-17 00:00:00.000 2012-03-17 14:00:00.000 2012-03-17 17:00:00.000 3

答案 2 :(得分:1)

Select
  *
FROM
  table
WHERE
  NOT EXISTS (
    SELECT
      *
    FROM
      table AS lookup
    WHERE
          ID       <> table.ID
      AND Card      = table.Card
      AND PunchTime = table.PunchTime
      AND PunchDate = table.PunchDate
  )

答案 3 :(得分:0)

Select ID 
from table 
where ID 
in 
(SELECT A.ID FROM (Select distinct ID, Card, PunchTime, PunchDate) A);

在你的查询中你写过..你应该在IN子句之外和IN子句中只有相同数量的列。如果您使用单个列,则不需要IN子句之外的任何括号,但如果您有多个列,则需要将它们包含在括号中。

Thumb规则:SELECT Col1,Col2 ..Coln FROM TABLE WHERE Col1 IN (SELECT Col1 FROM TABLE ...)(对于单列)

SELECT Col1,Col2 ..Coln FROM TABLE WHERE (Col1,Col2..Coln) IN (SELECT Col1,Col2..Coln FROM TABLE ...)(对于多列)

答案 4 :(得分:0)

Select ID from table where ID in (
select ID from (
   Select distinct ID, 
   Card, 
   PunchTime, 
   PunchDate
   FROM 
   OTHER_TABLE
   ) x
)

IN子句中只能有一列;因此,你需要别名(x - 在我的回答中)结果,然后从那里选择ID列。另请注意,在子选择内部,您需要指定从中选择额外列的表(请参阅我的答案中的CAPS)。